repos / pico

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

commit
54a5a59
parent
eb429da
author
Eric Bower
date
2024-03-24 18:27:37 +0000 UTC
chore(ui): cleanup api
3 files changed,  +62, -10
M db/db.go
+2, -1
 1@@ -281,9 +281,10 @@ type DB interface {
 2 	RegisterUser(name, pubkey string) (*User, error)
 3 	RemoveUsers(userIDs []string) error
 4 	LinkUserKey(userID string, pubkey string, tx *sql.Tx) error
 5-	UpdatePublicKey(pubkey, name string) (*PublicKey, error)
 6+	UpdatePublicKey(pubkeyID, name string) (*PublicKey, error)
 7 	InsertPublicKey(userID, pubkey, name string, tx *sql.Tx) (*PublicKey, error)
 8 	FindPublicKeyForKey(pubkey string) (*PublicKey, error)
 9+	FindPublicKey(pubkeyID string) (*PublicKey, error)
10 	FindKeysForUser(user *User) ([]*PublicKey, error)
11 	RemoveKeys(pubkeyIDs []string) error
12 
M db/postgres/storage.go
+31, -3
 1@@ -442,8 +442,8 @@ func (me *PsqlDB) InsertPublicKey(userID, key, name string, tx *sql.Tx) (*db.Pub
 2 	return pk, nil
 3 }
 4 
 5-func (me *PsqlDB) UpdatePublicKey(key, name string) (*db.PublicKey, error) {
 6-	pk, err := me.FindPublicKeyForKey(key)
 7+func (me *PsqlDB) UpdatePublicKey(pubkeyID, name string) (*db.PublicKey, error) {
 8+	pk, err := me.FindPublicKey(pubkeyID)
 9 	if err != nil {
10 		return nil, err
11 	}
12@@ -454,7 +454,7 @@ func (me *PsqlDB) UpdatePublicKey(key, name string) (*db.PublicKey, error) {
13 		return nil, err
14 	}
15 
16-	pk, err = me.FindPublicKeyForKey(key)
17+	pk, err = me.FindPublicKey(pubkeyID)
18 	if err != nil {
19 		return nil, err
20 	}
21@@ -497,6 +497,34 @@ func (me *PsqlDB) FindPublicKeyForKey(key string) (*db.PublicKey, error) {
22 	return keys[0], nil
23 }
24 
25+func (me *PsqlDB) FindPublicKey(pubkeyID string) (*db.PublicKey, error) {
26+	var keys []*db.PublicKey
27+	rs, err := me.Db.Query(`SELECT id, user_id, name, public_key, created_at FROM public_keys WHERE id = $1`, pubkeyID)
28+	if err != nil {
29+		return nil, err
30+	}
31+
32+	for rs.Next() {
33+		pk := &db.PublicKey{}
34+		err := rs.Scan(&pk.ID, &pk.UserID, &pk.Name, &pk.Key, &pk.CreatedAt)
35+		if err != nil {
36+			return nil, err
37+		}
38+
39+		keys = append(keys, pk)
40+	}
41+
42+	if rs.Err() != nil {
43+		return nil, rs.Err()
44+	}
45+
46+	if len(keys) == 0 {
47+		return nil, errors.New("no public keys found for key provided")
48+	}
49+
50+	return keys[0], nil
51+}
52+
53 func (me *PsqlDB) FindKeysForUser(user *db.User) ([]*db.PublicKey, error) {
54 	var keys []*db.PublicKey
55 	rs, err := me.Db.Query(sqlSelectPublicKeys, user.ID)
M ui/api.go
+29, -6
 1@@ -115,6 +115,14 @@ type pubkeysPayload struct {
 2 	Pubkeys []*db.PublicKey `json:"pubkeys"`
 3 }
 4 
 5+func toFingerprint(pubkey string) (string, error) {
 6+	kk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubkey))
 7+	if err != nil {
 8+		return "", err
 9+	}
10+	return shared.KeyForSha256(kk), nil
11+}
12+
13 func getPublicKeys(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
14 	logger := httpCtx.Cfg.Logger
15 	return func(w http.ResponseWriter, r *http.Request) {
16@@ -132,12 +140,12 @@ func getPublicKeys(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc
17 		}
18 
19 		for _, pk := range pubkeys {
20-			kk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pk.Key))
21+			fingerprint, err := toFingerprint(pk.Key)
22 			if err != nil {
23 				logger.Error("could not parse public key", "err", err.Error())
24 				continue
25 			}
26-			pk.Key = shared.KeyForSha256(kk)
27+			pk.Key = fingerprint
28 		}
29 
30 		err = json.NewEncoder(w).Encode(&pubkeysPayload{Pubkeys: pubkeys})
31@@ -171,6 +179,12 @@ func createPubkey(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
32 			return
33 		}
34 
35+		fingerprint, err := toFingerprint(pubkey.Key)
36+		if err != nil {
37+			shared.JSONError(w, err.Error(), http.StatusUnprocessableEntity)
38+			return
39+		}
40+		pubkey.Key = fingerprint
41 		err = json.NewEncoder(w).Encode(pubkey)
42 		if err != nil {
43 			logger.Error("json encode", "err", err.Error())
44@@ -230,30 +244,39 @@ func patchPubkey(httpCtx *shared.ApiConfig, ctx ssh.Context) http.HandlerFunc {
45 		}
46 
47 		dbpool := shared.GetDB(r)
48+		pubkeyID := shared.GetField(r, 0)
49+
50 		var payload createPubkeyPayload
51 		body, _ := io.ReadAll(r.Body)
52 		_ = json.Unmarshal(body, &payload)
53 
54-		auth, err := dbpool.FindUserForKey("", payload.Pubkey)
55+		auth, err := dbpool.FindPublicKey(pubkeyID)
56 		if err != nil {
57 			logger.Error("could not find user with pubkey provided", "err", err.Error())
58 			shared.JSONError(w, err.Error(), http.StatusUnprocessableEntity)
59 			return
60 		}
61 
62-		if auth.ID != user.ID {
63+		if auth.UserID != user.ID {
64 			logger.Error("user trying to update pubkey they do not own")
65 			shared.JSONError(w, "user trying to update pubkey they do not own", http.StatusUnauthorized)
66 			return
67 		}
68 
69-		pubkey, err := dbpool.UpdatePublicKey(payload.Pubkey, payload.Name)
70+		pubkey, err := dbpool.UpdatePublicKey(pubkeyID, payload.Name)
71 		if err != nil {
72 			logger.Error("could not update pubkey", "err", err.Error())
73 			shared.JSONError(w, err.Error(), http.StatusUnprocessableEntity)
74 			return
75 		}
76 
77+		fingerprint, err := toFingerprint(pubkey.Key)
78+		if err != nil {
79+			shared.JSONError(w, err.Error(), http.StatusUnprocessableEntity)
80+			return
81+		}
82+		pubkey.Key = fingerprint
83+
84 		err = json.NewEncoder(w).Encode(pubkey)
85 		if err != nil {
86 			logger.Error("json encode", "err", err.Error())
87@@ -519,7 +542,7 @@ func CreateRoutes(apiConfig *shared.ApiConfig, ctx ssh.Context) []shared.Route {
88 		shared.NewCorsRoute("GET", "/api/pubkeys", getPublicKeys(apiConfig, ctx)),
89 		shared.NewCorsRoute("POST", "/api/pubkeys", createPubkey(apiConfig, ctx)),
90 		shared.NewCorsRoute("DELETE", "/api/pubkeys/(.+)", deletePubkey(apiConfig, ctx)),
91-		shared.NewCorsRoute("PATCH", "/api/pubkeys", patchPubkey(apiConfig, ctx)),
92+		shared.NewCorsRoute("PATCH", "/api/pubkeys/(.+)", patchPubkey(apiConfig, ctx)),
93 		shared.NewCorsRoute("GET", "/api/tokens", getTokens(apiConfig, ctx)),
94 		shared.NewCorsRoute("POST", "/api/tokens", createToken(apiConfig, ctx)),
95 		shared.NewCorsRoute("DELETE", "/api/tokens/(.+)", deleteToken(apiConfig, ctx)),