Mercurial > gemma
view controllers/user.go @ 226:63dd5216eee4
Refactored gemma server to be more REST-like.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 26 Jul 2018 12:24:30 +0200 |
parents | cmd/gemma/user.go@bcd9016dcd4d |
children | 7d1f0ffdfa41 |
line wrap: on
line source
package controllers import ( "database/sql" "encoding/json" "errors" "log" "net/http" "regexp" "strings" "gemma.intevation.de/gemma/auth" "github.com/jackc/pgx" ) type ( Email string Country string Role string BoundingBox struct { X1 float64 `json:"x1"` Y1 float64 `json:"y1"` X2 float64 `json:"x2"` Y2 float64 `json:"y2"` } User struct { User string `json:"user"` Role Role `json:"role"` Password string `json:"password"` Email Email `json:"email"` Country Country `json:"country"` Extent *BoundingBox `json:"extent"` } ) const ( createUserSQL = `SELECT sys_admin.create_user($1, $2, $3, $4, NULL, $5)` createUserExtentSQL = `SELECT sys_admin.create_user($1, $2, $3, $4, ST_MakeBox2D(ST_Point($5, $6), ST_Point($7, $8)), $9)` ) var ( // https://stackoverflow.com/questions/201323/how-to-validate-an-email-address-using-a-regular-expression emailRe = regexp.MustCompile( `(?:[a-z0-9!#$%&'*+/=?^_` + "`" + `{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_` + "`" + `{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]` + `|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")` + `@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?` + `|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}` + `(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]` + `:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]` + `|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])`) errNoEmailAddress = errors.New("Not a valid email address") ) func (e *Email) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } if !emailRe.MatchString(s) { return errNoEmailAddress } *e = Email(s) return nil } var ( validCountries = []string{ "AT", "BG", "DE", "HU", "HR", "MD", "RO", "RS", "SK", "UA", } errNoValidCountry = errors.New("Not a valid country") ) func (c *Country) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } s = strings.ToUpper(s) for _, v := range validCountries { if v == s { *c = Country(v) return nil } } return errNoValidCountry } var ( validRoles = []string{ "waterway_user", "waterway_admin", "sys_admin", } errNoValidRole = errors.New("Not a valid role") ) func (r *Role) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } s = strings.ToLower(s) for _, v := range validRoles { if v == s { *r = Role(v) return nil } } return errNoValidRole } func createUser(rw http.ResponseWriter, req *http.Request) { var user User defer req.Body.Close() if err := json.NewDecoder(req.Body).Decode(&user); err != nil { http.Error(rw, "error: "+err.Error(), http.StatusBadRequest) return } token, _ := auth.GetToken(req) err := auth.ConnPool.Do(token, func(db *sql.DB) (err error) { if user.Extent == nil { _, err = db.Exec( createUserSQL, string(user.Role), user.User, user.Password, string(user.Country), string(user.Email), ) } else { _, err = db.Exec( createUserExtentSQL, string(user.Role), user.User, user.Password, string(user.Country), user.Extent.X1, user.Extent.Y1, user.Extent.X2, user.Extent.Y2, string(user.Email), ) } return }) var res struct { Result string `json:"result"` Code string `json:"code,omitempty"` Message string `json:"message,omitempty"` } if err != nil { if pgErr, ok := err.(pgx.PgError); ok { res.Result = "failure" res.Code = pgErr.Code res.Message = pgErr.Message } else { log.Printf("err: %v\n", err) http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError) return } } else { res.Result = "success" } rw.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(rw).Encode(&res); err != nil { log.Printf("error: %v\n", err) } }