💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Gemigit › files › e1d2c14edf853e9acf54bbc5fd… captured on 2023-09-08 at 16:28:29. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-05-24)
-=-=-=-=-=-=-
0 package db
1
2 import (
3 "errors"
4 "time"
5 "gemigit/config"
6 )
7
8 const descriptionMaxLength = 128
9
10 var users = make(map[string]User)
11
12 func (user *User) VerifySignature(signature string) error {
13 if user.Signature != signature {
14 return errors.New("wrong signature")
15 }
16 if users[signature].ID != user.ID {
17 return errors.New("signature doesn't match the user")
18 }
19 return nil
20 }
21
22 func userAlreadyExist(username string) error {
23 rows, err := db.Query(
24 "SELECT * FROM user WHERE UPPER(name) LIKE UPPER(?)",
25 username)
26 if err != nil {
27 return err
28 }
29 defer rows.Close()
30 if rows.Next() {
31 return errors.New("This username is already taken")
32 }
33 return nil
34 }
35
36 func GetPublicUser(name string) (User, error) {
37 rows, err := db.Query("SELECT userID, name, description, creation " +
38 "FROM user WHERE UPPER(name) LIKE UPPER(?)",
39 name)
40 if err != nil {
41 return User{}, err
42 }
43 defer rows.Close()
44 if !rows.Next() {
45 return User{}, errors.New(name + ", user not found")
46 }
47 var u = User{}
48 err = rows.Scan(&u.ID, &u.Name,
49 &u.Description,
50 &u.Registration)
51 if err != nil {
52 return User{}, err
53 }
54 return u, nil
55 }
56
57 func ChangePassword(username string, password string) error {
58 err := isPasswordValid(password)
59 if err != nil {
60 return err
61 }
62 hPassword, err := hashPassword(password)
63 if err != nil {
64 return err
65 }
66 statement, err := db.Exec("UPDATE user SET password=? " +
67 "WHERE UPPER(name) LIKE UPPER(?)",
68 hPassword, username)
69 if err != nil {
70 return err
71 }
72 rows, err := statement.RowsAffected()
73 if err != nil {
74 return err
75 }
76 if rows < 1 {
77 return errors.New("unknown user " + username)
78 }
79 return nil
80 }
81
82 func (user User) ChangePassword(password string, signature string) error {
83 if err := user.VerifySignature(signature); err != nil {
84 return err
85 }
86 return ChangePassword(user.Name, password)
87 }
88
89 func (user User) ChangeDescription(desc string, signature string) error {
90 if err := user.VerifySignature(signature); err != nil {
91 return err
92 }
93 if len(desc) >= descriptionMaxLength {
94 return errors.New("description too long")
95 }
96 statement, err := db.Exec("UPDATE user SET description=? " +
97 "WHERE UPPER(name) LIKE UPPER(?)",
98 desc, user.Name)
99 if err != nil {
100 return err
101 }
102 rows, err := statement.RowsAffected()
103 if err != nil {
104 return err
105 }
106 if rows < 1 {
107 return errors.New("no description changed")
108 }
109 u, b := users[signature]
110 if !b {
111 return errors.New("invalid signature detected")
112 }
113 u.Description = desc
114 users[signature] = u
115 return nil
116 }
117
118 func (user *User) UpdateDescription() error {
119 rows, err := db.Query("SELECT description FROM user WHERE userID=?",
120 user.ID)
121 if err != nil {
122 return err
123 }
124 defer rows.Close()
125 if rows.Next() {
126 var dDescription string
127 err = rows.Scan(&dDescription)
128 if err != nil {
129 return err
130 }
131 user.Description = dDescription
132 } else {
133 return errors.New("invalid user")
134 }
135 users[user.Signature] = *user
136 return nil
137 }
138
139 func (user *User) SetSecret(secret string) error {
140 res, err := db.Exec("UPDATE user SET secret = ? " +
141 "WHERE userID = ?", secret, user.ID)
142 if err != nil {
143 return err
144 }
145 rows, err := res.RowsAffected()
146 if err != nil {
147 return err
148 }
149 if rows != 1 {
150 return errors.New("user not found")
151 }
152 user.Secret = secret
153 users[user.Signature] = *user
154 return nil
155 }
156
157 func DeleteUser(username string) error {
158 statement, err := db.Exec("DELETE FROM repo " +
159 "WHERE userID in " +
160 "(SELECT userID FROM user " +
161 "where UPPER(name) LIKE UPPER(?))",
162 username)
163 if err != nil {
164 return err
165 }
166 rows, err := statement.RowsAffected()
167 if err != nil {
168 return err
169 }
170 statement, err = db.Exec("DELETE FROM user WHERE name=?", username)
171 if err != nil {
172 return err
173 }
174 rows, err = statement.RowsAffected()
175 if err != nil {
176 return err
177 }
178 if rows < 1 {
179 return errors.New("user " + username + " not found")
180 }
181 return nil
182 }
183
184 func GetUserID(name string) (int, error) {
185 query := "SELECT userID FROM user WHERE UPPER(?) = UPPER(name);"
186 rows, err := db.Query(query, name)
187 if err != nil {
188 return -1, err
189 }
190 defer rows.Close()
191 if !rows.Next() {
192 return -1, errors.New("User not found")
193 }
194 var id int
195 err = rows.Scan(&id)
196 if err != nil {
197 return -1, err
198 }
199 return id, nil
200 }
201
202 func GetUser(signature string) (User, bool) {
203 user, b := users[signature]
204 // should update description
205 if b {
206 return user, b
207 }
208 rows, err := db.Query(`SELECT a.userID, name, description, a.creation,
209 a.secret, a.securegit
210 FROM user a INNER JOIN certificate b ON
211 a.userID = b.userID WHERE b.hash = ?`,
212 signature)
213 if err != nil {
214 return User{}, false
215 }
216 defer rows.Close()
217 if !rows.Next() {
218 return User{}, false
219 }
220 err = rows.Scan(&user.ID, &user.Name, &user.Description,
221 &user.Registration, &user.Secret, &user.SecureGit)
222 if err != nil {
223 return User{}, false
224 }
225 user.Signature = signature
226 users[signature] = user
227 return user, true
228 }
229
230 func FetchUser(username string, signature string) (User, error) {
231 query := `SELECT userID, name, description, creation, secret, securegit
232 FROM user WHERE UPPER(name) LIKE UPPER(?)`
233 rows, err := db.Query(query, username)
234 if err != nil {
235 return User{}, err
236 }
237 defer rows.Close()
238 next := rows.Next()
239 if !next {
240 return User{}, errors.New("User not found")
241 }
242 var u = User{}
243 err = rows.Scan(&u.ID,
244 &u.Name,
245 &u.Description,
246 &u.Registration,
247 &u.Secret,
248 &u.SecureGit)
249 if err != nil {
250 return User{}, err
251 }
252 u.Connection = time.Now()
253 u.Signature = signature
254 return u, nil
255 }
256
257 func CheckAuth(username string, password string) error {
258 rows, err := db.Query("SELECT name, password FROM user " +
259 "WHERE UPPER(name) LIKE UPPER(?)",
260 username)
261 if err != nil {
262 return err
263 }
264 defer rows.Close()
265 if rows.Next() {
266 var dPassword string
267 var dName string
268 err = rows.Scan(&dName, &dPassword)
269 if err != nil {
270 return err
271 }
272 if checkPassword(password, dPassword) {
273 return nil
274 }
275 }
276 return errors.New("invalid credential")
277 }
278
279 func Register(username string, password string) error {
280
281 if !config.Cfg.Ldap.Enabled {
282 if err := isPasswordValid(password); err != nil {
283 return err
284 }
285 }
286
287 if err := isUsernameValid(username); err != nil {
288 return err
289 }
290
291 if err := userAlreadyExist(username); err != nil {
292 return err
293 }
294
295 if !config.Cfg.Ldap.Enabled {
296 hash, err := hashPassword(password)
297 if err != nil {
298 return err
299 }
300
301 _, err = db.Exec("INSERT INTO user(name,password,creation) " +
302 "VALUES(?, ?, " + unixTime + ");",
303 username, hash)
304 return err
305 }
306 _, err := db.Exec("INSERT INTO user(name,creation) " +
307 "VALUES(?, " + unixTime + ")", username)
308 return err
309 }
310