view pkg/models/user.go @ 904:e4b72a199258

New default bottleneck colors Mainly to make the stroke color one actually selectable in the ui. In addition the pink does better match the collors used on the ECDIS layer.
author Sascha Wilde <wilde@intevation.de>
date Tue, 02 Oct 2018 13:34:59 +0200
parents 756f3fc62da6
children a244b18cb916
line wrap: on
line source

package models

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
	"regexp"
	"strings"
)

type (
	Email    string
	Country  string
	Role     string
	UserName string

	BoundingBox struct {
		X1 float64 `json:"x1"`
		Y1 float64 `json:"y1"`
		X2 float64 `json:"x2"`
		Y2 float64 `json:"y2"`
	}

	User struct {
		User     UserName     `json:"user"`
		Role     Role         `json:"role"`
		Password string       `json:"password,omitempty"`
		Email    Email        `json:"email"`
		Country  Country      `json:"country"`
		Extent   *BoundingBox `json:"extent"`
	}

	PWResetUser struct {
		User string `json:"user"`
	}
)

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
}

func (e Email) Value() (driver.Value, error) {
	return string(e), nil
}

func (e *Email) Scan(src interface{}) (err error) {
	if s, ok := src.(string); ok {
		*e = Email(s)
	} else {
		err = errNoString
	}
	return
}

var errNoValidUser = errors.New("Not a valid user")

func (u UserName) IsValid() bool {
	return u != ""
}

func (u *UserName) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}
	if user := UserName(s); user.IsValid() {
		*u = user
		return nil
	}
	return errNoValidUser
}

func (u *UserName) Scan(src interface{}) (err error) {
	if s, ok := src.(string); ok {
		*u = UserName(s)
	} else {
		err = errNoString
	}
	return
}

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
}

func (c Country) Value() (driver.Value, error) {
	return string(c), nil
}

func (c *Country) Scan(src interface{}) (err error) {
	if s, ok := src.(string); ok {
		*c = Country(s)
	} else {
		err = errNoString
	}
	return
}

var (
	validRoles = []string{
		"waterway_user",
		"waterway_admin",
		"sys_admin",
	}
	errNoValidRole = errors.New("Not a valid role")
)

func (r Role) Value() (driver.Value, error) {
	return string(r), nil
}

func (r *Role) Scan(src interface{}) (err error) {
	if s, ok := src.(string); ok {
		*r = Role(s)
	} else {
		err = errNoString
	}
	return
}

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
}