feat(session/v2): user password lockout error response (#9233)

# Which Problems Are Solved

Adds `failed attempts` field to the grpc response when a user enters
wrong password when logging in

FYI:

this only covers the senario above; other senarios where this is not
applied are:
SetPasswordWithVerifyCode
setPassword
ChangPassword
setPasswordWithPermission

# How the Problems Are Solved 

Created new grpc message `CredentialsCheckError` -
`proto/zitadel/message.proto` to include `failed_attempts` field.

Had to create a new package -
`github.com/zitadel/zitadel/internal/command/errors` to resolve cycle
dependency between `github.com/zitadel/zitadel/internal/command` and
`github.com/zitadel/zitadel/internal/command`.

# Additional Changes

- none

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9198

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
This commit is contained in:
kkrime
2025-01-29 10:29:00 +00:00
committed by GitHub
parent 21f00c1e6b
commit 5eeff97ffe
6 changed files with 118 additions and 11 deletions

View File

@@ -7,7 +7,9 @@ import (
"github.com/zitadel/logging"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/protoadapt"
commandErrors "github.com/zitadel/zitadel/internal/command/errors"
"github.com/zitadel/zitadel/internal/zerrors"
"github.com/zitadel/zitadel/pkg/grpc/message"
)
@@ -23,7 +25,9 @@ func ZITADELToGRPCError(err error) error {
msg := key
msg += " (" + id + ")"
s, err := status.New(code, msg).WithDetails(&message.ErrorDetail{Id: id, Message: key})
errorInfo := getErrorInfo(id, key, err)
s, err := status.New(code, msg).WithDetails(errorInfo)
if err != nil {
logging.WithError(err).WithField("logID", "GRPC-gIeRw").Debug("unable to add detail")
return status.New(code, msg).Err()
@@ -71,3 +75,16 @@ func ExtractZITADELError(err error) (c codes.Code, msg, id string, ok bool) {
return codes.Unknown, err.Error(), "", false
}
}
func getErrorInfo(id, key string, err error) protoadapt.MessageV1 {
var errorInfo protoadapt.MessageV1
var wpe *commandErrors.WrongPasswordError
if err != nil && errors.As(err, &wpe) {
errorInfo = &message.CredentialsCheckError{Id: id, Message: key, FailedAttempts: wpe.FailedAttempts}
} else {
errorInfo = &message.ErrorDetail{Id: id, Message: key}
}
return errorInfo
}