2023-02-15 09:14:59 +01:00
package projection
import (
2023-09-29 11:26:14 +02:00
"encoding/json"
2023-02-15 09:14:59 +01:00
"testing"
2023-03-24 16:18:56 +01:00
"time"
2023-02-15 09:14:59 +01:00
2023-02-21 18:18:28 +01:00
"github.com/zitadel/zitadel/internal/database"
2023-02-15 09:14:59 +01:00
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
2023-10-19 12:19:10 +02:00
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
2023-02-15 09:14:59 +01:00
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
2023-12-08 16:30:55 +02:00
"github.com/zitadel/zitadel/internal/zerrors"
2023-02-15 09:14:59 +01:00
)
2023-03-13 17:34:29 +01:00
var (
2024-04-10 17:46:30 +02:00
idpTemplateInsertStmt = ` INSERT INTO projections.idp_templates6 ` +
` (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, owner_type, type, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking) ` +
` VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) `
idpTemplateUpdateMinimalStmt = ` UPDATE projections.idp_templates6 SET (is_creation_allowed, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5) `
idpTemplateUpdateStmt = ` UPDATE projections.idp_templates6 SET (name, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking, change_date, sequence) ` +
` = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (id = $9) AND (instance_id = $10) `
2023-03-13 17:34:29 +01:00
)
2023-02-15 09:14:59 +01:00
func TestIDPTemplateProjection_reducesRemove ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceInstanceRemoved" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . InstanceRemovedEventType ,
instance . AggregateType ,
nil ,
) , instance . InstanceRemovedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
reduce : reduceInstanceRemovedHelper ( IDPInstanceIDCol ) ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6 WHERE (instance_id = $1)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"agg-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOwnerRemoved" ,
reduce : ( & idpTemplateProjection { } ) . reduceOwnerRemoved ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . OrgRemovedEventType ,
org . AggregateType ,
nil ,
) , org . OrgRemovedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6 WHERE (instance_id = $1) AND (resource_owner = $2)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"instance-id" ,
"agg-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceIDPRemoved" ,
reduce : ( & idpTemplateProjection { } ) . reduceIDPRemoved ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPRemovedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-02-15 09:14:59 +01:00
"id" : "idp-id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPRemovedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6 WHERE (id = $1) AND (instance_id = $2)" ,
2023-04-17 10:20:49 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceIDPConfigRemoved" ,
reduce : ( & idpTemplateProjection { } ) . reduceIDPConfigRemoved ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPConfigRemovedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-04-17 10:20:49 +02:00
"idpConfigId" : "idp-id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPConfigRemovedEventMapper ) ,
2023-04-17 10:20:49 +02:00
} ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-04-17 10:20:49 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6 WHERE (id = $1) AND (instance_id = $2)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-02-15 09:14:59 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-02-24 15:16:06 +01:00
func TestIDPTemplateProjection_reducesOAuth ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceOAuthIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . OAuthIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-24 15:16:06 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-02-27 16:32:18 +01:00
"clientId" : "client_id" ,
"clientSecret" : {
2023-02-24 15:16:06 +01:00
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"authorizationEndpoint" : "auth" ,
"tokenEndpoint" : "token" ,
"userEndpoint" : "user" ,
"scopes" : [ "profile" ] ,
2023-03-03 11:38:49 +01:00
"idAttribute" : "id-attribute" ,
2025-02-26 13:20:47 +01:00
"usePKCE" : false ,
2023-02-24 15:16:06 +01:00
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-24 15:16:06 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . OAuthIDPAddedEventMapper ) ,
2023-02-24 15:16:06 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOAuthIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-24 15:16:06 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeOAuth ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-24 15:16:06 +01:00
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "INSERT INTO projections.idp_templates6_oauth2 (idp_id, instance_id, client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes, id_attribute, use_pkce) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)" ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
"auth" ,
"token" ,
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-03 11:38:49 +01:00
"id-attribute" ,
2025-02-26 13:20:47 +01:00
false ,
2023-02-24 15:16:06 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOAuthIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . OAuthIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-02-24 15:16:06 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-02-27 16:32:18 +01:00
"clientId" : "client_id" ,
"clientSecret" : {
2023-02-24 15:16:06 +01:00
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"authorizationEndpoint" : "auth" ,
"tokenEndpoint" : "token" ,
"userEndpoint" : "user" ,
"scopes" : [ "profile" ] ,
2023-03-03 11:38:49 +01:00
"idAttribute" : "id-attribute" ,
2025-02-26 13:20:47 +01:00
"usePKCE" : true ,
2023-02-24 15:16:06 +01:00
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-24 15:16:06 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . OAuthIDPAddedEventMapper ) ,
2023-02-24 15:16:06 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOAuthIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-24 15:16:06 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeOAuth ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-24 15:16:06 +01:00
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "INSERT INTO projections.idp_templates6_oauth2 (idp_id, instance_id, client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes, id_attribute, use_pkce) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)" ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
"auth" ,
"token" ,
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-03 11:38:49 +01:00
"id-attribute" ,
2025-02-26 13:20:47 +01:00
true ,
2023-02-24 15:16:06 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOAuthIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . OAuthIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-24 15:16:06 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
2023-02-27 16:32:18 +01:00
"clientId" : "id"
2023-02-24 15:16:06 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . OAuthIDPChangedEventMapper ) ,
2023-02-24 15:16:06 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOAuthIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-24 15:16:06 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateMinimalStmt ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_oauth2 SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOAuthIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . OAuthIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-24 15:16:06 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-02-27 16:32:18 +01:00
"clientId" : "client_id" ,
"clientSecret" : {
2023-02-24 15:16:06 +01:00
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"authorizationEndpoint" : "auth" ,
"tokenEndpoint" : "token" ,
"userEndpoint" : "user" ,
"scopes" : [ "profile" ] ,
2023-03-03 11:38:49 +01:00
"idAttribute" : "id-attribute" ,
2025-02-26 13:20:47 +01:00
"usePKCE" : true ,
2023-02-24 15:16:06 +01:00
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-24 15:16:06 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . OAuthIDPChangedEventMapper ) ,
2023-02-24 15:16:06 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOAuthIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-24 15:16:06 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateStmt ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-24 15:16:06 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "UPDATE projections.idp_templates6_oauth2 SET (client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes, id_attribute, use_pkce) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9) AND (instance_id = $10)" ,
2023-02-24 15:16:06 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
"auth" ,
"token" ,
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-03 11:38:49 +01:00
"id-attribute" ,
2025-02-26 13:20:47 +01:00
true ,
2023-02-24 15:16:06 +01:00
"idp-id" ,
"instance-id" ,
} ,
2023-03-08 11:17:28 +01:00
} ,
} ,
} ,
} ,
} ,
}
2023-03-15 07:48:37 +01:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-03-15 07:48:37 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
func TestIDPTemplateProjection_reducesAzureAD ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceAzureADIDPAdded minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . AzureADIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-15 07:48:37 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
}
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . AzureADIDPAddedEventMapper ) ,
2023-03-15 07:48:37 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAzureADIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-15 07:48:37 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeAzureAD ,
false ,
false ,
false ,
false ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUnspecified ,
2023-03-15 07:48:37 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-03-15 07:48:37 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] ( nil ) ,
2023-03-15 07:48:37 +01:00
"" ,
false ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceAzureADIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . AzureADIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-15 07:48:37 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"tenant" : "tenant" ,
"isEmailVerified" : true ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-15 07:48:37 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . AzureADIDPAddedEventMapper ) ,
2023-03-15 07:48:37 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAzureADIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-15 07:48:37 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeAzureAD ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-15 07:48:37 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-03-15 07:48:37 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-15 07:48:37 +01:00
"tenant" ,
true ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceAzureADIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . AzureADIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-15 07:48:37 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"tenant" : "tenant" ,
"isEmailVerified" : true ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-15 07:48:37 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . AzureADIDPAddedEventMapper ) ,
2023-03-15 07:48:37 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAzureADIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-15 07:48:37 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeAzureAD ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-15 07:48:37 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-03-15 07:48:37 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-15 07:48:37 +01:00
"tenant" ,
true ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceAzureADIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . AzureADIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-15 07:48:37 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"client_id" : "id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . AzureADIDPChangedEventMapper ) ,
2023-03-15 07:48:37 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAzureADIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-15 07:48:37 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateMinimalStmt ,
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_azure SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-03-15 07:48:37 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceAzureADIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . AzureADIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-15 07:48:37 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"tenant" : "tenant" ,
"isEmailVerified" : true ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-15 07:48:37 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . AzureADIDPChangedEventMapper ) ,
2023-03-15 07:48:37 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAzureADIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-15 07:48:37 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateStmt ,
expectedArgs : [ ] interface { } {
"name" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-15 07:48:37 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_azure SET (client_id, client_secret, scopes, tenant, is_email_verified) = ($1, $2, $3, $4, $5) WHERE (idp_id = $6) AND (instance_id = $7)" ,
2023-03-15 07:48:37 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-15 07:48:37 +01:00
"tenant" ,
true ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2023-03-08 11:17:28 +01:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-03-08 11:17:28 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
func TestIDPTemplateProjection_reducesGitHub ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceGitHubIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitHubIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-08 11:17:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitHubIDPAddedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeGitHub ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-08 11:17:28 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_github (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-08 11:17:28 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceGitHubIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . GitHubIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-08 11:17:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . GitHubIDPAddedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeGitHub ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-08 11:17:28 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_github (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-08 11:17:28 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitHubIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitHubIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"clientId" : "id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitHubIDPChangedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateMinimalStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_github SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitHubIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitHubIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-08 11:17:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitHubIDPChangedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"name" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-08 11:17:28 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_github SET (client_id, client_secret, scopes) = ($1, $2, $3) WHERE (idp_id = $4) AND (instance_id = $5)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-08 11:17:28 +01:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-03-08 11:17:28 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
func TestIDPTemplateProjection_reducesGitHubEnterprise ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceGitHubEnterpriseIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitHubEnterpriseIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"authorizationEndpoint" : "auth" ,
"tokenEndpoint" : "token" ,
"userEndpoint" : "user" ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-08 11:17:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitHubEnterpriseIDPAddedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubEnterpriseIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeGitHubEnterprise ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-08 11:17:28 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_github_enterprise (idp_id, instance_id, client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
"auth" ,
"token" ,
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-08 11:17:28 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceGitHubEnterpriseIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . GitHubEnterpriseIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"authorizationEndpoint" : "auth" ,
"tokenEndpoint" : "token" ,
"userEndpoint" : "user" ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-08 11:17:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . GitHubEnterpriseIDPAddedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubEnterpriseIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeGitHubEnterprise ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-08 11:17:28 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_github_enterprise (idp_id, instance_id, client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
"auth" ,
"token" ,
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-08 11:17:28 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitHubEnterpriseIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitHubEnterpriseIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"clientId" : "id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitHubEnterpriseIDPChangedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubEnterpriseIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateMinimalStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_github_enterprise SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitHubEnterpriseIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitHubEnterpriseIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-08 11:17:28 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"authorizationEndpoint" : "auth" ,
"tokenEndpoint" : "token" ,
"userEndpoint" : "user" ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-08 11:17:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitHubEnterpriseIDPChangedEventMapper ) ,
2023-03-08 11:17:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitHubEnterpriseIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-08 11:17:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateStmt ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"name" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-08 11:17:28 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_github_enterprise SET (client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes) = ($1, $2, $3, $4, $5, $6) WHERE (idp_id = $7) AND (instance_id = $8)" ,
2023-03-08 11:17:28 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
"auth" ,
"token" ,
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-08 11:17:28 +01:00
"idp-id" ,
"instance-id" ,
} ,
2023-02-24 15:16:06 +01:00
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-02-24 15:16:06 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-03-13 17:34:29 +01:00
func TestIDPTemplateProjection_reducesGitLab ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceGitLabIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitLabIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-13 17:34:29 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitLabIDPAddedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeGitLab ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-13 17:34:29 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_gitlab (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-13 17:34:29 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceGitLabIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . GitLabIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-13 17:34:29 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . GitLabIDPAddedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeGitLab ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-13 17:34:29 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_gitlab (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-13 17:34:29 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitLabIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitLabIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"client_id" : "id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitLabIDPChangedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateMinimalStmt ,
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_gitlab SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitLabIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitLabIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-13 17:34:29 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitLabIDPChangedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateStmt ,
expectedArgs : [ ] interface { } {
"name" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-13 17:34:29 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_gitlab SET (client_id, client_secret, scopes) = ($1, $2, $3) WHERE (idp_id = $4) AND (instance_id = $5)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-13 17:34:29 +01:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-03-13 17:34:29 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
func TestIDPTemplateProjection_reducesGitLabSelfHosted ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceGitLabSelfHostedIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitLabSelfHostedIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"issuer" : "issuer" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-13 17:34:29 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitLabSelfHostedIDPAddedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabSelfHostedIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeGitLabSelfHosted ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-13 17:34:29 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_gitlab_self_hosted (idp_id, instance_id, issuer, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5, $6)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"issuer" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-13 17:34:29 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceGitLabSelfHostedIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . GitLabSelfHostedIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"issuer" : "issuer" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-13 17:34:29 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . GitLabSelfHostedIDPAddedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabSelfHostedIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"name" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeGitLabSelfHosted ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-13 17:34:29 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_gitlab_self_hosted (idp_id, instance_id, issuer, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5, $6)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"issuer" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-13 17:34:29 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitLabSelfHostedIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitLabSelfHostedIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"issuer" : "issuer"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitLabSelfHostedIDPChangedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabSelfHostedIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateMinimalStmt ,
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_gitlab_self_hosted SET issuer = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"issuer" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGitLabSelfHostedIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GitLabSelfHostedIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-13 17:34:29 +01:00
"id" : "idp-id" ,
"name" : "name" ,
"issuer" : "issuer" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-03-13 17:34:29 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GitLabSelfHostedIDPChangedEventMapper ) ,
2023-03-13 17:34:29 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGitLabSelfHostedIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-13 17:34:29 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateStmt ,
expectedArgs : [ ] interface { } {
"name" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-03-13 17:34:29 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_gitlab_self_hosted SET (issuer, client_id, client_secret, scopes) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)" ,
2023-03-13 17:34:29 +01:00
expectedArgs : [ ] interface { } {
"issuer" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-13 17:34:29 +01:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-03-13 17:34:29 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-02-21 18:18:28 +01:00
func TestIDPTemplateProjection_reducesGoogle ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceGoogleIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GoogleIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-21 18:18:28 +01:00
"id" : "idp-id" ,
2023-02-27 16:32:18 +01:00
"clientId" : "client_id" ,
2023-02-21 18:18:28 +01:00
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-21 18:18:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GoogleIDPAddedEventMapper ) ,
2023-02-21 18:18:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGoogleIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-21 18:18:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeGoogle ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-21 18:18:28 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_google (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-02-21 18:18:28 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceGoogleIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . GoogleIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-02-21 18:18:28 +01:00
"id" : "idp-id" ,
2023-02-27 16:32:18 +01:00
"clientId" : "client_id" ,
2023-02-21 18:18:28 +01:00
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-21 18:18:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . GoogleIDPAddedEventMapper ) ,
2023-02-21 18:18:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGoogleIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-21 18:18:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeGoogle ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-21 18:18:28 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_google (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-02-21 18:18:28 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGoogleIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GoogleIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-21 18:18:28 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
2023-02-27 16:32:18 +01:00
"clientId" : "id"
2023-02-21 18:18:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GoogleIDPChangedEventMapper ) ,
2023-02-21 18:18:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGoogleIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-21 18:18:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateMinimalStmt ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_google SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceGoogleIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . GoogleIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-21 18:18:28 +01:00
"id" : "idp-id" ,
2023-03-13 17:34:29 +01:00
"name" : "name" ,
2023-02-27 16:32:18 +01:00
"clientId" : "client_id" ,
2023-02-21 18:18:28 +01:00
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-21 18:18:28 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . GoogleIDPChangedEventMapper ) ,
2023-02-21 18:18:28 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceGoogleIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-21 18:18:28 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateStmt ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
2023-03-13 17:34:29 +01:00
"name" ,
2023-02-21 18:18:28 +01:00
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-21 18:18:28 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_google SET (client_id, client_secret, scopes) = ($1, $2, $3) WHERE (idp_id = $4) AND (instance_id = $5)" ,
2023-02-21 18:18:28 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-02-21 18:18:28 +01:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-02-21 18:18:28 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-02-15 09:14:59 +01:00
func TestIDPTemplateProjection_reducesLDAP ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceLDAPIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . LDAPIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-15 09:14:59 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-03-24 16:18:56 +01:00
"servers" : [ "server" ] ,
"startTls" : false ,
"baseDN" : "basedn" ,
"bindDN" : "binddn" ,
"bindPassword" : {
2023-02-15 09:14:59 +01:00
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
2023-03-24 16:18:56 +01:00
"userBase" : "user" ,
"userObjectClasses" : [ "object" ] ,
"userFilters" : [ "filter" ] ,
"timeout" : 30000000000 ,
2025-03-18 15:23:12 +00:00
"rootCA" : ` +stringToJSONByte("certificate")+ ` ,
2023-02-15 09:14:59 +01:00
"idAttribute" : "id" ,
"firstNameAttribute" : "first" ,
"lastNameAttribute" : "last" ,
"displayNameAttribute" : "display" ,
"nickNameAttribute" : "nickname" ,
"preferredUsernameAttribute" : "username" ,
"emailAttribute" : "email" ,
"emailVerifiedAttribute" : "email_verified" ,
"phoneAttribute" : "phone" ,
"phoneVerifiedAttribute" : "phone_verified" ,
"preferredLanguageAttribute" : "lang" ,
"avatarURLAttribute" : "avatar" ,
"profileAttribute" : "profile" ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-15 09:14:59 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . LDAPIDPAddedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceLDAPIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeLDAP ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-15 09:14:59 +01:00
} ,
} ,
{
2025-03-18 15:23:12 +00:00
expectedStmt : "INSERT INTO projections.idp_templates6_ldap2 (idp_id, instance_id, servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, root_ca, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "server" } ,
2023-03-24 16:18:56 +01:00
false ,
"basedn" ,
"binddn" ,
2023-02-15 09:14:59 +01:00
anyArg { } ,
2023-03-24 16:18:56 +01:00
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "object" } ,
database . TextArray [ string ] { "filter" } ,
2023-03-24 16:18:56 +01:00
time . Duration ( 30000000000 ) ,
2025-02-18 10:06:50 +00:00
[ ] byte ( "certificate" ) ,
2023-02-15 09:14:59 +01:00
"id" ,
"first" ,
"last" ,
"display" ,
"nickname" ,
"username" ,
"email" ,
"email_verified" ,
"phone" ,
"phone_verified" ,
"lang" ,
"avatar" ,
"profile" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceLDAPIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . LDAPIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-02-15 09:14:59 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-03-24 16:18:56 +01:00
"servers" : [ "server" ] ,
"startTls" : false ,
"baseDN" : "basedn" ,
"bindDN" : "binddn" ,
"bindPassword" : {
2023-02-15 09:14:59 +01:00
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
2023-03-24 16:18:56 +01:00
"userBase" : "user" ,
"userObjectClasses" : [ "object" ] ,
"userFilters" : [ "filter" ] ,
"timeout" : 30000000000 ,
2025-03-18 15:23:12 +00:00
"rootCA" : ` +stringToJSONByte("certificate")+ ` ,
2023-02-15 09:14:59 +01:00
"idAttribute" : "id" ,
"firstNameAttribute" : "first" ,
"lastNameAttribute" : "last" ,
"displayNameAttribute" : "display" ,
"nickNameAttribute" : "nickname" ,
"preferredUsernameAttribute" : "username" ,
"emailAttribute" : "email" ,
"emailVerifiedAttribute" : "email_verified" ,
"phoneAttribute" : "phone" ,
"phoneVerifiedAttribute" : "phone_verified" ,
"preferredLanguageAttribute" : "lang" ,
"avatarURLAttribute" : "avatar" ,
"profileAttribute" : "profile" ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-15 09:14:59 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . LDAPIDPAddedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceLDAPIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeLDAP ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-15 09:14:59 +01:00
} ,
} ,
{
2025-03-18 15:23:12 +00:00
expectedStmt : "INSERT INTO projections.idp_templates6_ldap2 (idp_id, instance_id, servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, root_ca, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "server" } ,
2023-03-24 16:18:56 +01:00
false ,
"basedn" ,
"binddn" ,
2023-02-15 09:14:59 +01:00
anyArg { } ,
2023-03-24 16:18:56 +01:00
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "object" } ,
database . TextArray [ string ] { "filter" } ,
2023-03-24 16:18:56 +01:00
time . Duration ( 30000000000 ) ,
2025-02-18 10:06:50 +00:00
[ ] byte ( "certificate" ) ,
2023-02-15 09:14:59 +01:00
"id" ,
"first" ,
"last" ,
"display" ,
"nickname" ,
"username" ,
"email" ,
"email_verified" ,
"phone" ,
"phone_verified" ,
"lang" ,
"avatar" ,
"profile" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceLDAPIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . LDAPIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-15 09:14:59 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-03-24 16:18:56 +01:00
"baseDN" : "basedn"
2023-02-15 09:14:59 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . LDAPIDPChangedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceLDAPIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2025-03-18 15:23:12 +00:00
expectedStmt : "UPDATE projections.idp_templates6_ldap2 SET base_dn = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
2023-03-24 16:18:56 +01:00
"basedn" ,
2023-02-15 09:14:59 +01:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceLDAPIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . LDAPIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-15 09:14:59 +01:00
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
2023-03-24 16:18:56 +01:00
"servers" : [ "server" ] ,
"startTls" : false ,
"baseDN" : "basedn" ,
"bindDN" : "binddn" ,
"bindPassword" : {
2023-02-15 09:14:59 +01:00
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
2023-03-24 16:18:56 +01:00
"userBase" : "user" ,
"userObjectClasses" : [ "object" ] ,
"userFilters" : [ "filter" ] ,
"timeout" : 30000000000 ,
2025-03-18 15:23:12 +00:00
"rootCA" : ` +stringToJSONByte("certificate")+ ` ,
2023-02-15 09:14:59 +01:00
"idAttribute" : "id" ,
"firstNameAttribute" : "first" ,
"lastNameAttribute" : "last" ,
"displayNameAttribute" : "display" ,
"nickNameAttribute" : "nickname" ,
"preferredUsernameAttribute" : "username" ,
"emailAttribute" : "email" ,
"emailVerifiedAttribute" : "email_verified" ,
"phoneAttribute" : "phone" ,
"phoneVerifiedAttribute" : "phone_verified" ,
"preferredLanguageAttribute" : "lang" ,
"avatarURLAttribute" : "avatar" ,
"profileAttribute" : "profile" ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-15 09:14:59 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . LDAPIDPChangedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceLDAPIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateStmt ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-15 09:14:59 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2025-03-18 15:23:12 +00:00
expectedStmt : "UPDATE projections.idp_templates6_ldap2 SET (servers, start_tls, base_dn, bind_dn, bind_password, user_base, user_object_classes, user_filters, timeout, root_ca, id_attribute, first_name_attribute, last_name_attribute, display_name_attribute, nick_name_attribute, preferred_username_attribute, email_attribute, email_verified, phone_attribute, phone_verified_attribute, preferred_language_attribute, avatar_url_attribute, profile_attribute) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23) WHERE (idp_id = $24) AND (instance_id = $25)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "server" } ,
2023-03-24 16:18:56 +01:00
false ,
"basedn" ,
"binddn" ,
2023-02-15 09:14:59 +01:00
anyArg { } ,
2023-03-24 16:18:56 +01:00
"user" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "object" } ,
database . TextArray [ string ] { "filter" } ,
2023-03-24 16:18:56 +01:00
time . Duration ( 30000000000 ) ,
2025-02-18 10:06:50 +00:00
[ ] byte ( "certificate" ) ,
2023-02-15 09:14:59 +01:00
"id" ,
"first" ,
"last" ,
"display" ,
"nickname" ,
"username" ,
"email" ,
"email_verified" ,
"phone" ,
"phone_verified" ,
"lang" ,
"avatar" ,
"profile" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org.reduceOwnerRemoved" ,
reduce : ( & idpProjection { } ) . reduceOwnerRemoved ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . OrgRemovedEventType ,
org . AggregateType ,
nil ,
) , org . OrgRemovedEventMapper ) ,
2023-02-15 09:14:59 +01:00
} ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-15 09:14:59 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6 WHERE (instance_id = $1) AND (resource_owner = $2)" ,
2023-02-15 09:14:59 +01:00
expectedArgs : [ ] interface { } {
"instance-id" ,
"agg-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-02-15 09:14:59 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-02-27 16:32:18 +01:00
2023-08-31 08:39:16 +02:00
func TestIDPTemplateProjection_reducesApple ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceAppleIDPAdded" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . AppleIDPAddedEventType ,
2023-08-31 08:39:16 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"clientId" : "client_id" ,
"teamId" : "team_id" ,
"keyId" : "key_id" ,
"privateKey" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "name" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-08-31 08:39:16 +02:00
} ` ) ,
) , instance . AppleIDPAddedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAppleIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-08-31 08:39:16 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeApple ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-08-31 08:39:16 +02:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_apple (idp_id, instance_id, client_id, team_id, key_id, private_key, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-08-31 08:39:16 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
"team_id" ,
"key_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "name" } ,
2023-08-31 08:39:16 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceAppleIDPAdded" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
org . AppleIDPAddedEventType ,
2023-08-31 08:39:16 +02:00
org . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"clientId" : "client_id" ,
"teamId" : "team_id" ,
"keyId" : "key_id" ,
"privateKey" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "name" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-08-31 08:39:16 +02:00
} ` ) ,
) , org . AppleIDPAddedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAppleIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-08-31 08:39:16 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeApple ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-08-31 08:39:16 +02:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_apple (idp_id, instance_id, client_id, team_id, key_id, private_key, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-08-31 08:39:16 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
"team_id" ,
"key_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "name" } ,
2023-08-31 08:39:16 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceAppleIDPChanged minimal" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . AppleIDPChangedEventType ,
2023-08-31 08:39:16 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"clientId" : "id"
} ` ) ,
) , instance . AppleIDPChangedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAppleIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-08-31 08:39:16 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateMinimalStmt ,
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_apple SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-08-31 08:39:16 +02:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceAppleIDPChanged" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . AppleIDPChangedEventType ,
2023-08-31 08:39:16 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"teamId" : "team_id" ,
"keyId" : "key_id" ,
"privateKey" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "name" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-08-31 08:39:16 +02:00
} ` ) ,
) , instance . AppleIDPChangedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceAppleIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-08-31 08:39:16 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateStmt ,
expectedArgs : [ ] interface { } {
"name" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-08-31 08:39:16 +02:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_apple SET (client_id, team_id, key_id, private_key, scopes) = ($1, $2, $3, $4, $5) WHERE (idp_id = $6) AND (instance_id = $7)" ,
2023-08-31 08:39:16 +02:00
expectedArgs : [ ] interface { } {
"client_id" ,
"team_id" ,
"key_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "name" } ,
2023-08-31 08:39:16 +02:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-08-31 08:39:16 +02:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-09-29 11:26:14 +02:00
func TestIDPTemplateProjection_reducesSAML ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceSAMLIDPAdded" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . SAMLIDPAddedEventType ,
2023-09-29 11:26:14 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
"metadata" : ` +stringToJSONByte("metadata")+ ` ,
"key" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"certificate" : ` +stringToJSONByte("certificate")+ ` ,
"binding" : "binding" ,
2024-05-23 07:04:07 +02:00
"nameIDFormat" : 3 ,
"transientMappingAttributeName" : "customAttribute" ,
2023-09-29 11:26:14 +02:00
"withSignedRequest" : true ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
"autoLinkingOption" : 1 ,
"federatedLogoutEnabled" : true
2023-09-29 11:26:14 +02:00
} ` ) ,
) , instance . SAMLIDPAddedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceSAMLIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-09-29 11:26:14 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeSAML ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-09-29 11:26:14 +02:00
} ,
} ,
{
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_saml (idp_id, instance_id, metadata, key, certificate, binding, with_signed_request, transient_mapping_attribute_name, federated_logout_enabled, name_id_format) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)" ,
2023-09-29 11:26:14 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
[ ] byte ( "metadata" ) ,
anyArg { } ,
anyArg { } ,
"binding" ,
true ,
2024-05-23 07:04:07 +02:00
"customAttribute" ,
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
true ,
2024-05-23 07:04:07 +02:00
domain . SAMLNameIDFormatTransient ,
2023-09-29 11:26:14 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceSAMLIDPAdded" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
org . SAMLIDPAddedEventType ,
2023-09-29 11:26:14 +02:00
org . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
"metadata" : ` +stringToJSONByte("metadata")+ ` ,
"key" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"certificate" : ` +stringToJSONByte("certificate")+ ` ,
"binding" : "binding" ,
2024-05-23 07:04:07 +02:00
"nameIDFormat" : 3 ,
"transientMappingAttributeName" : "customAttribute" ,
2023-09-29 11:26:14 +02:00
"withSignedRequest" : true ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
"autoLinkingOption" : 1 ,
"federatedLogoutEnabled" : true
2023-09-29 11:26:14 +02:00
} ` ) ,
) , org . SAMLIDPAddedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceSAMLIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-09-29 11:26:14 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateInsertStmt ,
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeSAML ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-09-29 11:26:14 +02:00
} ,
} ,
{
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_saml (idp_id, instance_id, metadata, key, certificate, binding, with_signed_request, transient_mapping_attribute_name, federated_logout_enabled, name_id_format) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)" ,
2023-09-29 11:26:14 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
[ ] byte ( "metadata" ) ,
anyArg { } ,
anyArg { } ,
"binding" ,
true ,
2024-05-23 07:04:07 +02:00
"customAttribute" ,
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
true ,
2024-05-23 07:04:07 +02:00
domain . SAMLNameIDFormatTransient ,
2023-09-29 11:26:14 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceSAMLIDPChanged minimal" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . SAMLIDPChangedEventType ,
2023-09-29 11:26:14 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
"binding" : "binding"
} ` ) ,
) , instance . SAMLIDPChangedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceSAMLIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-09-29 11:26:14 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)" ,
2023-09-29 11:26:14 +02:00
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_saml SET binding = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-09-29 11:26:14 +02:00
expectedArgs : [ ] interface { } {
"binding" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceSAMLIDPChanged" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . SAMLIDPChangedEventType ,
2023-09-29 11:26:14 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "custom-zitadel-instance" ,
"metadata" : ` +stringToJSONByte("metadata")+ ` ,
"key" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"certificate" : ` +stringToJSONByte("certificate")+ ` ,
"binding" : "binding" ,
"withSignedRequest" : true ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
"autoLinkingOption" : 1 ,
"federatedLogoutEnabled" : true
2023-09-29 11:26:14 +02:00
} ` ) ,
) , instance . SAMLIDPChangedEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceSAMLIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-09-29 11:26:14 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
expectedStmt : idpTemplateUpdateStmt ,
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-09-29 11:26:14 +02:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
expectedStmt : "UPDATE projections.idp_templates6_saml SET (metadata, key, certificate, binding, with_signed_request, federated_logout_enabled) = ($1, $2, $3, $4, $5, $6) WHERE (idp_id = $7) AND (instance_id = $8)" ,
2023-09-29 11:26:14 +02:00
expectedArgs : [ ] interface { } {
[ ] byte ( "metadata" ) ,
anyArg { } ,
anyArg { } ,
"binding" ,
true ,
feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved
Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.
# How the Problems Are Solved
- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.
# Additional Changes
None
# Additional Context
- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228
- backport to 3.x
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
true ,
2023-09-29 11:26:14 +02:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org.reduceOwnerRemoved" ,
reduce : ( & idpProjection { } ) . reduceOwnerRemoved ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
org . OrgRemovedEventType ,
2023-09-29 11:26:14 +02:00
org . AggregateType ,
nil ,
) , org . OrgRemovedEventMapper ) ,
} ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-09-29 11:26:14 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6 WHERE (instance_id = $1) AND (resource_owner = $2)" ,
2023-09-29 11:26:14 +02:00
expectedArgs : [ ] interface { } {
"instance-id" ,
"agg-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-09-29 11:26:14 +02:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-02-27 16:32:18 +01:00
func TestIDPTemplateProjection_reducesOIDC ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceOIDCIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . OIDCIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"issuer" : "issuer" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
2023-03-16 16:47:22 +01:00
"idTokenMapping" : true ,
2025-02-26 13:20:47 +01:00
"usePKCE" : true ,
2023-02-27 16:32:18 +01:00
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-27 16:32:18 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . OIDCIDPAddedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeOIDC ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-27 16:32:18 +01:00
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "INSERT INTO projections.idp_templates6_oidc (idp_id, instance_id, issuer, client_id, client_secret, scopes, id_token_mapping, use_pkce) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"issuer" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-16 16:47:22 +01:00
true ,
2025-02-26 13:20:47 +01:00
true ,
2023-02-27 16:32:18 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOIDCIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . OIDCIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"issuer" : "issuer" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
2023-03-16 16:47:22 +01:00
"idTokenMapping" : true ,
2025-02-26 13:20:47 +01:00
"usePKCE" : true ,
2023-02-27 16:32:18 +01:00
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-27 16:32:18 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . OIDCIDPAddedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeOIDC ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-27 16:32:18 +01:00
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "INSERT INTO projections.idp_templates6_oidc (idp_id, instance_id, issuer, client_id, client_secret, scopes, id_token_mapping, use_pkce) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"issuer" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-16 16:47:22 +01:00
true ,
2025-02-26 13:20:47 +01:00
true ,
2023-02-27 16:32:18 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOIDCIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . OIDCIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"clientId" : "id"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . OIDCIDPChangedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateMinimalStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_oidc SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"id" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOIDCIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . OIDCIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
2023-03-13 17:34:29 +01:00
"name" : "name" ,
2023-02-27 16:32:18 +01:00
"issuer" : "issuer" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
2023-03-16 16:47:22 +01:00
"idTokenMapping" : true ,
2025-02-26 13:20:47 +01:00
"usePKCE" : true ,
2023-02-27 16:32:18 +01:00
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-27 16:32:18 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . OIDCIDPChangedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
2023-03-13 17:34:29 +01:00
"name" ,
2023-02-27 16:32:18 +01:00
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-27 16:32:18 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "UPDATE projections.idp_templates6_oidc SET (client_id, client_secret, issuer, scopes, id_token_mapping, use_pkce) = ($1, $2, $3, $4, $5, $6) WHERE (idp_id = $7) AND (instance_id = $8)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"client_id" ,
anyArg { } ,
"issuer" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-16 16:47:22 +01:00
true ,
2025-02-26 13:20:47 +01:00
true ,
2023-02-27 16:32:18 +01:00
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
2023-06-08 00:50:53 +02:00
{
name : "instance reduceOIDCIDPMigratedAzureAD" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . OIDCIDPMigratedAzureADEventType ,
2023-06-08 00:50:53 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"tenant" : "tenant" ,
"isEmailVerified" : true ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-06-08 00:50:53 +02:00
} ` ) ,
) , instance . OIDCIDPMigratedAzureADEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPMigratedAzureAD ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-06-08 00:50:53 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, name, type, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking) = ($1, $2, $3, $4, $5, $6, $7, $8, $9) WHERE (id = $10) AND (instance_id = $11)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"name" ,
domain . IDPTypeAzureAD ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-06-08 00:50:53 +02:00
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6_oidc WHERE (idp_id = $1) AND (instance_id = $2)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-06-08 00:50:53 +02:00
"tenant" ,
true ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOIDCIDPMigratedAzureAD" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
org . OIDCIDPMigratedAzureADEventType ,
2023-06-08 00:50:53 +02:00
org . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "name" ,
"client_id" : "client_id" ,
"client_secret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"tenant" : "tenant" ,
"isEmailVerified" : true ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-06-08 00:50:53 +02:00
} ` ) ,
) , org . OIDCIDPMigratedAzureADEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPMigratedAzureAD ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-06-08 00:50:53 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, name, type, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking) = ($1, $2, $3, $4, $5, $6, $7, $8, $9) WHERE (id = $10) AND (instance_id = $11)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"name" ,
domain . IDPTypeAzureAD ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-06-08 00:50:53 +02:00
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6_oidc WHERE (idp_id = $1) AND (instance_id = $2)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-06-08 00:50:53 +02:00
"tenant" ,
true ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOIDCIDPMigratedGoogle" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
instance . OIDCIDPMigratedGoogleEventType ,
2023-06-08 00:50:53 +02:00
instance . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-06-08 00:50:53 +02:00
} ` ) ,
) , instance . OIDCIDPMigratedGoogleEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPMigratedGoogle ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-06-08 00:50:53 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, name, type, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking) = ($1, $2, $3, $4, $5, $6, $7, $8, $9) WHERE (id = $10) AND (instance_id = $11)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"name" ,
domain . IDPTypeGoogle ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-06-08 00:50:53 +02:00
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6_oidc WHERE (idp_id = $1) AND (instance_id = $2)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_google (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-06-08 00:50:53 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOIDCIDPMigratedGoogle" ,
args : args {
event : getEvent ( testEvent (
2023-10-19 12:19:10 +02:00
org . OIDCIDPMigratedGoogleEventType ,
2023-06-08 00:50:53 +02:00
org . AggregateType ,
[ ] byte ( ` {
"id" : "idp-id" ,
"name" : "name" ,
"clientId" : "client_id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"scopes" : [ "profile" ] ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-06-08 00:50:53 +02:00
} ` ) ,
) , org . OIDCIDPMigratedGoogleEventMapper ) ,
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOIDCIDPMigratedGoogle ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-06-08 00:50:53 +02:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, name, type, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking) = ($1, $2, $3, $4, $5, $6, $7, $8, $9) WHERE (id = $10) AND (instance_id = $11)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"name" ,
domain . IDPTypeGoogle ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-06-08 00:50:53 +02:00
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "DELETE FROM projections.idp_templates6_oidc WHERE (idp_id = $1) AND (instance_id = $2)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_google (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)" ,
2023-06-08 00:50:53 +02:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"client_id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-06-08 00:50:53 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
2023-02-27 16:32:18 +01:00
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-02-27 16:32:18 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-03-07 11:35:47 +01:00
func TestIDPTemplateProjection_reducesOldConfig ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceOldConfigAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . IDPConfigAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"name" : "custom-zitadel-instance" ,
"idpType" : 0 ,
"stylingType" : 0 ,
"autoRegister" : true
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . IDPConfigAddedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldConfigAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"idp-config-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeUnspecified ,
true ,
true ,
true ,
false ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUnspecified ,
2023-03-07 11:35:47 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOldConfigAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPConfigAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"name" : "custom-zitadel-instance" ,
"idpType" : 0 ,
"stylingType" : 0 ,
"autoRegister" : true
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPConfigAddedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldConfigAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"idp-config-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"custom-zitadel-instance" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeUnspecified ,
true ,
true ,
true ,
false ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUnspecified ,
2023-03-07 11:35:47 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOldConfigChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . IDPConfigChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"name" : "custom-zitadel-instance" ,
"stylingType" : 1 ,
"autoRegister" : true
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . IDPConfigChangedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldConfigChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (name, is_auto_creation, change_date, sequence) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOldConfigChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPConfigChangedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"name" : "custom-zitadel-instance" ,
"stylingType" : 1 ,
"autoRegister" : true
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPConfigChangedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldConfigChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (name, is_auto_creation, change_date, sequence) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"custom-zitadel-instance" ,
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOldOIDCConfigAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . IDPOIDCConfigAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"clientId" : "client-id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"issuer" : "issuer" ,
"scopes" : [ "profile" ] ,
"idpDisplayNameMapping" : 0 ,
"usernameMapping" : 1
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . IDPOIDCConfigAddedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldOIDCConfigAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
domain . IDPTypeOIDC ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "INSERT INTO projections.idp_templates6_oidc (idp_id, instance_id, issuer, client_id, client_secret, scopes, id_token_mapping, use_pkce) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"idp-config-id" ,
"instance-id" ,
"issuer" ,
"client-id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-16 16:47:22 +01:00
true ,
2025-02-26 13:20:47 +01:00
false ,
2023-03-07 11:35:47 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOldOIDCConfigAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPOIDCConfigAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"clientId" : "client-id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"issuer" : "issuer" ,
"scopes" : [ "profile" ] ,
"idpDisplayNameMapping" : 0 ,
"usernameMapping" : 1
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPOIDCConfigAddedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldOIDCConfigAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
domain . IDPTypeOIDC ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2025-02-26 13:20:47 +01:00
expectedStmt : "INSERT INTO projections.idp_templates6_oidc (idp_id, instance_id, issuer, client_id, client_secret, scopes, id_token_mapping, use_pkce) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"idp-config-id" ,
"instance-id" ,
"issuer" ,
"client-id" ,
anyArg { } ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-16 16:47:22 +01:00
true ,
2025-02-26 13:20:47 +01:00
false ,
2023-03-07 11:35:47 +01:00
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOldOIDCConfigChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . IDPOIDCConfigChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"clientId" : "client-id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"issuer" : "issuer" ,
"scopes" : [ "profile" ] ,
"idpDisplayNameMapping" : 0 ,
"usernameMapping" : 1
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . IDPOIDCConfigChangedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldOIDCConfigChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_oidc SET (client_id, client_secret, issuer, scopes) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"client-id" ,
anyArg { } ,
"issuer" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-07 11:35:47 +01:00
"idp-config-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOldOIDCConfigChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPOIDCConfigChangedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"clientId" : "client-id" ,
"clientSecret" : {
"cryptoType" : 0 ,
"algorithm" : "RSA-265" ,
"keyId" : "key-id"
} ,
"issuer" : "issuer" ,
"scopes" : [ "profile" ] ,
"idpDisplayNameMapping" : 0 ,
"usernameMapping" : 1
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPOIDCConfigChangedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldOIDCConfigChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_oidc SET (client_id, client_secret, issuer, scopes) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"client-id" ,
anyArg { } ,
"issuer" ,
2023-10-19 12:19:10 +02:00
database . TextArray [ string ] { "profile" } ,
2023-03-07 11:35:47 +01:00
"idp-config-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOldJWTConfigAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . IDPJWTConfigAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"jwtEndpoint" : "https://api.zitadel.ch/jwt" ,
"issuer" : "issuer" ,
"keysEndpoint" : "https://api.zitadel.ch/keys" ,
"headerName" : "hodor"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . IDPJWTConfigAddedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldJWTConfigAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
domain . IDPTypeJWT ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_jwt (idp_id, instance_id, issuer, jwt_endpoint, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"idp-config-id" ,
"instance-id" ,
"issuer" ,
"https://api.zitadel.ch/jwt" ,
"https://api.zitadel.ch/keys" ,
"hodor" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOldJWTConfigAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPJWTConfigAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"jwtEndpoint" : "https://api.zitadel.ch/jwt" ,
"issuer" : "issuer" ,
"keysEndpoint" : "https://api.zitadel.ch/keys" ,
"headerName" : "hodor"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPJWTConfigAddedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldJWTConfigAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
domain . IDPTypeJWT ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_jwt (idp_id, instance_id, issuer, jwt_endpoint, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"idp-config-id" ,
"instance-id" ,
"issuer" ,
"https://api.zitadel.ch/jwt" ,
"https://api.zitadel.ch/keys" ,
"hodor" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceOldJWTConfigChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . IDPJWTConfigChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"jwtEndpoint" : "https://api.zitadel.ch/jwt" ,
"issuer" : "issuer" ,
"keysEndpoint" : "https://api.zitadel.ch/keys" ,
"headerName" : "hodor"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . IDPJWTConfigChangedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldJWTConfigChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_jwt SET (jwt_endpoint, keys_endpoint, header_name, issuer) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"https://api.zitadel.ch/jwt" ,
"https://api.zitadel.ch/keys" ,
"hodor" ,
"issuer" ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceOldJWTConfigChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . IDPJWTConfigChangedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-03-07 11:35:47 +01:00
"idpConfigId" : "idp-config-id" ,
"jwtEndpoint" : "https://api.zitadel.ch/jwt" ,
"issuer" : "issuer" ,
"keysEndpoint" : "https://api.zitadel.ch/keys" ,
"headerName" : "hodor"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . IDPJWTConfigChangedEventMapper ) ,
2023-03-07 11:35:47 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceOldJWTConfigChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-03-07 11:35:47 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
anyArg { } ,
uint64 ( 15 ) ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_jwt SET (jwt_endpoint, keys_endpoint, header_name, issuer) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)" ,
2023-03-07 11:35:47 +01:00
expectedArgs : [ ] interface { } {
"https://api.zitadel.ch/jwt" ,
"https://api.zitadel.ch/keys" ,
"hodor" ,
"issuer" ,
"idp-config-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-03-07 11:35:47 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-02-27 16:32:18 +01:00
func TestIDPTemplateProjection_reducesJWT ( t * testing . T ) {
type args struct {
event func ( t * testing . T ) eventstore . Event
}
tests := [ ] struct {
name string
args args
reduce func ( event eventstore . Event ) ( * handler . Statement , error )
want wantReduce
} {
{
name : "instance reduceJWTIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . JWTIDPAddedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"issuer" : "issuer" ,
"jwtEndpoint" : "jwt" ,
"keysEndpoint" : "keys" ,
"headerName" : "header" ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-27 16:32:18 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . JWTIDPAddedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceJWTIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeSystem ,
domain . IDPTypeJWT ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-27 16:32:18 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_jwt (idp_id, instance_id, issuer, jwt_endpoint, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"issuer" ,
"jwt" ,
"keys" ,
"header" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "org reduceJWTIDPAdded" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
org . JWTIDPAddedEventType ,
org . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"issuer" : "issuer" ,
"jwtEndpoint" : "jwt" ,
"keysEndpoint" : "keys" ,
"headerName" : "header" ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-27 16:32:18 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , org . JWTIDPAddedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceJWTIDPAdded ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "org" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateInsertStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
anyArg { } ,
anyArg { } ,
uint64 ( 15 ) ,
"ro-id" ,
"instance-id" ,
domain . IDPStateActive ,
"" ,
domain . IdentityProviderTypeOrg ,
domain . IDPTypeJWT ,
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-27 16:32:18 +01:00
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "INSERT INTO projections.idp_templates6_jwt (idp_id, instance_id, issuer, jwt_endpoint, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"idp-id" ,
"instance-id" ,
"issuer" ,
"jwt" ,
"keys" ,
"header" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceJWTIDPChanged minimal" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . JWTIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"isCreationAllowed" : true ,
"jwtEndpoint" : "jwt"
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . JWTIDPChangedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceJWTIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2023-03-13 17:34:29 +01:00
expectedStmt : idpTemplateUpdateMinimalStmt ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
true ,
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_jwt SET jwt_endpoint = $1 WHERE (idp_id = $2) AND (instance_id = $3)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"jwt" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
{
name : "instance reduceJWTIDPChanged" ,
args : args {
2023-10-19 12:19:10 +02:00
event : getEvent (
testEvent (
instance . JWTIDPChangedEventType ,
instance . AggregateType ,
[ ] byte ( ` {
2023-02-27 16:32:18 +01:00
"id" : "idp-id" ,
"issuer" : "issuer" ,
"jwtEndpoint" : "jwt" ,
"keysEndpoint" : "keys" ,
"headerName" : "header" ,
"isCreationAllowed" : true ,
"isLinkingAllowed" : true ,
"isAutoCreation" : true ,
2024-04-10 17:46:30 +02:00
"isAutoUpdate" : true ,
"autoLinkingOption" : 1
2023-02-27 16:32:18 +01:00
} ` ) ,
2023-10-19 12:19:10 +02:00
) , instance . JWTIDPChangedEventMapper ) ,
2023-02-27 16:32:18 +01:00
} ,
reduce : ( & idpTemplateProjection { } ) . reduceJWTIDPChanged ,
want : wantReduce {
2023-10-19 12:19:10 +02:00
aggregateType : eventstore . AggregateType ( "instance" ) ,
sequence : 15 ,
2023-02-27 16:32:18 +01:00
executer : & testExecuter {
executions : [ ] execution {
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6 SET (is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, auto_linking, change_date, sequence) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (instance_id = $9)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
true ,
true ,
true ,
true ,
2024-04-10 17:46:30 +02:00
domain . AutoLinkingOptionUsername ,
2023-02-27 16:32:18 +01:00
anyArg { } ,
uint64 ( 15 ) ,
"idp-id" ,
"instance-id" ,
} ,
} ,
{
2024-04-10 17:46:30 +02:00
expectedStmt : "UPDATE projections.idp_templates6_jwt SET (jwt_endpoint, keys_endpoint, header_name, issuer) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)" ,
2023-02-27 16:32:18 +01:00
expectedArgs : [ ] interface { } {
"jwt" ,
"keys" ,
"header" ,
"issuer" ,
"idp-id" ,
"instance-id" ,
} ,
} ,
} ,
} ,
} ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
event := baseEvent ( t )
got , err := tt . reduce ( event )
2023-12-08 16:30:55 +02:00
if ! zerrors . IsErrorInvalidArgument ( err ) {
2023-02-27 16:32:18 +01:00
t . Errorf ( "no wrong event mapping: %v, got: %v" , err , got )
}
event = tt . args . event ( t )
got , err = tt . reduce ( event )
assertReduce ( t , got , err , IDPTemplateTable , tt . want )
} )
}
}
2023-09-29 11:26:14 +02:00
func stringToJSONByte ( data string ) string {
jsondata , _ := json . Marshal ( [ ] byte ( data ) )
return string ( jsondata )
}