This commit is contained in:
@@ -9,27 +9,27 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
org_model "code.gitea.io/gitea/models/organization"
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/auth/password"
|
||||
"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"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/api/v1/user"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/convert"
|
||||
"code.gitea.io/gitea/services/mailer"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
asymkey_model "gitea.dev/models/asymkey"
|
||||
"gitea.dev/models/auth"
|
||||
"gitea.dev/models/db"
|
||||
org_model "gitea.dev/models/organization"
|
||||
packages_model "gitea.dev/models/packages"
|
||||
repo_model "gitea.dev/models/repo"
|
||||
user_model "gitea.dev/models/user"
|
||||
"gitea.dev/modules/auth/password"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/optional"
|
||||
"gitea.dev/modules/setting"
|
||||
api "gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/timeutil"
|
||||
"gitea.dev/modules/web"
|
||||
"gitea.dev/routers/api/v1/user"
|
||||
"gitea.dev/routers/api/v1/utils"
|
||||
asymkey_service "gitea.dev/services/asymkey"
|
||||
"gitea.dev/services/context"
|
||||
"gitea.dev/services/convert"
|
||||
"gitea.dev/services/mailer"
|
||||
user_service "gitea.dev/services/user"
|
||||
)
|
||||
|
||||
func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64) {
|
||||
@@ -40,7 +40,7 @@ func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64
|
||||
source, err := auth.GetSourceByID(ctx, sourceID)
|
||||
if err != nil {
|
||||
if auth.IsErrSourceNotExist(err) {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err)
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err.Error())
|
||||
} else {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
@@ -97,14 +97,12 @@ func CreateUser(ctx *context.APIContext) {
|
||||
|
||||
if u.LoginType == auth.Plain {
|
||||
if len(form.Password) < setting.MinPasswordLength {
|
||||
err := errors.New("PasswordIsRequired")
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, "PasswordIsRequired")
|
||||
return
|
||||
}
|
||||
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
err := errors.New("PasswordComplexity")
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, "PasswordComplexity")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -112,7 +110,7 @@ func CreateUser(ctx *context.APIContext) {
|
||||
if password.IsErrIsPwnedRequest(err) {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
ctx.APIError(http.StatusBadRequest, errors.New("PasswordPwned"))
|
||||
ctx.APIError(http.StatusBadRequest, "PasswordPwned")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -123,7 +121,7 @@ func CreateUser(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
if form.Visibility != "" {
|
||||
visibility := api.VisibilityModes[form.Visibility]
|
||||
visibility := api.VisibilityModes[string(form.Visibility)]
|
||||
overwriteDefault.Visibility = &visibility
|
||||
}
|
||||
|
||||
@@ -143,7 +141,7 @@ func CreateUser(ctx *context.APIContext) {
|
||||
user_model.IsErrEmailCharIsNotSupported(err) ||
|
||||
user_model.IsErrEmailInvalid(err) ||
|
||||
db.IsErrNamePatternNotAllowed(err) {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err)
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err.Error())
|
||||
} else {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
@@ -196,7 +194,7 @@ func EditUser(ctx *context.APIContext) {
|
||||
|
||||
authOpts := &user_service.UpdateAuthOptions{
|
||||
LoginSource: optional.FromNonDefault(form.SourceID),
|
||||
LoginName: optional.Some(form.LoginName),
|
||||
LoginName: optional.FromPtr(form.LoginName),
|
||||
Password: optional.FromNonDefault(form.Password),
|
||||
MustChangePassword: optional.FromPtr(form.MustChangePassword),
|
||||
ProhibitLogin: optional.FromPtr(form.ProhibitLogin),
|
||||
@@ -204,11 +202,11 @@ func EditUser(ctx *context.APIContext) {
|
||||
if err := user_service.UpdateAuth(ctx, ctx.ContextUser, authOpts); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, password.ErrMinLength):
|
||||
ctx.APIError(http.StatusBadRequest, fmt.Errorf("password must be at least %d characters", setting.MinPasswordLength))
|
||||
ctx.APIError(http.StatusBadRequest, fmt.Sprintf("password must be at least %d characters", setting.MinPasswordLength))
|
||||
case errors.Is(err, password.ErrComplexity):
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, err.Error())
|
||||
case errors.Is(err, password.ErrIsPwned), password.IsErrIsPwnedRequest(err):
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, err.Error())
|
||||
default:
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
@@ -222,9 +220,9 @@ func EditUser(ctx *context.APIContext) {
|
||||
if !user_model.IsEmailDomainAllowed(*form.Email) {
|
||||
err = fmt.Errorf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email)
|
||||
}
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, err.Error())
|
||||
case user_model.IsErrEmailAlreadyUsed(err):
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, err.Error())
|
||||
default:
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
@@ -239,7 +237,7 @@ func EditUser(ctx *context.APIContext) {
|
||||
Description: optional.FromPtr(form.Description),
|
||||
IsActive: optional.FromPtr(form.Active),
|
||||
IsAdmin: user_service.UpdateOptionFieldFromPtr(form.Admin),
|
||||
Visibility: optional.FromMapLookup(api.VisibilityModes, form.Visibility),
|
||||
Visibility: optional.FromMapLookup(api.VisibilityModes, string(form.Visibility)),
|
||||
AllowGitHook: optional.FromPtr(form.AllowGitHook),
|
||||
AllowImportLocal: optional.FromPtr(form.AllowImportLocal),
|
||||
MaxRepoCreation: optional.FromPtr(form.MaxRepoCreation),
|
||||
@@ -249,7 +247,7 @@ func EditUser(ctx *context.APIContext) {
|
||||
|
||||
if err := user_service.UpdateUser(ctx, ctx.ContextUser, opts); err != nil {
|
||||
if user_model.IsErrDeleteLastAdminUser(err) {
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
@@ -289,13 +287,13 @@ func DeleteUser(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/validationError"
|
||||
|
||||
if ctx.ContextUser.IsOrganization() {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name))
|
||||
ctx.APIError(http.StatusUnprocessableEntity, "target is an organization but not user")
|
||||
return
|
||||
}
|
||||
|
||||
// admin should not delete themself
|
||||
if ctx.ContextUser.ID == ctx.Doer.ID {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, errors.New("you cannot delete yourself"))
|
||||
ctx.APIError(http.StatusUnprocessableEntity, "you cannot delete yourself")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -304,7 +302,7 @@ func DeleteUser(ctx *context.APIContext) {
|
||||
org_model.IsErrUserHasOrgs(err) ||
|
||||
packages_model.IsErrUserOwnPackages(err) ||
|
||||
user_model.IsErrDeleteLastAdminUser(err) {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err)
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err.Error())
|
||||
} else {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
@@ -464,35 +462,18 @@ func SearchUsers(ctx *context.APIContext) {
|
||||
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
|
||||
orderBy := db.SearchOrderByAlphabetically
|
||||
sortMode := ctx.FormString("sort")
|
||||
if len(sortMode) > 0 {
|
||||
sortOrder := ctx.FormString("order")
|
||||
if len(sortOrder) == 0 {
|
||||
sortOrder = "asc"
|
||||
}
|
||||
if searchModeMap, ok := user_model.AdminUserOrderByMap[sortOrder]; ok {
|
||||
if order, ok := searchModeMap[sortMode]; ok {
|
||||
orderBy = order
|
||||
} else {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort mode: \"%s\"", sortMode))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort order: \"%s\"", sortOrder))
|
||||
return
|
||||
}
|
||||
orderBy, ok := utils.ResolveSortOrder(ctx, user_model.AdminUserOrderByMap, db.SearchOrderByAlphabetically)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var visible []api.VisibleType
|
||||
visibilityParam := ctx.FormString("visibility")
|
||||
if len(visibilityParam) > 0 {
|
||||
if visibility, ok := api.VisibilityModes[visibilityParam]; ok {
|
||||
visible = []api.VisibleType{visibility}
|
||||
} else {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid visibility: \"%s\"", visibilityParam))
|
||||
return
|
||||
}
|
||||
if visibility, ok := api.VisibilityModes[visibilityParam]; ok {
|
||||
visible = []api.VisibleType{visibility}
|
||||
} else if visibilityParam != "" {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, "invalid visibility")
|
||||
return
|
||||
}
|
||||
|
||||
searchOpts := user_model.SearchUserOptions{
|
||||
@@ -566,7 +547,7 @@ func RenameUser(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/validationError"
|
||||
|
||||
if ctx.ContextUser.IsOrganization() {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name))
|
||||
ctx.APIError(http.StatusUnprocessableEntity, "target is an organization but not user")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -575,7 +556,7 @@ func RenameUser(ctx *context.APIContext) {
|
||||
// Check if username has been changed
|
||||
if err := user_service.RenameUser(ctx, ctx.ContextUser, newName, ctx.Doer); err != nil {
|
||||
if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err)
|
||||
ctx.APIError(http.StatusUnprocessableEntity, err.Error())
|
||||
} else {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user