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
+}