- commit
- b4c0f63
- parent
- dd52190
- author
- Eric Bower
- date
- 2024-06-25 16:59:29 -0400 EDT
chore: prevent user collisions
M
db.go
+2,
-2
1@@ -10,7 +10,7 @@ import (
2 _ "modernc.org/sqlite"
3 )
4
5-// User is a db model for users
6+// User is a db model for users.
7 type User struct {
8 ID int64 `db:"id"`
9 Pubkey string `db:"pubkey"`
10@@ -19,7 +19,7 @@ type User struct {
11 UpdatedAt time.Time `db:"updated_at"`
12 }
13
14-// Acl is a db model for access control
15+// Acl is a db model for access control.
16 type Acl struct {
17 ID int64 `db:"id"`
18 Pubkey sql.NullString `db:"pubkey"`
M
pr.go
+21,
-2
1@@ -87,6 +87,20 @@ func (pr PrCmd) GetUserByPubkey(pubkey string) (*User, error) {
2 return &user, err
3 }
4
5+func (pr PrCmd) computeUserName(name string) (string, error) {
6+ var user User
7+ err := pr.Backend.DB.Get(&user, "SELECT * FROM app_users WHERE name=?", name)
8+ if err != nil {
9+ return name, err
10+ }
11+ // name is available
12+ if user.ID == 0 {
13+ return name, nil
14+ }
15+ // collision, generate random number and append
16+ return fmt.Sprintf("%s%s", name, randSeq(4)), nil
17+}
18+
19 func (pr PrCmd) createUser(pubkey, name string) (*User, error) {
20 if pubkey == "" {
21 return nil, fmt.Errorf("must provide pubkey when creating user")
22@@ -95,13 +109,18 @@ func (pr PrCmd) createUser(pubkey, name string) (*User, error) {
23 return nil, fmt.Errorf("must provide user name when creating user")
24 }
25
26+ userName, err := pr.computeUserName(name)
27+ if err != nil {
28+ pr.Backend.Logger.Error("could not compute username", "err", err)
29+ }
30+
31 var userID int64
32 row := pr.Backend.DB.QueryRow(
33 "INSERT INTO app_users (pubkey, name) VALUES (?, ?) RETURNING id",
34 pubkey,
35- name,
36+ userName,
37 )
38- err := row.Scan(&userID)
39+ err = row.Scan(&userID)
40 if err != nil {
41 return nil, err
42 }
M
util.go
+12,
-0
1@@ -6,6 +6,7 @@ import (
2 "errors"
3 "fmt"
4 "io"
5+ "math/rand"
6 "os"
7 "strconv"
8 "strings"
9@@ -13,6 +14,17 @@ import (
10 "github.com/charmbracelet/ssh"
11 )
12
13+var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
14+
15+// https://stackoverflow.com/a/22892986
16+func randSeq(n int) string {
17+ b := make([]rune, n)
18+ for i := range b {
19+ b[i] = letters[rand.Intn(len(letters))]
20+ }
21+ return string(b)
22+}
23+
24 func truncateSha(sha string) string {
25 return sha[:7]
26 }