Mercurial > gemma
view cmd/tokenserver/user.go @ 196:b67208d82543
Make test output more comprehensive
Running all tests in one transaction ensures the final output tells
about any failing test, not just in the last transaction (i.e.
test script).
The price is that no traces of the tests are left in the database
because we have to rollback in order to have no left-over test roles
in the cluster.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Fri, 20 Jul 2018 18:31:45 +0200 |
parents | 96bb671cdd98 |
children |
line wrap: on
line source
package main 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 create_user($1, $2, $3, $4, NULL, $5)` createUserExtentSQL = `SELECT 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( createUserSQL, 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) } }