repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
375ace8
parent
3ceca3b
author
Eric Bower
date
2024-04-30 14:10:04 +0000 UTC
fix: users not being able to register an account
9 files changed,  +43, -49
M db/db.go
+2, -3
 1@@ -318,11 +318,10 @@ var DenyList = []string{
 2 }
 3 
 4 type DB interface {
 5-	RegisterUser(name, pubkey string) (*User, error)
 6+	RegisterUser(name, pubkey, comment string) (*User, error)
 7 	RemoveUsers(userIDs []string) error
 8-	LinkUserKey(userID string, pubkey string, tx *sql.Tx) error
 9 	UpdatePublicKey(pubkeyID, name string) (*PublicKey, error)
10-	InsertPublicKey(userID, pubkey, name string, tx *sql.Tx) (*PublicKey, error)
11+	InsertPublicKey(userID, pubkey, name string, tx *sql.Tx) error
12 	FindPublicKeyForKey(pubkey string) (*PublicKey, error)
13 	FindPublicKey(pubkeyID string) (*PublicKey, error)
14 	FindKeysForUser(user *User) ([]*PublicKey, error)
M db/postgres/storage.go
+5, -23
 1@@ -349,7 +349,7 @@ func NewDB(databaseUrl string, logger *slog.Logger) *PsqlDB {
 2 	return d
 3 }
 4 
 5-func (me *PsqlDB) RegisterUser(username string, pubkey string) (*db.User, error) {
 6+func (me *PsqlDB) RegisterUser(username, pubkey, comment string) (*db.User, error) {
 7 	lowerName := strings.ToLower(username)
 8 	valid, err := me.ValidateName(lowerName)
 9 	if !valid {
10@@ -377,7 +377,7 @@ func (me *PsqlDB) RegisterUser(username string, pubkey string) (*db.User, error)
11 		return nil, err
12 	}
13 
14-	err = me.LinkUserKey(id, pubkey, tx)
15+	err = me.InsertPublicKey(id, pubkey, comment, tx)
16 	if err != nil {
17 		return nil, err
18 	}
19@@ -396,25 +396,11 @@ func (me *PsqlDB) RemoveUsers(userIDs []string) error {
20 	return err
21 }
22 
23-func (me *PsqlDB) LinkUserKey(userID string, key string, tx *sql.Tx) error {
24+func (me *PsqlDB) InsertPublicKey(userID, key, name string, tx *sql.Tx) error {
25 	pk, _ := me.FindPublicKeyForKey(key)
26 	if pk != nil {
27 		return db.ErrPublicKeyTaken
28 	}
29-	var err error
30-	if tx != nil {
31-		_, err = tx.Exec(sqlInsertPublicKey, userID, key)
32-	} else {
33-		_, err = me.Db.Exec(sqlInsertPublicKey, userID, key)
34-	}
35-	return err
36-}
37-
38-func (me *PsqlDB) InsertPublicKey(userID, key, name string, tx *sql.Tx) (*db.PublicKey, error) {
39-	pk, _ := me.FindPublicKeyForKey(key)
40-	if pk != nil {
41-		return nil, db.ErrPublicKeyTaken
42-	}
43 	query := `INSERT INTO public_keys (user_id, public_key, name) VALUES ($1, $2, $3)`
44 	var err error
45 	if tx != nil {
46@@ -423,14 +409,10 @@ func (me *PsqlDB) InsertPublicKey(userID, key, name string, tx *sql.Tx) (*db.Pub
47 		_, err = me.Db.Exec(query, userID, key, name)
48 	}
49 	if err != nil {
50-		return nil, err
51+		return err
52 	}
53 
54-	pk, err = me.FindPublicKeyForKey(key)
55-	if err != nil {
56-		return nil, err
57-	}
58-	return pk, nil
59+	return nil
60 }
61 
62 func (me *PsqlDB) UpdatePublicKey(pubkeyID, name string) (*db.PublicKey, error) {
M pico/cli.go
+6, -0
 1@@ -123,6 +123,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 2 
 3 	return func(next ssh.Handler) ssh.Handler {
 4 		return func(sesh ssh.Session) {
 5+			_, _, activePty := sesh.Pty()
 6+			if activePty {
 7+				next(sesh)
 8+				return
 9+			}
10+
11 			user, err := getUser(sesh, dbpool)
12 			if err != nil {
13 				utils.ErrorHandler(sesh, err)
M pico/file_handler.go
+1, -1
1@@ -222,7 +222,7 @@ func (h *UploadHandler) ProcessAuthorizedKeys(text []byte, logger *slog.Logger,
2 
3 		logger.Info("adding pubkey for user", "pubkey", key)
4 
5-		_, err = dbpool.InsertPublicKey(user.ID, key, pk.Comment, nil)
6+		err = dbpool.InsertPublicKey(user.ID, key, pk.Comment, nil)
7 		if err != nil {
8 			logger.Error("could not insert pubkey", "err", err.Error())
9 		}
M tui/account/create.go
+4, -4
 1@@ -236,10 +236,10 @@ func Update(msg tea.Msg, m CreateModel) (CreateModel, tea.Cmd) {
 2 
 3 // View renders current view from the model.
 4 func View(m CreateModel) string {
 5-	intro := "To create an account, enter a username.\n"
 6+	intro := "To create an account, enter a username.\n\n"
 7 	intro += "After that, go to https://pico.sh/getting-started#next-steps"
 8-	s := fmt.Sprintf("%s\n\n%s\n", "hacker labs", intro)
 9-	s += fmt.Sprintf("Public Key: %s\n\n", m.publicKey)
10+	s := fmt.Sprintf("%s\n\n%s\n\n", "hacker labs", intro)
11+	s += fmt.Sprintf("Public Key: %s\n\n", shared.KeyForSha256(m.publicKey))
12 	s += m.input.View() + "\n\n"
13 
14 	if m.state == submitting {
15@@ -271,7 +271,7 @@ func createAccount(m CreateModel) tea.Cmd {
16 			return errMsg{err}
17 		}
18 
19-		user, err := m.dbpool.RegisterUser(m.newName, key)
20+		user, err := m.dbpool.RegisterUser(m.newName, key, "")
21 		if err != nil {
22 			if errors.Is(err, db.ErrNameTaken) {
23 				return NameTakenMsg{}
M tui/cms.go
+0, -1
1@@ -155,7 +155,6 @@ func (m model) findUser() (*db.User, error) {
2 	}
3 
4 	user, err = m.dbpool.FindUserForKey(m.sshUser, key)
5-
6 	if err != nil {
7 		logger.Error("no user found for public key", "err", err.Error())
8 		// we only want to throw an error for specific cases
M tui/createkey/create.go
+2, -2
 1@@ -248,7 +248,7 @@ func spinnerView(m Model) string {
 2 
 3 func addPublicKey(m Model) tea.Cmd {
 4 	return func() tea.Msg {
 5-		pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(m.newKey))
 6+		pk, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(m.newKey))
 7 		if err != nil {
 8 			return KeyInvalidMsg{}
 9 		}
10@@ -257,7 +257,7 @@ func addPublicKey(m Model) tea.Cmd {
11 		if err != nil {
12 			return KeyInvalidMsg{}
13 		}
14-		err = m.dbpool.LinkUserKey(m.user.ID, key, nil)
15+		err = m.dbpool.InsertPublicKey(m.user.ID, key, comment, nil)
16 		if err != nil {
17 			if errors.Is(err, db.ErrPublicKeyTaken) {
18 				return KeyTakenMsg{}
M tui/keys/keyview.go
+3, -3
 1@@ -104,7 +104,7 @@ func (m Model) newStyledKey(styles common.Styles, key *db.PublicKey, active bool
 2 		gutter:       " ",
 3 		keyLabel:     "Key:",
 4 		dateLabel:    "Added:",
 5-		commentLabel: "Comment:",
 6+		commentLabel: "Name:",
 7 		commentVal:   key.Name,
 8 		dateVal:      styles.LabelDim.Render(date),
 9 		note:         note,
10@@ -116,7 +116,7 @@ func (k *styledKey) selected() {
11 	k.gutter = common.VerticalLine(k.styles.Renderer, common.StateSelected)
12 	k.keyLabel = k.styles.Label.Render("Key:")
13 	k.dateLabel = k.styles.Label.Render("Added:")
14-	k.commentLabel = k.styles.Label.Render("Comment:")
15+	k.commentLabel = k.styles.Label.Render("Name:")
16 }
17 
18 // Deleting state.
19@@ -124,7 +124,7 @@ func (k *styledKey) deleting() {
20 	k.gutter = common.VerticalLine(k.styles.Renderer, common.StateDeleting)
21 	k.keyLabel = k.styles.Delete.Render("Key:")
22 	k.dateLabel = k.styles.Delete.Render("Added:")
23-	k.commentLabel = k.styles.Delete.Render("Comment:")
24+	k.commentLabel = k.styles.Delete.Render("Name:")
25 	k.dateVal = k.styles.DeleteDim.Render(k.date)
26 }
27 
M ui/api.go
+20, -12
 1@@ -26,7 +26,7 @@ func ensureUser(w http.ResponseWriter, user *db.User) bool {
 2 	return true
 3 }
 4 
 5-func registerUser(apiConfig *shared.ApiConfig, ctx ssh.Context, pubkey ssh.PublicKey, pubkeyStr string) http.HandlerFunc {
 6+func registerUser(apiConfig *shared.ApiConfig, ctx ssh.Context, pubkey ssh.PublicKey) http.HandlerFunc {
 7 	logger := apiConfig.Cfg.Logger
 8 	return func(w http.ResponseWriter, r *http.Request) {
 9 		w.Header().Set("Content-Type", "application/json")
10@@ -35,10 +35,18 @@ func registerUser(apiConfig *shared.ApiConfig, ctx ssh.Context, pubkey ssh.Publi
11 		body, _ := io.ReadAll(r.Body)
12 		_ = json.Unmarshal(body, &payload)
13 
14-		user, err := dbpool.RegisterUser(payload.Name, pubkeyStr)
15+		pubkeyStr, err := shared.KeyForKeyText(pubkey)
16+		if err != nil {
17+			errMsg := fmt.Sprintf("could not get pubkey text: %s", err.Error())
18+			logger.Error("could not get pubkey text", "err", err.Error())
19+			shared.JSONError(w, errMsg, http.StatusUnprocessableEntity)
20+			return
21+		}
22+
23+		user, err := dbpool.RegisterUser(payload.Name, pubkeyStr, "")
24 		if err != nil {
25 			errMsg := fmt.Sprintf("error registering user: %s", err.Error())
26-			logger.Info(errMsg)
27+			logger.Error("error registering user", "err", err.Error())
28 			shared.JSONError(w, errMsg, http.StatusUnprocessableEntity)
29 			return
30 		}
31@@ -47,7 +55,7 @@ func registerUser(apiConfig *shared.ApiConfig, ctx ssh.Context, pubkey ssh.Publi
32 		shared.SetUserCtx(ctx, user)
33 		err = json.NewEncoder(w).Encode(picoApi)
34 		if err != nil {
35-			logger.Error(err.Error())
36+			logger.Error("json encoding error", "err", err.Error())
37 		}
38 	}
39 }
40@@ -175,7 +183,13 @@ func createPubkey(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
41 		var payload createPubkeyPayload
42 		body, _ := io.ReadAll(r.Body)
43 		_ = json.Unmarshal(body, &payload)
44-		pubkey, err := dbpool.InsertPublicKey(user.ID, payload.Pubkey, payload.Name, nil)
45+		err := dbpool.InsertPublicKey(user.ID, payload.Pubkey, payload.Name, nil)
46+		if err != nil {
47+			shared.JSONError(w, err.Error(), http.StatusUnprocessableEntity)
48+			return
49+		}
50+
51+		pubkey, err := dbpool.FindPublicKeyForKey(payload.Pubkey)
52 		if err != nil {
53 			shared.JSONError(w, err.Error(), http.StatusUnprocessableEntity)
54 			return
55@@ -652,14 +666,8 @@ func CreateRoutes(apiConfig *shared.ApiConfig, ctx ssh.Context) []shared.Route {
56 		return []shared.Route{}
57 	}
58 
59-	pubkeyStr, err := shared.KeyForKeyText(pubkey)
60-	if err != nil {
61-		logger.Error("could not convert key to text", "err", err.Error())
62-		return []shared.Route{}
63-	}
64-
65 	return []shared.Route{
66-		shared.NewCorsRoute("POST", "/api/users", registerUser(apiConfig, ctx, pubkey, pubkeyStr)),
67+		shared.NewCorsRoute("POST", "/api/users", registerUser(apiConfig, ctx, pubkey)),
68 		shared.NewCorsRoute("GET", "/api/features", getFeatures(apiConfig, ctx)),
69 		shared.NewCorsRoute("PUT", "/api/rss-token", findOrCreateRssToken(apiConfig, ctx)),
70 		shared.NewCorsRoute("GET", "/api/pubkeys", getPublicKeys(apiConfig, ctx)),