// BeforeSave invokes required actions before persisting. func (u *User) BeforeSave(db *gorm.DB) (err error) { if u.Slug == "" { for i := 0; true; i++ { if i == 0 { u.Slug = slugify.Slugify(u.Username) } else { u.Slug = slugify.Slugify( fmt.Sprintf("%s-%d", u.Username, i), ) } notFound := db.Where( "slug = ?", u.Slug, ).Not( "id", u.ID, ).First( &User{}, ).RecordNotFound() if notFound { break } } } if u.Email != "" { email, err := govalidator.NormalizeEmail( u.Email, ) if err != nil { return fmt.Errorf("Failed to normalize email") } u.Email = email } if u.Password != "" { encrypt, err := bcrypt.GenerateFromPassword( []byte(u.Password), bcrypt.DefaultCost, ) if err != nil { return fmt.Errorf("Failed to encrypt password") } u.Hashword = string(encrypt) } if u.Hash == "" { u.Hash = base32.StdEncoding.EncodeToString( securecookie.GenerateRandomKey(32), ) } return nil }
func NewAccountEmail(addr string) (AccountEmail, error) { norm, err := govalidator.NormalizeEmail(addr) if err != nil { return AccountEmail{}, err } return AccountEmail{ Address: addr, AddressNorm: norm, }, nil }
func GetAccountEmail(addr string) (*Account, error) { addr, err := govalidator.NormalizeEmail(addr) if err != nil { return nil, nil } acc := Account{} err = sess.DB("").C(accountC).Find(bson.M{"emails.address_norm": addr}).One(&acc) if err == mgo.ErrNotFound { return nil, nil } if err != nil { return nil, err } return &acc, nil }
// CreateUser create a new user. Checks for duplicate users and password-length requirement func CreateUser(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) { var user models.User user.Enable = true user.Domains = nil user.Variables = nil err := rest.Parse(handle.R, &user) if err != nil { return nil, tools.NewError(err, 400, "bad request: couldn't parse body") } if user.Username == "" { return nil, tools.NewError(nil, 400, "bad request: username is missing") } if user.Password == "" { return nil, tools.NewError(nil, 400, "bad request: password is missing") } if len(user.Password) < handle.C.PasswordMinLength { return nil, tools.NewError(nil, 400, "bad request: password is too short") } if user.Domains == nil || len(user.Domains) == 0 { return nil, tools.NewError(nil, 400, "bad request: domains is missing") } if user.Variables == nil { user.Variables = make(map[string]interface{}) } if govalidator.IsEmail(user.Username) == false { return nil, tools.NewError(nil, 400, "bad request: username must be a valid email") } user.Username, err = govalidator.NormalizeEmail(user.Username) if err != nil { return nil, tools.NewError(nil, 400, "bad request: username must be a valid email") } uid, err := user.Create(db) return CreateResponse{ Status: "ok", UserID: uid.Hex(), }, err }
func (u User) Login(username, password, domain string, lifespan int64, db *mgo.DbQueue) (Session, error) { var s Session var err error u.Username, err = govalidator.NormalizeEmail(username) if err != nil { return s, tools.NewError(nil, 400, "bad request: username must be a valid email") } u.Password = password if password == "" { return s, tools.NewError(nil, 400, "bad request: password is missing") } ok, err := u.Check(db) if err != nil { return s, err } if ok == false { return s, tools.NewError(nil, 403, "forbidden: invalid user or password") } if u.Enable == false { return s, tools.NewError(nil, 403, "forbidden: user is diabled") } ok = u.CheckDomain(domain) if ok == false { return s, tools.NewError(nil, 403, "forbidden: restricted domain") } s.UserID = u.ID s.Domain = domain _, err = s.Create(db, lifespan) if err != nil { return s, err } return s, nil }
// Validate does some validation to be able to store the record. func (u *User) Validate(db *gorm.DB) { if !govalidator.StringLength(u.Username, "2", "255") { db.AddError(fmt.Errorf("Username should be longer than 2 and shorter than 255")) } if u.Username != "" { notFound := db.Where( "username = ?", u.Username, ).Not( "id", u.ID, ).First( &User{}, ).RecordNotFound() if !notFound { db.AddError(fmt.Errorf("Username is already present")) } } if u.Hash != "" { notFound := db.Where( "hash = ?", u.Hash, ).Not( "id", u.ID, ).First( &User{}, ).RecordNotFound() if !notFound { db.AddError(fmt.Errorf("Hash is already present")) } } if !govalidator.IsEmail(u.Email) { db.AddError(fmt.Errorf( "Email must be a valid email address", )) } if u.Email != "" { normalized, _ := govalidator.NormalizeEmail( u.Email, ) notFound := db.Where( "email = ?", normalized, ).Not( "id", u.ID, ).First( &User{}, ).RecordNotFound() if !notFound { db.AddError(fmt.Errorf("Email is already present")) } } if db.NewRecord(u) { if !govalidator.StringLength(u.Password, "5", "255") { db.AddError(fmt.Errorf("Password should be longer than 5 and shorter than 255")) } } }
// Login a user, creating a new session. func Login(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) { var q LoginRequest var user models.User var session models.Session var resp LoginResponse err := rest.Parse(handle.R, &q) if err != nil { return nil, tools.NewError(err, 400, "bad request: couldn't parse body") } if q.Domain == "" { return nil, tools.NewError(nil, 400, "bad request: domain is missing") } if q.Domain == "/" { return nil, tools.NewError(nil, 400, "bad request: illegal domain") } if q.Username == "" { return nil, tools.NewError(nil, 400, "bad request: username is missing") } if q.Password == "" { return nil, tools.NewError(nil, 400, "bad request: password is missing") } user.Username = q.Username user.Password = q.Password if govalidator.IsEmail(user.Username) == false { return nil, tools.NewError(nil, 400, "bad request: username must be a valid email") } user.Username, err = govalidator.NormalizeEmail(user.Username) if err != nil { return nil, tools.NewError(nil, 400, "bad request: username must be a valid email") } ok, err := user.Check(db) if err != nil { return nil, err } if ok == false { return nil, tools.NewError(nil, 403, "forbidden: invalid user or password") } if user.Enable == false { return nil, tools.NewError(nil, 403, "forbidden: user is diabled") } ok = user.CheckDomain(q.Domain) if ok == false { return nil, tools.NewError(nil, 403, "forbidden: restricted domain") } session.UserID = user.ID session.Domain = q.Domain remaining, err := session.Create(db, handle.C.SessionLifespan) if err != nil { return nil, err } resp.Status = "ok" resp.Session.Token = session.ID.Hex() resp.Session.UserID = session.UserID.Hex() resp.Session.Expire = session.Expire resp.Session.Remaining = remaining return resp, nil }