aboutsummaryrefslogtreecommitdiffstats
path: root/routers/api/v1/admin/user.go
diff options
context:
space:
mode:
Diffstat (limited to 'routers/api/v1/admin/user.go')
-rw-r--r--routers/api/v1/admin/user.go148
1 files changed, 47 insertions, 101 deletions
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index b4cc42ea5d..272996f43d 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"net/http"
- "strings"
"code.gitea.io/gitea/models"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -18,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
@@ -107,9 +107,8 @@ func CreateUser(ctx *context.APIContext) {
return
}
- pwned, err := password.IsPwned(ctx, form.Password)
- if pwned {
- if err != nil {
+ if err := password.IsPwned(ctx, form.Password); err != nil {
+ if password.IsErrIsPwnedRequest(err) {
log.Error(err.Error())
}
ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned"))
@@ -192,115 +191,65 @@ func EditUser(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.EditUserOption)
- parseAuthSource(ctx, ctx.ContextUser, form.SourceID, form.LoginName)
- if ctx.Written() {
- return
+ authOpts := &user_service.UpdateAuthOptions{
+ LoginSource: optional.FromNonDefault(form.SourceID),
+ LoginName: optional.Some(form.LoginName),
+ Password: optional.FromNonDefault(form.Password),
+ MustChangePassword: optional.FromPtr(form.MustChangePassword),
+ ProhibitLogin: optional.FromPtr(form.ProhibitLogin),
}
-
- if len(form.Password) != 0 {
- if len(form.Password) < setting.MinPasswordLength {
+ if err := user_service.UpdateAuth(ctx, ctx.ContextUser, authOpts); err != nil {
+ switch {
+ case errors.Is(err, password.ErrMinLength):
ctx.Error(http.StatusBadRequest, "PasswordTooShort", fmt.Errorf("password must be at least %d characters", setting.MinPasswordLength))
- return
- }
- if !password.IsComplexEnough(form.Password) {
- err := errors.New("PasswordComplexity")
+ case errors.Is(err, password.ErrComplexity):
ctx.Error(http.StatusBadRequest, "PasswordComplexity", err)
- return
- }
- pwned, err := password.IsPwned(ctx, form.Password)
- if pwned {
- if err != nil {
- log.Error(err.Error())
- }
- ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned"))
- return
- }
- if ctx.ContextUser.Salt, err = user_model.GetUserSalt(); err != nil {
- ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
- return
- }
- if err = ctx.ContextUser.SetPassword(form.Password); err != nil {
- ctx.InternalServerError(err)
- return
+ case errors.Is(err, password.ErrIsPwned), password.IsErrIsPwnedRequest(err):
+ ctx.Error(http.StatusBadRequest, "PasswordIsPwned", err)
+ default:
+ ctx.Error(http.StatusInternalServerError, "UpdateAuth", err)
}
+ return
}
- if form.MustChangePassword != nil {
- ctx.ContextUser.MustChangePassword = *form.MustChangePassword
- }
-
- ctx.ContextUser.LoginName = form.LoginName
-
- if form.FullName != nil {
- ctx.ContextUser.FullName = *form.FullName
- }
- var emailChanged bool
if form.Email != nil {
- email := strings.TrimSpace(*form.Email)
- if len(email) == 0 {
- ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("email is not allowed to be empty string"))
- return
- }
-
- if err := user_model.ValidateEmail(email); err != nil {
- ctx.InternalServerError(err)
- return
- }
-
- emailChanged = !strings.EqualFold(ctx.ContextUser.Email, email)
- ctx.ContextUser.Email = email
- }
- if form.Website != nil {
- ctx.ContextUser.Website = *form.Website
- }
- if form.Location != nil {
- ctx.ContextUser.Location = *form.Location
- }
- if form.Description != nil {
- ctx.ContextUser.Description = *form.Description
- }
- if form.Active != nil {
- ctx.ContextUser.IsActive = *form.Active
- }
- if len(form.Visibility) != 0 {
- ctx.ContextUser.Visibility = api.VisibilityModes[form.Visibility]
- }
- if form.Admin != nil {
- if !*form.Admin && user_model.IsLastAdminUser(ctx, ctx.ContextUser) {
- ctx.Error(http.StatusBadRequest, "LastAdmin", ctx.Tr("auth.last_admin"))
+ if err := user_service.AddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil {
+ switch {
+ case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err):
+ ctx.Error(http.StatusBadRequest, "EmailInvalid", err)
+ case user_model.IsErrEmailAlreadyUsed(err):
+ ctx.Error(http.StatusBadRequest, "EmailUsed", err)
+ default:
+ ctx.Error(http.StatusInternalServerError, "AddOrSetPrimaryEmailAddress", err)
+ }
return
}
- ctx.ContextUser.IsAdmin = *form.Admin
- }
- if form.AllowGitHook != nil {
- ctx.ContextUser.AllowGitHook = *form.AllowGitHook
- }
- if form.AllowImportLocal != nil {
- ctx.ContextUser.AllowImportLocal = *form.AllowImportLocal
- }
- if form.MaxRepoCreation != nil {
- ctx.ContextUser.MaxRepoCreation = *form.MaxRepoCreation
- }
- if form.AllowCreateOrganization != nil {
- ctx.ContextUser.AllowCreateOrganization = *form.AllowCreateOrganization
- }
- if form.ProhibitLogin != nil {
- ctx.ContextUser.ProhibitLogin = *form.ProhibitLogin
- }
- if form.Restricted != nil {
- ctx.ContextUser.IsRestricted = *form.Restricted
}
- if err := user_model.UpdateUser(ctx, ctx.ContextUser, emailChanged); err != nil {
- if user_model.IsErrEmailAlreadyUsed(err) ||
- user_model.IsErrEmailCharIsNotSupported(err) ||
- user_model.IsErrEmailInvalid(err) {
- ctx.Error(http.StatusUnprocessableEntity, "", err)
+ opts := &user_service.UpdateOptions{
+ FullName: optional.FromPtr(form.FullName),
+ Website: optional.FromPtr(form.Website),
+ Location: optional.FromPtr(form.Location),
+ Description: optional.FromPtr(form.Description),
+ IsActive: optional.FromPtr(form.Active),
+ IsAdmin: optional.FromPtr(form.Admin),
+ Visibility: optional.FromNonDefault(api.VisibilityModes[form.Visibility]),
+ AllowGitHook: optional.FromPtr(form.AllowGitHook),
+ AllowImportLocal: optional.FromPtr(form.AllowImportLocal),
+ MaxRepoCreation: optional.FromPtr(form.MaxRepoCreation),
+ AllowCreateOrganization: optional.FromPtr(form.AllowCreateOrganization),
+ IsRestricted: optional.FromPtr(form.Restricted),
+ }
+
+ if err := user_service.UpdateUser(ctx, ctx.ContextUser, opts); err != nil {
+ if models.IsErrDeleteLastAdminUser(err) {
+ ctx.Error(http.StatusBadRequest, "LastAdmin", err)
} else {
ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
}
return
}
+
log.Trace("Account profile updated by admin (%s): %s", ctx.Doer.Name, ctx.ContextUser.Name)
ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.ContextUser, ctx.Doer))
@@ -527,9 +476,6 @@ func RenameUser(ctx *context.APIContext) {
// Check if user name has been changed
if err := user_service.RenameUser(ctx, ctx.ContextUser, newName); err != nil {
switch {
- case user_model.IsErrUsernameNotChanged(err):
- // Noop as username is not changed
- ctx.Status(http.StatusNoContent)
case user_model.IsErrUserAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.username_been_taken"))
case db.IsErrNameReserved(err):
@@ -545,5 +491,5 @@ func RenameUser(ctx *context.APIContext) {
}
log.Trace("User name changed: %s -> %s", oldName, newName)
- ctx.Status(http.StatusOK)
+ ctx.Status(http.StatusNoContent)
}