Mercurial > gemma
diff pkg/controllers/user.go @ 414:c1047fd04a3a
Moved project specific Go packages to new pkg folder.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 15 Aug 2018 17:30:50 +0200 |
parents | controllers/user.go@5b03f420957d |
children | c70ddc6eb168 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/controllers/user.go Wed Aug 15 17:30:50 2018 +0200 @@ -0,0 +1,288 @@ +package controllers + +import ( + "database/sql" + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "gemma.intevation.de/gemma/pkg/auth" +) + +const ( + createUserSQL = `INSERT INTO users.list_users + VALUES ($1, $2, $3, $4, NULL, $5)` + createUserExtentSQL = `INSERT INTO users.list_users + VALUES ($1, $2, $3, $4, + ST_MakeBox2D(ST_Point($5, $6), ST_Point($7, $8)), $9)` + + updateUserUnprivSQL = `UPDATE users.list_users + SET (pw, map_extent, email_address) + = ($2, ST_MakeBox2D(ST_Point($3, $4), ST_Point($5, $6)), $7) + WHERE username = $1` + updateUserSQL = `UPDATE users.list_users + SET (rolname, username, pw, country, map_extent, email_address) + = ($2, $3, $4, $5, NULL, $6) + WHERE username = $1` + updateUserExtentSQL = `UPDATE users.list_users + SET (rolname, username, pw, country, map_extent, email_address) + = ($2, $3, $4, $5, ST_MakeBox2D(ST_Point($6, $7), ST_Point($8, $9)), $10) + WHERE username = $1` + + deleteUserSQL = `DELETE FROM users.list_users WHERE username = $1` + + listUsersSQL = `SELECT + rolname, + username, + country, + email_address, + ST_XMin(map_extent), ST_YMin(map_extent), + ST_XMax(map_extent), ST_YMax(map_extent) +FROM users.list_users` + + listUserSQL = `SELECT + rolname, + country, + email_address, + ST_XMin(map_extent), ST_YMin(map_extent), + ST_XMax(map_extent), ST_YMax(map_extent) +FROM users.list_users +WHERE username = $1` +) + +func deleteUser( + _ interface{}, req *http.Request, + db *sql.DB, +) (jr JSONResult, err error) { + + user := mux.Vars(req)["user"] + if user == "" { + err = JSONError{http.StatusBadRequest, "error: user empty"} + return + } + + session, _ := auth.GetSession(req) + if session.User == user { + err = JSONError{http.StatusBadRequest, "error: cannot delete yourself"} + return + } + + var res sql.Result + + if res, err = db.Exec(deleteUserSQL, user); err != nil { + return + } + + if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { + err = JSONError{ + Code: http.StatusNotFound, + Message: fmt.Sprintf("Cannot find user %s.", user), + } + return + } + + // Running in a go routine should not be necessary. + go func() { auth.ConnPool.Logout(user) }() + + jr = JSONResult{Code: http.StatusNoContent} + return +} + +func updateUser( + input interface{}, req *http.Request, + db *sql.DB, +) (jr JSONResult, err error) { + + user := mux.Vars(req)["user"] + if user == "" { + err = JSONError{http.StatusBadRequest, "error: user empty"} + return + } + + newUser := input.(*User) + var res sql.Result + + if s, _ := auth.GetSession(req); s.Roles.Has("sys_admin") { + if newUser.Extent == nil { + res, err = db.Exec( + updateUserSQL, + user, + newUser.Role, + newUser.User, + newUser.Password, + newUser.Country, + newUser.Email, + ) + } else { + res, err = db.Exec( + updateUserExtentSQL, + user, + newUser.Role, + newUser.User, + newUser.Password, + newUser.Country, + newUser.Extent.X1, newUser.Extent.Y1, + newUser.Extent.X2, newUser.Extent.Y2, + newUser.Email, + ) + } + } else { + if newUser.Extent == nil { + err = JSONError{http.StatusBadRequest, "extent is mandatory"} + return + } + res, err = db.Exec( + updateUserUnprivSQL, + user, + newUser.Password, + newUser.Extent.X1, newUser.Extent.Y1, + newUser.Extent.X2, newUser.Extent.Y2, + newUser.Email, + ) + } + + if err != nil { + return + } + + if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { + err = JSONError{ + Code: http.StatusNotFound, + Message: fmt.Sprintf("Cannot find user %s.", user), + } + return + } + + if user != newUser.User { + // Running in a go routine should not be necessary. + go func() { auth.ConnPool.Logout(user) }() + } + + jr = JSONResult{ + Code: http.StatusCreated, + Result: struct { + Result string `json:"result"` + }{"success"}, + } + return +} + +func createUser( + input interface{}, req *http.Request, + db *sql.DB, +) (jr JSONResult, err error) { + + user := input.(*User) + + if user.Extent == nil { + _, err = db.Exec( + createUserSQL, + user.Role, + user.User, + user.Password, + user.Country, + user.Email, + ) + } else { + _, err = db.Exec( + createUserExtentSQL, + user.Role, + user.User, + user.Password, + user.Country, + user.Extent.X1, user.Extent.Y1, + user.Extent.X2, user.Extent.Y2, + user.Email, + ) + } + + if err != nil { + return + } + + jr = JSONResult{ + Code: http.StatusCreated, + Result: struct { + Result string `json:"result"` + }{"success"}, + } + return +} + +func listUsers( + _ interface{}, req *http.Request, + db *sql.DB, +) (jr JSONResult, err error) { + + var rows *sql.Rows + + rows, err = db.Query(listUsersSQL) + if err != nil { + return + } + defer rows.Close() + + var users []*User + + for rows.Next() { + user := &User{Extent: &BoundingBox{}} + if err = rows.Scan( + &user.Role, + &user.User, + &user.Country, + &user.Email, + &user.Extent.X1, &user.Extent.Y1, + &user.Extent.X2, &user.Extent.Y2, + ); err != nil { + return + } + users = append(users, user) + } + + jr = JSONResult{ + Result: struct { + Users []*User `json:"users"` + }{users}, + } + return +} + +func listUser( + _ interface{}, req *http.Request, + db *sql.DB, +) (jr JSONResult, err error) { + + user := mux.Vars(req)["user"] + if user == "" { + err = JSONError{http.StatusBadRequest, "error: user empty"} + return + } + + result := &User{ + User: user, + Extent: &BoundingBox{}, + } + + err = db.QueryRow(listUserSQL, user).Scan( + &result.Role, + &result.Country, + &result.Email, + &result.Extent.X1, &result.Extent.Y1, + &result.Extent.X2, &result.Extent.Y2, + ) + + switch { + case err == sql.ErrNoRows: + err = JSONError{ + Code: http.StatusNotFound, + Message: fmt.Sprintf("Cannot find user %s.", user), + } + return + case err != nil: + return + } + + jr.Result = result + return +}