mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-12 09:05:12 +00:00
feat: implement AddZitadelProvider in ManagementService (#12056)
# Which Problems Are Solved This PR adds implementation to add a Zitadel IdP at the organization-level. # How the Problems Are Solved - Added handling/converters for the `AddZitadelProvider` endpoint in `ManagementService` in the server layer - Registered a new `org.idp.zitadel.added` event for org-level Zitadel providers - Added `AddOrgZitadelProvider` command to validate the request and push `org.idp.zitadel.added` event to the eventstore - Added the `org.idp.zitadel.added` event to the projection reducer - Added unit and integration tests # Additional Changes added more tests for the ZitadelProvider in AdminService # Additional Context - Closes https://github.com/zitadel/zitadel/issues/11823 - Follow-up for PRs https://github.com/zitadel/zitadel/pull/12018, https://github.com/zitadel/zitadel/pull/12020, https://github.com/zitadel/zitadel/pull/12055
This commit is contained in:
@@ -694,6 +694,10 @@ func (p *idpTemplateProjection) Reducers() []handler.AggregateReducer {
|
||||
Event: org.SAMLIDPChangedEventType,
|
||||
Reduce: p.reduceSAMLIDPChanged,
|
||||
},
|
||||
{
|
||||
Event: org.ZitadelIDPAddedEventType,
|
||||
Reduce: p.reduceZitadelIDPAdded,
|
||||
},
|
||||
{
|
||||
Event: org.IDPConfigRemovedEventType,
|
||||
Reduce: p.reduceIDPConfigRemoved,
|
||||
@@ -2574,9 +2578,11 @@ func (p *idpTemplateProjection) reduceZitadelIDPAdded(event eventstore.Event) (*
|
||||
case *instance.ZitadelIDPAddedEvent:
|
||||
idpEvent = e.ZitadelIDPAddedEvent
|
||||
idpOwnerType = domain.IdentityProviderTypeSystem
|
||||
// todo (@grvijayan): org-level ZitadelIDPAddedEvent in the next PRs
|
||||
case *org.ZitadelIDPAddedEvent:
|
||||
idpEvent = e.ZitadelIDPAddedEvent
|
||||
idpOwnerType = domain.IdentityProviderTypeOrg
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZCpH41", "reduce.wrong.event.type %v", []eventstore.EventType{instance.ZitadelIDPAddedEventType})
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZCpH41", "reduce.wrong.event.type %v", []eventstore.EventType{instance.ZitadelIDPAddedEventType, org.ZitadelIDPAddedEventType})
|
||||
}
|
||||
|
||||
zitadelIDPCols := []handler.Column{
|
||||
|
||||
@@ -4659,6 +4659,149 @@ func TestIDPTemplateProjection_reducesZitadel(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org reduceZitadelIDPAdded without instance roles info",
|
||||
args: args{
|
||||
event: getEvent(
|
||||
testEvent(
|
||||
org.ZitadelIDPAddedEventType,
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"id": "idp-id",
|
||||
"name": "idp-name",
|
||||
"issuer": "issuer",
|
||||
"clientId": "client_id",
|
||||
"clientSecret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"scopes": ["profile"],
|
||||
"isCreationAllowed": true,
|
||||
"isLinkingAllowed": true,
|
||||
"isAutoCreation": true,
|
||||
"isAutoUpdate": true,
|
||||
"autoLinkingOption": 1
|
||||
}`),
|
||||
), eventstore.GenericEventMapper[org.ZitadelIDPAddedEvent]),
|
||||
},
|
||||
reduce: (&idpTemplateProjection{}).reduceZitadelIDPAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: idpTemplateInsertStmt,
|
||||
expectedArgs: []interface{}{
|
||||
"idp-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"ro-id",
|
||||
"instance-id",
|
||||
domain.IDPStateActive,
|
||||
"idp-name",
|
||||
domain.IdentityProviderTypeOrg,
|
||||
domain.IDPTypeZitadel,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
domain.AutoLinkingOptionUsername,
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.idp_templates6_zitadel (idp_id, instance_id, issuer, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5, $6)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
"issuer",
|
||||
"client_id",
|
||||
anyArg{},
|
||||
database.TextArray[string]{"profile"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org reduceZitadelIDPAdded with instance roles info",
|
||||
args: args{
|
||||
event: getEvent(
|
||||
testEvent(
|
||||
org.ZitadelIDPAddedEventType,
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"id": "idp-id",
|
||||
"name": "idp-name",
|
||||
"issuer": "issuer",
|
||||
"clientId": "client_id",
|
||||
"clientSecret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"scopes": ["profile"],
|
||||
"isCreationAllowed": true,
|
||||
"isLinkingAllowed": true,
|
||||
"isAutoCreation": true,
|
||||
"isAutoUpdate": true,
|
||||
"autoLinkingOption": 1,
|
||||
"instanceRolesInfo": [{
|
||||
"organizationId": "org1",
|
||||
"organizationDomain": "org1.com"
|
||||
},
|
||||
{
|
||||
"organizationId": "org2",
|
||||
"organizationDomain": "org2.com"
|
||||
}]
|
||||
}`),
|
||||
), eventstore.GenericEventMapper[org.ZitadelIDPAddedEvent]),
|
||||
},
|
||||
reduce: (&idpTemplateProjection{}).reduceZitadelIDPAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: idpTemplateInsertStmt,
|
||||
expectedArgs: []interface{}{
|
||||
"idp-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"ro-id",
|
||||
"instance-id",
|
||||
domain.IDPStateActive,
|
||||
"idp-name",
|
||||
domain.IdentityProviderTypeOrg,
|
||||
domain.IDPTypeZitadel,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
domain.AutoLinkingOptionUsername,
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.idp_templates6_zitadel (idp_id, instance_id, issuer, client_id, client_secret, scopes, instance_roles_info) VALUES ($1, $2, $3, $4, $5, $6, $7)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-id",
|
||||
"instance-id",
|
||||
"issuer",
|
||||
"client_id",
|
||||
anyArg{},
|
||||
database.TextArray[string]{"profile"},
|
||||
[]byte(`[{"organizationId":"org1","organizationDomain":"org1.com"},{"organizationId":"org2","organizationDomain":"org2.com"}]`),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user