feat: add azure provider templates (#5441)

Adds possibility to manage and use Microsoft Azure template based providers
This commit is contained in:
Livio Spring
2023-03-15 07:48:37 +01:00
committed by GitHub
parent 93e1fe0056
commit 5a307afe62
30 changed files with 2843 additions and 60 deletions

View File

@@ -37,6 +37,7 @@ type IDPTemplate struct {
*OAuthIDPTemplate
*OIDCIDPTemplate
*JWTIDPTemplate
*AzureADIDPTemplate
*GitHubIDPTemplate
*GitHubEnterpriseIDPTemplate
*GitLabIDPTemplate
@@ -77,6 +78,15 @@ type JWTIDPTemplate struct {
Endpoint string
}
type AzureADIDPTemplate struct {
IDPID string
ClientID string
ClientSecret *crypto.CryptoValue
Scopes database.StringArray
Tenant string
IsEmailVerified bool
}
type GitHubIDPTemplate struct {
IDPID string
ClientID string
@@ -301,6 +311,41 @@ var (
}
)
var (
azureadIdpTemplateTable = table{
name: projection.IDPTemplateAzureADTable,
instanceIDCol: projection.AzureADInstanceIDCol,
}
AzureADIDCol = Column{
name: projection.AzureADIDCol,
table: azureadIdpTemplateTable,
}
AzureADInstanceIDCol = Column{
name: projection.AzureADInstanceIDCol,
table: azureadIdpTemplateTable,
}
AzureADClientIDCol = Column{
name: projection.AzureADClientIDCol,
table: azureadIdpTemplateTable,
}
AzureADClientSecretCol = Column{
name: projection.AzureADClientSecretCol,
table: azureadIdpTemplateTable,
}
AzureADScopesCol = Column{
name: projection.AzureADScopesCol,
table: azureadIdpTemplateTable,
}
AzureADTenantCol = Column{
name: projection.AzureADTenantCol,
table: azureadIdpTemplateTable,
}
AzureADIsEmailVerified = Column{
name: projection.AzureADIsEmailVerified,
table: azureadIdpTemplateTable,
}
)
var (
githubIdpTemplateTable = table{
name: projection.IDPTemplateGitHubTable,
@@ -683,6 +728,13 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
JWTEndpointCol.identifier(),
JWTKeysEndpointCol.identifier(),
JWTHeaderNameCol.identifier(),
// azure
AzureADIDCol.identifier(),
AzureADClientIDCol.identifier(),
AzureADClientSecretCol.identifier(),
AzureADScopesCol.identifier(),
AzureADTenantCol.identifier(),
AzureADIsEmailVerified.identifier(),
// github
GitHubIDCol.identifier(),
GitHubClientIDCol.identifier(),
@@ -739,6 +791,7 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
LeftJoin(join(OAuthIDCol, IDPTemplateIDCol)).
LeftJoin(join(OIDCIDCol, IDPTemplateIDCol)).
LeftJoin(join(JWTIDCol, IDPTemplateIDCol)).
LeftJoin(join(AzureADIDCol, IDPTemplateIDCol)).
LeftJoin(join(GitHubIDCol, IDPTemplateIDCol)).
LeftJoin(join(GitHubEnterpriseIDCol, IDPTemplateIDCol)).
LeftJoin(join(GitLabIDCol, IDPTemplateIDCol)).
@@ -772,6 +825,13 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
jwtKeysEndpoint := sql.NullString{}
jwtHeaderName := sql.NullString{}
azureadID := sql.NullString{}
azureadClientID := sql.NullString{}
azureadClientSecret := new(crypto.CryptoValue)
azureadScopes := database.StringArray{}
azureadTenant := sql.NullString{}
azureadIsEmailVerified := sql.NullBool{}
githubID := sql.NullString{}
githubClientID := sql.NullString{}
githubClientSecret := new(crypto.CryptoValue)
@@ -859,6 +919,13 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
&jwtEndpoint,
&jwtKeysEndpoint,
&jwtHeaderName,
// azure
&azureadID,
&azureadClientID,
&azureadClientSecret,
&azureadScopes,
&azureadTenant,
&azureadIsEmailVerified,
// github
&githubID,
&githubClientID,
@@ -951,6 +1018,16 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
Endpoint: jwtEndpoint.String,
}
}
if azureadID.Valid {
idpTemplate.AzureADIDPTemplate = &AzureADIDPTemplate{
IDPID: azureadID.String,
ClientID: azureadClientID.String,
ClientSecret: azureadClientSecret,
Scopes: azureadScopes,
Tenant: azureadTenant.String,
IsEmailVerified: azureadIsEmailVerified.Bool,
}
}
if githubID.Valid {
idpTemplate.GitHubIDPTemplate = &GitHubIDPTemplate{
IDPID: githubID.String,
@@ -1064,6 +1141,13 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
JWTEndpointCol.identifier(),
JWTKeysEndpointCol.identifier(),
JWTHeaderNameCol.identifier(),
// azure
AzureADIDCol.identifier(),
AzureADClientIDCol.identifier(),
AzureADClientSecretCol.identifier(),
AzureADScopesCol.identifier(),
AzureADTenantCol.identifier(),
AzureADIsEmailVerified.identifier(),
// github
GitHubIDCol.identifier(),
GitHubClientIDCol.identifier(),
@@ -1121,6 +1205,7 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
LeftJoin(join(OAuthIDCol, IDPTemplateIDCol)).
LeftJoin(join(OIDCIDCol, IDPTemplateIDCol)).
LeftJoin(join(JWTIDCol, IDPTemplateIDCol)).
LeftJoin(join(AzureADIDCol, IDPTemplateIDCol)).
LeftJoin(join(GitHubIDCol, IDPTemplateIDCol)).
LeftJoin(join(GitHubEnterpriseIDCol, IDPTemplateIDCol)).
LeftJoin(join(GitLabIDCol, IDPTemplateIDCol)).
@@ -1157,6 +1242,13 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
jwtKeysEndpoint := sql.NullString{}
jwtHeaderName := sql.NullString{}
azureadID := sql.NullString{}
azureadClientID := sql.NullString{}
azureadClientSecret := new(crypto.CryptoValue)
azureadScopes := database.StringArray{}
azureadTenant := sql.NullString{}
azureadIsEmailVerified := sql.NullBool{}
githubID := sql.NullString{}
githubClientID := sql.NullString{}
githubClientSecret := new(crypto.CryptoValue)
@@ -1244,6 +1336,13 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
&jwtEndpoint,
&jwtKeysEndpoint,
&jwtHeaderName,
// azure
&azureadID,
&azureadClientID,
&azureadClientSecret,
&azureadScopes,
&azureadTenant,
&azureadIsEmailVerified,
// github
&githubID,
&githubClientID,
@@ -1335,6 +1434,16 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
Endpoint: jwtEndpoint.String,
}
}
if azureadID.Valid {
idpTemplate.AzureADIDPTemplate = &AzureADIDPTemplate{
IDPID: azureadID.String,
ClientID: azureadClientID.String,
ClientSecret: azureadClientSecret,
Scopes: azureadScopes,
Tenant: azureadTenant.String,
IsEmailVerified: azureadIsEmailVerified.Bool,
}
}
if githubID.Valid {
idpTemplate.GitHubIDPTemplate = &GitHubIDPTemplate{
IDPID: githubID.String,

View File

@@ -49,6 +49,13 @@ var (
` projections.idp_templates3_jwt.jwt_endpoint,` +
` projections.idp_templates3_jwt.keys_endpoint,` +
` projections.idp_templates3_jwt.header_name,` +
// azure
` projections.idp_templates3_azure.idp_id,` +
` projections.idp_templates3_azure.client_id,` +
` projections.idp_templates3_azure.client_secret,` +
` projections.idp_templates3_azure.scopes,` +
` projections.idp_templates3_azure.tenant,` +
` projections.idp_templates3_azure.is_email_verified,` +
// github
` projections.idp_templates3_github.idp_id,` +
` projections.idp_templates3_github.client_id,` +
@@ -105,6 +112,7 @@ var (
` LEFT JOIN projections.idp_templates3_oauth2 ON projections.idp_templates3.id = projections.idp_templates3_oauth2.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_oauth2.instance_id` +
` LEFT JOIN projections.idp_templates3_oidc ON projections.idp_templates3.id = projections.idp_templates3_oidc.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_oidc.instance_id` +
` LEFT JOIN projections.idp_templates3_jwt ON projections.idp_templates3.id = projections.idp_templates3_jwt.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_jwt.instance_id` +
` LEFT JOIN projections.idp_templates3_azure ON projections.idp_templates3.id = projections.idp_templates3_azure.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_azure.instance_id` +
` LEFT JOIN projections.idp_templates3_github ON projections.idp_templates3.id = projections.idp_templates3_github.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_github.instance_id` +
` LEFT JOIN projections.idp_templates3_github_enterprise ON projections.idp_templates3.id = projections.idp_templates3_github_enterprise.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_github_enterprise.instance_id` +
` LEFT JOIN projections.idp_templates3_gitlab ON projections.idp_templates3.id = projections.idp_templates3_gitlab.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_gitlab.instance_id` +
@@ -147,6 +155,13 @@ var (
"jwt_endpoint",
"keys_endpoint",
"header_name",
// azure
"idp_id",
"client_id",
"client_secret",
"scopes",
"tenant",
"is_email_verified",
// github config
"idp_id",
"client_id",
@@ -234,6 +249,13 @@ var (
` projections.idp_templates3_jwt.jwt_endpoint,` +
` projections.idp_templates3_jwt.keys_endpoint,` +
` projections.idp_templates3_jwt.header_name,` +
// azure
` projections.idp_templates3_azure.idp_id,` +
` projections.idp_templates3_azure.client_id,` +
` projections.idp_templates3_azure.client_secret,` +
` projections.idp_templates3_azure.scopes,` +
` projections.idp_templates3_azure.tenant,` +
` projections.idp_templates3_azure.is_email_verified,` +
// github
` projections.idp_templates3_github.idp_id,` +
` projections.idp_templates3_github.client_id,` +
@@ -291,6 +313,7 @@ var (
` LEFT JOIN projections.idp_templates3_oauth2 ON projections.idp_templates3.id = projections.idp_templates3_oauth2.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_oauth2.instance_id` +
` LEFT JOIN projections.idp_templates3_oidc ON projections.idp_templates3.id = projections.idp_templates3_oidc.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_oidc.instance_id` +
` LEFT JOIN projections.idp_templates3_jwt ON projections.idp_templates3.id = projections.idp_templates3_jwt.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_jwt.instance_id` +
` LEFT JOIN projections.idp_templates3_azure ON projections.idp_templates3.id = projections.idp_templates3_azure.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_azure.instance_id` +
` LEFT JOIN projections.idp_templates3_github ON projections.idp_templates3.id = projections.idp_templates3_github.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_github.instance_id` +
` LEFT JOIN projections.idp_templates3_github_enterprise ON projections.idp_templates3.id = projections.idp_templates3_github_enterprise.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_github_enterprise.instance_id` +
` LEFT JOIN projections.idp_templates3_gitlab ON projections.idp_templates3.id = projections.idp_templates3_gitlab.idp_id AND projections.idp_templates3.instance_id = projections.idp_templates3_gitlab.instance_id` +
@@ -333,6 +356,13 @@ var (
"jwt_endpoint",
"keys_endpoint",
"header_name",
// azure
"idp_id",
"client_id",
"client_secret",
"scopes",
"tenant",
"is_email_verified",
// github config
"idp_id",
"client_id",
@@ -460,6 +490,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -583,6 +620,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -703,6 +747,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
"jwt",
"keys",
"header",
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -823,6 +874,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
"idp-id",
"client_id",
@@ -942,6 +1000,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1061,6 +1126,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1181,6 +1253,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1300,6 +1379,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1438,6 +1524,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1587,6 +1680,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1734,6 +1834,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1856,6 +1963,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -1944,6 +2058,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -2032,6 +2153,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -2120,6 +2248,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
nil,
nil,
nil,
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,
@@ -2208,6 +2343,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
"jwt",
"keys",
"header",
// azure
nil,
nil,
nil,
nil,
nil,
nil,
// github
nil,
nil,

View File

@@ -21,6 +21,7 @@ const (
IDPTemplateOAuthTable = IDPTemplateTable + "_" + IDPTemplateOAuthSuffix
IDPTemplateOIDCTable = IDPTemplateTable + "_" + IDPTemplateOIDCSuffix
IDPTemplateJWTTable = IDPTemplateTable + "_" + IDPTemplateJWTSuffix
IDPTemplateAzureADTable = IDPTemplateTable + "_" + IDPTemplateAzureADSuffix
IDPTemplateGitHubTable = IDPTemplateTable + "_" + IDPTemplateGitHubSuffix
IDPTemplateGitHubEnterpriseTable = IDPTemplateTable + "_" + IDPTemplateGitHubEnterpriseSuffix
IDPTemplateGitLabTable = IDPTemplateTable + "_" + IDPTemplateGitLabSuffix
@@ -31,6 +32,7 @@ const (
IDPTemplateOAuthSuffix = "oauth2"
IDPTemplateOIDCSuffix = "oidc"
IDPTemplateJWTSuffix = "jwt"
IDPTemplateAzureADSuffix = "azure"
IDPTemplateGitHubSuffix = "github"
IDPTemplateGitHubEnterpriseSuffix = "github_enterprise"
IDPTemplateGitLabSuffix = "gitlab"
@@ -78,6 +80,14 @@ const (
JWTKeysEndpointCol = "keys_endpoint"
JWTHeaderNameCol = "header_name"
AzureADIDCol = "idp_id"
AzureADInstanceIDCol = "instance_id"
AzureADClientIDCol = "client_id"
AzureADClientSecretCol = "client_secret"
AzureADScopesCol = "scopes"
AzureADTenantCol = "tenant"
AzureADIsEmailVerified = "is_email_verified"
GitHubIDCol = "idp_id"
GitHubInstanceIDCol = "instance_id"
GitHubClientIDCol = "client_id"
@@ -206,6 +216,19 @@ func newIDPTemplateProjection(ctx context.Context, config crdb.StatementHandlerC
IDPTemplateJWTSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(AzureADIDCol, crdb.ColumnTypeText),
crdb.NewColumn(AzureADInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(AzureADClientIDCol, crdb.ColumnTypeText),
crdb.NewColumn(AzureADClientSecretCol, crdb.ColumnTypeJSONB),
crdb.NewColumn(AzureADScopesCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(AzureADTenantCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(AzureADIsEmailVerified, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(AzureADInstanceIDCol, AzureADIDCol),
IDPTemplateAzureADSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(GitHubIDCol, crdb.ColumnTypeText),
crdb.NewColumn(GitHubInstanceIDCol, crdb.ColumnTypeText),
@@ -352,6 +375,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
Event: instance.IDPJWTConfigChangedEventType,
Reduce: p.reduceOldJWTConfigChanged,
},
{
Event: instance.AzureADIDPAddedEventType,
Reduce: p.reduceAzureADIDPAdded,
},
{
Event: instance.AzureADIDPChangedEventType,
Reduce: p.reduceAzureADIDPChanged,
},
{
Event: instance.GitHubIDPAddedEventType,
Reduce: p.reduceGitHubIDPAdded,
@@ -429,7 +460,6 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
Event: org.OIDCIDPChangedEventType,
Reduce: p.reduceOIDCIDPChanged,
},
{
Event: org.JWTIDPAddedEventType,
Reduce: p.reduceJWTIDPAdded,
@@ -462,6 +492,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
Event: org.IDPJWTConfigChangedEventType,
Reduce: p.reduceOldJWTConfigChanged,
},
{
Event: org.AzureADIDPAddedEventType,
Reduce: p.reduceAzureADIDPAdded,
},
{
Event: org.AzureADIDPChangedEventType,
Reduce: p.reduceAzureADIDPChanged,
},
{
Event: org.GitHubIDPAddedEventType,
Reduce: p.reduceGitHubIDPAdded,
@@ -1049,6 +1087,96 @@ func (p *idpTemplateProjection) reduceOldJWTConfigChanged(event eventstore.Event
), nil
}
func (p *idpTemplateProjection) reduceAzureADIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var idpEvent idp.AzureADIDPAddedEvent
var idpOwnerType domain.IdentityProviderType
switch e := event.(type) {
case *org.AzureADIDPAddedEvent:
idpEvent = e.AzureADIDPAddedEvent
idpOwnerType = domain.IdentityProviderTypeOrg
case *instance.AzureADIDPAddedEvent:
idpEvent = e.AzureADIDPAddedEvent
idpOwnerType = domain.IdentityProviderTypeSystem
default:
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-x9a022b", "reduce.wrong.event.type %v", []eventstore.EventType{org.AzureADIDPAddedEventType, instance.AzureADIDPAddedEventType})
}
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.IDPTypeAzureAD),
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(AzureADIDCol, idpEvent.ID),
handler.NewCol(AzureADInstanceIDCol, idpEvent.Aggregate().InstanceID),
handler.NewCol(AzureADClientIDCol, idpEvent.ClientID),
handler.NewCol(AzureADClientSecretCol, idpEvent.ClientSecret),
handler.NewCol(AzureADScopesCol, database.StringArray(idpEvent.Scopes)),
handler.NewCol(AzureADTenantCol, idpEvent.Tenant),
handler.NewCol(AzureADIsEmailVerified, idpEvent.IsEmailVerified),
},
crdb.WithTableSuffix(IDPTemplateAzureADSuffix),
),
), nil
}
func (p *idpTemplateProjection) reduceAzureADIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var idpEvent idp.AzureADIDPChangedEvent
switch e := event.(type) {
case *org.AzureADIDPChangedEvent:
idpEvent = e.AzureADIDPChangedEvent
case *instance.AzureADIDPChangedEvent:
idpEvent = e.AzureADIDPChangedEvent
default:
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-p1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.AzureADIDPChangedEventType, instance.AzureADIDPChangedEventType})
}
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),
},
),
)
githubCols := reduceAzureADIDPChangedColumns(idpEvent)
if len(githubCols) > 0 {
ops = append(ops,
crdb.AddUpdateStatement(
githubCols,
[]handler.Condition{
handler.NewCond(AzureADIDCol, idpEvent.ID),
handler.NewCond(AzureADInstanceIDCol, idpEvent.Aggregate().InstanceID),
},
crdb.WithTableSuffix(IDPTemplateAzureADSuffix),
),
)
}
return crdb.NewMultiStatement(
&idpEvent,
ops...,
), nil
}
func (p *idpTemplateProjection) reduceGitHubIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var idpEvent idp.GitHubIDPAddedEvent
var idpOwnerType domain.IdentityProviderType
@@ -1723,6 +1851,26 @@ func reduceJWTIDPChangedColumns(idpEvent idp.JWTIDPChangedEvent) []handler.Colum
return jwtCols
}
func reduceAzureADIDPChangedColumns(idpEvent idp.AzureADIDPChangedEvent) []handler.Column {
azureADCols := make([]handler.Column, 0, 5)
if idpEvent.ClientID != nil {
azureADCols = append(azureADCols, handler.NewCol(AzureADClientIDCol, *idpEvent.ClientID))
}
if idpEvent.ClientSecret != nil {
azureADCols = append(azureADCols, handler.NewCol(AzureADClientSecretCol, *idpEvent.ClientSecret))
}
if idpEvent.Scopes != nil {
azureADCols = append(azureADCols, handler.NewCol(AzureADScopesCol, database.StringArray(idpEvent.Scopes)))
}
if idpEvent.Tenant != nil {
azureADCols = append(azureADCols, handler.NewCol(AzureADTenantCol, *idpEvent.Tenant))
}
if idpEvent.IsEmailVerified != nil {
azureADCols = append(azureADCols, handler.NewCol(AzureADIsEmailVerified, *idpEvent.IsEmailVerified))
}
return azureADCols
}
func reduceGitHubIDPChangedColumns(idpEvent idp.GitHubIDPChangedEvent) []handler.Column {
oauthCols := make([]handler.Column, 0, 3)
if idpEvent.ClientID != nil {

View File

@@ -410,6 +410,330 @@ func TestIDPTemplateProjection_reducesOAuth(t *testing.T) {
}
}
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{
event: getEvent(testEvent(
repository.EventType(instance.AzureADIDPAddedEventType),
instance.AggregateType,
[]byte(`{
"id": "idp-id",
"name": "name",
"client_id": "client_id",
"client_secret": {
"cryptoType": 0,
"algorithm": "RSA-265",
"keyId": "key-id"
}
}`),
), instance.AzureADIDPAddedEventMapper),
},
reduce: (&idpTemplateProjection{}).reduceAzureADIDPAdded,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
previousSequence: 10,
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,
},
},
{
expectedStmt: "INSERT INTO projections.idp_templates3_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)",
expectedArgs: []interface{}{
"idp-id",
"instance-id",
"client_id",
anyArg{},
database.StringArray(nil),
"",
false,
},
},
},
},
},
},
{
name: "instance reduceAzureADIDPAdded",
args: args{
event: getEvent(testEvent(
repository.EventType(instance.AzureADIDPAddedEventType),
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,
"isAutoUpdate": true
}`),
), instance.AzureADIDPAddedEventMapper),
},
reduce: (&idpTemplateProjection{}).reduceAzureADIDPAdded,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
previousSequence: 10,
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,
},
},
{
expectedStmt: "INSERT INTO projections.idp_templates3_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)",
expectedArgs: []interface{}{
"idp-id",
"instance-id",
"client_id",
anyArg{},
database.StringArray{"profile"},
"tenant",
true,
},
},
},
},
},
},
{
name: "org reduceAzureADIDPAdded",
args: args{
event: getEvent(testEvent(
repository.EventType(org.AzureADIDPAddedEventType),
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,
"isAutoUpdate": true
}`),
), org.AzureADIDPAddedEventMapper),
},
reduce: (&idpTemplateProjection{}).reduceAzureADIDPAdded,
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
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,
},
},
{
expectedStmt: "INSERT INTO projections.idp_templates3_azure (idp_id, instance_id, client_id, client_secret, scopes, tenant, is_email_verified) VALUES ($1, $2, $3, $4, $5, $6, $7)",
expectedArgs: []interface{}{
"idp-id",
"instance-id",
"client_id",
anyArg{},
database.StringArray{"profile"},
"tenant",
true,
},
},
},
},
},
},
{
name: "instance reduceAzureADIDPChanged minimal",
args: args{
event: getEvent(testEvent(
repository.EventType(instance.AzureADIDPChangedEventType),
instance.AggregateType,
[]byte(`{
"id": "idp-id",
"isCreationAllowed": true,
"client_id": "id"
}`),
), instance.AzureADIDPChangedEventMapper),
},
reduce: (&idpTemplateProjection{}).reduceAzureADIDPChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: idpTemplateUpdateMinimalStmt,
expectedArgs: []interface{}{
true,
anyArg{},
uint64(15),
"idp-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.idp_templates3_azure SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"id",
"idp-id",
"instance-id",
},
},
},
},
},
},
{
name: "instance reduceAzureADIDPChanged",
args: args{
event: getEvent(testEvent(
repository.EventType(instance.AzureADIDPChangedEventType),
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,
"isAutoUpdate": true
}`),
), instance.AzureADIDPChangedEventMapper),
},
reduce: (&idpTemplateProjection{}).reduceAzureADIDPChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("instance"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: idpTemplateUpdateStmt,
expectedArgs: []interface{}{
"name",
true,
true,
true,
true,
anyArg{},
uint64(15),
"idp-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.idp_templates3_azure SET (client_id, client_secret, scopes, tenant, is_email_verified) = ($1, $2, $3, $4, $5) WHERE (idp_id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
"client_id",
anyArg{},
database.StringArray{"profile"},
"tenant",
true,
"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_reducesGitHub(t *testing.T) {
type args struct {
event func(t *testing.T) eventstore.Event