1
0
mirror of https://github.com/zitadel/zitadel.git synced 2025-08-11 07:37:39 +00:00
Files
.artifacts
.codecov
.github
build
cmd
console
deploy
docs
e2e
internal
actions
admin
api
auth
auth_request
authz
cache
command
preparation
auth_checks.go
command.go
converter.go
crypto.go
crypto_test.go
custom_login_text.go
custom_login_text_model.go
custom_message_text_model.go
custom_text_model.go
debug_notification_model.go
device_auth.go
device_auth_model.go
device_auth_test.go
email.go
existing_label_policies_model.go
flow_model.go
identity_provider_model.go
idp.go
idp_config_model.go
idp_intent.go
idp_intent_model.go
idp_intent_test.go
idp_model.go
idp_model_test.go
instance.go
instance_converter.go
instance_custom_login_text.go
instance_custom_login_text_model.go
instance_custom_login_text_test.go
instance_custom_message_text.go
instance_custom_message_text_model.go
instance_custom_message_text_test.go
instance_custom_text.go
instance_custom_text_model.go
instance_debug_notification_file.go
instance_debug_notification_file_model.go
instance_debug_notification_file_test.go
instance_debug_notification_log.go
instance_debug_notification_log_model.go
instance_debug_notification_log_test.go
instance_domain.go
instance_domain_model.go
instance_domain_test.go
instance_idp.go
instance_idp_config.go
instance_idp_config_model.go
instance_idp_config_test.go
instance_idp_jwt_config.go
instance_idp_jwt_config_model.go
instance_idp_jwt_config_test.go
instance_idp_model.go
instance_idp_oidc_config.go
instance_idp_oidc_config_model.go
instance_idp_oidc_config_test.go
instance_idp_test.go
instance_member.go
instance_member_model.go
instance_member_test.go
instance_model.go
instance_oidc_settings.go
instance_oidc_settings_model.go
instance_oidc_settings_test.go
instance_policy_domain.go
instance_policy_domain_model.go
instance_policy_domain_test.go
instance_policy_label.go
instance_policy_label_model.go
instance_policy_label_test.go
instance_policy_login.go
instance_policy_login_factors_model.go
instance_policy_login_identity_provider_model.go
instance_policy_login_model.go
instance_policy_login_test.go
instance_policy_mail_template.go
instance_policy_mail_template_model.go
instance_policy_mail_template_test.go
instance_policy_notification.go
instance_policy_notification_model.go
instance_policy_notification_test.go
instance_policy_password_age.go
instance_policy_password_age_model.go
instance_policy_password_age_test.go
instance_policy_password_complexity.go
instance_policy_password_complexity_model.go
instance_policy_password_complexity_test.go
instance_policy_password_lockout.go
instance_policy_password_lockout_model.go
instance_policy_password_lockout_test.go
instance_policy_privacy.go
instance_policy_privacy_model.go
instance_policy_privacy_test.go
instance_policy_security.go
instance_policy_security_model.go
instance_secret_generator_model.go
instance_settings.go
instance_settings_test.go
instance_smtp_config_model.go
instance_test.go
jwt_config_model.go
key_pair.go
key_pair_model.go
main_test.go
member_model.go
metadata_model.go
oidc_config_model.go
org.go
org_action.go
org_action_model.go
org_action_test.go
org_converter.go
org_custom_login_text.go
org_custom_login_text_model.go
org_custom_login_text_test.go
org_custom_message_model.go
org_custom_message_text.go
org_custom_message_text_test.go
org_domain.go
org_domain_model.go
org_domain_test.go
org_flow.go
org_flow_model.go
org_flow_test.go
org_idp.go
org_idp_config.go
org_idp_config_model.go
org_idp_config_test.go
org_idp_jwt_config.go
org_idp_jwt_config_model.go
org_idp_jwt_config_test.go
org_idp_model.go
org_idp_oidc_config.go
org_idp_oidc_config_model.go
org_idp_oidc_config_test.go
org_idp_test.go
org_member.go
org_member_model.go
org_member_test.go
org_metadata.go
org_metadata_model.go
org_metadata_test.go
org_model.go
org_policy_domain.go
org_policy_domain_model.go
org_policy_domain_test.go
org_policy_label.go
org_policy_label_model.go
org_policy_label_test.go
org_policy_lockout.go
org_policy_lockout_model.go
org_policy_lockout_test.go
org_policy_login.go
org_policy_login_factors_model.go
org_policy_login_identity_provider_model.go
org_policy_login_model.go
org_policy_login_test.go
org_policy_mail_template.go
org_policy_mail_template_model.go
org_policy_mail_template_test.go
org_policy_notification.go
org_policy_notification_model.go
org_policy_notification_test.go
org_policy_password_age.go
org_policy_password_age_model.go
org_policy_password_age_test.go
org_policy_password_complexity.go
org_policy_password_complexity_model.go
org_policy_password_complexity_test.go
org_policy_privacy.go
org_policy_privacy_model.go
org_policy_privacy_test.go
org_test.go
phone.go
phone_test.go
policy_label_model.go
policy_login_factors_model.go
policy_login_model.go
policy_mail_template_model.go
policy_notification_model.go
policy_org_model.go
policy_password_age_model.go
policy_password_complexity_model.go
policy_password_lockout_model.go
policy_privacy_model.go
preparation_test.go
project.go
project_application.go
project_application_api.go
project_application_api_model.go
project_application_api_test.go
project_application_key.go
project_application_key_model.go
project_application_key_test.go
project_application_model.go
project_application_oidc.go
project_application_oidc_model.go
project_application_oidc_test.go
project_application_saml.go
project_application_saml_model.go
project_application_saml_test.go
project_application_test.go
project_converter.go
project_grant.go
project_grant_member.go
project_grant_member_model.go
project_grant_member_test.go
project_grant_model.go
project_grant_test.go
project_member.go
project_member_model.go
project_member_test.go
project_model.go
project_role.go
project_role_model.go
project_role_test.go
project_test.go
quota.go
quota_model.go
quota_report.go
session.go
session_model.go
session_test.go
sms_config.go
sms_config_model.go
sms_config_test.go
smtp.go
smtp_test.go
statics.go
system_model.go
unique_constraints_model.go
user.go
user_converter.go
user_domain_policy.go
user_domain_policy_test.go
user_grant.go
user_grant_converter.go
user_grant_model.go
user_grant_test.go
user_human.go
user_human_access_token_model.go
user_human_address.go
user_human_address_model.go
user_human_adress_test.go
user_human_avatar.go
user_human_avatar_test.go
user_human_email.go
user_human_email_model.go
user_human_email_test.go
user_human_init.go
user_human_init_model.go
user_human_init_test.go
user_human_model.go
user_human_otp.go
user_human_otp_model.go
user_human_otp_test.go
user_human_password.go
user_human_password_model.go
user_human_password_test.go
user_human_phone.go
user_human_phone_model.go
user_human_phone_test.go
user_human_profile.go
user_human_profile_model.go
user_human_profile_test.go
user_human_refresh_token.go
user_human_refresh_token_model.go
user_human_refresh_token_test.go
user_human_test.go
user_human_webauthn.go
user_human_webauthn_model.go
user_idp_link.go
user_idp_link_model.go
user_idp_link_test.go
user_machine.go
user_machine_key.go
user_machine_key_model.go
user_machine_key_test.go
user_machine_model.go
user_machine_secret.go
user_machine_secret_test.go
user_machine_test.go
user_membership.go
user_metadata.go
user_metadata_model.go
user_metadata_test.go
user_model.go
user_password_complexity_policy.go
user_password_complexity_policy_test.go
user_personal_access_token.go
user_personal_access_token_model.go
user_personal_access_token_test.go
user_test.go
user_v2_email.go
user_v2_email_test.go
user_v2_passkey.go
user_v2_passkey_test.go
config
crypto
database
domain
errors
eventstore
form
i18n
iam
id
idp
integration
logstore
migration
notification
org
project
proto
protoc
qrcode
query
renderer
repository
static
statik
telemetry
test
user
view
webauthn
openapi
pkg
proto
statik
tools
.dockerignore
.gitignore
.golangci.yaml
.goreleaser.yaml
.releaserc.js
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE
README.md
SECURITY.md
buf.work.yaml
changelog.config.js
go.mod
go.sum
main.go
release-channels.yaml
yarn.lock
zitadel/internal/command/crypto_test.go
Tim Möhlmann a301c40f9f feat: implement register Passkey user API v2 ()
* command/crypto: DRY the code

- reuse the the algorithm switch to create a secret generator
- add a verifyCryptoCode function

* command: crypto code tests

* migrate webauthn package

* finish integration tests with webauthn mock client
2023-05-24 10:22:00 +00:00

243 lines
7.1 KiB
Go

package command
import (
"context"
"io"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zitadel/zitadel/internal/command/preparation"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/instance"
)
func mockCode(code string, exp time.Duration) cryptoCodeFunc {
return func(ctx context.Context, filter preparation.FilterToQueryReducer, _ domain.SecretGeneratorType, alg crypto.Crypto) (*CryptoCodeWithExpiry, error) {
return &CryptoCodeWithExpiry{
Crypted: &crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
Algorithm: "enc",
KeyID: "id",
Crypted: []byte(code),
},
Plain: code,
Expiry: exp,
}, nil
}
}
var (
testGeneratorConfig = crypto.GeneratorConfig{
Length: 12,
Expiry: 60000000000,
IncludeLowerLetters: true,
IncludeUpperLetters: true,
IncludeDigits: true,
IncludeSymbols: true,
}
)
func testSecretGeneratorAddedEvent(typ domain.SecretGeneratorType) *instance.SecretGeneratorAddedEvent {
return instance.NewSecretGeneratorAddedEvent(context.Background(),
&instance.NewAggregate("inst1").Aggregate, typ,
testGeneratorConfig.Length,
testGeneratorConfig.Expiry,
testGeneratorConfig.IncludeLowerLetters,
testGeneratorConfig.IncludeUpperLetters,
testGeneratorConfig.IncludeDigits,
testGeneratorConfig.IncludeSymbols,
)
}
func Test_newCryptoCode(t *testing.T) {
type args struct {
typ domain.SecretGeneratorType
alg crypto.Crypto
}
tests := []struct {
name string
eventstore *eventstore.Eventstore
args args
wantErr error
}{
{
name: "filter config error",
eventstore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
wantErr: io.ErrClosedPipe,
},
{
name: "success",
eventstore: eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := newCryptoCodeWithExpiry(context.Background(), tt.eventstore.Filter, tt.args.typ, tt.args.alg)
require.ErrorIs(t, err, tt.wantErr)
if tt.wantErr == nil {
require.NotNil(t, got)
assert.NotNil(t, got.Crypted)
assert.NotEmpty(t, got)
assert.Equal(t, testGeneratorConfig.Expiry, got.Expiry)
}
})
}
}
func Test_verifyCryptoCode(t *testing.T) {
es := eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
))
code, err := newCryptoCodeWithExpiry(context.Background(), es.Filter, domain.SecretGeneratorTypeVerifyEmailCode, crypto.CreateMockHashAlg(gomock.NewController(t)))
require.NoError(t, err)
type args struct {
typ domain.SecretGeneratorType
alg crypto.Crypto
expiry time.Duration
crypted *crypto.CryptoValue
plain string
}
tests := []struct {
name string
eventsore *eventstore.Eventstore
args args
wantErr bool
}{
{
name: "filter config error",
eventsore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
expiry: code.Expiry,
crypted: code.Crypted,
plain: code.Plain,
},
wantErr: true,
},
{
name: "success",
eventsore: eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
expiry: code.Expiry,
crypted: code.Crypted,
plain: code.Plain,
},
},
{
name: "wrong plain",
eventsore: eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
expiry: code.Expiry,
crypted: code.Crypted,
plain: "wrong",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := verifyCryptoCode(context.Background(), tt.eventsore.Filter, tt.args.typ, tt.args.alg, time.Now(), tt.args.expiry, tt.args.crypted, tt.args.plain)
if tt.wantErr {
assert.Error(t, err)
return
}
require.NoError(t, err)
})
}
}
func Test_secretGenerator(t *testing.T) {
type args struct {
typ domain.SecretGeneratorType
alg crypto.Crypto
}
tests := []struct {
name string
eventsore *eventstore.Eventstore
args args
want crypto.Generator
wantConf *crypto.GeneratorConfig
wantErr error
}{
{
name: "filter config error",
eventsore: eventstoreExpect(t, expectFilterError(io.ErrClosedPipe)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
wantErr: io.ErrClosedPipe,
},
{
name: "hash generator",
eventsore: eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockHashAlg(gomock.NewController(t)),
},
want: crypto.NewHashGenerator(testGeneratorConfig, crypto.CreateMockHashAlg(gomock.NewController(t))),
wantConf: &testGeneratorConfig,
},
{
name: "encryption generator",
eventsore: eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
},
want: crypto.NewEncryptionGenerator(testGeneratorConfig, crypto.CreateMockEncryptionAlg(gomock.NewController(t))),
wantConf: &testGeneratorConfig,
},
{
name: "unsupported type",
eventsore: eventstoreExpect(t, expectFilter(
eventFromEventPusher(testSecretGeneratorAddedEvent(domain.SecretGeneratorTypeVerifyEmailCode)),
)),
args: args{
typ: domain.SecretGeneratorTypeVerifyEmailCode,
alg: nil,
},
wantErr: errors.ThrowInternalf(nil, "COMMA-RreV6", "Errors.Internal unsupported crypto algorithm type %T", nil),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, gotConf, err := secretGenerator(context.Background(), tt.eventsore.Filter, tt.args.typ, tt.args.alg)
require.ErrorIs(t, err, tt.wantErr)
assert.IsType(t, tt.want, got)
assert.Equal(t, tt.wantConf, gotConf)
})
}
}