Skip to content
Snippets Groups Projects
Commit 991b71f4 authored by Theo's avatar Theo :troll:
Browse files

Finish bulk prototype and remove course option

parent 080d7ef1
No related branches found
No related tags found
No related merge requests found
...@@ -48,16 +48,16 @@ To create a user you can use: ...@@ -48,16 +48,16 @@ To create a user you can use:
the command needs some basic info to create a user. The baseline is this: the command needs some basic info to create a user. The baseline is this:
useradm user create -n "<User Full Name>" -g <User group> -c <User course> useradm user create -n "<User Full Name>" -g <User group>
but if we run something like but if we run something like
useradm user create -n "Joao da Silva" -g bcc -c bcc useradm user create -n "Joao da Silva" -g bcc
we will get an error. That is because the login generation needs the user GRR we will get an error. That is because the login generation needs the user GRR
for the default 'ini' login type. So this is now correct: for the default 'ini' login type. So this is now correct:
useradm user create -n "Joao da Silva" -g bcc -c bcc -t last useradm user create -n "Joao da Silva" -g bcc -t last
the auto generation will be explained in the section "Implementation" the auto generation will be explained in the section "Implementation"
...@@ -99,8 +99,6 @@ To reset a user's password you can do: ...@@ -99,8 +99,6 @@ To reset a user's password you can do:
with no flag a password will be auto-generated. Passing the flag -p you can with no flag a password will be auto-generated. Passing the flag -p you can
specify the new password. Passwords need to be good lol. specify the new password. Passwords need to be good lol.
Note: Check "Implementation" to learn about kadmin.local command
### Bulk ### Bulk
TODO :)))))) TODO :))))))
......
...@@ -14,9 +14,10 @@ new users, please do so with the bulk subcommand.`, ...@@ -14,9 +14,10 @@ new users, please do so with the bulk subcommand.`,
} }
func init() { func init() {
userCmd.AddCommand(user.CreateUserCmd)
userCmd.AddCommand(user.RemoveUserCmd)
userCmd.AddCommand(user.ModCmd) userCmd.AddCommand(user.ModCmd)
userCmd.AddCommand(user.ShowCmd) userCmd.AddCommand(user.ShowCmd)
userCmd.AddCommand(user.BulkCmd)
userCmd.AddCommand(user.ResetCmd) userCmd.AddCommand(user.ResetCmd)
userCmd.AddCommand(user.CreateCmd)
userCmd.AddCommand(user.RemoveCmd)
} }
package user
// TODO: PQ Q N FUNCIONA??????????????
import (
"fmt"
"os"
"strconv"
"github.com/spf13/cobra"
"gitlab.c3sl.ufpr.br/tss24/useradm/model"
)
var BulkCmd = &cobra.Command{
Use: "bulk",
Short: "Create a lot of similar users",
RunE: bulkCreate,
}
func init() {
BulkCmd.Flags().StringP("passwd", "p", "", "Base password, will generate <password>#[1..number]")
BulkCmd.Flags().StringP("login", "l", "", "Base login, will generate <login>[1..number]")
BulkCmd.Flags().StringP("expiry", "e", "_", "Accounts' expiry date (format dd.mm.yy)")
BulkCmd.Flags().StringP("resp", "r", "_", "Person responsible for the accounts")
BulkCmd.Flags().StringP("group", "g", "", "Base group of the accounts")
BulkCmd.Flags().IntP("number", "n", 0, "Number of accounts to be created")
BulkCmd.MarkFlagRequired("login")
BulkCmd.MarkFlagRequired("passwd")
BulkCmd.MarkFlagRequired("group")
BulkCmd.MarkFlagRequired("number")
}
func bulkCreate(cmd *cobra.Command, args []string) error {
var opts model.Opts
var users []model.User
users, err := getUsers()
if err != nil {
return err
}
err = opts.RetrieveOpts(cmd)
if err != nil {
return err
}
for i := 1; i <= opts.Number; i++ {
if loginExists(users, opts.UID+strconv.Itoa(i)) {
return fmt.Errorf("User found with login %v%v, won't overwrite", opts.UID, i)
}
}
err = validateGID(opts.GID)
if err != nil {
return err
}
base := model.User{
GRR: "_",
UID: opts.UID,
GID: opts.GID,
Name: "_",
Resp: opts.Resp,
Ltype: "_",
Shell: "/bin/bash",
Status: "Active",
Expiry: opts.Expiry,
Webdir: "_",
Password: opts.Passwd + "#",
}
base.Homedir, err = genDirPath("/home", base.GID, base.UID, "")
if err != nil {
return err
}
base.Nobackup, err = genDirPath("/nobackup", base.GID, base.UID, "")
if err != nil {
return err
}
i := 1
success := false
defer func() {
if !success {
fmt.Println("Error found, cleaning up...")
for ; i > 0; i-- {
istring := strconv.Itoa(i)
_ = delKerberosPrincipal(base.UID + istring)
_ = delUserLDAP(base.UID + istring)
_ = os.RemoveAll(base.Nobackup + istring)
_ = os.RemoveAll(base.Homedir + istring)
}
}
}()
for ; i <= opts.Number; i++ {
err := createTempUser(base, i)
if err != nil {
return err
}
}
success = true
return nil
}
func createTempUser(base model.User, num int) error {
var err error
var groups map[string]string
numstring := strconv.Itoa(num)
groups, err = getGroups()
if err != nil {
return err
}
// gen login
base.UID = base.UID + numstring
// gen dn
base.DN = "uid=" + base.UID + ",ou=usuarios,dc=c3local"
// no webdir for temps
// gen home path
base.Homedir = base.Homedir + numstring
// gen nobkp path
base.Nobackup = base.Nobackup + numstring
// gen password
base.Password = base.Password + numstring
// gen gecos
base.Gecos = genGecos(base)
// get group id
base.GIDNumber, err = findGIDNumber(groups, base.GID)
if err != nil {
return err
}
// gen newuid
base.UIDNumber, err = getNewUIDNumber()
if err != nil {
return err
}
fmt.Printf("Pronto para criar:\n%v\n\n", base.FullToString())
confirmationPrompt(false, "creation")
// create ldap
err = addUserLDAP(base)
if err != nil {
return err
}
// create kerberos
err = addKerberosPrincipal(base.UID)
if err != nil {
return err
}
// change pass
err = modKerberosPassword(base.UID, base.Password)
if err != nil {
return err
}
// create dirs
err = createUserDirs(base)
if err != nil {
return err
}
return nil
}
...@@ -23,7 +23,7 @@ const ( ...@@ -23,7 +23,7 @@ const (
MAX_UID = 6000 MAX_UID = 6000
) )
var CreateUserCmd = &cobra.Command{ var CreateCmd = &cobra.Command{
Use: "create", Use: "create",
Short: "Create new user", Short: "Create new user",
RunE: createUserFunc, RunE: createUserFunc,
...@@ -32,28 +32,25 @@ var CreateUserCmd = &cobra.Command{ ...@@ -32,28 +32,25 @@ var CreateUserCmd = &cobra.Command{
func init() { func init() {
// possible flags // possible flags
// FIXME: maybe leave less flags for user input // FIXME: maybe leave less flags for user input
CreateUserCmd.Flags().StringP("grr", "r", "_", "User GRR, required for ini type") CreateCmd.Flags().StringP("grr", "r", "_", "User GRR, required for ini type")
CreateUserCmd.Flags().StringP("type", "t", "ini", "Type of auto-generated login: ini, first or last") CreateCmd.Flags().StringP("type", "t", "ini", "Type of auto-generated login: ini, first or last")
CreateUserCmd.Flags().StringP("path", "w", "", "Full path to webdir, /home/html/inf/login if empty") CreateCmd.Flags().StringP("path", "w", "", "Full path to webdir, /home/html/inf/login if empty")
CreateUserCmd.Flags().StringP("name", "n", "_", "User full name, required, use quotes for spaces") CreateCmd.Flags().StringP("name", "n", "_", "User full name, required, use quotes for spaces")
CreateUserCmd.Flags().StringP("login", "l", "", "User login name, auto-generated if empty") CreateCmd.Flags().StringP("login", "l", "", "User login name, auto-generated if empty")
CreateUserCmd.Flags().StringP("group", "g", "", "User base group, required") CreateCmd.Flags().StringP("group", "g", "", "User base group, required")
CreateUserCmd.Flags().StringP("shell", "s", "/bin/bash", "Full path to shell") CreateCmd.Flags().StringP("shell", "s", "/bin/bash", "Full path to shell")
CreateUserCmd.Flags().StringP("homedir", "d", "", "Home directory path, /home/group/login if empty") CreateCmd.Flags().StringP("homedir", "d", "", "Home directory path, /home/group/login if empty")
CreateUserCmd.Flags().StringP("passwd", "p", "", "User password, auto-generated if empty") CreateCmd.Flags().StringP("passwd", "p", "", "User password, auto-generated if empty")
CreateUserCmd.Flags().StringP("status", "a", "Active", "User status, Active or Blocked") CreateCmd.Flags().StringP("status", "a", "Active", "User status, Active or Blocked")
CreateUserCmd.Flags().StringP("resp", "i", "_", "Person responsible for the account") CreateCmd.Flags().StringP("resp", "i", "_", "Person responsible for the account")
CreateUserCmd.Flags().StringP("expiry", "e", "_", "Expiry date in format dd.mm.yy") CreateCmd.Flags().StringP("expiry", "e", "_", "Expiry date in format dd.mm.yy")
CreateUserCmd.Flags().StringP("course", "c", "_", "User course/minicourse, even temp ones") CreateCmd.Flags().StringP("nobkp", "b", "", "User nobackup directory path")
CreateUserCmd.Flags().StringP("nobkp", "b", "", "User nobackup directory path")
// required flags // required flags
CreateUserCmd.MarkFlagRequired("name") CreateCmd.MarkFlagRequired("name")
CreateUserCmd.MarkFlagRequired("group") CreateCmd.MarkFlagRequired("group")
// made it required, may be overkill...
CreateUserCmd.MarkFlagRequired("course")
CreateUserCmd.Flags().BoolP("confirm", "y", false, "Skip confirmation prompt") CreateCmd.Flags().BoolP("confirm", "y", false, "Skip confirmation prompt")
} }
func createUserFunc(cmd *cobra.Command, args []string) error { func createUserFunc(cmd *cobra.Command, args []string) error {
...@@ -67,7 +64,7 @@ func createUserFunc(cmd *cobra.Command, args []string) error { ...@@ -67,7 +64,7 @@ func createUserFunc(cmd *cobra.Command, args []string) error {
defer func() { defer func() {
if !success { if !success {
_ = delKerberosPrincipal(usr.UID) _ = delKerberosPrincipal(usr.UID)
_ = delUserLDAP(usr) _ = delUserLDAP(usr.UID)
} }
}() }()
...@@ -173,28 +170,24 @@ func createNewUserModel(cmd *cobra.Command) (model.User, bool, error) { ...@@ -173,28 +170,24 @@ func createNewUserModel(cmd *cobra.Command) (model.User, bool, error) {
Shell: opts.Shell, Shell: opts.Shell,
Status: opts.Status, Status: opts.Status,
Expiry: opts.Expiry, Expiry: opts.Expiry,
Course: opts.Course,
Webdir: opts.Webdir, Webdir: opts.Webdir,
Homedir: opts.Homedir, Homedir: opts.Homedir,
Nobackup: opts.Nobkp, Nobackup: opts.Nobkp,
Password: ifThenElse(opts.Passwd != "", opts.Passwd, "[auto-generate]"), Password: ifThenElse(opts.Passwd != "", opts.Passwd, "[auto-generate]"),
} }
u = genGecos(u) u.Gecos = genGecos(u)
// get a new UIDNumber // get a new UIDNumber
newUIDNumber, err := getNewUIDNumber() u.UIDNumber, err = getNewUIDNumber()
if err != nil { if err != nil {
return u, false, fmt.Errorf("failed to generate new UIDNumber for user: %v", err) return u, false, fmt.Errorf("failed to generate new UIDNumber for user: %v", err)
} }
u.UIDNumber = newUIDNumber
// assign GIDNumber by traversing the groups // assign GIDNumber by traversing the groups
for key, val := range groups { u.GIDNumber, err = findGIDNumber(groups, u.GID)
if val == u.GID { if err != nil {
u.GIDNumber = key return u, false, err
break
}
} }
u.DN = "uid=" + u.UID + ",ou=usuarios,dc=c3local" u.DN = "uid=" + u.UID + ",ou=usuarios,dc=c3local"
...@@ -210,18 +203,16 @@ func genDirPath(base, group, login, input string) (string, error) { ...@@ -210,18 +203,16 @@ func genDirPath(base, group, login, input string) (string, error) {
return p, validatePath(p) return p, validatePath(p)
} }
func genGecos(u model.User) model.User { func genGecos(u model.User) string {
gecos := u.Name + "," gecos := u.Name + ","
gecos += u.GRR + "," gecos += u.GRR + ","
gecos += u.Resp + "," gecos += u.Resp + ","
gecos += u.Course + ","
gecos += u.Expiry + "," gecos += u.Expiry + ","
gecos += u.Status + "," gecos += u.Status + ","
gecos += u.Ltype + "," gecos += u.Ltype + ","
gecos += u.Webdir + "," gecos += u.Webdir + ","
gecos += u.Nobackup gecos += u.Nobackup
u.Gecos = gecos return gecos
return u
} }
type LoginType int type LoginType int
...@@ -328,6 +319,15 @@ func genUniqueUID(name, grr string, ltypeString string, users []model.User) (str ...@@ -328,6 +319,15 @@ func genUniqueUID(name, grr string, ltypeString string, users []model.User) (str
return uid, nil return uid, nil
} }
func findGIDNumber(groups map[string]string, GID string) (string, error) {
for key, val := range groups {
if val == GID {
return key, nil
}
}
return "", fmt.Errorf("Couldn't find group GIDNumber")
}
// queries to check if the alias exists // queries to check if the alias exists
func mailAliasExists(alias string) bool { func mailAliasExists(alias string) bool {
cmd := exec.Command("/usr/sbin/postalias", "-q", alias, MAIL_ALIAS_FILE) cmd := exec.Command("/usr/sbin/postalias", "-q", alias, MAIL_ALIAS_FILE)
...@@ -482,6 +482,11 @@ func createHome(u model.User, homeDir string) error { ...@@ -482,6 +482,11 @@ func createHome(u model.User, homeDir string) error {
func createWeb(u model.User) error { func createWeb(u model.User) error {
success := false success := false
if u.Webdir == "_" {
success = true
return nil
}
perm := DEF_PERMISSION perm := DEF_PERMISSION
if u.Status == "Blocked" { if u.Status == "Blocked" {
perm = BLK_PERMISSION perm = BLK_PERMISSION
......
...@@ -19,7 +19,6 @@ type cfg struct { ...@@ -19,7 +19,6 @@ type cfg struct {
Group string `yaml:"Group"` Group string `yaml:"Group"`
Status string `yaml:"Status"` Status string `yaml:"Status"`
Shell string `yaml:"Shell"` Shell string `yaml:"Shell"`
Course string `yaml:"Course"`
Resp string `yaml:"Resp"` Resp string `yaml:"Resp"`
Expiry string `yaml:"Expiry"` Expiry string `yaml:"Expiry"`
} }
...@@ -37,25 +36,17 @@ func init() { ...@@ -37,25 +36,17 @@ func init() {
} }
func modifyUserFunc(cmd *cobra.Command, args []string) error { func modifyUserFunc(cmd *cobra.Command, args []string) error {
var users []model.User
var opts model.Opts var opts model.Opts
users, err := getUsers()
if err != nil {
return err
}
err = opts.RetrieveOpts(cmd) err := opts.RetrieveOpts(cmd)
if err != nil { if err != nil {
return err return err
} }
login := args[0] curr, err := locateUser(args[0])
res := searchUser(users, false, true, login, "", "", "", "", "") if err != nil {
if len(res) != 1 {
err = fmt.Errorf("More than one user found")
return err return err
} }
curr := res[0]
state := cfg{ state := cfg{
Name: curr.Name, Name: curr.Name,
...@@ -63,7 +54,6 @@ func modifyUserFunc(cmd *cobra.Command, args []string) error { ...@@ -63,7 +54,6 @@ func modifyUserFunc(cmd *cobra.Command, args []string) error {
Group: curr.GID, Group: curr.GID,
Status: curr.Status, Status: curr.Status,
Shell: curr.Shell, Shell: curr.Shell,
Course: curr.Course,
Resp: curr.Resp, Resp: curr.Resp,
Expiry: curr.Expiry, Expiry: curr.Expiry,
} }
...@@ -177,7 +167,7 @@ func genRequest(curr model.User, changes cfg) (*ldap.ModifyRequest, error) { ...@@ -177,7 +167,7 @@ func genRequest(curr model.User, changes cfg) (*ldap.ModifyRequest, error) {
changed := applyChangesToUser(curr, changes) changed := applyChangesToUser(curr, changes)
changed = genGecos(changed) changed.Gecos = genGecos(changed)
// changed gecos // changed gecos
if curr.Gecos != changed.Gecos { if curr.Gecos != changed.Gecos {
...@@ -194,7 +184,6 @@ func applyChangesToUser(c model.User, n cfg) model.User { ...@@ -194,7 +184,6 @@ func applyChangesToUser(c model.User, n cfg) model.User {
c.Resp = n.Resp c.Resp = n.Resp
c.Shell = n.Shell c.Shell = n.Shell
c.Status = n.Status c.Status = n.Status
c.Course = n.Course
c.Expiry = n.Expiry c.Expiry = n.Expiry
return c return c
} }
......
...@@ -21,7 +21,7 @@ var ( ...@@ -21,7 +21,7 @@ var (
WEB_TRASH = "/home/contas_removidas/html/" + ANO WEB_TRASH = "/home/contas_removidas/html/" + ANO
) )
var RemoveUserCmd = &cobra.Command{ var RemoveCmd = &cobra.Command{
Use: "remove [username]", Use: "remove [username]",
Short: "Delete a user", Short: "Delete a user",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
...@@ -29,7 +29,7 @@ var RemoveUserCmd = &cobra.Command{ ...@@ -29,7 +29,7 @@ var RemoveUserCmd = &cobra.Command{
} }
func init() { func init() {
RemoveUserCmd.Flags().BoolP("confirm", "y", false, "Skip confirmation prompt") RemoveCmd.Flags().BoolP("confirm", "y", false, "Skip confirmation prompt")
} }
func removeUserFunc(cmd *cobra.Command, args []string) error { func removeUserFunc(cmd *cobra.Command, args []string) error {
...@@ -68,7 +68,7 @@ func removeUserFunc(cmd *cobra.Command, args []string) error { ...@@ -68,7 +68,7 @@ func removeUserFunc(cmd *cobra.Command, args []string) error {
return err return err
} }
err = delUserLDAP(u) err = delUserLDAP(u.UID)
if err != nil { if err != nil {
return err return err
} }
...@@ -91,7 +91,7 @@ func locateUser(login string) (model.User, error) { ...@@ -91,7 +91,7 @@ func locateUser(login string) (model.User, error) {
filter := searchUser(users, false, true, login, "", "", "", "", "") filter := searchUser(users, false, true, login, "", "", "", "", "")
if len(filter) != 1 { if len(filter) != 1 {
return u, fmt.Errorf(`More than one user matched the login given. return u, fmt.Errorf(`More than one user matched the login given.
search made: "useradm user show -l %v"`, login) search made: "useradm user show -l %v -e"`, login)
} }
u = filter[0] u = filter[0]
...@@ -118,7 +118,7 @@ func removeDirs(u model.User) error { ...@@ -118,7 +118,7 @@ func removeDirs(u model.User) error {
return nil return nil
} }
func delUserLDAP(u model.User) error { func delUserLDAP(UID string) error {
l, err := connLDAP() l, err := connLDAP()
if err != nil { if err != nil {
return err return err
...@@ -130,7 +130,7 @@ func delUserLDAP(u model.User) error { ...@@ -130,7 +130,7 @@ func delUserLDAP(u model.User) error {
"ou=grupos,dc=c3local,dc=com", "ou=grupos,dc=c3local,dc=com",
ldap.ScopeWholeSubtree, ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases, 0, 0, false, ldap.NeverDerefAliases, 0, 0, false,
"(memberUid="+u.UID+")", // Filter by UID membership "(memberUid="+UID+")", // Filter by UID membership
[]string{"dn", "cn"}, []string{"dn", "cn"},
nil, nil,
) )
...@@ -143,13 +143,14 @@ func delUserLDAP(u model.User) error { ...@@ -143,13 +143,14 @@ func delUserLDAP(u model.User) error {
// iterate and remove user from each group // iterate and remove user from each group
for _, entry := range groups.Entries { for _, entry := range groups.Entries {
groupName := entry.GetAttributeValue("cn") groupName := entry.GetAttributeValue("cn")
if err := delUserFromGroupLDAP(l, u.UID, groupName); err != nil { if err := delUserFromGroupLDAP(l, UID, groupName); err != nil {
log.Printf("Warning: %v", err) log.Printf("Warning: %v", err)
} }
} }
// removing user entry // removing user entry
delReq := ldap.NewDelRequest(u.DN, nil) userDN := "uid=" + UID + "ou=usuarios,dc=c3local"
delReq := ldap.NewDelRequest(userDN, nil)
if err := l.Del(delReq); err != nil && if err := l.Del(delReq); err != nil &&
!ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) { !ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
return fmt.Errorf("User deletion failed: %v", err) return fmt.Errorf("User deletion failed: %v", err)
......
...@@ -214,13 +214,12 @@ func getLDAPPassword(path string) (string, error) { ...@@ -214,13 +214,12 @@ func getLDAPPassword(path string) (string, error) {
// 0. users full name // 0. users full name
// 1. users grr // 1. users grr
// 2. responsible professor // 2. responsible professor
// 3. users course/minicourse (even temp) // 3. account expiry date (may be used for deletion)
// 4. account expiry date (may be used for deletion) // 4. account status (Blocked/Active)
// 5. account status (Blocked/Active) // 5. login type (ini, first or last)
// 6. login type (ini, first or last) // 6. users webdir
// 7. users webdir // 7. users nobackup dir
// 8. users nobackup dir // 8. to be continued...
// 9. to be continued...
func parseGecos(user model.User) model.User { func parseGecos(user model.User) model.User {
result := [NUM_GECOS_FIELDS]string{0: "_"} result := [NUM_GECOS_FIELDS]string{0: "_"}
for i := range result { for i := range result {
...@@ -236,15 +235,14 @@ func parseGecos(user model.User) model.User { ...@@ -236,15 +235,14 @@ func parseGecos(user model.User) model.User {
user.GRR = result[1] user.GRR = result[1]
user.Resp = result[2] user.Resp = result[2]
user.Course = result[3] user.Expiry = result[3]
user.Expiry = result[4]
// only set with gecos if empty // only set with gecos if empty
if user.Status == "_" { if user.Status == "_" {
user.Status = result[5] user.Status = result[4]
} }
user.Ltype = result[6] user.Ltype = result[5]
user.Webdir = result[7] user.Webdir = result[6]
user.Nobackup = result[8] user.Nobackup = result[7]
return user return user
} }
......
...@@ -18,7 +18,6 @@ type Opts struct { ...@@ -18,7 +18,6 @@ type Opts struct {
Passwd string Passwd string
Webdir string Webdir string
Status string Status string
Course string
Expiry string Expiry string
Homedir string Homedir string
Ignore bool Ignore bool
...@@ -26,6 +25,7 @@ type Opts struct { ...@@ -26,6 +25,7 @@ type Opts struct {
Block bool Block bool
Unblock bool Unblock bool
Confirm bool Confirm bool
Number int
} }
func (o *Opts) ToString() string { func (o *Opts) ToString() string {
...@@ -41,17 +41,17 @@ func (o *Opts) ToString() string { ...@@ -41,17 +41,17 @@ func (o *Opts) ToString() string {
Passwd %s Passwd %s
Webdir %s Webdir %s
Status %s Status %s
Course %s
Expiry %s Expiry %s
Homedir %s Homedir %s
Ignore %v Ignore %v
Exact %v Exact %v
Block %v Block %v
Unblock %v Unblock %v
Confirm %v`, Confirm %v
Number %v`,
o.GRR, o.GID, o.UID, o.Resp, o.Name, o.Nobkp, o.Ltype, o.Shell, o.GRR, o.GID, o.UID, o.Resp, o.Name, o.Nobkp, o.Ltype, o.Shell,
o.Passwd, o.Webdir, o.Status, o.Course, o.Expiry, o.Homedir, o.Ignore, o.Passwd, o.Webdir, o.Status, o.Expiry, o.Homedir, o.Ignore,
o.Exact, o.Block, o.Unblock, o.Confirm) o.Exact, o.Block, o.Unblock, o.Confirm, o.Number)
} }
func (o *Opts) RetrieveOpts(cmd *cobra.Command) error { func (o *Opts) RetrieveOpts(cmd *cobra.Command) error {
...@@ -107,11 +107,6 @@ func (o *Opts) RetrieveOpts(cmd *cobra.Command) error { ...@@ -107,11 +107,6 @@ func (o *Opts) RetrieveOpts(cmd *cobra.Command) error {
return err return err
} }
o.Course, err = getFlagString(cmd, "course")
if err != nil {
return err
}
o.Expiry, err = getFlagString(cmd, "expiry") o.Expiry, err = getFlagString(cmd, "expiry")
if err != nil { if err != nil {
return err return err
...@@ -152,6 +147,11 @@ func (o *Opts) RetrieveOpts(cmd *cobra.Command) error { ...@@ -152,6 +147,11 @@ func (o *Opts) RetrieveOpts(cmd *cobra.Command) error {
return err return err
} }
o.Number, err = getFlagInt(cmd, "number")
if err != nil {
return err
}
return nil return nil
} }
...@@ -172,6 +172,18 @@ func getFlagString(cmd *cobra.Command, flag string) (string, error) { ...@@ -172,6 +172,18 @@ func getFlagString(cmd *cobra.Command, flag string) (string, error) {
return flagValue, nil return flagValue, nil
} }
func getFlagInt(cmd *cobra.Command, flag string) (int, error) {
if cmd.Flags().Lookup(flag) == nil {
return 0, nil
}
flagValue, err := cmd.Flags().GetInt(flag)
if err != nil {
return 0, fmt.Errorf("failed to get flag %q: %w", flag, err)
}
return flagValue, nil
}
func getFlagBool(cmd *cobra.Command, flag string) (bool, error) { func getFlagBool(cmd *cobra.Command, flag string) (bool, error) {
if cmd.Flags().Lookup(flag) == nil { if cmd.Flags().Lookup(flag) == nil {
return false, nil return false, nil
......
...@@ -12,7 +12,6 @@ type User struct { ...@@ -12,7 +12,6 @@ type User struct {
Ltype string Ltype string
Gecos string Gecos string
Shell string Shell string
Course string
Status string Status string
Webdir string Webdir string
Expiry string Expiry string
...@@ -35,10 +34,9 @@ func (u *User) ToString() string { ...@@ -35,10 +34,9 @@ func (u *User) ToString() string {
Nobkp: %s Nobkp: %s
Status: %s Status: %s
Resp: %s Resp: %s
Course: %s
Expiry: %s`, Expiry: %s`,
u.Name, u.UID, u.GRR, u.GID, u.Shell, u.Homedir, u.Webdir, u.Name, u.UID, u.GRR, u.GID, u.Shell, u.Homedir, u.Webdir,
u.Nobackup, u.Status, u.Resp, u.Course, u.Expiry) u.Nobackup, u.Status, u.Resp, u.Expiry)
} }
// useful for debugging :) // useful for debugging :)
...@@ -53,7 +51,6 @@ func (u *User) FullToString() string { ...@@ -53,7 +51,6 @@ func (u *User) FullToString() string {
Ltype: %s Ltype: %s
Gecos: %s Gecos: %s
Shell: %s Shell: %s
Course: %s
Status: %s Status: %s
Webdir: %s Webdir: %s
Expiry: %s Expiry: %s
...@@ -63,6 +60,6 @@ func (u *User) FullToString() string { ...@@ -63,6 +60,6 @@ func (u *User) FullToString() string {
GIDNumber: %s GIDNumber: %s
UIDNumber: %s`, UIDNumber: %s`,
u.DN, u.GRR, u.UID, u.GID, u.Name, u.Resp, u.Ltype, u.Gecos, u.DN, u.GRR, u.UID, u.GID, u.Name, u.Resp, u.Ltype, u.Gecos,
u.Shell, u.Course, u.Status, u.Webdir, u.Expiry, u.Homedir, u.Shell, u.Status, u.Webdir, u.Expiry, u.Homedir, u.Password,
u.Password, u.Nobackup, u.GIDNumber, u.UIDNumber) u.Nobackup, u.GIDNumber, u.UIDNumber)
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment