package models import ( "errors" "strings" "time" "git.kirsle.net/apps/gosocial/pkg/config" "golang.org/x/crypto/bcrypt" ) // User account table. type User struct { ID uint64 `gorm:"primaryKey` Username string `gorm:"uniqueIndex"` Email string `gorm:"uniqueIndex"` HashedPassword string IsAdmin bool `gorm:"index"` Status string `gorm:"index"` // pending, active, disabled Visibility string `gorm:"index"` // public, private Name *string Certified bool CreatedAt time.Time `gorm:"index"` UpdatedAt time.Time `gorm:"index"` } // CreateUser. It is assumed username and email are correctly formatted. func CreateUser(username, email, password string) (*User, error) { // Verify username and email are unique. if _, err := FindUser(username); err == nil { return nil, errors.New("That username already exists. Please try a different username.") } else if _, err := FindUser(email); err == nil { return nil, errors.New("That email address is already registered.") } u := &User{ Username: username, Email: email, } if err := u.HashPassword(password); err != nil { return nil, err } result := DB.Create(u) return u, result.Error } // GetUser by ID. func GetUser(userId uint64) (*User, error) { user := &User{} result := DB.First(&user, userId) return user, result.Error } // FindUser by username or email. func FindUser(username string) (*User, error) { u := &User{} if strings.ContainsRune(username, '@') { result := DB.Where("email = ?", username).Limit(1).First(u) return u, result.Error } result := DB.Where("username = ?", username).Limit(1).First(u) return u, result.Error } // HashPassword sets the user's hashed (bcrypt) password. func (u *User) HashPassword(password string) error { passwd, err := bcrypt.GenerateFromPassword([]byte(password), config.BcryptCost) if err != nil { return err } u.HashedPassword = string(passwd) return nil } // CheckPassword verifies the password is correct. Returns nil on success. func (u *User) CheckPassword(password string) error { return bcrypt.CompareHashAndPassword([]byte(u.HashedPassword), []byte(password)) } // Save user. func (u *User) Save() error { result := DB.Save(u) return result.Error }