Library/models/user.go

152 lines
3.7 KiB
Go

package models
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/labstack/echo"
"golang.org/x/crypto/bcrypt"
)
// UserLogin Object to recive user credentials in JSON format
type UserLogin struct {
Username string `json:"username" form:"username"`
Password string `json:"password" form:"password"`
}
// User holds information about an user
type User struct {
ID int64 `xorm:"int(11) autoincr not null unique pk"`
Name string `xorm:"varchar(250)"`
Username string `xorm:"varchar(250) not null unique"`
Password string `xorm:"varchar(250) not null"`
Email string `xorm:"varchar(250)"`
IsAdmin bool `xorm:"tinyint(1) not null"`
Created int64 `xorm:"created"`
Updated int64 `xorm:"updated"`
}
// UserLog logs user actions
type UserLog struct {
ID int64 `xorm:"int(11) autoincr not null unique pk"`
UserID int64 `xorm:"int(11)"`
Log string `xorm:"varchar(250)"`
ItemID int64 `xorm:"int(11)"`
Time int64 `xorm:"created"`
}
// TableName returns the table name for users
func (User) TableName() string {
return "users"
}
// GetUserByID gets informations about a user by its ID
func GetUserByID(id int64) (user User, exists bool, err error) {
return GetUser(User{ID: id})
}
// GetUser gets a user object
func GetUser(user User) (userOut User, exists bool, err error) {
userOut = user
exists, err = x.Get(&userOut)
return userOut, exists, err
}
// CreateUser creates a new user and inserts it into the database
func CreateUser(user User) (newUser User, err error) {
newUser = user
// Check if we have all needed informations
if newUser.Password == "" || newUser.Username == "" {
return User{}, fmt.Errorf("you need to specify at least a username and a password")
}
// Check if the user already existst
_, exists, err := GetUser(User{Name: newUser.Name})
if err != nil {
return User{}, err
}
if exists {
return User{}, fmt.Errorf("this username is already taken. Please use another")
}
// Hash the password
newUser.Password, err = hashPassword(user.Password)
if err != nil {
return User{}, err
}
// Insert it
_, err = x.Insert(newUser)
if err != nil {
return User{}, err
}
return newUser, nil
}
// HashPassword hashes a password
func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(bytes), err
}
// CheckUserCredentials checks user credentials
func CheckUserCredentials(u *UserLogin) (User, error) {
// Check if the user exists
var user = User{Username: u.Username}
exists, err := x.Get(&user)
if err != nil {
return User{}, err
}
if !exists {
return User{}, fmt.Errorf("user does not exist")
}
// Check the users password
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(u.Password))
if err != nil {
return User{}, err
}
return user, nil
}
// GetCurrentUser returns the current user based on its jwt token
func GetCurrentUser(c echo.Context) (user User, err error) {
jwtinf := c.Get("user").(*jwt.Token)
claims := jwtinf.Claims.(jwt.MapClaims)
userID, ok := claims["id"].(float64)
if !ok {
return user, fmt.Errorf("Error getting UserID")
}
user = User{
ID: int64(userID),
Name: claims["name"].(string),
Email: claims["email"].(string),
Username: claims["username"].(string),
}
return
}
// LogAction logs a user action
func logAction(action string, user User, itemID int64) (err error) {
_, err = x.Insert(UserLog{Log: action, UserID: user.ID, ItemID: itemID})
return
}
// LogAction logs a user action
func LogAction(action string, itemID int64, c echo.Context) (err error) {
// Get the user options
user, err := GetCurrentUser(c)
if err != nil {
return err
}
return logAction(action, user, itemID)
}