Mercurial > gemma
comparison pkg/controllers/user.go @ 5345:95dafb72a288 extented-report
Added a PATCH endpoint for /api/users/{user}
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sun, 20 Jun 2021 04:17:53 +0200 |
parents | b1b9b384540d |
children | 566c8063223b |
comparison
equal
deleted
inserted
replaced
5344:7df6062a1371 | 5345:95dafb72a288 |
---|---|
19 "bytes" | 19 "bytes" |
20 "database/sql" | 20 "database/sql" |
21 "fmt" | 21 "fmt" |
22 "log" | 22 "log" |
23 "net/http" | 23 "net/http" |
24 "strconv" | |
25 "strings" | |
24 "text/template" | 26 "text/template" |
25 "time" | 27 "time" |
26 | 28 |
27 "github.com/gorilla/mux" | 29 "github.com/gorilla/mux" |
28 | 30 |
243 }{"success"}, | 245 }{"success"}, |
244 } | 246 } |
245 return | 247 return |
246 } | 248 } |
247 | 249 |
250 func patchUser(req *http.Request) (jr mw.JSONResult, err error) { | |
251 | |
252 user := models.UserName(mux.Vars(req)["user"]) | |
253 if !user.IsValid() { | |
254 err = mw.JSONError{ | |
255 Code: http.StatusBadRequest, | |
256 Message: "error: user invalid", | |
257 } | |
258 return | |
259 } | |
260 | |
261 s, ok := auth.GetSession(req) | |
262 if !ok { | |
263 err = mw.JSONError{ | |
264 Code: http.StatusUnauthorized, | |
265 Message: "error: not logged in", | |
266 } | |
267 return | |
268 } | |
269 | |
270 priv := s.Roles.Has("sys_admin") | |
271 | |
272 if !priv && s.User != string(user) { | |
273 err = mw.JSONError{ | |
274 Code: http.StatusUnauthorized, | |
275 Message: "error: not allowed to modify someone else", | |
276 } | |
277 return | |
278 } | |
279 | |
280 var ( | |
281 columns []string | |
282 positions []string | |
283 args []interface{} | |
284 ) | |
285 | |
286 update := func(column string, value interface{}) { | |
287 columns = append(columns, column) | |
288 positions = append(positions, "$"+strconv.Itoa(len(positions)+1)) | |
289 args = append(args, value) | |
290 } | |
291 | |
292 updateBox := func(column string, extent *models.BoundingBox) { | |
293 columns = append(columns, column) | |
294 pos := len(positions) | |
295 position := fmt.Sprintf("ST_MakeBox2D(ST_Point($%d, $%d), ST_Point($%d, $%d))", | |
296 pos+1, pos+2, pos+3, pos+4) | |
297 positions = append(positions, position) | |
298 args = append(args, extent.X1, extent.Y1, extent.X2, extent.Y2) | |
299 } | |
300 | |
301 patch := mw.JSONInput(req).(*models.UserPatch) | |
302 | |
303 if patch.User != nil && priv { | |
304 update("user", *patch.User) | |
305 } | |
306 if patch.Role != nil && priv { | |
307 update("rolname", *patch.Role) | |
308 } | |
309 if patch.Password != nil { | |
310 update("pw", *patch.Password) | |
311 } | |
312 if patch.Email != nil { | |
313 update("email_address", *patch.Email) | |
314 } | |
315 if patch.Country != nil && priv { | |
316 update("country", *patch.Country) | |
317 } | |
318 if patch.Reports != nil && priv { | |
319 update("report_reciever", *patch.Reports) | |
320 } | |
321 if patch.Extent != nil { | |
322 updateBox("map_extent", patch.Extent) | |
323 } | |
324 | |
325 var colsS, posS string | |
326 | |
327 switch len(columns) { | |
328 case 0: // Nothing to do | |
329 jr = mw.JSONResult{ | |
330 Code: http.StatusCreated, | |
331 Result: struct { | |
332 Result string `json:"result"` | |
333 }{"success"}, | |
334 } | |
335 return | |
336 case 1: // No brackets if there is only one argument. | |
337 colsS = columns[0] | |
338 posS = positions[0] | |
339 default: | |
340 colsS = "(" + strings.Join(columns, ",") + ")" | |
341 posS = "(" + strings.Join(positions, ",") + ")" | |
342 } | |
343 | |
344 stmt := fmt.Sprintf( | |
345 `UPDATE users.list_users SET %s = %s WHERE username = $%d`, | |
346 colsS, | |
347 posS, | |
348 len(positions)+1) | |
349 | |
350 args = append(args, user) | |
351 | |
352 db := mw.JSONConn(req) | |
353 | |
354 var res sql.Result | |
355 if res, err = db.ExecContext(req.Context(), stmt, args...); err != nil { | |
356 return | |
357 } | |
358 | |
359 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { | |
360 err = mw.JSONError{ | |
361 Code: http.StatusNotFound, | |
362 Message: fmt.Sprintf("Cannot find user %s.", user), | |
363 } | |
364 return | |
365 } | |
366 | |
367 if patch.User != nil && *patch.User != user { | |
368 // Running in a go routine should not be necessary. | |
369 go func() { auth.Sessions.Logout(string(user)) }() | |
370 } | |
371 | |
372 jr = mw.JSONResult{ | |
373 Code: http.StatusCreated, | |
374 Result: struct { | |
375 Result string `json:"result"` | |
376 }{"success"}, | |
377 } | |
378 return | |
379 } | |
380 | |
248 func createUser(req *http.Request) (jr mw.JSONResult, err error) { | 381 func createUser(req *http.Request) (jr mw.JSONResult, err error) { |
249 | 382 |
250 user := mw.JSONInput(req).(*models.User) | 383 user := mw.JSONInput(req).(*models.User) |
251 | 384 |
252 db := mw.JSONConn(req) | 385 db := mw.JSONConn(req) |