vikunja-api/pkg/models/user_add_update.go

175 lines
4.3 KiB
Go
Raw Normal View History

2018-11-26 21:17:33 +01:00
// Vikunja is a todo-list application to facilitate your life.
// Copyright 2018 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
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/metrics"
2018-10-31 13:42:38 +01:00
"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
}
// 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
}
// Update the metrics
metrics.UpdateCount(1, metrics.ActiveUsersKey)
2018-06-10 11:11:41 +02:00
// 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
}
// Create the user's namespace
newN := &Namespace{Name: newUserOut.Username, Description: newUserOut.Username + "'s namespace.", Owner: newUserOut}
err = newN.Create(&newUserOut)
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
}
// 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
func UpdateUserPassword(user *User, newPassword string) (err error) {
2018-06-10 11:11:41 +02:00
// Get all user details
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
}
theUser.Password = hashed
2018-06-10 11:11:41 +02:00
// Update it
_, err = x.Id(user.ID).Update(theUser)
2018-06-10 11:11:41 +02:00
if err != nil {
return err
}
return err
}