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 }