💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Gemigit › files › b353a974c06ec924444f07c3df… captured on 2023-04-19 at 23:33:41. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 package db
1
2 import (
3 "crypto/rand"
4 "crypto/sha256"
5 "encoding/base64"
6 "time"
7 "log"
8 "errors"
9 )
10
11 func CanUsePassword(repo string, owner string, username string) (bool, error) {
12 row, err := db.Query(`SELECT securegit FROM user WHERE
13 UPPER(name) LIKE UPPER(?)`, username)
14 if err != nil {
15 log.Println(err)
16 return false, err
17 }
18 defer row.Close()
19 var secure int
20 if (!row.Next()) {
21 return false, errors.New("not found")
22 }
23 row.Scan(&secure)
24 if secure != 0 {
25 return false, nil
26 }
27 row.Close()
28
29 row, err = db.Query(`SELECT b.securegit FROM user a
30 INNER JOIN repo b ON a.userID = b.UserID WHERE
31 UPPER(a.name) LIKE UPPER(?) AND
32 UPPER(b.name) LIKE UPPER(?)`,
33 owner, repo)
34 if err != nil {
35 log.Println(err)
36 return false, err
37 }
38 if (!row.Next()) {
39 return false, errors.New("not found")
40 }
41 defer row.Close()
42 row.Scan(&secure)
43 return secure == 0, nil
44 }
45
46 func (user User) CreateToken() (string, error) {
47 data := make([]byte, 32)
48 if _, err := rand.Read(data); err != nil {
49 return "", err
50 }
51 token := base64.RawStdEncoding.EncodeToString(data)
52 sum := sha256.Sum224(data)
53 hash := base64.RawStdEncoding.EncodeToString(sum[:])
54 _, err := db.Exec(`INSERT INTO token(userID, token, hint, expiration)
55 VALUES(?, ?, ?, ?);`,
56 user.ID, hash, token[0:4],
57 time.Now().Unix() + 3600 * 24 * 30)
58 if err != nil {
59 return "", err
60 }
61
62 return token, nil
63 }
64
65 func (user User) RenewToken(tokenID int) (error) {
66 _, err := db.Exec(`UPDATE token SET expiration = ?
67 WHERE tokenID = ? AND userID = ?`,
68 time.Now().Unix() + 3600 * 24 * 30,
69 tokenID, user.ID)
70 return err
71 }
72
73 func (user User) DeleteToken(tokenID int) (error) {
74 row, err := db.Exec(`DELETE FROM token WHERE tokenID = ? AND userID = ?`,
75 tokenID, user.ID)
76 if err != nil {
77 return err
78 }
79 count, err := row.RowsAffected()
80 if err != nil {
81 return err
82 }
83 if count < 1 {
84 return errors.New("invalid token")
85 }
86 return nil
87 }
88
89 func (user User) GetTokens() ([]Token, error) {
90 rows, err := db.Query(`SELECT tokenID, expiration, hint FROM token
91 WHERE userID = ?`, user.ID)
92 if err != nil {
93 log.Println(err)
94 return nil, errors.New("unexpected error")
95 }
96 defer rows.Close()
97
98 tokens := []Token{}
99 for rows.Next() {
100 var r Token
101 err = rows.Scan(&r.ID, &r.Expiration, &r.Hint)
102 if err != nil {
103 return nil, err
104 }
105 r.ExpirationFormat = time.Unix(r.Expiration, 0).UTC().
106 Format(time.RFC1123)
107 tokens = append(tokens, r)
108 }
109 return tokens, nil
110 }
111
112 func (user *User) ToggleSecure() error {
113 user.SecureGit = !user.SecureGit
114
115 _, err := db.Exec("UPDATE user SET securegit = ? " +
116 "WHERE userID = ?", user.SecureGit, user.ID)
117 if err != nil {
118 return err
119 }
120
121 users[user.Signature] = *user
122 return nil
123 }
124
125 func TokenAuth(username string, token string) error {
126 decoded, err := base64.RawStdEncoding.DecodeString(token)
127 if err != nil {
128 log.Println(err)
129 return errors.New("unexpected error")
130 }
131 sum := sha256.Sum224(decoded)
132 hash := base64.RawStdEncoding.EncodeToString(sum[:])
133 row, err := db.Query(`SELECT b.expiration FROM user a
134 INNER JOIN token b ON a.userID = b.UserID WHERE
135 UPPER(a.name) LIKE UPPER(?) AND
136 UPPER(b.token) LIKE UPPER(?)`,
137 username, hash)
138 if err != nil {
139 log.Println(err)
140 return errors.New("unexpected error")
141 }
142 defer row.Close()
143 if !row.Next() {
144 return errors.New("invalid token")
145 }
146 var expiration int64
147 row.Scan(&expiration)
148 if expiration <= time.Now().Unix() {
149 return errors.New("token expired")
150 }
151 return nil
152 }
153