1
0

Manage users via cli (#632)

Add users cli commands to docs

Fix checking for changing username or user email

Add user status change command

Make sure only one user exists with a particular email when updating

Add password reset

Add user id to help

Remove user delete (too many possible side effects, postponed until later)

Make sure to fail on any errors

Fail if changing the username would result in duplicate users

Add user update command

Add user create command

Add command stubs for all commands

Render users in a beautiful table

Started adding user list command

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/632
This commit is contained in:
konrad
2020-08-13 15:34:02 +00:00
parent 0169ecc37e
commit 16dbcfda7e
5 changed files with 353 additions and 7 deletions

View File

@ -315,7 +315,7 @@ func hashPassword(password string) (string, error) {
func UpdateUser(user *User) (updatedUser *User, err error) {
// Check if it exists
theUser, err := GetUserByID(user.ID)
theUser, err := GetUserWithEmail(&User{ID: user.ID})
if err != nil {
return &User{}, err
}
@ -324,9 +324,29 @@ func UpdateUser(user *User) (updatedUser *User, err error) {
if user.Username == "" {
//return User{}, ErrNoUsername{user.ID}
user.Username = theUser.Username // Dont change the username if we dont have one
} else {
// Check if the new username already exists
uu, err := GetUserByUsername(user.Username)
if err != nil && !IsErrUserDoesNotExist(err) {
return nil, err
}
if uu.ID != 0 && uu.ID != user.ID {
return nil, &ErrUsernameExists{Username: user.Username, UserID: uu.ID}
}
}
user.Password = theUser.Password // set the password to the one in the database to not accedently resetting it
// Check if the email is already used
if user.Email == "" {
user.Email = theUser.Email
} else {
uu, err := getUser(&User{Email: user.Email}, true)
if err != nil && !IsErrUserDoesNotExist(err) {
return nil, err
}
if uu.ID != 0 && uu.ID != user.ID {
return nil, &ErrUserEmailExists{Email: user.Email, UserID: uu.ID}
}
}
// Validate the avatar type
if user.AvatarProvider != "" {
@ -339,7 +359,10 @@ func UpdateUser(user *User) (updatedUser *User, err error) {
}
// Update it
_, err = x.ID(user.ID).Update(user)
_, err = x.
ID(user.ID).
Cols("username", "email", "avatar_provider", "is_active").
Update(user)
if err != nil {
return &User{}, err
}

View File

@ -82,8 +82,8 @@ type PasswordTokenRequest struct {
Email string `json:"email" valid:"email,length(0|250)" maxLength:"250"`
}
// RequestUserPasswordResetToken inserts a random token to reset a users password into the databsse
func RequestUserPasswordResetToken(tr *PasswordTokenRequest) (err error) {
// RequestUserPasswordResetTokenByEmail inserts a random token to reset a users password into the databsse
func RequestUserPasswordResetTokenByEmail(tr *PasswordTokenRequest) (err error) {
if tr.Email == "" {
return ErrNoUsernamePassword{}
}
@ -94,6 +94,11 @@ func RequestUserPasswordResetToken(tr *PasswordTokenRequest) (err error) {
return
}
return RequestUserPasswordResetToken(user)
}
// RequestUserPasswordResetToken sends a user a password reset email.
func RequestUserPasswordResetToken(user *User) (err error) {
// Generate a token and save it
user.PasswordResetToken = utils.MakeRandomString(400)