Mercurial > gemma
comparison pkg/controllers/user.go @ 4244:4394daeea96a json-handler-middleware
Moved JSONHandler into middleware package.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 22 Aug 2019 11:26:48 +0200 |
parents | d776110b4db0 |
children | e020e6e34ad7 |
comparison
equal
deleted
inserted
replaced
4243:d776110b4db0 | 4244:4394daeea96a |
---|---|
29 "gemma.intevation.de/gemma/pkg/auth" | 29 "gemma.intevation.de/gemma/pkg/auth" |
30 "gemma.intevation.de/gemma/pkg/misc" | 30 "gemma.intevation.de/gemma/pkg/misc" |
31 "gemma.intevation.de/gemma/pkg/models" | 31 "gemma.intevation.de/gemma/pkg/models" |
32 "gemma.intevation.de/gemma/pkg/pgxutils" | 32 "gemma.intevation.de/gemma/pkg/pgxutils" |
33 "gemma.intevation.de/gemma/pkg/scheduler" | 33 "gemma.intevation.de/gemma/pkg/scheduler" |
34 | |
35 mw "gemma.intevation.de/gemma/pkg/middleware" | |
34 ) | 36 ) |
35 | 37 |
36 const ( | 38 const ( |
37 createUserSQL = `INSERT INTO users.list_users | 39 createUserSQL = `INSERT INTO users.list_users |
38 VALUES ($1, $2, $3, $4, NULL, $5)` | 40 VALUES ($1, $2, $3, $4, NULL, $5)` |
95 When the status of an data import managed by you changes an automated mail will | 97 When the status of an data import managed by you changes an automated mail will |
96 be send to the address: {{ .Email }} with details on the new import status | 98 be send to the address: {{ .Email }} with details on the new import status |
97 (inkluding import errors) and details on the concerned import.`)) | 99 (inkluding import errors) and details on the concerned import.`)) |
98 ) | 100 ) |
99 | 101 |
100 func deleteUser(req *http.Request) (jr JSONResult, err error) { | 102 func deleteUser(req *http.Request) (jr mw.JSONResult, err error) { |
101 | 103 |
102 user := mux.Vars(req)["user"] | 104 user := mux.Vars(req)["user"] |
103 if !models.UserName(user).IsValid() { | 105 if !models.UserName(user).IsValid() { |
104 err = JSONError{http.StatusBadRequest, "error: user invalid"} | 106 err = mw.JSONError{http.StatusBadRequest, "error: user invalid"} |
105 return | 107 return |
106 } | 108 } |
107 | 109 |
108 session, _ := auth.GetSession(req) | 110 session, _ := auth.GetSession(req) |
109 if session.User == user { | 111 if session.User == user { |
110 err = JSONError{http.StatusBadRequest, "error: cannot delete yourself"} | 112 err = mw.JSONError{http.StatusBadRequest, "error: cannot delete yourself"} |
111 return | 113 return |
112 } | 114 } |
113 | 115 |
114 ctx := req.Context() | 116 ctx := req.Context() |
115 | 117 |
116 db := JSONConn(req) | 118 db := mw.JSONConn(req) |
117 | 119 |
118 // Remove scheduled tasks. | 120 // Remove scheduled tasks. |
119 ids, err2 := scheduler.ScheduledUserIDs(ctx, db, user) | 121 ids, err2 := scheduler.ScheduledUserIDs(ctx, db, user) |
120 if err2 == nil { | 122 if err2 == nil { |
121 if len(ids) > 0 { | 123 if len(ids) > 0 { |
130 if res, err = db.ExecContext(ctx, deleteUserSQL, user); err != nil { | 132 if res, err = db.ExecContext(ctx, deleteUserSQL, user); err != nil { |
131 return | 133 return |
132 } | 134 } |
133 | 135 |
134 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { | 136 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { |
135 err = JSONError{ | 137 err = mw.JSONError{ |
136 Code: http.StatusNotFound, | 138 Code: http.StatusNotFound, |
137 Message: fmt.Sprintf("Cannot find user %s.", user), | 139 Message: fmt.Sprintf("Cannot find user %s.", user), |
138 } | 140 } |
139 return | 141 return |
140 } | 142 } |
141 | 143 |
142 // Running in a go routine should not be necessary. | 144 // Running in a go routine should not be necessary. |
143 go func() { auth.Sessions.Logout(user) }() | 145 go func() { auth.Sessions.Logout(user) }() |
144 | 146 |
145 jr = JSONResult{Code: http.StatusNoContent} | 147 jr = mw.JSONResult{Code: http.StatusNoContent} |
146 return | 148 return |
147 } | 149 } |
148 | 150 |
149 func updateUser(req *http.Request) (jr JSONResult, err error) { | 151 func updateUser(req *http.Request) (jr mw.JSONResult, err error) { |
150 | 152 |
151 user := models.UserName(mux.Vars(req)["user"]) | 153 user := models.UserName(mux.Vars(req)["user"]) |
152 if !user.IsValid() { | 154 if !user.IsValid() { |
153 err = JSONError{http.StatusBadRequest, "error: user invalid"} | 155 err = mw.JSONError{http.StatusBadRequest, "error: user invalid"} |
154 return | 156 return |
155 } | 157 } |
156 | 158 |
157 newUser := JSONInput(req).(*models.User) | 159 newUser := mw.JSONInput(req).(*models.User) |
158 var res sql.Result | 160 var res sql.Result |
159 | 161 |
160 db := JSONConn(req) | 162 db := mw.JSONConn(req) |
161 | 163 |
162 if s, _ := auth.GetSession(req); s.Roles.Has("sys_admin") { | 164 if s, _ := auth.GetSession(req); s.Roles.Has("sys_admin") { |
163 if newUser.Extent == nil { | 165 if newUser.Extent == nil { |
164 res, err = db.ExecContext( | 166 res, err = db.ExecContext( |
165 req.Context(), | 167 req.Context(), |
185 newUser.Email, | 187 newUser.Email, |
186 ) | 188 ) |
187 } | 189 } |
188 } else { | 190 } else { |
189 if newUser.Extent == nil { | 191 if newUser.Extent == nil { |
190 err = JSONError{http.StatusBadRequest, "extent is mandatory"} | 192 err = mw.JSONError{http.StatusBadRequest, "extent is mandatory"} |
191 return | 193 return |
192 } | 194 } |
193 res, err = db.ExecContext( | 195 res, err = db.ExecContext( |
194 req.Context(), | 196 req.Context(), |
195 updateUserUnprivSQL, | 197 updateUserUnprivSQL, |
204 if err != nil { | 206 if err != nil { |
205 return | 207 return |
206 } | 208 } |
207 | 209 |
208 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { | 210 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { |
209 err = JSONError{ | 211 err = mw.JSONError{ |
210 Code: http.StatusNotFound, | 212 Code: http.StatusNotFound, |
211 Message: fmt.Sprintf("Cannot find user %s.", user), | 213 Message: fmt.Sprintf("Cannot find user %s.", user), |
212 } | 214 } |
213 return | 215 return |
214 } | 216 } |
216 if user != newUser.User { | 218 if user != newUser.User { |
217 // Running in a go routine should not be necessary. | 219 // Running in a go routine should not be necessary. |
218 go func() { auth.Sessions.Logout(string(user)) }() | 220 go func() { auth.Sessions.Logout(string(user)) }() |
219 } | 221 } |
220 | 222 |
221 jr = JSONResult{ | 223 jr = mw.JSONResult{ |
222 Code: http.StatusCreated, | 224 Code: http.StatusCreated, |
223 Result: struct { | 225 Result: struct { |
224 Result string `json:"result"` | 226 Result string `json:"result"` |
225 }{"success"}, | 227 }{"success"}, |
226 } | 228 } |
227 return | 229 return |
228 } | 230 } |
229 | 231 |
230 func createUser(req *http.Request) (jr JSONResult, err error) { | 232 func createUser(req *http.Request) (jr mw.JSONResult, err error) { |
231 | 233 |
232 user := JSONInput(req).(*models.User) | 234 user := mw.JSONInput(req).(*models.User) |
233 | 235 |
234 db := JSONConn(req) | 236 db := mw.JSONConn(req) |
235 | 237 |
236 if user.Extent == nil { | 238 if user.Extent == nil { |
237 _, err = db.ExecContext( | 239 _, err = db.ExecContext( |
238 req.Context(), | 240 req.Context(), |
239 createUserSQL, | 241 createUserSQL, |
257 ) | 259 ) |
258 } | 260 } |
259 | 261 |
260 if err != nil { | 262 if err != nil { |
261 m, c := pgxutils.ReadableError{Err: err}.MessageAndCode() | 263 m, c := pgxutils.ReadableError{Err: err}.MessageAndCode() |
262 err = JSONError{Code: c, Message: m} | 264 err = mw.JSONError{Code: c, Message: m} |
263 return | 265 return |
264 } | 266 } |
265 | 267 |
266 jr = JSONResult{ | 268 jr = mw.JSONResult{ |
267 Code: http.StatusCreated, | 269 Code: http.StatusCreated, |
268 Result: struct { | 270 Result: struct { |
269 Result string `json:"result"` | 271 Result string `json:"result"` |
270 }{"success"}, | 272 }{"success"}, |
271 } | 273 } |
272 return | 274 return |
273 } | 275 } |
274 | 276 |
275 func listUsers(req *http.Request) (jr JSONResult, err error) { | 277 func listUsers(req *http.Request) (jr mw.JSONResult, err error) { |
276 | 278 |
277 var rows *sql.Rows | 279 var rows *sql.Rows |
278 | 280 |
279 rows, err = JSONConn(req).QueryContext(req.Context(), listUsersSQL) | 281 rows, err = mw.JSONConn(req).QueryContext(req.Context(), listUsersSQL) |
280 if err != nil { | 282 if err != nil { |
281 return | 283 return |
282 } | 284 } |
283 defer rows.Close() | 285 defer rows.Close() |
284 | 286 |
297 return | 299 return |
298 } | 300 } |
299 users = append(users, user) | 301 users = append(users, user) |
300 } | 302 } |
301 | 303 |
302 jr = JSONResult{ | 304 jr = mw.JSONResult{ |
303 Result: struct { | 305 Result: struct { |
304 Users []*models.User `json:"users"` | 306 Users []*models.User `json:"users"` |
305 }{users}, | 307 }{users}, |
306 } | 308 } |
307 return | 309 return |
308 } | 310 } |
309 | 311 |
310 func listUser(req *http.Request) (jr JSONResult, err error) { | 312 func listUser(req *http.Request) (jr mw.JSONResult, err error) { |
311 | 313 |
312 user := models.UserName(mux.Vars(req)["user"]) | 314 user := models.UserName(mux.Vars(req)["user"]) |
313 if !user.IsValid() { | 315 if !user.IsValid() { |
314 err = JSONError{http.StatusBadRequest, "error: user invalid"} | 316 err = mw.JSONError{http.StatusBadRequest, "error: user invalid"} |
315 return | 317 return |
316 } | 318 } |
317 | 319 |
318 result := &models.User{ | 320 result := &models.User{ |
319 User: user, | 321 User: user, |
320 Extent: &models.BoundingBox{}, | 322 Extent: &models.BoundingBox{}, |
321 } | 323 } |
322 | 324 |
323 err = JSONConn(req).QueryRowContext(req.Context(), listUserSQL, user).Scan( | 325 err = mw.JSONConn(req).QueryRowContext(req.Context(), listUserSQL, user).Scan( |
324 &result.Role, | 326 &result.Role, |
325 &result.Country, | 327 &result.Country, |
326 &result.Email, | 328 &result.Email, |
327 &result.Extent.X1, &result.Extent.Y1, | 329 &result.Extent.X1, &result.Extent.Y1, |
328 &result.Extent.X2, &result.Extent.Y2, | 330 &result.Extent.X2, &result.Extent.Y2, |
329 ) | 331 ) |
330 | 332 |
331 switch { | 333 switch { |
332 case err == sql.ErrNoRows: | 334 case err == sql.ErrNoRows: |
333 err = JSONError{ | 335 err = mw.JSONError{ |
334 Code: http.StatusNotFound, | 336 Code: http.StatusNotFound, |
335 Message: fmt.Sprintf("Cannot find user %s.", user), | 337 Message: fmt.Sprintf("Cannot find user %s.", user), |
336 } | 338 } |
337 return | 339 return |
338 case err != nil: | 340 case err != nil: |
341 | 343 |
342 jr.Result = result | 344 jr.Result = result |
343 return | 345 return |
344 } | 346 } |
345 | 347 |
346 func sendTestMail(req *http.Request) (jr JSONResult, err error) { | 348 func sendTestMail(req *http.Request) (jr mw.JSONResult, err error) { |
347 | 349 |
348 user := models.UserName(mux.Vars(req)["user"]) | 350 user := models.UserName(mux.Vars(req)["user"]) |
349 if !user.IsValid() { | 351 if !user.IsValid() { |
350 err = JSONError{http.StatusBadRequest, "error: user invalid"} | 352 err = mw.JSONError{http.StatusBadRequest, "error: user invalid"} |
351 return | 353 return |
352 } | 354 } |
353 | 355 |
354 userData := &models.User{ | 356 userData := &models.User{ |
355 User: user, | 357 User: user, |
356 Extent: &models.BoundingBox{}, | 358 Extent: &models.BoundingBox{}, |
357 } | 359 } |
358 | 360 |
359 err = JSONConn(req).QueryRowContext(req.Context(), listUserSQL, user).Scan( | 361 err = mw.JSONConn(req).QueryRowContext(req.Context(), listUserSQL, user).Scan( |
360 &userData.Role, | 362 &userData.Role, |
361 &userData.Country, | 363 &userData.Country, |
362 &userData.Email, | 364 &userData.Email, |
363 &userData.Extent.X1, &userData.Extent.Y1, | 365 &userData.Extent.X1, &userData.Extent.Y1, |
364 &userData.Extent.X2, &userData.Extent.Y2, | 366 &userData.Extent.X2, &userData.Extent.Y2, |
365 ) | 367 ) |
366 | 368 |
367 switch { | 369 switch { |
368 case err == sql.ErrNoRows: | 370 case err == sql.ErrNoRows: |
369 err = JSONError{ | 371 err = mw.JSONError{ |
370 Code: http.StatusNotFound, | 372 Code: http.StatusNotFound, |
371 Message: fmt.Sprintf("Cannot find user %s.", user), | 373 Message: fmt.Sprintf("Cannot find user %s.", user), |
372 } | 374 } |
373 return | 375 return |
374 case err != nil: | 376 case err != nil: |
393 bodyTmpl = testSysadminNotifyMailTmpl | 395 bodyTmpl = testSysadminNotifyMailTmpl |
394 } else if userData.Role == "waterway_admin" { | 396 } else if userData.Role == "waterway_admin" { |
395 subject = "Gemma: Waterway Admin Notification TEST" | 397 subject = "Gemma: Waterway Admin Notification TEST" |
396 bodyTmpl = testWWAdminNotifyMailTmpl | 398 bodyTmpl = testWWAdminNotifyMailTmpl |
397 } else { | 399 } else { |
398 err = JSONError{ | 400 err = mw.JSONError{ |
399 Code: http.StatusBadRequest, | 401 Code: http.StatusBadRequest, |
400 Message: "Test mails can only be generated for admin roles.", | 402 Message: "Test mails can only be generated for admin roles.", |
401 } | 403 } |
402 return | 404 return |
403 } | 405 } |