mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:57:31 +00:00
feat(users/v2): return prompt information (#9255)
# Which Problems Are Solved
Add the ability to update the timestamp when MFA initialization was last
skipped.
Get User By ID now also returns the timestamps when MFA setup was last
skipped.
# How the Problems Are Solved
- Add a `HumanMFAInitSkipped` method to the `users/v2` API.
- MFA skipped was already projected in the `auth.users3` table. In this
PR the same column is added to the users projection. Event handling is
kept the same as in the `UserView`:
<details>
62804ca45f/internal/user/repository/view/model/user.go (L243-L377)
</details>
# Additional Changes
- none
# Additional Context
- Closes https://github.com/zitadel/zitadel/issues/9197
This commit is contained in:
@@ -3179,3 +3179,75 @@ func TestServer_VerifyInviteCode(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_HumanMFAInitSkipped(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.HumanMFAInitSkippedRequest
|
||||
prepare func(request *user.HumanMFAInitSkippedRequest) error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *user.HumanMFAInitSkippedResponse
|
||||
checkState func(t *testing.T, userID string, resp *user.HumanMFAInitSkippedResponse)
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "user not existing",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.HumanMFAInitSkippedRequest{
|
||||
UserId: "notexisting",
|
||||
},
|
||||
func(request *user.HumanMFAInitSkippedRequest) error { return nil },
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "ok",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.HumanMFAInitSkippedRequest{},
|
||||
func(request *user.HumanMFAInitSkippedRequest) error {
|
||||
resp := Instance.CreateHumanUser(CTX)
|
||||
request.UserId = resp.GetUserId()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
want: &user.HumanMFAInitSkippedResponse{
|
||||
Details: &object.Details{
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: Instance.DefaultOrg.Id,
|
||||
},
|
||||
},
|
||||
checkState: func(t *testing.T, userID string, resp *user.HumanMFAInitSkippedResponse) {
|
||||
state, err := Client.GetUserByID(CTX, &user.GetUserByIDRequest{
|
||||
UserId: userID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
integration.EqualProto(t,
|
||||
state.GetUser().GetHuman().GetMfaInitSkipped(),
|
||||
resp.GetDetails().GetChangeDate(),
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.args.prepare(tt.args.req)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := Client.HumanMFAInitSkipped(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
integration.AssertDetails(t, tt.want, got)
|
||||
if tt.checkState != nil {
|
||||
tt.checkState(t, tt.args.req.GetUserId(), got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -82,10 +82,13 @@ func userTypeToPb(userQ *query.User, assetPrefix string) user.UserType {
|
||||
}
|
||||
|
||||
func humanToPb(userQ *query.Human, assetPrefix, owner string) *user.HumanUser {
|
||||
var passwordChanged *timestamppb.Timestamp
|
||||
var passwordChanged, mfaInitSkipped *timestamppb.Timestamp
|
||||
if !userQ.PasswordChanged.IsZero() {
|
||||
passwordChanged = timestamppb.New(userQ.PasswordChanged)
|
||||
}
|
||||
if !userQ.MFAInitSkipped.IsZero() {
|
||||
mfaInitSkipped = timestamppb.New(userQ.MFAInitSkipped)
|
||||
}
|
||||
return &user.HumanUser{
|
||||
Profile: &user.HumanProfile{
|
||||
GivenName: userQ.FirstName,
|
||||
@@ -106,6 +109,7 @@ func humanToPb(userQ *query.Human, assetPrefix, owner string) *user.HumanUser {
|
||||
},
|
||||
PasswordChangeRequired: userQ.PasswordChangeRequired,
|
||||
PasswordChanged: passwordChanged,
|
||||
MfaInitSkipped: mfaInitSkipped,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -711,3 +711,13 @@ func createInviteCodeRequestToCommand(req *user.CreateInviteCodeRequest) (*comma
|
||||
return &command.CreateUserInvite{UserID: req.GetUserId()}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) HumanMFAInitSkipped(ctx context.Context, req *user.HumanMFAInitSkippedRequest) (_ *user.HumanMFAInitSkippedResponse, err error) {
|
||||
details, err := s.command.HumanMFAInitSkippedV2(ctx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.HumanMFAInitSkippedResponse{
|
||||
Details: object.DomainToDetailsPb(details),
|
||||
}, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user