2018-06-10 11:11:41 +02:00
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
2018-10-31 13:42:38 +01:00
|
|
|
"code.vikunja.io/api/pkg/mail"
|
|
|
|
"code.vikunja.io/api/pkg/utils"
|
2018-06-10 11:11:41 +02:00
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// CreateUser creates a new user and inserts it into the database
|
2018-06-10 11:34:59 +02:00
|
|
|
func CreateUser(user User) (newUser User, err error) {
|
2018-06-10 11:11:41 +02:00
|
|
|
|
|
|
|
newUser = user
|
|
|
|
|
|
|
|
// Check if we have all needed informations
|
|
|
|
if newUser.Password == "" || newUser.Username == "" {
|
|
|
|
return User{}, ErrNoUsernamePassword{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the user already existst with that username
|
2018-09-04 19:39:31 +02:00
|
|
|
exists := true
|
2018-08-30 19:14:02 +02:00
|
|
|
existingUser, err := GetUser(User{Username: newUser.Username})
|
|
|
|
if err != nil {
|
|
|
|
if IsErrUserDoesNotExist(err) {
|
2018-09-04 19:39:31 +02:00
|
|
|
exists = false
|
2018-08-30 19:14:02 +02:00
|
|
|
} else {
|
|
|
|
return User{}, err
|
|
|
|
}
|
2018-06-10 11:11:41 +02:00
|
|
|
}
|
|
|
|
if exists {
|
2018-09-04 19:39:31 +02:00
|
|
|
return User{}, ErrUsernameExists{newUser.ID, newUser.Username}
|
2018-06-10 11:11:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the user already existst with that email
|
2018-09-04 19:39:31 +02:00
|
|
|
exists = true
|
2018-08-30 19:14:02 +02:00
|
|
|
existingUser, err = GetUser(User{Email: newUser.Email})
|
2018-09-04 19:39:31 +02:00
|
|
|
if err != nil {
|
2018-08-30 19:14:02 +02:00
|
|
|
if IsErrUserDoesNotExist(err) {
|
2018-09-04 19:39:31 +02:00
|
|
|
exists = false
|
2018-08-30 19:14:02 +02:00
|
|
|
} else {
|
|
|
|
return User{}, err
|
|
|
|
}
|
2018-06-10 11:11:41 +02:00
|
|
|
}
|
|
|
|
if exists {
|
|
|
|
return User{}, ErrUserEmailExists{existingUser.ID, existingUser.Email}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hash the password
|
|
|
|
newUser.Password, err = hashPassword(user.Password)
|
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
|
|
|
|
2018-10-27 15:14:55 +02:00
|
|
|
// Generate a confirm token
|
|
|
|
newUser.EmailConfirmToken = utils.MakeRandomString(400)
|
|
|
|
|
|
|
|
// The new user should not be activated until it confirms his mail address
|
|
|
|
newUser.IsActive = false
|
|
|
|
|
2018-06-10 11:11:41 +02:00
|
|
|
// Insert it
|
|
|
|
_, err = x.Insert(newUser)
|
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the full new User
|
2018-08-30 19:14:02 +02:00
|
|
|
newUserOut, err := GetUser(newUser)
|
2018-06-10 11:11:41 +02:00
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
|
|
|
|
2018-07-02 08:40:24 +02:00
|
|
|
// Create the user's namespace
|
2018-07-12 00:30:31 +02:00
|
|
|
newN := &Namespace{Name: newUserOut.Username, Description: newUserOut.Username + "'s namespace.", Owner: newUserOut}
|
2018-07-18 08:56:19 +02:00
|
|
|
err = newN.Create(&newUserOut)
|
2018-07-02 08:40:24 +02:00
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
|
|
|
|
2018-10-28 17:30:10 +01:00
|
|
|
// Dont send a mail if we're testing
|
|
|
|
if IsTesting {
|
|
|
|
return newUserOut, err
|
|
|
|
}
|
|
|
|
|
2018-10-27 15:14:55 +02:00
|
|
|
// Send the user a mail with a link to confirm the mail
|
|
|
|
data := map[string]interface{}{
|
|
|
|
"User": newUserOut,
|
|
|
|
}
|
|
|
|
|
|
|
|
mail.SendMailWithTemplate(user.Email, newUserOut.Username+" + Vikunja = <3", "confirm-email", data)
|
|
|
|
|
2018-06-10 11:11:41 +02:00
|
|
|
return newUserOut, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// HashPassword hashes a password
|
|
|
|
func hashPassword(password string) (string, error) {
|
|
|
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
|
|
|
return string(bytes), err
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateUser updates a user
|
2018-06-10 11:34:59 +02:00
|
|
|
func UpdateUser(user User) (updatedUser User, err error) {
|
2018-06-10 11:11:41 +02:00
|
|
|
|
|
|
|
// Check if it exists
|
2018-08-30 19:14:02 +02:00
|
|
|
theUser, err := GetUserByID(user.ID)
|
2018-06-10 11:11:41 +02:00
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
|
|
|
|
2018-08-30 19:14:16 +02:00
|
|
|
// Check if we have at least a username
|
|
|
|
if user.Username == "" {
|
|
|
|
//return User{}, ErrNoUsername{user.ID}
|
|
|
|
user.Username = theUser.Username // Dont change the username if we dont have one
|
|
|
|
}
|
2018-06-10 11:11:41 +02:00
|
|
|
|
2018-08-30 19:14:16 +02:00
|
|
|
user.Password = theUser.Password // set the password to the one in the database to not accedently resetting it
|
2018-06-10 11:11:41 +02:00
|
|
|
|
2018-08-30 19:14:16 +02:00
|
|
|
// Update it
|
|
|
|
_, err = x.Id(user.ID).Update(user)
|
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
2018-06-10 11:11:41 +02:00
|
|
|
|
2018-08-30 19:14:16 +02:00
|
|
|
// Get the newly updated user
|
|
|
|
updatedUser, err = GetUserByID(user.ID)
|
|
|
|
if err != nil {
|
|
|
|
return User{}, err
|
|
|
|
}
|
2018-06-10 11:11:41 +02:00
|
|
|
|
2018-08-30 19:14:16 +02:00
|
|
|
return updatedUser, err
|
2018-06-10 11:11:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateUserPassword updates the password of a user
|
2018-10-03 19:28:17 +02:00
|
|
|
func UpdateUserPassword(user *User, newPassword string) (err error) {
|
2018-06-10 11:11:41 +02:00
|
|
|
|
|
|
|
// Get all user details
|
2018-10-03 19:28:17 +02:00
|
|
|
theUser, err := GetUserByID(user.ID)
|
2018-06-10 11:11:41 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hash the new password and set it
|
|
|
|
hashed, err := hashPassword(newPassword)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-10-03 19:28:17 +02:00
|
|
|
theUser.Password = hashed
|
2018-06-10 11:11:41 +02:00
|
|
|
|
|
|
|
// Update it
|
2018-10-03 19:28:17 +02:00
|
|
|
_, err = x.Id(user.ID).Update(theUser)
|
2018-06-10 11:11:41 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|