- commit
- 7f9ad09
- parent
- c687eee
- author
- Eric Bower
- date
- 2024-06-25 09:56:40 -0400 EDT
refactor: user model
5 files changed,
+72,
-40
+11,
-0
1@@ -1,6 +1,8 @@
2 package git
3
4 import (
5+ "encoding/base64"
6+ "fmt"
7 "log/slog"
8 "path/filepath"
9
10@@ -28,9 +30,18 @@ func (be *Backend) RepoID(name string) string {
11 }
12
13 func (be *Backend) Pubkey(pk ssh.PublicKey) string {
14+ return be.KeyForKeyText(pk)
15+}
16+
17+func (be *Backend) KeyForFingerprint(pk ssh.PublicKey) string {
18 return gossh.FingerprintSHA256(pk)
19 }
20
21+func (be *Backend) KeyForKeyText(pk ssh.PublicKey) string {
22+ kb := base64.StdEncoding.EncodeToString(pk.Marshal())
23+ return fmt.Sprintf("%s %s", pk.Type(), kb)
24+}
25+
26 func (be *Backend) KeysEqual(pka, pkb string) bool {
27 return pka == pkb
28 }
M
cli.go
+6,
-24
1@@ -216,10 +216,7 @@ Here's how it works:
2 Args: true,
3 ArgsUsage: "[repoID]",
4 Action: func(cCtx *cli.Context) error {
5- user, err := pr.UpsertUser(&User{
6- Pubkey: pubkey,
7- Name: userName,
8- })
9+ user, err := pr.UpsertUser(pubkey, userName)
10 if err != nil {
11 return err
12 }
13@@ -452,10 +449,7 @@ Here's how it works:
14 return fmt.Errorf("PR has already been accepted")
15 }
16
17- user, err := pr.UpsertUser(&User{
18- Pubkey: pubkey,
19- Name: userName,
20- })
21+ user, err := pr.UpsertUser(pubkey, userName)
22 if err != nil {
23 return err
24 }
25@@ -478,10 +472,7 @@ Here's how it works:
26 return err
27 }
28
29- user, err := pr.UpsertUser(&User{
30- Pubkey: pubkey,
31- Name: userName,
32- })
33+ user, err := pr.UpsertUser(pubkey, userName)
34 if err != nil {
35 return err
36 }
37@@ -524,10 +515,7 @@ Here's how it works:
38 return err
39 }
40
41- user, err := pr.UpsertUser(&User{
42- Pubkey: pubkey,
43- Name: userName,
44- })
45+ user, err := pr.UpsertUser(pubkey, userName)
46 if err != nil {
47 return err
48 }
49@@ -565,10 +553,7 @@ Here's how it works:
50 return err
51 }
52
53- user, err := pr.UpsertUser(&User{
54- Pubkey: pubkey,
55- Name: userName,
56- })
57+ user, err := pr.UpsertUser(pubkey, userName)
58 if err != nil {
59 return err
60 }
61@@ -622,10 +607,7 @@ Here's how it works:
62 return err
63 }
64
65- user, err := pr.UpsertUser(&User{
66- Pubkey: pubkey,
67- Name: userName,
68- })
69+ user, err := pr.UpsertUser(pubkey, userName)
70 if err != nil {
71 return err
72 }
M
db.go
+5,
-5
1@@ -68,13 +68,13 @@ type DB struct {
2 var schema = `
3 CREATE TABLE IF NOT EXISTS app_users (
4 id INTEGER PRIMARY KEY AUTOINCREMENT,
5- pubkey UNIQUE TEXT NOT NULL,
6- name UNIQUE TEXT NOT NULL,
7+ pubkey TEXT NOT NULL UNIQUE,
8+ name TEXT NOT NULL UNIQUE,
9 created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
10- updated_at DATETIME NOT NULL,
11+ updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
12 );
13
14-CREATE TABLE IF NOT EXISTS acl {
15+CREATE TABLE IF NOT EXISTS acl (
16 id INTEGER PRIMARY KEY AUTOINCREMENT,
17 user_id INTEGER,
18 ip_address string,
19@@ -84,7 +84,7 @@ CREATE TABLE IF NOT EXISTS acl {
20 FOREIGN KEY(user_id) REFERENCES app_users(id)
21 ON DELETE CASCADE
22 ON UPDATE CASCADE
23-}
24+);
25
26 CREATE TABLE IF NOT EXISTS patch_requests (
27 id INTEGER PRIMARY KEY AUTOINCREMENT,
M
pr.go
+45,
-6
1@@ -27,7 +27,7 @@ type GitPatchRequest interface {
2 GetUsers() ([]*User, error)
3 GetUserByID(userID int64) (*User, error)
4 GetUserByPubkey(pubkey string) (*User, error)
5- UpsertUser(user *User) (*User, error)
6+ UpsertUser(pubkey, name string) (*User, error)
7 GetRepos() ([]*Repo, error)
8 GetReposWithLatestPr() ([]RepoWithLatestPr, error)
9 GetRepoByID(repoID string) (*Repo, error)
10@@ -55,19 +55,58 @@ var _ GitPatchRequest = PrCmd{}
11 var _ GitPatchRequest = (*PrCmd)(nil)
12
13 func (pr PrCmd) GetUsers() ([]*User, error) {
14- return []*User{}, nil
15+ users := []*User{}
16+ err := pr.Backend.DB.Select(&users, "SELECT * FROM app_users")
17+ return users, err
18 }
19
20 func (pr PrCmd) GetUserByID(id int64) (*User, error) {
21- return nil, nil
22+ var user User
23+ err := pr.Backend.DB.Get(&user, "SELECT * FROM app_users WHERE id=?", id)
24+ return &user, err
25 }
26
27 func (pr PrCmd) GetUserByPubkey(pubkey string) (*User, error) {
28- return nil, nil
29+ var user User
30+ err := pr.Backend.DB.Get(&user, "SELECT * FROM app_users WHERE pubkey=?", pubkey)
31+ return &user, err
32 }
33
34-func (pr PrCmd) UpsertUser(user *User) (*User, error) {
35- return nil, nil
36+func (pr PrCmd) createUser(pubkey, name string) (*User, error) {
37+ if pubkey == "" {
38+ return nil, fmt.Errorf("must provide pubkey when creating user")
39+ }
40+ if name == "" {
41+ return nil, fmt.Errorf("must provide user name when creating user")
42+ }
43+
44+ var userID int64
45+ row := pr.Backend.DB.QueryRow(
46+ "INSERT INTO app_users (pubkey, name) VALUES (?, ?) RETURNING id",
47+ pubkey,
48+ name,
49+ )
50+ err := row.Scan(&userID)
51+ if err != nil {
52+ return nil, err
53+ }
54+ if userID == 0 {
55+ return nil, fmt.Errorf("could not create user")
56+ }
57+
58+ user, err := pr.GetUserByID(userID)
59+ return user, err
60+}
61+
62+func (pr PrCmd) UpsertUser(pubkey, name string) (*User, error) {
63+ if pubkey == "" {
64+ return nil, fmt.Errorf("must provide pubkey during upsert")
65+ }
66+ user, err := pr.GetUserByPubkey(pubkey)
67+ if err != nil {
68+ user, err = pr.createUser(pubkey, name)
69+ }
70+ return user, err
71 }
72
73 type PrWithRepo struct {
M
web.go
+5,
-5
1@@ -141,7 +141,7 @@ func repoListHandler(w http.ResponseWriter, r *http.Request) {
2 Repos: repoData,
3 })
4 if err != nil {
5- fmt.Println(err)
6+ web.Backend.Logger.Error("cannot execute template", "err", err)
7 }
8 }
9
10@@ -169,7 +169,7 @@ func repoDetailHandler(w http.ResponseWriter, r *http.Request) {
11
12 web, err := getWebCtx(r)
13 if err != nil {
14- fmt.Println(err)
15+ web.Logger.Error("fetch web", "err", err)
16 w.WriteHeader(http.StatusInternalServerError)
17 return
18 }
19@@ -231,7 +231,7 @@ func repoDetailHandler(w http.ResponseWriter, r *http.Request) {
20 ReviewedPrs: reviewedList,
21 })
22 if err != nil {
23- fmt.Println(err)
24+ web.Backend.Logger.Error("cannot execute template", "err", err)
25 }
26 }
27
28@@ -334,7 +334,7 @@ func prDetailHandler(w http.ResponseWriter, r *http.Request) {
29 },
30 })
31 if err != nil {
32- fmt.Println(err)
33+ web.Backend.Logger.Error("cannot execute template", "err", err)
34 }
35 }
36
37@@ -452,7 +452,7 @@ func chromaStyleHandler(w http.ResponseWriter, r *http.Request) {
38 w.Header().Add("content-type", "text/css")
39 err = web.Formatter.WriteCSS(w, web.Theme)
40 if err != nil {
41- fmt.Println(err)
42+ web.Backend.Logger.Error("cannot write css file", "err", err)
43 }
44 }
45