mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-29 03:51:54 +08:00
feat(keystone): more specific error return during authentication
add error class UserNotFound, UserLocked, UserDisabled and WrongPassword
This commit is contained in:
@@ -30,7 +30,6 @@ const (
|
||||
ErrSpecNotFound = errors.Error("SpecNotFoundError")
|
||||
ErrActionNotFound = errors.Error("ActionNotFoundError")
|
||||
ErrTenantNotFound = errors.Error("TenantNotFoundError")
|
||||
ErrUserNotFound = errors.Error("UserNotFoundError")
|
||||
|
||||
ErrServerStatus = errors.Error("ServerStatusError")
|
||||
ErrInvalidStatus = errors.ErrInvalidStatus
|
||||
@@ -84,12 +83,15 @@ const (
|
||||
ErrTooManyAttempts = errors.Error("TooManyFailedAttempts")
|
||||
ErrTooManyRequests = errors.Error("TooManyRequests")
|
||||
|
||||
ErrUserLocked = errors.Error("User Locked")
|
||||
ErrUserDisabled = errors.Error("User Disabled")
|
||||
|
||||
ErrUnsupportedProtocol = errors.Error("UnsupportedProtocol")
|
||||
|
||||
ErrPolicyDefinition = errors.Error("PolicyDefinitionError")
|
||||
|
||||
ErrUserNotFound = errors.Error("UserNotFound")
|
||||
ErrUserLocked = errors.Error("UserLocked")
|
||||
ErrUserDisabled = errors.Error("UserDisabled")
|
||||
ErrWrongPassword = errors.Error("WrongPassword")
|
||||
ErrIncorrectUsernameOrPassword = errors.Error("IncorrectUsernameOrPassword")
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -166,6 +168,9 @@ var (
|
||||
ErrUserLocked: 423,
|
||||
ErrUserDisabled: 423,
|
||||
|
||||
ErrWrongPassword: 401,
|
||||
ErrIncorrectUsernameOrPassword: 401,
|
||||
|
||||
ErrPolicyDefinition: 409,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -207,3 +207,11 @@ func NewUnclassifiedError(msg string, params ...interface{}) *httputils.JSONClie
|
||||
func NewTooLargeEntityError(msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
return httputils.NewJsonClientError(httpErrorCode[ErrTooLarge], string(ErrTooLarge), msg, params...)
|
||||
}
|
||||
|
||||
func NewJsonClientError(err errors.Error, msg string, params ...interface{}) *httputils.JSONClientError {
|
||||
code, ok := httpErrorCode[err]
|
||||
if !ok {
|
||||
code = 500
|
||||
}
|
||||
return httputils.NewJsonClientError(code, string(err), msg, params...)
|
||||
}
|
||||
|
||||
@@ -294,6 +294,12 @@ func (self *SLDAPDriver) Authenticate(ctx context.Context, ident mcclient.SAuthe
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("LDAP AUTH error: %s", err)
|
||||
if errors.Cause(err) == ldaputils.ErrUserNotFound {
|
||||
return nil, httperrors.ErrUserNotFound
|
||||
}
|
||||
if errors.Cause(err) == ldaputils.ErrUserBadCredential {
|
||||
return nil, httperrors.ErrWrongPassword
|
||||
}
|
||||
return nil, errors.Wrap(err, "Authenticate error")
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -282,6 +281,9 @@ func (manager *SUserManager) FetchUserExtended(userId, userName, domainId, domai
|
||||
extUser := api.SUserExtended{}
|
||||
err := q.First(&extUser)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.ErrUserNotFound
|
||||
}
|
||||
return nil, errors.Wrap(err, "query")
|
||||
}
|
||||
|
||||
@@ -312,7 +314,7 @@ func localUserVerifyPassword(user *api.SUserExtended, passwd string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return errors.Error(fmt.Sprintf("invalid password: %v", err))
|
||||
return httperrors.ErrWrongPassword
|
||||
}
|
||||
|
||||
// 用户列表
|
||||
|
||||
+12
-12
@@ -83,7 +83,7 @@ func authUserByIdentity(ctx context.Context, ident mcclient.SAuthenticationIdent
|
||||
return nil, sqlchemy.ErrDuplicateEntry
|
||||
} else if usrCnt == 0 {
|
||||
log.Errorf("find no user with name %s", ident.Password.User.Name)
|
||||
return nil, sqlchemy.ErrEmptyQuery
|
||||
return nil, httperrors.ErrUserNotFound
|
||||
} else {
|
||||
// userCnt == 1
|
||||
usr := models.SUser{}
|
||||
@@ -99,20 +99,11 @@ func authUserByIdentity(ctx context.Context, ident mcclient.SAuthenticationIdent
|
||||
|
||||
usrExt, err := models.UserManager.FetchUserExtended(ident.Password.User.Id, ident.Password.User.Name,
|
||||
ident.Password.User.Domain.Id, ident.Password.User.Domain.Name)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
if err != nil && errors.Cause(err) != httperrors.ErrUserNotFound {
|
||||
return nil, errors.Wrap(err, "UserManager.FetchUserExtended")
|
||||
}
|
||||
// checn enable
|
||||
if !usrExt.Enabled {
|
||||
if usrExt.IsLocal && usrExt.LocalFailedAuthCount > o.Options.PasswordErrorLockCount {
|
||||
// user locked
|
||||
return nil, errors.Wrap(httperrors.ErrUserLocked, "please contact the administrator")
|
||||
}
|
||||
// user disabled
|
||||
return nil, errors.Wrap(httperrors.ErrUserLocked, "please contact the administrator")
|
||||
}
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
if err != nil {
|
||||
// no such user locally, query domain idp
|
||||
domain, err := models.DomainManager.FetchDomain(ident.Password.User.Domain.Id, ident.Password.User.Domain.Name)
|
||||
if err != nil {
|
||||
@@ -124,6 +115,15 @@ func authUserByIdentity(ctx context.Context, ident mcclient.SAuthenticationIdent
|
||||
}
|
||||
idpId = mapping.IdpId
|
||||
} else {
|
||||
// check enable
|
||||
if !usrExt.Enabled {
|
||||
if usrExt.IsLocal && usrExt.LocalFailedAuthCount > o.Options.PasswordErrorLockCount {
|
||||
// user locked
|
||||
return nil, httperrors.ErrUserLocked
|
||||
}
|
||||
// user disabled
|
||||
return nil, httperrors.ErrUserLocked
|
||||
}
|
||||
// user exists, query user's idp
|
||||
idps, err := models.IdentityProviderManager.FetchIdentityProvidersByUserId(usrExt.Id, api.PASSWORD_PROTECTED_IDPS)
|
||||
if err != nil {
|
||||
|
||||
@@ -89,7 +89,7 @@ func authenticateTokensV3(ctx context.Context, w http.ResponseWriter, r *http.Re
|
||||
switch errors.Cause(err) {
|
||||
case sqlchemy.ErrDuplicateEntry:
|
||||
httperrors.ConflictError(ctx, w, "duplicate username")
|
||||
case httperrors.ErrTooManyAttempts, httperrors.ErrUserNotFound, httperrors.ErrUserDisabled, httperrors.ErrUserLocked:
|
||||
case httperrors.ErrTooManyAttempts, httperrors.ErrUserNotFound, httperrors.ErrUserDisabled, httperrors.ErrUserLocked, httperrors.ErrWrongPassword:
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
default:
|
||||
httperrors.UnauthorizedError(ctx, w, "unauthorized %s", err)
|
||||
|
||||
Reference in New Issue
Block a user