- commit
- 067bd37
- parent
- c44fec8
- author
- Eric Bower
- date
- 2026-02-23 11:40:18 -0500 EST
refactor: require user to create an account We have noticed that users are accidentally creating accounts because we automatically create an account for any operation. So instead we are going to require a one-line remote cli command to register the account first we can help users figure out they are using the wrong pubkey.
4 files changed,
+53,
-24
M
cli.go
+34,
-15
1@@ -13,6 +13,10 @@ import (
2 "github.com/urfave/cli/v2"
3 )
4
5+func errNotExist(host, pubkey string) error {
6+ return fmt.Errorf("User does not exist, run `ssh <username>@%s register` to create an account\nPubkey: %s", host, pubkey)
7+}
8+
9 func NewTabWriter(out io.Writer) *tabwriter.Writer {
10 return tabwriter.NewWriter(out, 0, 0, 1, ' ', tabwriter.TabIndent)
11 }
12@@ -237,7 +241,7 @@ To get started, submit a new patch request:
13 pubkey := be.Pubkey(sesh.PublicKey())
14 user, err := pr.GetUserByPubkey(pubkey)
15 if err != nil {
16- return err
17+ return errNotExist(be.Cfg.Host, pubkey)
18 }
19 isPubkey := cCtx.Bool("pubkey")
20 prID := cCtx.Int64("pr")
21@@ -290,6 +294,21 @@ To get started, submit a new patch request:
22 return nil
23 },
24 },
25+ {
26+ Name: "register",
27+ Usage: "Create an account",
28+ Args: true,
29+ Flags: []cli.Flag{},
30+ Action: func(cCtx *cli.Context) error {
31+ pubkey := be.Pubkey(sesh.PublicKey())
32+ user, err := pr.RegisterUser(pubkey, userName)
33+ if err != nil {
34+ return err
35+ }
36+ wish.Printf(sesh, "User created successfully!\nUser: %s\nPubkey: %s\n", user.Name, pubkey)
37+ return nil
38+ },
39+ },
40 {
41 Name: "ps",
42 Usage: "Mange patchsets",
43@@ -347,9 +366,9 @@ To get started, submit a new patch request:
44 Args: true,
45 ArgsUsage: "[repoName]",
46 Action: func(cCtx *cli.Context) error {
47- user, err := pr.UpsertUser(pubkey, userName)
48+ user, err := pr.GetUserByPubkey(pubkey)
49 if err != nil {
50- return err
51+ return errNotExist(be.Cfg.Host, pubkey)
52 }
53
54 args := cCtx.Args()
55@@ -528,9 +547,9 @@ To get started, submit a new patch request:
56 Args: true,
57 ArgsUsage: "[repoName]",
58 Action: func(cCtx *cli.Context) error {
59- user, err := pr.UpsertUser(pubkey, userName)
60+ user, err := pr.GetUserByPubkey(pubkey)
61 if err != nil {
62- return err
63+ return errNotExist(be.Cfg.Host, pubkey)
64 }
65
66 args := cCtx.Args()
67@@ -631,9 +650,9 @@ To get started, submit a new patch request:
68 return err
69 }
70
71- user, err := pr.UpsertUser(pubkey, userName)
72+ user, err := pr.GetUserByPubkey(pubkey)
73 if err != nil {
74- return err
75+ return errNotExist(be.Cfg.Host, pubkey)
76 }
77
78 repo, err := pr.GetRepoByID(prq.RepoID)
79@@ -717,9 +736,9 @@ To get started, submit a new patch request:
80 return fmt.Errorf("PR has already been closed")
81 }
82
83- user, err := pr.UpsertUser(pubkey, userName)
84+ user, err := pr.GetUserByPubkey(pubkey)
85 if err != nil {
86- return err
87+ return errNotExist(be.Cfg.Host, pubkey)
88 }
89
90 err = pr.UpdatePatchRequestStatus(prID, user.ID, StatusClosed, cCtx.String("comment"))
91@@ -782,9 +801,9 @@ To get started, submit a new patch request:
92 return fmt.Errorf("PR is already open")
93 }
94
95- user, err := pr.UpsertUser(pubkey, userName)
96+ user, err := pr.GetUserByPubkey(pubkey)
97 if err != nil {
98- return err
99+ return errNotExist(be.Cfg.Host, pubkey)
100 }
101
102 err = pr.UpdatePatchRequestStatus(prID, user.ID, StatusOpen, cCtx.String("comment"))
103@@ -814,9 +833,9 @@ To get started, submit a new patch request:
104 return err
105 }
106
107- user, err := pr.UpsertUser(pubkey, userName)
108+ user, err := pr.GetUserByPubkey(pubkey)
109 if err != nil {
110- return err
111+ return errNotExist(be.Cfg.Host, pubkey)
112 }
113
114 repo, err := pr.GetRepoByID(prq.RepoID)
115@@ -885,9 +904,9 @@ To get started, submit a new patch request:
116 return err
117 }
118
119- user, err := pr.UpsertUser(pubkey, userName)
120+ user, err := pr.GetUserByPubkey(pubkey)
121 if err != nil {
122- return err
123+ return errNotExist(be.Cfg.Host, pubkey)
124 }
125
126 isReview := cCtx.Bool("review")
+6,
-0
1@@ -31,6 +31,9 @@ func testSingleTenantE2E(t *testing.T) {
2 // Hack to wait for startup
3 time.Sleep(time.Millisecond * 100)
4
5+ suite.userKey.MustCmd(suite.patch, "register")
6+ suite.adminKey.MustCmd(suite.patch, "register")
7+
8 t.Log("User cannot create repo")
9 _, err := suite.userKey.Cmd(suite.patch, "pr create test")
10 if err == nil {
11@@ -63,6 +66,9 @@ func testMultiTenantE2E(t *testing.T) {
12
13 time.Sleep(time.Millisecond * 100)
14
15+ suite.userKey.MustCmd(suite.patch, "register")
16+ suite.adminKey.MustCmd(suite.patch, "register")
17+
18 t.Log("Admin should be able to create a repo")
19 suite.adminKey.MustCmd(nil, "repo create test")
20
M
pr.go
+6,
-6
1@@ -31,7 +31,7 @@ type GitPatchRequest interface {
2 GetRepoByID(repoID int64) (*Repo, error)
3 GetRepoByName(user *User, repoName string) (*Repo, error)
4 CreateRepo(user *User, repoName string) (*Repo, error)
5- UpsertUser(pubkey, name string) (*User, error)
6+ RegisterUser(pubkey, name string) (*User, error)
7 IsBanned(pubkey, ipAddress string) error
8 SubmitPatchRequest(repoID int64, userID int64, patchset io.Reader) (*PatchRequest, error)
9 SubmitPatchset(prID, userID int64, op PatchsetOp, patchset io.Reader) ([]*Patch, error)
10@@ -194,16 +194,16 @@ func (pr PrCmd) createUser(pubkey, name string) (*User, error) {
11 return user, err
12 }
13
14-func (pr PrCmd) UpsertUser(pubkey, name string) (*User, error) {
15+func (pr PrCmd) RegisterUser(pubkey, name string) (*User, error) {
16 sanName := strings.ToLower(name)
17 if pubkey == "" {
18 return nil, fmt.Errorf("must provide pubkey during upsert")
19 }
20- user, err := pr.GetUserByPubkey(pubkey)
21- if err != nil {
22- user, err = pr.createUser(pubkey, sanName)
23+ _, err := pr.GetUserByPubkey(pubkey)
24+ if err == nil {
25+ return nil, fmt.Errorf("pubkey is already registered by another user")
26 }
27- return user, err
28+ return pr.createUser(pubkey, sanName)
29 }
30
31 func (pr PrCmd) GetPatchsetsByPrID(prID int64) ([]*Patchset, error) {
+7,
-3
1@@ -227,12 +227,16 @@ git push origin main
2 <summary>First time user?</summary>
3
4 <div>
5- Using this service for the first time? Creating a patch request is simple:
6+ Using this service for the first time? First you need to create an account:
7 </div>
8
9- <pre>git format-patch main --stdout | ssh {{.MetaData.URL}} pr create {repo}</pre>
10+ <blockquote>{username} is the name of your account</blockquote>
11+
12+ <pre>ssh {username}@{{.MetaData.URL}} register</pre>
13
14- <div>When running that command we will automatically create a user and a repo if one doesn't exist.</div>
15+ <div>After that, creating a patch request is simple:</div>
16+
17+ <pre>git format-patch main --stdout | ssh {{.MetaData.URL}} pr create {repo}</pre>
18
19 <div>Want to submit a v2 of the patch request?</div>
20