diff --git a/db.go b/db.go index abc8453..e40b2f9 100644 --- a/db.go +++ b/db.go @@ -36,8 +36,10 @@ type Host struct { type UserKey struct { gorm.Model - Key []byte - UserID uint + Key []byte + UserID uint + User *User + Comment string } type User struct { @@ -205,3 +207,23 @@ func FindUsersByIdOrEmail(db *gorm.DB, queries []string) ([]*User, error) { } return users, nil } + +func FindUserkeyById(db *gorm.DB, query string) (*UserKey, error) { + var userkey UserKey + if err := db.Preload("User").Where("id = ?", query).First(&userkey).Error; err != nil { + return nil, err + } + return &userkey, nil +} + +func FindUserkeysById(db *gorm.DB, queries []string) ([]*UserKey, error) { + var userkeys []*UserKey + for _, query := range queries { + userkey, err := FindUserkeyById(db, query) + if err != nil { + return nil, err + } + userkeys = append(userkeys, userkey) + } + return userkeys, nil +} diff --git a/main.go b/main.go index 52bb507..695e472 100644 --- a/main.go +++ b/main.go @@ -143,8 +143,9 @@ func server(c *cli.Context) error { } db.Create(&user) userKey = UserKey{ - UserID: user.ID, - Key: key.Marshal(), + UserID: user.ID, + Key: key.Marshal(), + Comment: "created by sshportal", } db.Create(&userKey) diff --git a/shell.go b/shell.go index 2b19ec8..b415169 100644 --- a/shell.go +++ b/shell.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "encoding/json" "fmt" "io" @@ -363,14 +364,14 @@ GLOBAL OPTIONS: return cli.ShowSubcommandHelp(c) } - hosts, err := FindUsersByIdOrEmail(db, c.Args()) + users, err := FindUsersByIdOrEmail(db, c.Args()) if err != nil { return nil } enc := json.NewEncoder(s) enc.SetIndent("", " ") - return enc.Encode(hosts) + return enc.Encode(users) }, }, { Name: "ls", @@ -421,6 +422,117 @@ GLOBAL OPTIONS: }, }, }, + }, { + Name: "userkey", + Usage: "Manages userkeys", + Subcommands: []cli.Command{ + { + Name: "create", + ArgsUsage: "", + Usage: "Creates a new userkey", + Description: "$> userkey create bob\n $> user create --name=mykey bob", + Flags: []cli.Flag{ + cli.StringFlag{Name: "comment"}, + }, + Action: func(c *cli.Context) error { + if c.NArg() != 1 { + return cli.ShowSubcommandHelp(c) + } + + user, err := FindUserByIdOrEmail(db, c.Args().First()) + if err != nil { + return err + } + + fmt.Fprintf(s, "Enter key:\n") + reader := bufio.NewReader(s) + text, _ := reader.ReadString('\n') + fmt.Println(text) + + key, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(text)) + if err != nil { + return err + } + + userkey := UserKey{ + UserID: user.ID, + Key: key.Marshal(), + Comment: comment, + } + if c.String("comment") != "" { + userkey.Comment = c.String("comment") + } + + // save the userkey in database + if err := db.Create(&userkey).Error; err != nil { + return err + } + fmt.Fprintf(s, "%d\n", userkey.ID) + return nil + }, + }, { + Name: "inspect", + Usage: "Shows detailed information on one or more userkeys", + ArgsUsage: " [ [...]]", + Action: func(c *cli.Context) error { + if c.NArg() < 1 { + return cli.ShowSubcommandHelp(c) + } + + userkeys, err := FindUserkeysById(db, c.Args()) + if err != nil { + return nil + } + + enc := json.NewEncoder(s) + enc.SetIndent("", " ") + return enc.Encode(userkeys) + }, + }, { + Name: "ls", + Usage: "Lists userkeys", + Action: func(c *cli.Context) error { + var userkeys []UserKey + if err := db.Preload("User").Find(&userkeys).Error; err != nil { + return err + } + table := tablewriter.NewWriter(s) + table.SetHeader([]string{"ID", "User", "Comment"}) + table.SetBorder(false) + table.SetCaption(true, fmt.Sprintf("Total: %d userkeys.", len(userkeys))) + for _, userkey := range userkeys { + table.Append([]string{ + fmt.Sprintf("%d", userkey.ID), + userkey.User.Email, + // FIXME: add fingerprint + userkey.Comment, + }) + } + table.Render() + return nil + }, + }, { + Name: "rm", + Usage: "Removes one or more userkeys", + ArgsUsage: " [ [...]]", + Action: func(c *cli.Context) error { + if c.NArg() < 1 { + return cli.ShowSubcommandHelp(c) + } + + userkeys, err := FindUserkeysById(db, c.Args()) + if err != nil { + return nil + } + + for _, userkey := range userkeys { + db.Where("id = ?", userkey.ID).Delete(&UserKey{}) + fmt.Fprintf(s, "%d\n", userkey.ID) + } + return nil + }, + }, + }, }, { Name: "version", Usage: "Shows the SSHPortal version information",