mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 07:37:39 +00:00
.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

* 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
243 lines
7.1 KiB
Go
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)
|
|
})
|
|
}
|
|
}
|