woodpecker/pkg/model/user.go
2014-02-07 03:10:01 -07:00

110 lines
3.2 KiB
Go

package model
import (
"errors"
"fmt"
"regexp"
"time"
"code.google.com/p/go.crypto/bcrypt"
)
var (
ErrInvalidUserName = errors.New("Invalid User Name")
ErrInvalidPassword = errors.New("Invalid Password")
ErrInvalidEmail = errors.New("Invalid Email Address")
)
// Gravatar URL pattern
var GravatarPattern = "https://gravatar.com/avatar/%s?s=%v"
// Simple regular expression used to verify that an email
// address matches the expected standard format.
var RegexpEmail = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`)
type User struct {
ID int64 `meddler:"id,pk" json:"id"`
Email string `meddler:"email" json:"email"`
Password string `meddler:"password" json:"-"`
Token string `meddler:"token" json:"-"`
Name string `meddler:"name" json:"name"`
Gravatar string `meddler:"gravatar" json:"gravatar"`
Created time.Time `meddler:"created,utctime" json:"created"`
Updated time.Time `meddler:"updated,utctime" json:"updated"`
Admin bool `meddler:"admin" json:"-"`
// GitHub OAuth2 token for accessing public repositories.
GithubLogin string `meddler:"github_login" json:"-"`
GithubToken string `meddler:"github_token" json:"-"`
// Bitbucket OAuth1.0a token and token secret.
BitbucketLogin string `meddler:"bitbucket_login" json:"-"`
BitbucketToken string `meddler:"bitbucket_token" json:"-"`
BitbucketSecret string `meddler:"bitbucket_secret" json:"-"`
}
// Creates a new User from the given Name and Email.
func NewUser(name, email string) *User {
user := User{}
user.Name = name
user.Token = createToken()
user.SetEmail(email)
return &user
}
// Returns the Gravatar Image URL.
func (u *User) Image() string { return fmt.Sprintf(GravatarPattern, u.Gravatar, 42) }
func (u *User) ImageSmall() string { return fmt.Sprintf(GravatarPattern, u.Gravatar, 32) }
func (u *User) ImageLarge() string { return fmt.Sprintf(GravatarPattern, u.Gravatar, 160) }
// Set the email address and calculate the
// Gravatar hash.
func (u *User) SetEmail(email string) {
u.Email = email
u.Gravatar = createGravatar(email)
}
// Set the password and hash with bcrypt
func (u *User) SetPassword(password string) error {
// validate the password is an appropriate size
switch {
case len(password) < 6:
return ErrInvalidPassword
case len(password) > 256:
return ErrInvalidPassword
}
// convert the password to a hash
b, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return err
}
// update the user
u.Password = string(b)
return nil
}
// Validate verifies all required fields are correctly populated.
func (u *User) Validate() error {
switch {
case len(u.Name) == 0:
return ErrInvalidUserName
case len(u.Name) >= 255:
return ErrInvalidUserName
case len(u.Email) == 0:
return ErrInvalidEmail
case len(u.Email) >= 255:
return ErrInvalidEmail
case RegexpEmail.MatchString(u.Email) == false:
return ErrInvalidEmail
default:
return nil
}
}
// ComparePassword compares the supplied password to
// the user password stored in the database.
func (u *User) ComparePassword(password string) error {
return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
}