mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 08:07:32 +00:00
feat(api): add generic oauth provider template (#5260)
adds functionality to manage templates based OIDC IDPs
This commit is contained in:
@@ -33,6 +33,7 @@ type IDPTemplate struct {
|
||||
IsLinkingAllowed bool
|
||||
IsAutoCreation bool
|
||||
IsAutoUpdate bool
|
||||
*OAuthIDPTemplate
|
||||
*GoogleIDPTemplate
|
||||
*LDAPIDPTemplate
|
||||
}
|
||||
@@ -42,6 +43,16 @@ type IDPTemplates struct {
|
||||
Templates []*IDPTemplate
|
||||
}
|
||||
|
||||
type OAuthIDPTemplate struct {
|
||||
IDPID string
|
||||
ClientID string
|
||||
ClientSecret *crypto.CryptoValue
|
||||
AuthorizationEndpoint string
|
||||
TokenEndpoint string
|
||||
UserEndpoint string
|
||||
Scopes database.StringArray
|
||||
}
|
||||
|
||||
type GoogleIDPTemplate struct {
|
||||
IDPID string
|
||||
ClientID string
|
||||
@@ -129,6 +140,45 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
oauthIdpTemplateTable = table{
|
||||
name: projection.IDPTemplateOAuthTable,
|
||||
instanceIDCol: projection.OAuthInstanceIDCol,
|
||||
}
|
||||
OAuthIDCol = Column{
|
||||
name: projection.OAuthIDCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthInstanceIDCol = Column{
|
||||
name: projection.OAuthInstanceIDCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthClientIDCol = Column{
|
||||
name: projection.OAuthClientIDCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthClientSecretCol = Column{
|
||||
name: projection.OAuthClientSecretCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthAuthorizationEndpointCol = Column{
|
||||
name: projection.OAuthAuthorizationEndpointCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthTokenEndpointCol = Column{
|
||||
name: projection.OAuthTokenEndpointCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthUserEndpointCol = Column{
|
||||
name: projection.OAuthUserEndpointCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
OAuthScopesCol = Column{
|
||||
name: projection.OAuthScopesCol,
|
||||
table: oauthIdpTemplateTable,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
googleIdpTemplateTable = table{
|
||||
name: projection.IDPTemplateGoogleTable,
|
||||
@@ -370,10 +420,20 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
||||
IDPTemplateIsLinkingAllowedCol.identifier(),
|
||||
IDPTemplateIsAutoCreationCol.identifier(),
|
||||
IDPTemplateIsAutoUpdateCol.identifier(),
|
||||
// oauth
|
||||
OAuthIDCol.identifier(),
|
||||
OAuthClientIDCol.identifier(),
|
||||
OAuthClientSecretCol.identifier(),
|
||||
OAuthAuthorizationEndpointCol.identifier(),
|
||||
OAuthTokenEndpointCol.identifier(),
|
||||
OAuthUserEndpointCol.identifier(),
|
||||
OAuthScopesCol.identifier(),
|
||||
// google
|
||||
GoogleIDCol.identifier(),
|
||||
GoogleClientIDCol.identifier(),
|
||||
GoogleClientSecretCol.identifier(),
|
||||
GoogleScopesCol.identifier(),
|
||||
// ldap
|
||||
LDAPIDCol.identifier(),
|
||||
LDAPHostCol.identifier(),
|
||||
LDAPPortCol.identifier(),
|
||||
@@ -397,6 +457,7 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
||||
LDAPAvatarURLAttributeCol.identifier(),
|
||||
LDAPProfileAttributeCol.identifier(),
|
||||
).From(idpTemplateTable.identifier()).
|
||||
LeftJoin(join(OAuthIDCol, IDPTemplateIDCol)).
|
||||
LeftJoin(join(GoogleIDCol, IDPTemplateIDCol)).
|
||||
LeftJoin(join(LDAPIDCol, IDPTemplateIDCol)).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
@@ -405,6 +466,14 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
||||
|
||||
name := sql.NullString{}
|
||||
|
||||
oauthID := sql.NullString{}
|
||||
oauthClientID := sql.NullString{}
|
||||
oauthClientSecret := new(crypto.CryptoValue)
|
||||
oauthAuthorizationEndpoint := sql.NullString{}
|
||||
oauthTokenEndpoint := sql.NullString{}
|
||||
oauthUserEndpoint := sql.NullString{}
|
||||
oauthScopes := database.StringArray{}
|
||||
|
||||
googleID := sql.NullString{}
|
||||
googleClientID := sql.NullString{}
|
||||
googleClientSecret := new(crypto.CryptoValue)
|
||||
@@ -447,10 +516,20 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
||||
&idpTemplate.IsLinkingAllowed,
|
||||
&idpTemplate.IsAutoCreation,
|
||||
&idpTemplate.IsAutoUpdate,
|
||||
// oauth
|
||||
&oauthID,
|
||||
&oauthClientID,
|
||||
&oauthClientSecret,
|
||||
&oauthAuthorizationEndpoint,
|
||||
&oauthTokenEndpoint,
|
||||
&oauthUserEndpoint,
|
||||
&oauthScopes,
|
||||
// google
|
||||
&googleID,
|
||||
&googleClientID,
|
||||
&googleClientSecret,
|
||||
&googleScopes,
|
||||
// ldap
|
||||
&ldapID,
|
||||
&ldapHost,
|
||||
&ldapPort,
|
||||
@@ -483,6 +562,17 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
||||
|
||||
idpTemplate.Name = name.String
|
||||
|
||||
if oauthID.Valid {
|
||||
idpTemplate.OAuthIDPTemplate = &OAuthIDPTemplate{
|
||||
IDPID: oauthID.String,
|
||||
ClientID: oauthClientID.String,
|
||||
ClientSecret: oauthClientSecret,
|
||||
AuthorizationEndpoint: oauthAuthorizationEndpoint.String,
|
||||
TokenEndpoint: oauthTokenEndpoint.String,
|
||||
UserEndpoint: oauthUserEndpoint.String,
|
||||
Scopes: oauthScopes,
|
||||
}
|
||||
}
|
||||
if googleID.Valid {
|
||||
idpTemplate.GoogleIDPTemplate = &GoogleIDPTemplate{
|
||||
IDPID: googleID.String,
|
||||
@@ -490,7 +580,8 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
||||
ClientSecret: googleClientSecret,
|
||||
Scopes: googleScopes,
|
||||
}
|
||||
} else if ldapID.Valid {
|
||||
}
|
||||
if ldapID.Valid {
|
||||
idpTemplate.LDAPIDPTemplate = &LDAPIDPTemplate{
|
||||
IDPID: ldapID.String,
|
||||
Host: ldapHost.String,
|
||||
@@ -538,10 +629,20 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
||||
IDPTemplateIsLinkingAllowedCol.identifier(),
|
||||
IDPTemplateIsAutoCreationCol.identifier(),
|
||||
IDPTemplateIsAutoUpdateCol.identifier(),
|
||||
// oauth
|
||||
OAuthIDCol.identifier(),
|
||||
OAuthClientIDCol.identifier(),
|
||||
OAuthClientSecretCol.identifier(),
|
||||
OAuthAuthorizationEndpointCol.identifier(),
|
||||
OAuthTokenEndpointCol.identifier(),
|
||||
OAuthUserEndpointCol.identifier(),
|
||||
OAuthScopesCol.identifier(),
|
||||
// google
|
||||
GoogleIDCol.identifier(),
|
||||
GoogleClientIDCol.identifier(),
|
||||
GoogleClientSecretCol.identifier(),
|
||||
GoogleScopesCol.identifier(),
|
||||
// ldap
|
||||
LDAPIDCol.identifier(),
|
||||
LDAPHostCol.identifier(),
|
||||
LDAPPortCol.identifier(),
|
||||
@@ -566,6 +667,7 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
||||
LDAPProfileAttributeCol.identifier(),
|
||||
countColumn.identifier(),
|
||||
).From(idpTemplateTable.identifier()).
|
||||
LeftJoin(join(OAuthIDCol, IDPTemplateIDCol)).
|
||||
LeftJoin(join(GoogleIDCol, IDPTemplateIDCol)).
|
||||
LeftJoin(join(LDAPIDCol, IDPTemplateIDCol)).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
@@ -577,6 +679,14 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
||||
|
||||
name := sql.NullString{}
|
||||
|
||||
oauthID := sql.NullString{}
|
||||
oauthClientID := sql.NullString{}
|
||||
oauthClientSecret := new(crypto.CryptoValue)
|
||||
oauthAuthorizationEndpoint := sql.NullString{}
|
||||
oauthTokenEndpoint := sql.NullString{}
|
||||
oauthUserEndpoint := sql.NullString{}
|
||||
oauthScopes := database.StringArray{}
|
||||
|
||||
googleID := sql.NullString{}
|
||||
googleClientID := sql.NullString{}
|
||||
googleClientSecret := new(crypto.CryptoValue)
|
||||
@@ -619,10 +729,20 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
||||
&idpTemplate.IsLinkingAllowed,
|
||||
&idpTemplate.IsAutoCreation,
|
||||
&idpTemplate.IsAutoUpdate,
|
||||
// oauth
|
||||
&oauthID,
|
||||
&oauthClientID,
|
||||
&oauthClientSecret,
|
||||
&oauthAuthorizationEndpoint,
|
||||
&oauthTokenEndpoint,
|
||||
&oauthUserEndpoint,
|
||||
&oauthScopes,
|
||||
// google
|
||||
&googleID,
|
||||
&googleClientID,
|
||||
&googleClientSecret,
|
||||
&googleScopes,
|
||||
// ldap
|
||||
&ldapID,
|
||||
&ldapHost,
|
||||
&ldapPort,
|
||||
@@ -654,6 +774,17 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
||||
|
||||
idpTemplate.Name = name.String
|
||||
|
||||
if oauthID.Valid {
|
||||
idpTemplate.OAuthIDPTemplate = &OAuthIDPTemplate{
|
||||
IDPID: oauthID.String,
|
||||
ClientID: oauthClientID.String,
|
||||
ClientSecret: oauthClientSecret,
|
||||
AuthorizationEndpoint: oauthAuthorizationEndpoint.String,
|
||||
TokenEndpoint: oauthTokenEndpoint.String,
|
||||
UserEndpoint: oauthUserEndpoint.String,
|
||||
Scopes: oauthScopes,
|
||||
}
|
||||
}
|
||||
if googleID.Valid {
|
||||
idpTemplate.GoogleIDPTemplate = &GoogleIDPTemplate{
|
||||
IDPID: googleID.String,
|
||||
@@ -661,7 +792,8 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
||||
ClientSecret: googleClientSecret,
|
||||
Scopes: googleScopes,
|
||||
}
|
||||
} else if ldapID.Valid {
|
||||
}
|
||||
if ldapID.Valid {
|
||||
idpTemplate.LDAPIDPTemplate = &LDAPIDPTemplate{
|
||||
IDPID: ldapID.String,
|
||||
Host: ldapHost.String,
|
||||
|
@@ -28,10 +28,20 @@ var (
|
||||
` projections.idp_templates.is_linking_allowed,` +
|
||||
` projections.idp_templates.is_auto_creation,` +
|
||||
` projections.idp_templates.is_auto_update,` +
|
||||
// oauth
|
||||
` projections.idp_templates_oauth.idp_id,` +
|
||||
` projections.idp_templates_oauth.client_id,` +
|
||||
` projections.idp_templates_oauth.client_secret,` +
|
||||
` projections.idp_templates_oauth.authorization_endpoint,` +
|
||||
` projections.idp_templates_oauth.token_endpoint,` +
|
||||
` projections.idp_templates_oauth.user_endpoint,` +
|
||||
` projections.idp_templates_oauth.scopes,` +
|
||||
// google
|
||||
` projections.idp_templates_google.idp_id,` +
|
||||
` projections.idp_templates_google.client_id,` +
|
||||
` projections.idp_templates_google.client_secret,` +
|
||||
` projections.idp_templates_google.scopes,` +
|
||||
// ldap
|
||||
` projections.idp_templates_ldap.idp_id,` +
|
||||
` projections.idp_templates_ldap.host,` +
|
||||
` projections.idp_templates_ldap.port,` +
|
||||
@@ -55,6 +65,7 @@ var (
|
||||
` projections.idp_templates_ldap.avatar_url_attribute,` +
|
||||
` projections.idp_templates_ldap.profile_attribute` +
|
||||
` FROM projections.idp_templates` +
|
||||
` LEFT JOIN projections.idp_templates_oauth ON projections.idp_templates.id = projections.idp_templates_oauth.idp_id AND projections.idp_templates.instance_id = projections.idp_templates_oauth.instance_id` +
|
||||
` LEFT JOIN projections.idp_templates_google ON projections.idp_templates.id = projections.idp_templates_google.idp_id AND projections.idp_templates.instance_id = projections.idp_templates_google.instance_id` +
|
||||
` LEFT JOIN projections.idp_templates_ldap ON projections.idp_templates.id = projections.idp_templates_ldap.idp_id AND projections.idp_templates.instance_id = projections.idp_templates_ldap.instance_id`
|
||||
idpTemplateCols = []string{
|
||||
@@ -71,6 +82,14 @@ var (
|
||||
"is_linking_allowed",
|
||||
"is_auto_creation",
|
||||
"is_auto_update",
|
||||
// oauth config
|
||||
"idp_id",
|
||||
"client_id",
|
||||
"client_secret",
|
||||
"authorization_endpoint",
|
||||
"token_endpoint",
|
||||
"user_endpoint",
|
||||
"scopes",
|
||||
// google config
|
||||
"idp_id",
|
||||
"client_id",
|
||||
@@ -113,10 +132,20 @@ var (
|
||||
` projections.idp_templates.is_linking_allowed,` +
|
||||
` projections.idp_templates.is_auto_creation,` +
|
||||
` projections.idp_templates.is_auto_update,` +
|
||||
// oauth
|
||||
` projections.idp_templates_oauth.idp_id,` +
|
||||
` projections.idp_templates_oauth.client_id,` +
|
||||
` projections.idp_templates_oauth.client_secret,` +
|
||||
` projections.idp_templates_oauth.authorization_endpoint,` +
|
||||
` projections.idp_templates_oauth.token_endpoint,` +
|
||||
` projections.idp_templates_oauth.user_endpoint,` +
|
||||
` projections.idp_templates_oauth.scopes,` +
|
||||
// google
|
||||
` projections.idp_templates_google.idp_id,` +
|
||||
` projections.idp_templates_google.client_id,` +
|
||||
` projections.idp_templates_google.client_secret,` +
|
||||
` projections.idp_templates_google.scopes,` +
|
||||
// ldap
|
||||
` projections.idp_templates_ldap.idp_id,` +
|
||||
` projections.idp_templates_ldap.host,` +
|
||||
` projections.idp_templates_ldap.port,` +
|
||||
@@ -141,6 +170,7 @@ var (
|
||||
` projections.idp_templates_ldap.profile_attribute,` +
|
||||
` COUNT(*) OVER ()` +
|
||||
` FROM projections.idp_templates` +
|
||||
` LEFT JOIN projections.idp_templates_oauth ON projections.idp_templates.id = projections.idp_templates_oauth.idp_id AND projections.idp_templates.instance_id = projections.idp_templates_oauth.instance_id` +
|
||||
` LEFT JOIN projections.idp_templates_google ON projections.idp_templates.id = projections.idp_templates_google.idp_id AND projections.idp_templates.instance_id = projections.idp_templates_google.instance_id` +
|
||||
` LEFT JOIN projections.idp_templates_ldap ON projections.idp_templates.id = projections.idp_templates_ldap.idp_id AND projections.idp_templates.instance_id = projections.idp_templates_ldap.instance_id`
|
||||
idpTemplatesCols = []string{
|
||||
@@ -157,6 +187,14 @@ var (
|
||||
"is_linking_allowed",
|
||||
"is_auto_creation",
|
||||
"is_auto_update",
|
||||
// oauth config
|
||||
"idp_id",
|
||||
"client_id",
|
||||
"client_secret",
|
||||
"authorization_endpoint",
|
||||
"token_endpoint",
|
||||
"user_endpoint",
|
||||
"scopes",
|
||||
// google config
|
||||
"idp_id",
|
||||
"client_id",
|
||||
@@ -218,7 +256,91 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
},
|
||||
object: (*IDPTemplate)(nil),
|
||||
},
|
||||
|
||||
{
|
||||
name: "prepareIDPTemplateByIDQuery oauth idp",
|
||||
prepare: prepareIDPTemplateByIDQuery,
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
regexp.QuoteMeta(idpTemplateQuery),
|
||||
idpTemplateCols,
|
||||
[]driver.Value{
|
||||
"idp-id",
|
||||
"ro",
|
||||
testNow,
|
||||
testNow,
|
||||
uint64(20211109),
|
||||
domain.IDPConfigStateActive,
|
||||
"idp-name",
|
||||
domain.IDPTypeOAuth,
|
||||
domain.IdentityProviderTypeOrg,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
"idp-id",
|
||||
"client_id",
|
||||
nil,
|
||||
"authorization",
|
||||
"token",
|
||||
"user",
|
||||
database.StringArray{"profile"},
|
||||
// google
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// ldap config
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
),
|
||||
},
|
||||
object: &IDPTemplate{
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211109,
|
||||
ResourceOwner: "ro",
|
||||
ID: "idp-id",
|
||||
State: domain.IDPStateActive,
|
||||
Name: "idp-name",
|
||||
Type: domain.IDPTypeOAuth,
|
||||
OwnerType: domain.IdentityProviderTypeOrg,
|
||||
IsCreationAllowed: true,
|
||||
IsLinkingAllowed: true,
|
||||
IsAutoCreation: true,
|
||||
IsAutoUpdate: true,
|
||||
OAuthIDPTemplate: &OAuthIDPTemplate{
|
||||
IDPID: "idp-id",
|
||||
ClientID: "client_id",
|
||||
ClientSecret: nil,
|
||||
AuthorizationEndpoint: "authorization",
|
||||
TokenEndpoint: "token",
|
||||
UserEndpoint: "user",
|
||||
Scopes: []string{"profile"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prepareIDPTemplateByIDQuery google idp",
|
||||
prepare: prepareIDPTemplateByIDQuery,
|
||||
@@ -240,6 +362,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google
|
||||
"idp-id",
|
||||
"client_id",
|
||||
@@ -314,6 +444,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google
|
||||
nil,
|
||||
nil,
|
||||
@@ -407,6 +545,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google config
|
||||
nil,
|
||||
nil,
|
||||
@@ -511,6 +657,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google config
|
||||
nil,
|
||||
nil,
|
||||
@@ -613,6 +767,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google config
|
||||
nil,
|
||||
nil,
|
||||
@@ -690,6 +852,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google config
|
||||
nil,
|
||||
nil,
|
||||
@@ -733,6 +903,14 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// google
|
||||
"idp-id-google",
|
||||
"client_id",
|
||||
@@ -762,12 +940,63 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"idp-id-oauth",
|
||||
"ro",
|
||||
testNow,
|
||||
testNow,
|
||||
uint64(20211109),
|
||||
domain.IDPConfigStateActive,
|
||||
"idp-name",
|
||||
domain.IDPTypeOAuth,
|
||||
domain.IdentityProviderTypeOrg,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
// oauth
|
||||
"idp-id-oauth",
|
||||
"client_id",
|
||||
nil,
|
||||
"authorization",
|
||||
"token",
|
||||
"user",
|
||||
database.StringArray{"profile"},
|
||||
// google
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
// ldap config
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
object: &IDPTemplates{
|
||||
SearchResponse: SearchResponse{
|
||||
Count: 2,
|
||||
Count: 3,
|
||||
},
|
||||
Templates: []*IDPTemplate{
|
||||
{
|
||||
@@ -831,6 +1060,31 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
||||
Scopes: []string{"profile"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211109,
|
||||
ResourceOwner: "ro",
|
||||
ID: "idp-id-oauth",
|
||||
State: domain.IDPStateActive,
|
||||
Name: "idp-name",
|
||||
Type: domain.IDPTypeOAuth,
|
||||
OwnerType: domain.IdentityProviderTypeOrg,
|
||||
IsCreationAllowed: true,
|
||||
IsLinkingAllowed: true,
|
||||
IsAutoCreation: true,
|
||||
IsAutoUpdate: true,
|
||||
OAuthIDPTemplate: &OAuthIDPTemplate{
|
||||
IDPID: "idp-id-oauth",
|
||||
ClientID: "client_id",
|
||||
ClientSecret: nil,
|
||||
AuthorizationEndpoint: "authorization",
|
||||
TokenEndpoint: "token",
|
||||
UserEndpoint: "user",
|
||||
Scopes: []string{"profile"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@@ -17,9 +17,11 @@ import (
|
||||
|
||||
const (
|
||||
IDPTemplateTable = "projections.idp_templates"
|
||||
IDPTemplateOAuthTable = IDPTemplateTable + "_" + IDPTemplateOAuthSuffix
|
||||
IDPTemplateGoogleTable = IDPTemplateTable + "_" + IDPTemplateGoogleSuffix
|
||||
IDPTemplateLDAPTable = IDPTemplateTable + "_" + IDPTemplateLDAPSuffix
|
||||
|
||||
IDPTemplateOAuthSuffix = "oauth"
|
||||
IDPTemplateGoogleSuffix = "google"
|
||||
IDPTemplateLDAPSuffix = "ldap"
|
||||
|
||||
@@ -39,6 +41,15 @@ const (
|
||||
IDPTemplateIsAutoCreationCol = "is_auto_creation"
|
||||
IDPTemplateIsAutoUpdateCol = "is_auto_update"
|
||||
|
||||
OAuthIDCol = "idp_id"
|
||||
OAuthInstanceIDCol = "instance_id"
|
||||
OAuthClientIDCol = "client_id"
|
||||
OAuthClientSecretCol = "client_secret"
|
||||
OAuthAuthorizationEndpointCol = "authorization_endpoint"
|
||||
OAuthTokenEndpointCol = "token_endpoint"
|
||||
OAuthUserEndpointCol = "user_endpoint"
|
||||
OAuthScopesCol = "scopes"
|
||||
|
||||
GoogleIDCol = "idp_id"
|
||||
GoogleInstanceIDCol = "instance_id"
|
||||
GoogleClientIDCol = "client_id"
|
||||
@@ -100,6 +111,20 @@ func newIDPTemplateProjection(ctx context.Context, config crdb.StatementHandlerC
|
||||
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{IDPTemplateResourceOwnerCol})),
|
||||
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{IDPTemplateOwnerRemovedCol})),
|
||||
),
|
||||
crdb.NewSuffixedTable([]*crdb.Column{
|
||||
crdb.NewColumn(OAuthIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(OAuthInstanceIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(OAuthClientIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(OAuthClientSecretCol, crdb.ColumnTypeJSONB),
|
||||
crdb.NewColumn(OAuthAuthorizationEndpointCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(OAuthTokenEndpointCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(OAuthUserEndpointCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(OAuthScopesCol, crdb.ColumnTypeTextArray, crdb.Nullable()),
|
||||
},
|
||||
crdb.NewPrimaryKey(OAuthInstanceIDCol, OAuthIDCol),
|
||||
IDPTemplateOAuthSuffix,
|
||||
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
|
||||
),
|
||||
crdb.NewSuffixedTable([]*crdb.Column{
|
||||
crdb.NewColumn(GoogleIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(GoogleInstanceIDCol, crdb.ColumnTypeText),
|
||||
@@ -150,6 +175,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
||||
{
|
||||
Aggregate: instance.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: instance.OAuthIDPAddedEventType,
|
||||
Reduce: p.reduceOAuthIDPAdded,
|
||||
},
|
||||
{
|
||||
Event: instance.OAuthIDPChangedEventType,
|
||||
Reduce: p.reduceOAuthIDPChanged,
|
||||
},
|
||||
{
|
||||
Event: instance.GoogleIDPAddedEventType,
|
||||
Reduce: p.reduceGoogleIDPAdded,
|
||||
@@ -179,6 +212,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
||||
{
|
||||
Aggregate: org.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: org.OAuthIDPAddedEventType,
|
||||
Reduce: p.reduceOAuthIDPAdded,
|
||||
},
|
||||
{
|
||||
Event: org.OAuthIDPChangedEventType,
|
||||
Reduce: p.reduceOAuthIDPChanged,
|
||||
},
|
||||
{
|
||||
Event: org.GoogleIDPAddedEventType,
|
||||
Reduce: p.reduceGoogleIDPAdded,
|
||||
@@ -208,6 +249,97 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *idpTemplateProjection) reduceOAuthIDPAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
var idpEvent idp.OAuthIDPAddedEvent
|
||||
var idpOwnerType domain.IdentityProviderType
|
||||
switch e := event.(type) {
|
||||
case *org.OAuthIDPAddedEvent:
|
||||
idpEvent = e.OAuthIDPAddedEvent
|
||||
idpOwnerType = domain.IdentityProviderTypeOrg
|
||||
case *instance.OAuthIDPAddedEvent:
|
||||
idpEvent = e.OAuthIDPAddedEvent
|
||||
idpOwnerType = domain.IdentityProviderTypeSystem
|
||||
default:
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ap9ihb", "reduce.wrong.event.type %v", []eventstore.EventType{org.OAuthIDPAddedEventType, instance.OAuthIDPAddedEventType})
|
||||
}
|
||||
|
||||
return crdb.NewMultiStatement(
|
||||
&idpEvent,
|
||||
crdb.AddCreateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPTemplateIDCol, idpEvent.ID),
|
||||
handler.NewCol(IDPTemplateCreationDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPTemplateChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPTemplateSequenceCol, idpEvent.Sequence()),
|
||||
handler.NewCol(IDPTemplateResourceOwnerCol, idpEvent.Aggregate().ResourceOwner),
|
||||
handler.NewCol(IDPTemplateInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||
handler.NewCol(IDPTemplateStateCol, domain.IDPStateActive),
|
||||
handler.NewCol(IDPTemplateNameCol, idpEvent.Name),
|
||||
handler.NewCol(IDPTemplateOwnerTypeCol, idpOwnerType),
|
||||
handler.NewCol(IDPTemplateTypeCol, domain.IDPTypeOAuth),
|
||||
handler.NewCol(IDPTemplateIsCreationAllowedCol, idpEvent.IsCreationAllowed),
|
||||
handler.NewCol(IDPTemplateIsLinkingAllowedCol, idpEvent.IsLinkingAllowed),
|
||||
handler.NewCol(IDPTemplateIsAutoCreationCol, idpEvent.IsAutoCreation),
|
||||
handler.NewCol(IDPTemplateIsAutoUpdateCol, idpEvent.IsAutoUpdate),
|
||||
},
|
||||
),
|
||||
crdb.AddCreateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(OAuthIDCol, idpEvent.ID),
|
||||
handler.NewCol(OAuthInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||
handler.NewCol(OAuthClientIDCol, idpEvent.ClientID),
|
||||
handler.NewCol(OAuthClientSecretCol, idpEvent.ClientSecret),
|
||||
handler.NewCol(OAuthAuthorizationEndpointCol, idpEvent.AuthorizationEndpoint),
|
||||
handler.NewCol(OAuthTokenEndpointCol, idpEvent.TokenEndpoint),
|
||||
handler.NewCol(OAuthUserEndpointCol, idpEvent.UserEndpoint),
|
||||
handler.NewCol(OAuthScopesCol, database.StringArray(idpEvent.Scopes)),
|
||||
},
|
||||
crdb.WithTableSuffix(IDPTemplateOAuthSuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *idpTemplateProjection) reduceOAuthIDPChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||
var idpEvent idp.OAuthIDPChangedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.OAuthIDPChangedEvent:
|
||||
idpEvent = e.OAuthIDPChangedEvent
|
||||
case *instance.OAuthIDPChangedEvent:
|
||||
idpEvent = e.OAuthIDPChangedEvent
|
||||
default:
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-p1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.OAuthIDPChangedEventType, instance.OAuthIDPChangedEventType})
|
||||
}
|
||||
|
||||
ops := make([]func(eventstore.Event) crdb.Exec, 0, 2)
|
||||
ops = append(ops,
|
||||
crdb.AddUpdateStatement(
|
||||
reduceIDPChangedTemplateColumns(idpEvent.Name, idpEvent.CreationDate(), idpEvent.Sequence(), idpEvent.OptionChanges),
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPTemplateIDCol, idpEvent.ID),
|
||||
handler.NewCond(IDPTemplateInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||
},
|
||||
),
|
||||
)
|
||||
oauthCols := reduceOAuthIDPChangedColumns(idpEvent)
|
||||
if len(oauthCols) > 0 {
|
||||
ops = append(ops,
|
||||
crdb.AddUpdateStatement(
|
||||
oauthCols,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(OAuthIDCol, idpEvent.ID),
|
||||
handler.NewCond(OAuthInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||
},
|
||||
crdb.WithTableSuffix(IDPTemplateOAuthSuffix),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return crdb.NewMultiStatement(
|
||||
&idpEvent,
|
||||
ops...,
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *idpTemplateProjection) reduceGoogleIDPAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
var idpEvent idp.GoogleIDPAddedEvent
|
||||
var idpOwnerType domain.IdentityProviderType
|
||||
@@ -466,6 +598,29 @@ func reduceIDPChangedTemplateColumns(name *string, creationDate time.Time, seque
|
||||
)
|
||||
}
|
||||
|
||||
func reduceOAuthIDPChangedColumns(idpEvent idp.OAuthIDPChangedEvent) []handler.Column {
|
||||
oauthCols := make([]handler.Column, 0, 6)
|
||||
if idpEvent.ClientID != nil {
|
||||
oauthCols = append(oauthCols, handler.NewCol(OAuthClientIDCol, *idpEvent.ClientID))
|
||||
}
|
||||
if idpEvent.ClientSecret != nil {
|
||||
oauthCols = append(oauthCols, handler.NewCol(OAuthClientSecretCol, *idpEvent.ClientSecret))
|
||||
}
|
||||
if idpEvent.AuthorizationEndpoint != nil {
|
||||
oauthCols = append(oauthCols, handler.NewCol(OAuthAuthorizationEndpointCol, *idpEvent.AuthorizationEndpoint))
|
||||
}
|
||||
if idpEvent.TokenEndpoint != nil {
|
||||
oauthCols = append(oauthCols, handler.NewCol(OAuthTokenEndpointCol, *idpEvent.TokenEndpoint))
|
||||
}
|
||||
if idpEvent.UserEndpoint != nil {
|
||||
oauthCols = append(oauthCols, handler.NewCol(OAuthUserEndpointCol, *idpEvent.UserEndpoint))
|
||||
}
|
||||
if idpEvent.Scopes != nil {
|
||||
oauthCols = append(oauthCols, handler.NewCol(OAuthScopesCol, database.StringArray(idpEvent.Scopes)))
|
||||
}
|
||||
return oauthCols
|
||||
}
|
||||
|
||||
func reduceGoogleIDPChangedColumns(idpEvent idp.GoogleIDPChangedEvent) []handler.Column {
|
||||
googleCols := make([]handler.Column, 0, 3)
|
||||
if idpEvent.ClientID != nil {
|
||||
|
@@ -125,6 +125,276 @@ func TestIDPTemplateProjection_reducesRemove(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(instance.OAuthIDPAddedEventType),
|
||||
instance.AggregateType,
|
||||
[]byte(`{
|
||||
"id": "idp-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"client_id": "client_id",
|
||||
"client_secret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"authorizationEndpoint": "auth",
|
||||
"tokenEndpoint": "token",
|
||||
"userEndpoint": "user",
|
||||
"scopes": ["profile"],
|
||||
"isCreationAllowed": true,
|
||||
"isLinkingAllowed": true,
|
||||
"isAutoCreation": true,
|
||||
"isAutoUpdate": true
|
||||
}`),
|
||||
), instance.OAuthIDPAddedEventMapper),
|
||||
},
|
||||
reduce: (&idpTemplateProjection{}).reduceOAuthIDPAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("instance"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.idp_templates (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) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
|
||||
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,
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.idp_templates_oauth (idp_id, instance_id, client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
"client_id",
|
||||
anyArg{},
|
||||
"auth",
|
||||
"token",
|
||||
"user",
|
||||
database.StringArray{"profile"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org reduceOAuthIDPAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.OAuthIDPAddedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"id": "idp-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"client_id": "client_id",
|
||||
"client_secret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"authorizationEndpoint": "auth",
|
||||
"tokenEndpoint": "token",
|
||||
"userEndpoint": "user",
|
||||
"scopes": ["profile"],
|
||||
"isCreationAllowed": true,
|
||||
"isLinkingAllowed": true,
|
||||
"isAutoCreation": true,
|
||||
"isAutoUpdate": true
|
||||
}`),
|
||||
), org.OAuthIDPAddedEventMapper),
|
||||
},
|
||||
reduce: (&idpTemplateProjection{}).reduceOAuthIDPAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.idp_templates (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) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
|
||||
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,
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.idp_templates_oauth (idp_id, instance_id, client_id, client_secret, authorization_endpoint, token_endpoint, user_endpoint, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
"client_id",
|
||||
anyArg{},
|
||||
"auth",
|
||||
"token",
|
||||
"user",
|
||||
database.StringArray{"profile"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "instance reduceOAuthIDPChanged minimal",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(instance.OAuthIDPChangedEventType),
|
||||
instance.AggregateType,
|
||||
[]byte(`{
|
||||
"id": "idp-id",
|
||||
"isCreationAllowed": true,
|
||||
"client_id": "id"
|
||||
}`),
|
||||
), instance.OAuthIDPChangedEventMapper),
|
||||
},
|
||||
reduce: (&idpTemplateProjection{}).reduceOAuthIDPChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("instance"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.idp_templates SET (is_creation_allowed, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
true,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.idp_templates_oauth SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
"id",
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "instance reduceOAuthIDPChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(instance.OAuthIDPChangedEventType),
|
||||
instance.AggregateType,
|
||||
[]byte(`{
|
||||
"id": "idp-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"client_id": "client_id",
|
||||
"client_secret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"authorizationEndpoint": "auth",
|
||||
"tokenEndpoint": "token",
|
||||
"userEndpoint": "user",
|
||||
"scopes": ["profile"],
|
||||
"isCreationAllowed": true,
|
||||
"isLinkingAllowed": true,
|
||||
"isAutoCreation": true,
|
||||
"isAutoUpdate": true
|
||||
}`),
|
||||
), instance.OAuthIDPChangedEventMapper),
|
||||
},
|
||||
reduce: (&idpTemplateProjection{}).reduceOAuthIDPChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("instance"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.idp_templates SET (name, is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, change_date, sequence) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (instance_id = $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"custom-zitadel-instance",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE projections.idp_templates_oauth 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)",
|
||||
expectedArgs: []interface{}{
|
||||
"client_id",
|
||||
anyArg{},
|
||||
"auth",
|
||||
"token",
|
||||
"user",
|
||||
database.StringArray{"profile"},
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
event := baseEvent(t)
|
||||
got, err := tt.reduce(event)
|
||||
if !errors.IsErrorInvalidArgument(err) {
|
||||
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_reducesGoogle(t *testing.T) {
|
||||
type args struct {
|
||||
event func(t *testing.T) eventstore.Event
|
||||
|
Reference in New Issue
Block a user