fix: import totp in add human user with secret (#7936)

* fix: import totp in add human user with secret

* fix: import totp in add human user with secret

* fix: import totp in add human user with secret

* fix: review comment changes
This commit is contained in:
Stefan Benz
2024-05-14 09:20:31 +02:00
committed by GitHub
parent 15d5338b91
commit 0e9ebed8d0
13 changed files with 397 additions and 53 deletions
+3 -1
View File
@@ -829,7 +829,9 @@ func TestCheckTOTP(t *testing.T) {
ctx := authz.NewMockContext("instance1", "org1", "user1")
cryptoAlg := crypto.CreateMockEncryptionAlg(gomock.NewController(t))
key, secret, err := domain.NewTOTPKey("example.com", "user1", cryptoAlg)
key, err := domain.NewTOTPKey("example.com", "user1")
require.NoError(t, err)
secret, err := crypto.Encrypt([]byte(key.Secret()), cryptoAlg)
require.NoError(t, err)
sessAgg := &session.NewAggregate("session1", "instance1").Aggregate
+3
View File
@@ -68,6 +68,9 @@ type AddHuman struct {
// Links are optional
Links []*AddLink
// TOTPSecret is optional
TOTPSecret string
// Details are set after a successful execution of the command
Details *domain.ObjectDetails
+6 -2
View File
@@ -106,7 +106,11 @@ func (c *Commands) createHumanTOTP(ctx context.Context, userID, resourceOwner st
if issuer == "" {
issuer = authz.GetInstance(ctx).RequestedDomain()
}
key, secret, err := domain.NewTOTPKey(issuer, accountName, c.multifactors.OTP.CryptoMFA)
key, err := domain.NewTOTPKey(issuer, accountName)
if err != nil {
return nil, err
}
encryptedSecret, err := crypto.Encrypt([]byte(key.Secret()), c.multifactors.OTP.CryptoMFA)
if err != nil {
return nil, err
}
@@ -115,7 +119,7 @@ func (c *Commands) createHumanTOTP(ctx context.Context, userID, resourceOwner st
userAgg: userAgg,
key: key,
cmds: []eventstore.Command{
user.NewHumanOTPAddedEvent(ctx, userAgg, secret),
user.NewHumanOTPAddedEvent(ctx, userAgg, encryptedSecret),
},
}, nil
}
+3 -1
View File
@@ -620,7 +620,9 @@ func TestCommands_HumanCheckMFATOTPSetup(t *testing.T) {
ctx := authz.NewMockContext("", "org1", "user1")
cryptoAlg := crypto.CreateMockEncryptionAlg(gomock.NewController(t))
key, secret, err := domain.NewTOTPKey("example.com", "user1", cryptoAlg)
key, err := domain.NewTOTPKey("example.com", "user1")
require.NoError(t, err)
secret, err := crypto.Encrypt([]byte(key.Secret()), cryptoAlg)
require.NoError(t, err)
userAgg := &user.NewAggregate("user1", "org1").Aggregate
userAgg2 := &user.NewAggregate("user2", "org1").Aggregate
+11
View File
@@ -218,6 +218,17 @@ func (c *Commands) AddUserHuman(ctx context.Context, resourceOwner string, human
cmds = append(cmds, cmd)
}
if human.TOTPSecret != "" {
encryptedSecret, err := crypto.Encrypt([]byte(human.TOTPSecret), c.multifactors.OTP.CryptoMFA)
if err != nil {
return err
}
cmds = append(cmds,
user.NewHumanOTPAddedEvent(ctx, &existingHuman.Aggregate().Aggregate, encryptedSecret),
user.NewHumanOTPVerifiedEvent(ctx, &existingHuman.Aggregate().Aggregate, ""),
)
}
if len(cmds) == 0 {
human.Details = writeModelToObjectDetails(&existingHuman.WriteModel)
return nil
+95
View File
@@ -8,6 +8,7 @@ import (
"github.com/muhlemmer/gu"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"golang.org/x/text/language"
@@ -47,6 +48,11 @@ func TestCommandSide_AddUserHuman(t *testing.T) {
userAgg := user.NewAggregate("user1", "org1")
cryptoAlg := crypto.CreateMockEncryptionAlg(gomock.NewController(t))
totpSecret := "TOTPSecret"
totpSecretEnc, err := crypto.Encrypt([]byte(totpSecret), cryptoAlg)
require.NoError(t, err)
tests := []struct {
name string
fields fields
@@ -1394,6 +1400,89 @@ func TestCommandSide_AddUserHuman(t *testing.T) {
wantID: "user1",
},
},
{
name: "register human with TOTPSecret, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(),
expectFilter(
eventFromEventPusher(
org.NewDomainPolicyAddedEvent(context.Background(),
&userAgg.Aggregate,
true,
true,
true,
),
),
),
expectPush(
user.NewHumanRegisteredEvent(context.Background(),
&userAgg.Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.English,
domain.GenderUnspecified,
"[email protected]",
true,
"userAgentID",
),
user.NewHumanInitialCodeAddedEvent(context.Background(),
&userAgg.Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte("userinit"),
},
time.Hour*1,
"authRequestID",
),
user.NewHumanOTPAddedEvent(context.Background(),
&userAgg.Aggregate,
totpSecretEnc,
),
user.NewHumanOTPVerifiedEvent(context.Background(),
&userAgg.Aggregate,
"",
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
newCode: mockEncryptedCode("userinit", time.Hour),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &AddHuman{
Username: "username",
FirstName: "firstname",
LastName: "lastname",
Email: Email{
Address: "[email protected]",
},
PreferredLanguage: language.English,
Register: true,
UserAgentID: "userAgentID",
AuthRequestID: "authRequestID",
TOTPSecret: totpSecret,
},
secretGenerator: GetMockSecretGenerator(t),
allowInitMail: true,
codeAlg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
res: res{
want: &domain.ObjectDetails{
Sequence: 0,
EventDate: time.Time{},
ResourceOwner: "org1",
},
wantID: "user1",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -1403,6 +1492,12 @@ func TestCommandSide_AddUserHuman(t *testing.T) {
idGenerator: tt.fields.idGenerator,
newEncryptedCode: tt.fields.newCode,
checkPermission: tt.fields.checkPermission,
multifactors: domain.MultifactorConfigs{
OTP: domain.OTPConfig{
Issuer: "zitadel.com",
CryptoMFA: cryptoAlg,
},
},
}
err := r.AddUserHuman(tt.args.ctx, tt.args.orgID, tt.args.human, tt.args.allowInitMail, tt.args.codeAlg)
if tt.res.err == nil {
+4 -1
View File
@@ -262,8 +262,11 @@ func TestCommands_CheckUserTOTP(t *testing.T) {
ctx := authz.NewMockContext("", "org1", "user1")
cryptoAlg := crypto.CreateMockEncryptionAlg(gomock.NewController(t))
key, secret, err := domain.NewTOTPKey("example.com", "user1", cryptoAlg)
key, err := domain.NewTOTPKey("example.com", "user1")
require.NoError(t, err)
secret, err := crypto.Encrypt([]byte(key.Secret()), cryptoAlg)
require.NoError(t, err)
userAgg := &user.NewAggregate("user1", "org1").Aggregate
code, err := totp.GenerateCode(key.Secret(), time.Now())