package models import ( "errors" "fmt" "golang.org/x/crypto/bcrypt" "log" "rate-it-api/database" "regexp" "strings" ) // User define a user type User struct { UUID string Pseudo string Firstname string `default:""` Lastname string `default:"bite"` Password string Email string Hash string Verify int } type regexCheck struct { Regexp string Message string } func validatePassword(password string) error { if password == "" { return errors.New("Password must be provided") } regexPassword := [5]regexCheck{ {".{6,}", "must be at least 6 character long"}, {"[0-9]+", "must contains one digit from 0-9"}, {"[a-z]+", "must contains one lowercase characters"}, {"[A-Z]+", "must contains one uppercase characters"}, {"[\\^#\\.\\@\\$\\%\\[\\]\\;\\:\\,]+", "must contains one of this special parameters : ^, #, ., @, $, %, [, ], ;, or comma:"}, } /** * Passwword must fit some requirements: * - length at least 6 characters * - must contains one digit from 0-9 * - must contains one lowercase characters * - must contains one uppercase characters * - must contains one special symbols in the list \"@#$%\" * - match anything with previous condition checking */ for _, regex := range regexPassword { r, _ := regexp.Compile(regex.Regexp) match := r.MatchString(password) if !match { return errors.New(strings.Join([]string{"Password incorrect", regex.Message}, ": ")) } } return nil } func validateEmail(email string) error { if email == "" { return errors.New("Email must be provided") } r, _ := regexp.Compile(".+@.+") match := r.MatchString(email) if !match { return errors.New(strings.Join([]string{"Email incorrect"}, ": ")) } return nil } func (u *User) validate() error { err := validatePassword(u.Password) if err != nil { return err } err = validateEmail(u.Email) if err != nil { return err } return nil } // UserGetByEmail retrieve a user following its email func UserGetByEmail(userEmail string) (User, error) { var user User err := validateEmail(userEmail) if err != nil { return user, err } query := fmt.Sprintf("SELECT uuid, email, password, verify FROM users WHERE email=\"%s\"", userEmail) return userGet(query) } // UserGetByUUID retrieve a user following its hash func UserGetByUUID(UUID string) (User, error) { query := fmt.Sprintf("SELECT uuid, email, password, verify FROM users WHERE uuid=\"%s\"", UUID) return userGet(query) } // UserValidate validate a user mail func UserValidate(uuid string) error { query := fmt.Sprintf(`UPDATE users SET verify=1 WHERE uuid='%s'`, uuid) fmt.Println(query) _, err := database.MysqlExecInsert(query) if err != nil { fmt.Println(err.Error()) return err } return nil } // UserUpdatePassword validate a user mail func UserUpdatePassword(email string, password string) error { query := fmt.Sprintf(`UPDATE users SET password="%s" WHERE email='%s'`, password, email) fmt.Println(query) _, err := database.MysqlExecInsert(query) if err != nil { fmt.Println(err.Error()) return err } return nil } // userGet retrieve a user func userGet(query string) (User, error) { var user User results, errSelect := database.MysqlExecSelect(query) if errSelect != nil { return user, errSelect } var ( uuid string email string password string verify int ) if !results.Next() { return user, errors.New("User not found") } err := results.Scan(&uuid, &email, &password, &verify) if err != nil { log.Fatal(err) } user = User{ UUID: uuid, Email: email, Password: password, Verify: verify, } return user, nil } // Create create a new user from json data func (u *User) Create() error { err := u.validate() if err != nil { return err } // password hashing password, err := bcrypt.GenerateFromPassword([]byte(u.Password), 2) if err != nil { return err } //Set up hashing data u.Verify = 0 query := fmt.Sprintf(`INSERT INTO users (uuid, email, password, lastname, firstname, verify) VALUES ("%s", "%s", "%s", "%s", "%s", "%d")`, u.UUID, u.Email, password, u.Lastname, u.Firstname, u.Verify) _, err = database.MysqlExecInsert(query) if err != nil { return err } return nil }