mirror of
https://github.com/zitadel/zitadel.git
synced 2025-03-01 01:37:24 +00:00
feat(api): add google provider template (#5247)
add functionality to manage templates based Google IDP
This commit is contained in:
parent
94116fa04b
commit
40e7356f3e
@ -593,12 +593,36 @@ Returns an identity provider of the instance
|
|||||||
GET: /idps/templates/{id}
|
GET: /idps/templates/{id}
|
||||||
|
|
||||||
|
|
||||||
|
### AddGoogleProvider
|
||||||
|
|
||||||
|
> **rpc** AddGoogleProvider([AddGoogleProviderRequest](#addgoogleproviderrequest))
|
||||||
|
[AddGoogleProviderResponse](#addgoogleproviderresponse)
|
||||||
|
|
||||||
|
Add a new Google identity provider on the instance
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
POST: /idps/google
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateGoogleProvider
|
||||||
|
|
||||||
|
> **rpc** UpdateGoogleProvider([UpdateGoogleProviderRequest](#updategoogleproviderrequest))
|
||||||
|
[UpdateGoogleProviderResponse](#updategoogleproviderresponse)
|
||||||
|
|
||||||
|
Change an existing Google identity provider on the instance
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PUT: /idps/google/{id}
|
||||||
|
|
||||||
|
|
||||||
### AddLDAPProvider
|
### AddLDAPProvider
|
||||||
|
|
||||||
> **rpc** AddLDAPProvider([AddLDAPProviderRequest](#addldapproviderrequest))
|
> **rpc** AddLDAPProvider([AddLDAPProviderRequest](#addldapproviderrequest))
|
||||||
[AddLDAPProviderResponse](#addldapproviderresponse)
|
[AddLDAPProviderResponse](#addldapproviderresponse)
|
||||||
|
|
||||||
Add a new ldap identity provider on the instance
|
Add a new LDAP identity provider on the instance
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -610,7 +634,7 @@ Add a new ldap identity provider on the instance
|
|||||||
> **rpc** UpdateLDAPProvider([UpdateLDAPProviderRequest](#updateldapproviderrequest))
|
> **rpc** UpdateLDAPProvider([UpdateLDAPProviderRequest](#updateldapproviderrequest))
|
||||||
[UpdateLDAPProviderResponse](#updateldapproviderresponse)
|
[UpdateLDAPProviderResponse](#updateldapproviderresponse)
|
||||||
|
|
||||||
Change an existing ldap identity provider on the instance
|
Change an existing LDAP identity provider on the instance
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1849,6 +1873,33 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### AddGoogleProviderRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| name | string | Google will be used as default, if no name is provided | string.max_len: 200<br /> |
|
||||||
|
| client_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| client_secret | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| scopes | repeated string | - | repeated.max_items: 20<br /> repeated.items.string.min_len: 1<br /> repeated.items.string.max_len: 100<br /> |
|
||||||
|
| provider_options | zitadel.idp.v1.Options | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### AddGoogleProviderResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
| id | string | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### AddIAMMemberRequest
|
### AddIAMMemberRequest
|
||||||
|
|
||||||
|
|
||||||
@ -4788,6 +4839,33 @@ this is en empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateGoogleProviderRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| name | string | - | string.max_len: 200<br /> |
|
||||||
|
| client_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| client_secret | string | client_secret will only be updated if provided | string.max_len: 200<br /> |
|
||||||
|
| scopes | repeated string | - | repeated.max_items: 20<br /> repeated.items.string.min_len: 1<br /> repeated.items.string.max_len: 100<br /> |
|
||||||
|
| provider_options | zitadel.idp.v1.Options | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateGoogleProviderResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateIAMMemberRequest
|
### UpdateIAMMemberRequest
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,18 @@ title: zitadel/idp.proto
|
|||||||
## Messages
|
## Messages
|
||||||
|
|
||||||
|
|
||||||
|
### GoogleConfig
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| client_id | string | - | |
|
||||||
|
| scopes | repeated string | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### IDP
|
### IDP
|
||||||
|
|
||||||
|
|
||||||
@ -201,6 +213,7 @@ title: zitadel/idp.proto
|
|||||||
| ----- | ---- | ----------- | ----------- |
|
| ----- | ---- | ----------- | ----------- |
|
||||||
| options | Options | - | |
|
| options | Options | - | |
|
||||||
| [**oneof**](https://developers.google.com/protocol-buffers/docs/proto3#oneof) config.ldap | LDAPConfig | - | |
|
| [**oneof**](https://developers.google.com/protocol-buffers/docs/proto3#oneof) config.ldap | LDAPConfig | - | |
|
||||||
|
| [**oneof**](https://developers.google.com/protocol-buffers/docs/proto3#oneof) config.google | GoogleConfig | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3050,12 +3050,36 @@ Returns an identity provider of the organisation
|
|||||||
GET: /idps/templates/{id}
|
GET: /idps/templates/{id}
|
||||||
|
|
||||||
|
|
||||||
|
### AddGoogleProvider
|
||||||
|
|
||||||
|
> **rpc** AddGoogleProvider([AddGoogleProviderRequest](#addgoogleproviderrequest))
|
||||||
|
[AddGoogleProviderResponse](#addgoogleproviderresponse)
|
||||||
|
|
||||||
|
Add a new Google identity provider in the organisation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
POST: /idps/google
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateGoogleProvider
|
||||||
|
|
||||||
|
> **rpc** UpdateGoogleProvider([UpdateGoogleProviderRequest](#updategoogleproviderrequest))
|
||||||
|
[UpdateGoogleProviderResponse](#updategoogleproviderresponse)
|
||||||
|
|
||||||
|
Change an existing Google identity provider in the organisation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PUT: /idps/google/{id}
|
||||||
|
|
||||||
|
|
||||||
### AddLDAPProvider
|
### AddLDAPProvider
|
||||||
|
|
||||||
> **rpc** AddLDAPProvider([AddLDAPProviderRequest](#addldapproviderrequest))
|
> **rpc** AddLDAPProvider([AddLDAPProviderRequest](#addldapproviderrequest))
|
||||||
[AddLDAPProviderResponse](#addldapproviderresponse)
|
[AddLDAPProviderResponse](#addldapproviderresponse)
|
||||||
|
|
||||||
Add a new ldap identity provider in the organisation
|
Add a new LDAP identity provider in the organisation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -3067,7 +3091,7 @@ Add a new ldap identity provider in the organisation
|
|||||||
> **rpc** UpdateLDAPProvider([UpdateLDAPProviderRequest](#updateldapproviderrequest))
|
> **rpc** UpdateLDAPProvider([UpdateLDAPProviderRequest](#updateldapproviderrequest))
|
||||||
[UpdateLDAPProviderResponse](#updateldapproviderresponse)
|
[UpdateLDAPProviderResponse](#updateldapproviderresponse)
|
||||||
|
|
||||||
Change an existing ldap identity provider in the organisation
|
Change an existing LDAP identity provider in the organisation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -3523,6 +3547,33 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### AddGoogleProviderRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| name | string | Google will be used as default, if no name is provided | string.max_len: 200<br /> |
|
||||||
|
| client_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| client_secret | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| scopes | repeated string | - | repeated.max_items: 20<br /> repeated.items.string.min_len: 1<br /> repeated.items.string.max_len: 100<br /> |
|
||||||
|
| provider_options | zitadel.idp.v1.Options | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### AddGoogleProviderResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
| id | string | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### AddHumanUserRequest
|
### AddHumanUserRequest
|
||||||
|
|
||||||
|
|
||||||
@ -8860,6 +8911,33 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateGoogleProviderRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| name | string | - | string.max_len: 200<br /> |
|
||||||
|
| client_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
| client_secret | string | client_secret will only be updated if provided | string.max_len: 200<br /> |
|
||||||
|
| scopes | repeated string | - | repeated.max_items: 20<br /> repeated.items.string.min_len: 1<br /> repeated.items.string.max_len: 100<br /> |
|
||||||
|
| provider_options | zitadel.idp.v1.Options | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateGoogleProviderResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateHumanEmailRequest
|
### UpdateHumanEmailRequest
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,6 +174,27 @@ func (s *Server) ListProviders(ctx context.Context, req *admin_pb.ListProvidersR
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) AddGoogleProvider(ctx context.Context, req *admin_pb.AddGoogleProviderRequest) (*admin_pb.AddGoogleProviderResponse, error) {
|
||||||
|
id, details, err := s.command.AddOrgGoogleProvider(ctx, authz.GetCtxData(ctx).OrgID, addGoogleProviderToCommand(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.AddGoogleProviderResponse{
|
||||||
|
Id: id,
|
||||||
|
Details: object_pb.DomainToAddDetailsPb(details),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdateGoogleProvider(ctx context.Context, req *admin_pb.UpdateGoogleProviderRequest) (*admin_pb.UpdateGoogleProviderResponse, error) {
|
||||||
|
details, err := s.command.UpdateOrgGoogleProvider(ctx, authz.GetCtxData(ctx).OrgID, req.Id, updateGoogleProviderToCommand(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.UpdateGoogleProviderResponse{
|
||||||
|
Details: object_pb.DomainToChangeDetailsPb(details),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) AddLDAPProvider(ctx context.Context, req *admin_pb.AddLDAPProviderRequest) (*admin_pb.AddLDAPProviderResponse, error) {
|
func (s *Server) AddLDAPProvider(ctx context.Context, req *admin_pb.AddLDAPProviderRequest) (*admin_pb.AddLDAPProviderResponse, error) {
|
||||||
id, details, err := s.command.AddInstanceLDAPProvider(ctx, addLDAPProviderToCommand(req))
|
id, details, err := s.command.AddInstanceLDAPProvider(ctx, addLDAPProviderToCommand(req))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -201,6 +201,26 @@ func providerQueryToQuery(idpQuery *admin_pb.ProviderQuery) (query.SearchQuery,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addGoogleProviderToCommand(req *admin_pb.AddGoogleProviderRequest) command.GoogleProvider {
|
||||||
|
return command.GoogleProvider{
|
||||||
|
Name: req.Name,
|
||||||
|
ClientID: req.ClientId,
|
||||||
|
ClientSecret: req.ClientSecret,
|
||||||
|
Scopes: req.Scopes,
|
||||||
|
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateGoogleProviderToCommand(req *admin_pb.UpdateGoogleProviderRequest) command.GoogleProvider {
|
||||||
|
return command.GoogleProvider{
|
||||||
|
Name: req.Name,
|
||||||
|
ClientID: req.ClientId,
|
||||||
|
ClientSecret: req.ClientSecret,
|
||||||
|
Scopes: req.Scopes,
|
||||||
|
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func addLDAPProviderToCommand(req *admin_pb.AddLDAPProviderRequest) command.LDAPProvider {
|
func addLDAPProviderToCommand(req *admin_pb.AddLDAPProviderRequest) command.LDAPProvider {
|
||||||
return command.LDAPProvider{
|
return command.LDAPProvider{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
|
@ -402,6 +402,14 @@ func configToPb(config *query.IDPTemplate) *idp_pb.ProviderConfig {
|
|||||||
IsAutoUpdate: config.IsAutoUpdate,
|
IsAutoUpdate: config.IsAutoUpdate,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if config.GoogleIDPTemplate != nil {
|
||||||
|
providerConfig.Config = &idp_pb.ProviderConfig_Google{
|
||||||
|
Google: &idp_pb.GoogleConfig{
|
||||||
|
ClientId: config.GoogleIDPTemplate.ClientID,
|
||||||
|
Scopes: config.GoogleIDPTemplate.Scopes,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
if config.LDAPIDPTemplate != nil {
|
if config.LDAPIDPTemplate != nil {
|
||||||
providerConfig.Config = &idp_pb.ProviderConfig_Ldap{
|
providerConfig.Config = &idp_pb.ProviderConfig_Ldap{
|
||||||
Ldap: &idp_pb.LDAPConfig{
|
Ldap: &idp_pb.LDAPConfig{
|
||||||
|
@ -166,6 +166,27 @@ func (s *Server) ListProviders(ctx context.Context, req *mgmt_pb.ListProvidersRe
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) AddGoogleProvider(ctx context.Context, req *mgmt_pb.AddGoogleProviderRequest) (*mgmt_pb.AddGoogleProviderResponse, error) {
|
||||||
|
id, details, err := s.command.AddOrgGoogleProvider(ctx, authz.GetCtxData(ctx).OrgID, addGoogleProviderToCommand(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.AddGoogleProviderResponse{
|
||||||
|
Id: id,
|
||||||
|
Details: object_pb.DomainToAddDetailsPb(details),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdateGoogleProvider(ctx context.Context, req *mgmt_pb.UpdateGoogleProviderRequest) (*mgmt_pb.UpdateGoogleProviderResponse, error) {
|
||||||
|
details, err := s.command.UpdateOrgGoogleProvider(ctx, authz.GetCtxData(ctx).OrgID, req.Id, updateGoogleProviderToCommand(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.UpdateGoogleProviderResponse{
|
||||||
|
Details: object_pb.DomainToChangeDetailsPb(details),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) AddLDAPProvider(ctx context.Context, req *mgmt_pb.AddLDAPProviderRequest) (*mgmt_pb.AddLDAPProviderResponse, error) {
|
func (s *Server) AddLDAPProvider(ctx context.Context, req *mgmt_pb.AddLDAPProviderRequest) (*mgmt_pb.AddLDAPProviderResponse, error) {
|
||||||
id, details, err := s.command.AddOrgLDAPProvider(ctx, authz.GetCtxData(ctx).OrgID, addLDAPProviderToCommand(req))
|
id, details, err := s.command.AddOrgLDAPProvider(ctx, authz.GetCtxData(ctx).OrgID, addLDAPProviderToCommand(req))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -218,6 +218,26 @@ func providerQueryToQuery(idpQuery *mgmt_pb.ProviderQuery) (query.SearchQuery, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addGoogleProviderToCommand(req *mgmt_pb.AddGoogleProviderRequest) command.GoogleProvider {
|
||||||
|
return command.GoogleProvider{
|
||||||
|
Name: req.Name,
|
||||||
|
ClientID: req.ClientId,
|
||||||
|
ClientSecret: req.ClientSecret,
|
||||||
|
Scopes: req.Scopes,
|
||||||
|
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateGoogleProviderToCommand(req *mgmt_pb.UpdateGoogleProviderRequest) command.GoogleProvider {
|
||||||
|
return command.GoogleProvider{
|
||||||
|
Name: req.Name,
|
||||||
|
ClientID: req.ClientId,
|
||||||
|
ClientSecret: req.ClientSecret,
|
||||||
|
Scopes: req.Scopes,
|
||||||
|
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func addLDAPProviderToCommand(req *mgmt_pb.AddLDAPProviderRequest) command.LDAPProvider {
|
func addLDAPProviderToCommand(req *mgmt_pb.AddLDAPProviderRequest) command.LDAPProvider {
|
||||||
return command.LDAPProvider{
|
return command.LDAPProvider{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
|
@ -2,6 +2,14 @@ package command
|
|||||||
|
|
||||||
import "github.com/zitadel/zitadel/internal/repository/idp"
|
import "github.com/zitadel/zitadel/internal/repository/idp"
|
||||||
|
|
||||||
|
type GoogleProvider struct {
|
||||||
|
Name string
|
||||||
|
ClientID string
|
||||||
|
ClientSecret string
|
||||||
|
Scopes []string
|
||||||
|
IDPOptions idp.Options
|
||||||
|
}
|
||||||
|
|
||||||
type LDAPProvider struct {
|
type LDAPProvider struct {
|
||||||
Name string
|
Name string
|
||||||
Host string
|
Host string
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
@ -8,6 +10,93 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/idpconfig"
|
"github.com/zitadel/zitadel/internal/repository/idpconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GoogleIDPWriteModel struct {
|
||||||
|
eventstore.WriteModel
|
||||||
|
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
ClientID string
|
||||||
|
ClientSecret *crypto.CryptoValue
|
||||||
|
Scopes []string
|
||||||
|
idp.Options
|
||||||
|
|
||||||
|
State domain.IDPState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *GoogleIDPWriteModel) Reduce() error {
|
||||||
|
for _, event := range wm.Events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *idp.GoogleIDPAddedEvent:
|
||||||
|
wm.reduceAddedEvent(e)
|
||||||
|
case *idp.GoogleIDPChangedEvent:
|
||||||
|
wm.reduceChangedEvent(e)
|
||||||
|
case *idp.RemovedEvent:
|
||||||
|
wm.State = domain.IDPStateRemoved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wm.WriteModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *GoogleIDPWriteModel) reduceAddedEvent(e *idp.GoogleIDPAddedEvent) {
|
||||||
|
wm.Name = e.Name
|
||||||
|
wm.ClientID = e.ClientID
|
||||||
|
wm.ClientSecret = e.ClientSecret
|
||||||
|
wm.Scopes = e.Scopes
|
||||||
|
wm.Options = e.Options
|
||||||
|
wm.State = domain.IDPStateActive
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *GoogleIDPWriteModel) reduceChangedEvent(e *idp.GoogleIDPChangedEvent) {
|
||||||
|
if e.Name != nil {
|
||||||
|
wm.Name = *e.Name
|
||||||
|
}
|
||||||
|
if e.ClientID != nil {
|
||||||
|
wm.ClientID = *e.ClientID
|
||||||
|
}
|
||||||
|
if e.ClientSecret != nil {
|
||||||
|
wm.ClientSecret = e.ClientSecret
|
||||||
|
}
|
||||||
|
if e.Scopes != nil {
|
||||||
|
wm.Scopes = e.Scopes
|
||||||
|
}
|
||||||
|
wm.Options.ReduceChanges(e.OptionChanges)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *GoogleIDPWriteModel) NewChanges(
|
||||||
|
name string,
|
||||||
|
clientID string,
|
||||||
|
clientSecretString string,
|
||||||
|
secretCrypto crypto.Crypto,
|
||||||
|
scopes []string,
|
||||||
|
options idp.Options,
|
||||||
|
) ([]idp.GoogleIDPChanges, error) {
|
||||||
|
changes := make([]idp.GoogleIDPChanges, 0)
|
||||||
|
var clientSecret *crypto.CryptoValue
|
||||||
|
var err error
|
||||||
|
if clientSecretString != "" {
|
||||||
|
clientSecret, err = crypto.Crypt([]byte(clientSecretString), secretCrypto)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
changes = append(changes, idp.ChangeGoogleClientSecret(clientSecret))
|
||||||
|
}
|
||||||
|
if wm.Name != name {
|
||||||
|
changes = append(changes, idp.ChangeGoogleName(name))
|
||||||
|
}
|
||||||
|
if wm.ClientID != clientID {
|
||||||
|
changes = append(changes, idp.ChangeGoogleClientID(clientID))
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(wm.Scopes, scopes) {
|
||||||
|
changes = append(changes, idp.ChangeGoogleScopes(scopes))
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := wm.Options.Changes(options)
|
||||||
|
if !opts.IsZero() {
|
||||||
|
changes = append(changes, idp.ChangeGoogleOptions(opts))
|
||||||
|
}
|
||||||
|
return changes, nil
|
||||||
|
}
|
||||||
|
|
||||||
type LDAPIDPWriteModel struct {
|
type LDAPIDPWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
@ -34,7 +123,7 @@ func (wm *LDAPIDPWriteModel) Reduce() error {
|
|||||||
if wm.ID != e.ID {
|
if wm.ID != e.ID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wm.reduceAddeddEvent(e)
|
wm.reduceAddedEvent(e)
|
||||||
case *idp.LDAPIDPChangedEvent:
|
case *idp.LDAPIDPChangedEvent:
|
||||||
if wm.ID != e.ID {
|
if wm.ID != e.ID {
|
||||||
continue
|
continue
|
||||||
@ -50,7 +139,7 @@ func (wm *LDAPIDPWriteModel) Reduce() error {
|
|||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *LDAPIDPWriteModel) reduceAddeddEvent(e *idp.LDAPIDPAddedEvent) {
|
func (wm *LDAPIDPWriteModel) reduceAddedEvent(e *idp.LDAPIDPAddedEvent) {
|
||||||
wm.Name = e.Name
|
wm.Name = e.Name
|
||||||
wm.Host = e.Host
|
wm.Host = e.Host
|
||||||
wm.Port = e.Port
|
wm.Port = e.Port
|
||||||
@ -170,6 +259,10 @@ type IDPRemoveWriteModel struct {
|
|||||||
func (wm *IDPRemoveWriteModel) Reduce() error {
|
func (wm *IDPRemoveWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
|
case *idp.GoogleIDPAddedEvent:
|
||||||
|
wm.reduceAdded(e.ID, e.Name)
|
||||||
|
case *idp.GoogleIDPChangedEvent:
|
||||||
|
wm.reduceChanged(e.ID, e.Name)
|
||||||
case *idp.LDAPIDPAddedEvent:
|
case *idp.LDAPIDPAddedEvent:
|
||||||
wm.reduceAdded(e.ID, e.Name)
|
wm.reduceAdded(e.ID, e.Name)
|
||||||
case *idp.LDAPIDPChangedEvent:
|
case *idp.LDAPIDPChangedEvent:
|
||||||
|
@ -13,6 +13,40 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (c *Commands) AddInstanceGoogleProvider(ctx context.Context, provider GoogleProvider) (string, *domain.ObjectDetails, error) {
|
||||||
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
|
id, err := c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, c.prepareAddInstanceGoogleProvider(instanceAgg, id, provider))
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
pushedEvents, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return id, pushedEventsToObjectDetails(pushedEvents), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) UpdateInstanceGoogleProvider(ctx context.Context, id string, provider GoogleProvider) (*domain.ObjectDetails, error) {
|
||||||
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, c.prepareUpdateInstanceGoogleProvider(instanceAgg, id, provider))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(cmds) == 0 {
|
||||||
|
// no change, so return directly
|
||||||
|
return &domain.ObjectDetails{}, nil
|
||||||
|
}
|
||||||
|
pushedEvents, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pushedEventsToObjectDetails(pushedEvents), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) AddInstanceLDAPProvider(ctx context.Context, provider LDAPProvider) (string, *domain.ObjectDetails, error) {
|
func (c *Commands) AddInstanceLDAPProvider(ctx context.Context, provider LDAPProvider) (string, *domain.ObjectDetails, error) {
|
||||||
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
id, err := c.idGenerator.Next()
|
id, err := c.idGenerator.Next()
|
||||||
@ -60,6 +94,87 @@ func (c *Commands) DeleteInstanceProvider(ctx context.Context, id string) (*doma
|
|||||||
return pushedEventsToObjectDetails(pushedEvents), nil
|
return pushedEventsToObjectDetails(pushedEvents), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) prepareAddInstanceGoogleProvider(a *instance.Aggregate, id string, provider GoogleProvider) preparation.Validation {
|
||||||
|
return func() (preparation.CreateCommands, error) {
|
||||||
|
if provider.ClientID = strings.TrimSpace(provider.ClientID); provider.ClientID == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "INST-D3fvs", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
if provider.ClientSecret = strings.TrimSpace(provider.ClientSecret); provider.ClientSecret == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "INST-W2vqs", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
writeModel := NewGoogleInstanceIDPWriteModel(a.InstanceID, id)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
if err = writeModel.Reduce(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
secret, err := crypto.Encrypt([]byte(provider.ClientSecret), c.idpConfigEncryption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
instance.NewGoogleIDPAddedEvent(
|
||||||
|
ctx,
|
||||||
|
&a.Aggregate,
|
||||||
|
id,
|
||||||
|
provider.Name,
|
||||||
|
provider.ClientID,
|
||||||
|
secret,
|
||||||
|
provider.Scopes,
|
||||||
|
provider.IDPOptions,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) prepareUpdateInstanceGoogleProvider(a *instance.Aggregate, id string, provider GoogleProvider) preparation.Validation {
|
||||||
|
return func() (preparation.CreateCommands, error) {
|
||||||
|
if id = strings.TrimSpace(id); id == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "INST-S32t1", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
if provider.ClientID = strings.TrimSpace(provider.ClientID); provider.ClientID == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "INST-ds432", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
writeModel := NewGoogleInstanceIDPWriteModel(a.InstanceID, id)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
if err = writeModel.Reduce(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !writeModel.State.Exists() {
|
||||||
|
return nil, caos_errs.ThrowNotFound(nil, "INST-D3r1s", "Errors.Instance.IDPConfig.NotExisting")
|
||||||
|
}
|
||||||
|
event, err := writeModel.NewChangedEvent(
|
||||||
|
ctx,
|
||||||
|
&a.Aggregate,
|
||||||
|
id,
|
||||||
|
provider.Name,
|
||||||
|
provider.ClientID,
|
||||||
|
provider.ClientSecret,
|
||||||
|
c.idpConfigEncryption,
|
||||||
|
provider.Scopes,
|
||||||
|
provider.IDPOptions,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if event == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return []eventstore.Command{event}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) prepareAddInstanceLDAPProvider(a *instance.Aggregate, id string, provider LDAPProvider) preparation.Validation {
|
func (c *Commands) prepareAddInstanceLDAPProvider(a *instance.Aggregate, id string, provider LDAPProvider) preparation.Validation {
|
||||||
return func() (preparation.CreateCommands, error) {
|
return func() (preparation.CreateCommands, error) {
|
||||||
if provider.Name = strings.TrimSpace(provider.Name); provider.Name == "" {
|
if provider.Name = strings.TrimSpace(provider.Name); provider.Name == "" {
|
||||||
|
@ -9,6 +9,80 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InstanceGoogleIDPWriteModel struct {
|
||||||
|
GoogleIDPWriteModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleInstanceIDPWriteModel(instanceID, id string) *InstanceGoogleIDPWriteModel {
|
||||||
|
return &InstanceGoogleIDPWriteModel{
|
||||||
|
GoogleIDPWriteModel{
|
||||||
|
WriteModel: eventstore.WriteModel{
|
||||||
|
AggregateID: instanceID,
|
||||||
|
ResourceOwner: instanceID,
|
||||||
|
},
|
||||||
|
ID: id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *InstanceGoogleIDPWriteModel) Reduce() error {
|
||||||
|
return wm.GoogleIDPWriteModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *InstanceGoogleIDPWriteModel) AppendEvents(events ...eventstore.Event) {
|
||||||
|
for _, event := range events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *instance.GoogleIDPAddedEvent:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(&e.GoogleIDPAddedEvent)
|
||||||
|
case *instance.GoogleIDPChangedEvent:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(&e.GoogleIDPChangedEvent)
|
||||||
|
case *instance.IDPRemovedEvent:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(&e.RemovedEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *InstanceGoogleIDPWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
ResourceOwner(wm.ResourceOwner).
|
||||||
|
AddQuery().
|
||||||
|
AggregateTypes(instance.AggregateType).
|
||||||
|
AggregateIDs(wm.AggregateID).
|
||||||
|
EventTypes(
|
||||||
|
instance.GoogleIDPAddedEventType,
|
||||||
|
instance.GoogleIDPChangedEventType,
|
||||||
|
instance.IDPRemovedEventType,
|
||||||
|
).
|
||||||
|
EventData(map[string]interface{}{"id": wm.ID}).
|
||||||
|
Builder()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *InstanceGoogleIDPWriteModel) NewChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID,
|
||||||
|
clientSecretString string,
|
||||||
|
secretCrypto crypto.Crypto,
|
||||||
|
scopes []string,
|
||||||
|
options idp.Options,
|
||||||
|
) (*instance.GoogleIDPChangedEvent, error) {
|
||||||
|
|
||||||
|
changes, err := wm.GoogleIDPWriteModel.NewChanges(name, clientID, clientSecretString, secretCrypto, scopes, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
changeEvent, err := instance.NewGoogleIDPChangedEvent(ctx, aggregate, id, changes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return changeEvent, nil
|
||||||
|
}
|
||||||
|
|
||||||
type InstanceLDAPIDPWriteModel struct {
|
type InstanceLDAPIDPWriteModel struct {
|
||||||
LDAPIDPWriteModel
|
LDAPIDPWriteModel
|
||||||
}
|
}
|
||||||
@ -136,6 +210,10 @@ func (wm *InstanceIDPRemoveWriteModel) Reduce() error {
|
|||||||
func (wm *InstanceIDPRemoveWriteModel) AppendEvents(events ...eventstore.Event) {
|
func (wm *InstanceIDPRemoveWriteModel) AppendEvents(events ...eventstore.Event) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
|
case *instance.GoogleIDPAddedEvent:
|
||||||
|
wm.IDPRemoveWriteModel.AppendEvents(&e.GoogleIDPAddedEvent)
|
||||||
|
case *instance.GoogleIDPChangedEvent:
|
||||||
|
wm.IDPRemoveWriteModel.AppendEvents(&e.GoogleIDPChangedEvent)
|
||||||
case *instance.LDAPIDPAddedEvent:
|
case *instance.LDAPIDPAddedEvent:
|
||||||
wm.IDPRemoveWriteModel.AppendEvents(&e.LDAPIDPAddedEvent)
|
wm.IDPRemoveWriteModel.AppendEvents(&e.LDAPIDPAddedEvent)
|
||||||
case *instance.LDAPIDPChangedEvent:
|
case *instance.LDAPIDPChangedEvent:
|
||||||
@ -155,6 +233,8 @@ func (wm *InstanceIDPRemoveWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
AggregateTypes(instance.AggregateType).
|
AggregateTypes(instance.AggregateType).
|
||||||
AggregateIDs(wm.AggregateID).
|
AggregateIDs(wm.AggregateID).
|
||||||
EventTypes(
|
EventTypes(
|
||||||
|
instance.GoogleIDPAddedEventType,
|
||||||
|
instance.GoogleIDPChangedEventType,
|
||||||
instance.LDAPIDPAddedEventType,
|
instance.LDAPIDPAddedEventType,
|
||||||
instance.LDAPIDPChangedEventType,
|
instance.LDAPIDPChangedEventType,
|
||||||
instance.IDPRemovedEventType,
|
instance.IDPRemovedEventType,
|
||||||
|
@ -20,6 +20,363 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestCommandSide_AddInstanceGoogleIDP(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
idGenerator id.Generator
|
||||||
|
secretCrypto crypto.EncryptionAlgorithm
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
provider GoogleProvider
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
id string
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"invalid clientID",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
provider: GoogleProvider{},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid clientSecret",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"instance1",
|
||||||
|
instance.NewGoogleIDPAddedEvent(context.Background(), &instance.NewAggregate("instance1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
idp.Options{},
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
ClientSecret: "clientSecret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
id: "id1",
|
||||||
|
want: &domain.ObjectDetails{ResourceOwner: "instance1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ok all set",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"instance1",
|
||||||
|
instance.NewGoogleIDPAddedEvent(context.Background(), &instance.NewAggregate("instance1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
[]string{"openid"},
|
||||||
|
idp.Options{
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
ClientSecret: "clientSecret",
|
||||||
|
Scopes: []string{"openid"},
|
||||||
|
IDPOptions: idp.Options{
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
id: "id1",
|
||||||
|
want: &domain.ObjectDetails{ResourceOwner: "instance1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
idGenerator: tt.fields.idGenerator,
|
||||||
|
idpConfigEncryption: tt.fields.secretCrypto,
|
||||||
|
}
|
||||||
|
id, got, err := c.AddInstanceGoogleProvider(tt.args.ctx, tt.args.provider)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.id, id)
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandSide_UpdateInstanceGoogleIDP(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
secretCrypto crypto.EncryptionAlgorithm
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
id string
|
||||||
|
provider GoogleProvider
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"invalid id",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
provider: GoogleProvider{},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid clientID",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not found",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errors.IsNotFound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no changes",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
instance.NewGoogleIDPAddedEvent(context.Background(), &instance.NewAggregate("instance1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
idp.Options{},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "change ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
instance.NewGoogleIDPAddedEvent(context.Background(), &instance.NewAggregate("instance1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
idp.Options{},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"instance1",
|
||||||
|
func() eventstore.Command {
|
||||||
|
t := true
|
||||||
|
event, _ := instance.NewGoogleIDPChangedEvent(context.Background(), &instance.NewAggregate("instance1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
[]idp.GoogleIDPChanges{
|
||||||
|
idp.ChangeGoogleClientID("clientID2"),
|
||||||
|
idp.ChangeGoogleClientSecret(&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("newSecret"),
|
||||||
|
}),
|
||||||
|
idp.ChangeGoogleScopes([]string{"openid", "profile"}),
|
||||||
|
idp.ChangeGoogleOptions(idp.OptionChanges{
|
||||||
|
IsCreationAllowed: &t,
|
||||||
|
IsLinkingAllowed: &t,
|
||||||
|
IsAutoCreation: &t,
|
||||||
|
IsAutoUpdate: &t,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return event
|
||||||
|
}(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "instance1"),
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID2",
|
||||||
|
ClientSecret: "newSecret",
|
||||||
|
Scopes: []string{"openid", "profile"},
|
||||||
|
IDPOptions: idp.Options{
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{ResourceOwner: "instance1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
idpConfigEncryption: tt.fields.secretCrypto,
|
||||||
|
}
|
||||||
|
got, err := c.UpdateInstanceGoogleProvider(tt.args.ctx, tt.args.id, tt.args.provider)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCommandSide_AddInstanceLDAPIDP(t *testing.T) {
|
func TestCommandSide_AddInstanceLDAPIDP(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
|
@ -12,6 +12,40 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (c *Commands) AddOrgGoogleProvider(ctx context.Context, resourceOwner string, provider GoogleProvider) (string, *domain.ObjectDetails, error) {
|
||||||
|
orgAgg := org.NewAggregate(resourceOwner)
|
||||||
|
id, err := c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, c.prepareAddOrgGoogleProvider(orgAgg, resourceOwner, id, provider))
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
pushedEvents, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return id, pushedEventsToObjectDetails(pushedEvents), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) UpdateOrgGoogleProvider(ctx context.Context, resourceOwner, id string, provider GoogleProvider) (*domain.ObjectDetails, error) {
|
||||||
|
orgAgg := org.NewAggregate(resourceOwner)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, c.prepareUpdateOrgGoogleProvider(orgAgg, resourceOwner, id, provider))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(cmds) == 0 {
|
||||||
|
// no change, so return directly
|
||||||
|
return &domain.ObjectDetails{}, nil
|
||||||
|
}
|
||||||
|
pushedEvents, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pushedEventsToObjectDetails(pushedEvents), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) AddOrgLDAPProvider(ctx context.Context, resourceOwner string, provider LDAPProvider) (string, *domain.ObjectDetails, error) {
|
func (c *Commands) AddOrgLDAPProvider(ctx context.Context, resourceOwner string, provider LDAPProvider) (string, *domain.ObjectDetails, error) {
|
||||||
orgAgg := org.NewAggregate(resourceOwner)
|
orgAgg := org.NewAggregate(resourceOwner)
|
||||||
id, err := c.idGenerator.Next()
|
id, err := c.idGenerator.Next()
|
||||||
@ -59,6 +93,78 @@ func (c *Commands) DeleteOrgProvider(ctx context.Context, resourceOwner, id stri
|
|||||||
return pushedEventsToObjectDetails(pushedEvents), nil
|
return pushedEventsToObjectDetails(pushedEvents), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) prepareAddOrgGoogleProvider(a *org.Aggregate, resourceOwner, id string, provider GoogleProvider) preparation.Validation {
|
||||||
|
return func() (preparation.CreateCommands, error) {
|
||||||
|
if provider.ClientID = strings.TrimSpace(provider.ClientID); provider.ClientID == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "ORG-D3fvs", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
if provider.ClientSecret = strings.TrimSpace(provider.ClientSecret); provider.ClientSecret == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "ORG-W2vqs", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
writeModel := NewGoogleOrgIDPWriteModel(resourceOwner, id)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
if err = writeModel.Reduce(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
secret, err := crypto.Encrypt([]byte(provider.ClientSecret), c.idpConfigEncryption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
org.NewGoogleIDPAddedEvent(ctx, &a.Aggregate, id, provider.Name, provider.ClientID, secret, provider.Scopes, provider.IDPOptions),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) prepareUpdateOrgGoogleProvider(a *org.Aggregate, resourceOwner, id string, provider GoogleProvider) preparation.Validation {
|
||||||
|
return func() (preparation.CreateCommands, error) {
|
||||||
|
if id = strings.TrimSpace(id); id == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "ORG-S32t1", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
if provider.ClientID = strings.TrimSpace(provider.ClientID); provider.ClientID == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "ORG-ds432", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
writeModel := NewGoogleOrgIDPWriteModel(resourceOwner, id)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
if err = writeModel.Reduce(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !writeModel.State.Exists() {
|
||||||
|
return nil, caos_errs.ThrowNotFound(nil, "ORG-Dqrg1", "Errors.Org.IDPConfig.NotExisting")
|
||||||
|
}
|
||||||
|
event, err := writeModel.NewChangedEvent(
|
||||||
|
ctx,
|
||||||
|
&a.Aggregate,
|
||||||
|
id,
|
||||||
|
provider.Name,
|
||||||
|
provider.ClientID,
|
||||||
|
provider.ClientSecret,
|
||||||
|
c.idpConfigEncryption,
|
||||||
|
provider.Scopes,
|
||||||
|
provider.IDPOptions,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if event == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return []eventstore.Command{event}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) prepareAddOrgLDAPProvider(a *org.Aggregate, resourceOwner, id string, provider LDAPProvider) preparation.Validation {
|
func (c *Commands) prepareAddOrgLDAPProvider(a *org.Aggregate, resourceOwner, id string, provider LDAPProvider) preparation.Validation {
|
||||||
return func() (preparation.CreateCommands, error) {
|
return func() (preparation.CreateCommands, error) {
|
||||||
if provider.Name = strings.TrimSpace(provider.Name); provider.Name == "" {
|
if provider.Name = strings.TrimSpace(provider.Name); provider.Name == "" {
|
||||||
|
@ -9,6 +9,82 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OrgGoogleIDPWriteModel struct {
|
||||||
|
GoogleIDPWriteModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleOrgIDPWriteModel(orgID, id string) *OrgGoogleIDPWriteModel {
|
||||||
|
return &OrgGoogleIDPWriteModel{
|
||||||
|
GoogleIDPWriteModel{
|
||||||
|
WriteModel: eventstore.WriteModel{
|
||||||
|
AggregateID: orgID,
|
||||||
|
ResourceOwner: orgID,
|
||||||
|
},
|
||||||
|
ID: id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgGoogleIDPWriteModel) Reduce() error {
|
||||||
|
return wm.GoogleIDPWriteModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgGoogleIDPWriteModel) AppendEvents(events ...eventstore.Event) {
|
||||||
|
for _, event := range events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *org.GoogleIDPAddedEvent:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(&e.GoogleIDPAddedEvent)
|
||||||
|
case *org.GoogleIDPChangedEvent:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(&e.GoogleIDPChangedEvent)
|
||||||
|
case *org.IDPRemovedEvent:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(&e.RemovedEvent)
|
||||||
|
default:
|
||||||
|
wm.GoogleIDPWriteModel.AppendEvents(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgGoogleIDPWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
ResourceOwner(wm.ResourceOwner).
|
||||||
|
AddQuery().
|
||||||
|
AggregateTypes(org.AggregateType).
|
||||||
|
AggregateIDs(wm.AggregateID).
|
||||||
|
EventTypes(
|
||||||
|
org.GoogleIDPAddedEventType,
|
||||||
|
org.GoogleIDPChangedEventType,
|
||||||
|
org.IDPRemovedEventType,
|
||||||
|
).
|
||||||
|
EventData(map[string]interface{}{"id": wm.ID}).
|
||||||
|
Builder()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *OrgGoogleIDPWriteModel) NewChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID,
|
||||||
|
clientSecretString string,
|
||||||
|
secretCrypto crypto.Crypto,
|
||||||
|
scopes []string,
|
||||||
|
options idp.Options,
|
||||||
|
) (*org.GoogleIDPChangedEvent, error) {
|
||||||
|
|
||||||
|
changes, err := wm.GoogleIDPWriteModel.NewChanges(name, clientID, clientSecretString, secretCrypto, scopes, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
changeEvent, err := org.NewGoogleIDPChangedEvent(ctx, aggregate, id, changes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return changeEvent, nil
|
||||||
|
}
|
||||||
|
|
||||||
type OrgLDAPIDPWriteModel struct {
|
type OrgLDAPIDPWriteModel struct {
|
||||||
LDAPIDPWriteModel
|
LDAPIDPWriteModel
|
||||||
}
|
}
|
||||||
@ -136,6 +212,10 @@ func (wm *OrgIDPRemoveWriteModel) Reduce() error {
|
|||||||
func (wm *OrgIDPRemoveWriteModel) AppendEvents(events ...eventstore.Event) {
|
func (wm *OrgIDPRemoveWriteModel) AppendEvents(events ...eventstore.Event) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
|
case *org.GoogleIDPAddedEvent:
|
||||||
|
wm.IDPRemoveWriteModel.AppendEvents(&e.GoogleIDPAddedEvent)
|
||||||
|
case *org.GoogleIDPChangedEvent:
|
||||||
|
wm.IDPRemoveWriteModel.AppendEvents(&e.GoogleIDPChangedEvent)
|
||||||
case *org.LDAPIDPAddedEvent:
|
case *org.LDAPIDPAddedEvent:
|
||||||
wm.IDPRemoveWriteModel.AppendEvents(&e.LDAPIDPAddedEvent)
|
wm.IDPRemoveWriteModel.AppendEvents(&e.LDAPIDPAddedEvent)
|
||||||
case *org.LDAPIDPChangedEvent:
|
case *org.LDAPIDPChangedEvent:
|
||||||
@ -155,6 +235,8 @@ func (wm *OrgIDPRemoveWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
AggregateTypes(org.AggregateType).
|
AggregateTypes(org.AggregateType).
|
||||||
AggregateIDs(wm.AggregateID).
|
AggregateIDs(wm.AggregateID).
|
||||||
EventTypes(
|
EventTypes(
|
||||||
|
org.GoogleIDPAddedEventType,
|
||||||
|
org.GoogleIDPChangedEventType,
|
||||||
org.LDAPIDPAddedEventType,
|
org.LDAPIDPAddedEventType,
|
||||||
org.LDAPIDPChangedEventType,
|
org.LDAPIDPChangedEventType,
|
||||||
org.IDPRemovedEventType,
|
org.IDPRemovedEventType,
|
||||||
|
@ -18,6 +18,365 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestCommandSide_AddOrgGoogleIDP(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
idGenerator id.Generator
|
||||||
|
secretCrypto crypto.EncryptionAlgorithm
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
resourceOwner string
|
||||||
|
provider GoogleProvider
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
id string
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"invalid clientID",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
provider: GoogleProvider{},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid clientSecret",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(),
|
||||||
|
expectPush(
|
||||||
|
eventPusherToEvents(
|
||||||
|
org.NewGoogleIDPAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
idp.Options{},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
ClientSecret: "clientSecret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
id: "id1",
|
||||||
|
want: &domain.ObjectDetails{ResourceOwner: "org1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ok all set",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(),
|
||||||
|
expectPush(
|
||||||
|
eventPusherToEvents(
|
||||||
|
org.NewGoogleIDPAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
[]string{"openid"},
|
||||||
|
idp.Options{
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "id1"),
|
||||||
|
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
ClientSecret: "clientSecret",
|
||||||
|
Scopes: []string{"openid"},
|
||||||
|
IDPOptions: idp.Options{
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
id: "id1",
|
||||||
|
want: &domain.ObjectDetails{ResourceOwner: "org1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
idGenerator: tt.fields.idGenerator,
|
||||||
|
idpConfigEncryption: tt.fields.secretCrypto,
|
||||||
|
}
|
||||||
|
id, got, err := c.AddOrgGoogleProvider(tt.args.ctx, tt.args.resourceOwner, tt.args.provider)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.id, id)
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandSide_UpdateOrgGoogleIDP(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
secretCrypto crypto.EncryptionAlgorithm
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
resourceOwner string
|
||||||
|
id string
|
||||||
|
provider GoogleProvider
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"invalid id",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
provider: GoogleProvider{},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid clientID",
|
||||||
|
fields{
|
||||||
|
eventstore: eventstoreExpect(t),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{},
|
||||||
|
},
|
||||||
|
res{
|
||||||
|
err: caos_errors.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not found",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errors.IsNotFound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no changes",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewGoogleIDPAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
idp.Options{},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "change ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewGoogleIDPAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
"",
|
||||||
|
"clientID",
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("clientSecret"),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
idp.Options{},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
expectPush(
|
||||||
|
eventPusherToEvents(
|
||||||
|
func() eventstore.Command {
|
||||||
|
t := true
|
||||||
|
event, _ := org.NewGoogleIDPChangedEvent(context.Background(), &org.NewAggregate("org1").Aggregate,
|
||||||
|
"id1",
|
||||||
|
[]idp.GoogleIDPChanges{
|
||||||
|
idp.ChangeGoogleClientID("clientID2"),
|
||||||
|
idp.ChangeGoogleClientSecret(&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeEncryption,
|
||||||
|
Algorithm: "enc",
|
||||||
|
KeyID: "id",
|
||||||
|
Crypted: []byte("newSecret"),
|
||||||
|
}),
|
||||||
|
idp.ChangeGoogleScopes([]string{"openid", "profile"}),
|
||||||
|
idp.ChangeGoogleOptions(idp.OptionChanges{
|
||||||
|
IsCreationAllowed: &t,
|
||||||
|
IsLinkingAllowed: &t,
|
||||||
|
IsAutoCreation: &t,
|
||||||
|
IsAutoUpdate: &t,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return event
|
||||||
|
}(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
resourceOwner: "org1",
|
||||||
|
id: "id1",
|
||||||
|
provider: GoogleProvider{
|
||||||
|
ClientID: "clientID2",
|
||||||
|
ClientSecret: "newSecret",
|
||||||
|
Scopes: []string{"openid", "profile"},
|
||||||
|
IDPOptions: idp.Options{
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{ResourceOwner: "org1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
idpConfigEncryption: tt.fields.secretCrypto,
|
||||||
|
}
|
||||||
|
got, err := c.UpdateOrgGoogleProvider(tt.args.ctx, tt.args.resourceOwner, tt.args.id, tt.args.provider)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCommandSide_AddOrgLDAPIDP(t *testing.T) {
|
func TestCommandSide_AddOrgLDAPIDP(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/query/projection"
|
"github.com/zitadel/zitadel/internal/query/projection"
|
||||||
@ -32,6 +33,7 @@ type IDPTemplate struct {
|
|||||||
IsLinkingAllowed bool
|
IsLinkingAllowed bool
|
||||||
IsAutoCreation bool
|
IsAutoCreation bool
|
||||||
IsAutoUpdate bool
|
IsAutoUpdate bool
|
||||||
|
*GoogleIDPTemplate
|
||||||
*LDAPIDPTemplate
|
*LDAPIDPTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +42,13 @@ type IDPTemplates struct {
|
|||||||
Templates []*IDPTemplate
|
Templates []*IDPTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GoogleIDPTemplate struct {
|
||||||
|
IDPID string
|
||||||
|
ClientID string
|
||||||
|
ClientSecret *crypto.CryptoValue
|
||||||
|
Scopes database.StringArray
|
||||||
|
}
|
||||||
|
|
||||||
type LDAPIDPTemplate struct {
|
type LDAPIDPTemplate struct {
|
||||||
IDPID string
|
IDPID string
|
||||||
Host string
|
Host string
|
||||||
@ -51,7 +60,6 @@ type LDAPIDPTemplate struct {
|
|||||||
Admin string
|
Admin string
|
||||||
Password *crypto.CryptoValue
|
Password *crypto.CryptoValue
|
||||||
idp.LDAPAttributes
|
idp.LDAPAttributes
|
||||||
idp.Options
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -121,6 +129,33 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
googleIdpTemplateTable = table{
|
||||||
|
name: projection.IDPTemplateGoogleTable,
|
||||||
|
instanceIDCol: projection.GoogleInstanceIDCol,
|
||||||
|
}
|
||||||
|
GoogleIDCol = Column{
|
||||||
|
name: projection.GoogleIDCol,
|
||||||
|
table: googleIdpTemplateTable,
|
||||||
|
}
|
||||||
|
GoogleInstanceIDCol = Column{
|
||||||
|
name: projection.GoogleInstanceIDCol,
|
||||||
|
table: googleIdpTemplateTable,
|
||||||
|
}
|
||||||
|
GoogleClientIDCol = Column{
|
||||||
|
name: projection.GoogleClientIDCol,
|
||||||
|
table: googleIdpTemplateTable,
|
||||||
|
}
|
||||||
|
GoogleClientSecretCol = Column{
|
||||||
|
name: projection.GoogleClientSecretCol,
|
||||||
|
table: googleIdpTemplateTable,
|
||||||
|
}
|
||||||
|
GoogleScopesCol = Column{
|
||||||
|
name: projection.GoogleScopesCol,
|
||||||
|
table: googleIdpTemplateTable,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ldapIdpTemplateTable = table{
|
ldapIdpTemplateTable = table{
|
||||||
name: projection.IDPTemplateLDAPTable,
|
name: projection.IDPTemplateLDAPTable,
|
||||||
@ -335,6 +370,10 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
|||||||
IDPTemplateIsLinkingAllowedCol.identifier(),
|
IDPTemplateIsLinkingAllowedCol.identifier(),
|
||||||
IDPTemplateIsAutoCreationCol.identifier(),
|
IDPTemplateIsAutoCreationCol.identifier(),
|
||||||
IDPTemplateIsAutoUpdateCol.identifier(),
|
IDPTemplateIsAutoUpdateCol.identifier(),
|
||||||
|
GoogleIDCol.identifier(),
|
||||||
|
GoogleClientIDCol.identifier(),
|
||||||
|
GoogleClientSecretCol.identifier(),
|
||||||
|
GoogleScopesCol.identifier(),
|
||||||
LDAPIDCol.identifier(),
|
LDAPIDCol.identifier(),
|
||||||
LDAPHostCol.identifier(),
|
LDAPHostCol.identifier(),
|
||||||
LDAPPortCol.identifier(),
|
LDAPPortCol.identifier(),
|
||||||
@ -358,11 +397,19 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
|||||||
LDAPAvatarURLAttributeCol.identifier(),
|
LDAPAvatarURLAttributeCol.identifier(),
|
||||||
LDAPProfileAttributeCol.identifier(),
|
LDAPProfileAttributeCol.identifier(),
|
||||||
).From(idpTemplateTable.identifier()).
|
).From(idpTemplateTable.identifier()).
|
||||||
|
LeftJoin(join(GoogleIDCol, IDPTemplateIDCol)).
|
||||||
LeftJoin(join(LDAPIDCol, IDPTemplateIDCol)).
|
LeftJoin(join(LDAPIDCol, IDPTemplateIDCol)).
|
||||||
PlaceholderFormat(sq.Dollar),
|
PlaceholderFormat(sq.Dollar),
|
||||||
func(row *sql.Row) (*IDPTemplate, error) {
|
func(row *sql.Row) (*IDPTemplate, error) {
|
||||||
idpTemplate := new(IDPTemplate)
|
idpTemplate := new(IDPTemplate)
|
||||||
|
|
||||||
|
name := sql.NullString{}
|
||||||
|
|
||||||
|
googleID := sql.NullString{}
|
||||||
|
googleClientID := sql.NullString{}
|
||||||
|
googleClientSecret := new(crypto.CryptoValue)
|
||||||
|
googleScopes := database.StringArray{}
|
||||||
|
|
||||||
ldapID := sql.NullString{}
|
ldapID := sql.NullString{}
|
||||||
ldapHost := sql.NullString{}
|
ldapHost := sql.NullString{}
|
||||||
ldapPort := sql.NullString{}
|
ldapPort := sql.NullString{}
|
||||||
@ -393,13 +440,17 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
|||||||
&idpTemplate.ChangeDate,
|
&idpTemplate.ChangeDate,
|
||||||
&idpTemplate.Sequence,
|
&idpTemplate.Sequence,
|
||||||
&idpTemplate.State,
|
&idpTemplate.State,
|
||||||
&idpTemplate.Name,
|
&name,
|
||||||
&idpTemplate.Type,
|
&idpTemplate.Type,
|
||||||
&idpTemplate.OwnerType,
|
&idpTemplate.OwnerType,
|
||||||
&idpTemplate.IsCreationAllowed,
|
&idpTemplate.IsCreationAllowed,
|
||||||
&idpTemplate.IsLinkingAllowed,
|
&idpTemplate.IsLinkingAllowed,
|
||||||
&idpTemplate.IsAutoCreation,
|
&idpTemplate.IsAutoCreation,
|
||||||
&idpTemplate.IsAutoUpdate,
|
&idpTemplate.IsAutoUpdate,
|
||||||
|
&googleID,
|
||||||
|
&googleClientID,
|
||||||
|
&googleClientSecret,
|
||||||
|
&googleScopes,
|
||||||
&ldapID,
|
&ldapID,
|
||||||
&ldapHost,
|
&ldapHost,
|
||||||
&ldapPort,
|
&ldapPort,
|
||||||
@ -430,7 +481,16 @@ func prepareIDPTemplateByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDPTempla
|
|||||||
return nil, errors.ThrowInternal(err, "QUERY-ADG42", "Errors.Internal")
|
return nil, errors.ThrowInternal(err, "QUERY-ADG42", "Errors.Internal")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ldapID.Valid {
|
idpTemplate.Name = name.String
|
||||||
|
|
||||||
|
if googleID.Valid {
|
||||||
|
idpTemplate.GoogleIDPTemplate = &GoogleIDPTemplate{
|
||||||
|
IDPID: googleID.String,
|
||||||
|
ClientID: googleClientID.String,
|
||||||
|
ClientSecret: googleClientSecret,
|
||||||
|
Scopes: googleScopes,
|
||||||
|
}
|
||||||
|
} else if ldapID.Valid {
|
||||||
idpTemplate.LDAPIDPTemplate = &LDAPIDPTemplate{
|
idpTemplate.LDAPIDPTemplate = &LDAPIDPTemplate{
|
||||||
IDPID: ldapID.String,
|
IDPID: ldapID.String,
|
||||||
Host: ldapHost.String,
|
Host: ldapHost.String,
|
||||||
@ -478,6 +538,10 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
|||||||
IDPTemplateIsLinkingAllowedCol.identifier(),
|
IDPTemplateIsLinkingAllowedCol.identifier(),
|
||||||
IDPTemplateIsAutoCreationCol.identifier(),
|
IDPTemplateIsAutoCreationCol.identifier(),
|
||||||
IDPTemplateIsAutoUpdateCol.identifier(),
|
IDPTemplateIsAutoUpdateCol.identifier(),
|
||||||
|
GoogleIDCol.identifier(),
|
||||||
|
GoogleClientIDCol.identifier(),
|
||||||
|
GoogleClientSecretCol.identifier(),
|
||||||
|
GoogleScopesCol.identifier(),
|
||||||
LDAPIDCol.identifier(),
|
LDAPIDCol.identifier(),
|
||||||
LDAPHostCol.identifier(),
|
LDAPHostCol.identifier(),
|
||||||
LDAPPortCol.identifier(),
|
LDAPPortCol.identifier(),
|
||||||
@ -502,6 +566,7 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
|||||||
LDAPProfileAttributeCol.identifier(),
|
LDAPProfileAttributeCol.identifier(),
|
||||||
countColumn.identifier(),
|
countColumn.identifier(),
|
||||||
).From(idpTemplateTable.identifier()).
|
).From(idpTemplateTable.identifier()).
|
||||||
|
LeftJoin(join(GoogleIDCol, IDPTemplateIDCol)).
|
||||||
LeftJoin(join(LDAPIDCol, IDPTemplateIDCol)).
|
LeftJoin(join(LDAPIDCol, IDPTemplateIDCol)).
|
||||||
PlaceholderFormat(sq.Dollar),
|
PlaceholderFormat(sq.Dollar),
|
||||||
func(rows *sql.Rows) (*IDPTemplates, error) {
|
func(rows *sql.Rows) (*IDPTemplates, error) {
|
||||||
@ -510,6 +575,13 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
|||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
idpTemplate := new(IDPTemplate)
|
idpTemplate := new(IDPTemplate)
|
||||||
|
|
||||||
|
name := sql.NullString{}
|
||||||
|
|
||||||
|
googleID := sql.NullString{}
|
||||||
|
googleClientID := sql.NullString{}
|
||||||
|
googleClientSecret := new(crypto.CryptoValue)
|
||||||
|
googleScopes := database.StringArray{}
|
||||||
|
|
||||||
ldapID := sql.NullString{}
|
ldapID := sql.NullString{}
|
||||||
ldapHost := sql.NullString{}
|
ldapHost := sql.NullString{}
|
||||||
ldapPort := sql.NullString{}
|
ldapPort := sql.NullString{}
|
||||||
@ -540,13 +612,17 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
|||||||
&idpTemplate.ChangeDate,
|
&idpTemplate.ChangeDate,
|
||||||
&idpTemplate.Sequence,
|
&idpTemplate.Sequence,
|
||||||
&idpTemplate.State,
|
&idpTemplate.State,
|
||||||
&idpTemplate.Name,
|
&name,
|
||||||
&idpTemplate.Type,
|
&idpTemplate.Type,
|
||||||
&idpTemplate.OwnerType,
|
&idpTemplate.OwnerType,
|
||||||
&idpTemplate.IsCreationAllowed,
|
&idpTemplate.IsCreationAllowed,
|
||||||
&idpTemplate.IsLinkingAllowed,
|
&idpTemplate.IsLinkingAllowed,
|
||||||
&idpTemplate.IsAutoCreation,
|
&idpTemplate.IsAutoCreation,
|
||||||
&idpTemplate.IsAutoUpdate,
|
&idpTemplate.IsAutoUpdate,
|
||||||
|
&googleID,
|
||||||
|
&googleClientID,
|
||||||
|
&googleClientSecret,
|
||||||
|
&googleScopes,
|
||||||
&ldapID,
|
&ldapID,
|
||||||
&ldapHost,
|
&ldapHost,
|
||||||
&ldapPort,
|
&ldapPort,
|
||||||
@ -576,7 +652,16 @@ func prepareIDPTemplatesQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPTemplate
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ldapID.Valid {
|
idpTemplate.Name = name.String
|
||||||
|
|
||||||
|
if googleID.Valid {
|
||||||
|
idpTemplate.GoogleIDPTemplate = &GoogleIDPTemplate{
|
||||||
|
IDPID: googleID.String,
|
||||||
|
ClientID: googleClientID.String,
|
||||||
|
ClientSecret: googleClientSecret,
|
||||||
|
Scopes: googleScopes,
|
||||||
|
}
|
||||||
|
} else if ldapID.Valid {
|
||||||
idpTemplate.LDAPIDPTemplate = &LDAPIDPTemplate{
|
idpTemplate.LDAPIDPTemplate = &LDAPIDPTemplate{
|
||||||
IDPID: ldapID.String,
|
IDPID: ldapID.String,
|
||||||
Host: ldapHost.String,
|
Host: ldapHost.String,
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
errs "github.com/zitadel/zitadel/internal/errors"
|
errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/repository/idp"
|
"github.com/zitadel/zitadel/internal/repository/idp"
|
||||||
@ -27,6 +28,10 @@ var (
|
|||||||
` projections.idp_templates.is_linking_allowed,` +
|
` projections.idp_templates.is_linking_allowed,` +
|
||||||
` projections.idp_templates.is_auto_creation,` +
|
` projections.idp_templates.is_auto_creation,` +
|
||||||
` projections.idp_templates.is_auto_update,` +
|
` projections.idp_templates.is_auto_update,` +
|
||||||
|
` projections.idp_templates_google.idp_id,` +
|
||||||
|
` projections.idp_templates_google.client_id,` +
|
||||||
|
` projections.idp_templates_google.client_secret,` +
|
||||||
|
` projections.idp_templates_google.scopes,` +
|
||||||
` projections.idp_templates_ldap.idp_id,` +
|
` projections.idp_templates_ldap.idp_id,` +
|
||||||
` projections.idp_templates_ldap.host,` +
|
` projections.idp_templates_ldap.host,` +
|
||||||
` projections.idp_templates_ldap.port,` +
|
` projections.idp_templates_ldap.port,` +
|
||||||
@ -50,6 +55,7 @@ var (
|
|||||||
` projections.idp_templates_ldap.avatar_url_attribute,` +
|
` projections.idp_templates_ldap.avatar_url_attribute,` +
|
||||||
` projections.idp_templates_ldap.profile_attribute` +
|
` projections.idp_templates_ldap.profile_attribute` +
|
||||||
` FROM projections.idp_templates` +
|
` FROM projections.idp_templates` +
|
||||||
|
` 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`
|
` 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{
|
idpTemplateCols = []string{
|
||||||
"id",
|
"id",
|
||||||
@ -65,6 +71,11 @@ var (
|
|||||||
"is_linking_allowed",
|
"is_linking_allowed",
|
||||||
"is_auto_creation",
|
"is_auto_creation",
|
||||||
"is_auto_update",
|
"is_auto_update",
|
||||||
|
// google config
|
||||||
|
"idp_id",
|
||||||
|
"client_id",
|
||||||
|
"client_secret",
|
||||||
|
"scopes",
|
||||||
// ldap config
|
// ldap config
|
||||||
"idp_id",
|
"idp_id",
|
||||||
"host",
|
"host",
|
||||||
@ -102,6 +113,10 @@ var (
|
|||||||
` projections.idp_templates.is_linking_allowed,` +
|
` projections.idp_templates.is_linking_allowed,` +
|
||||||
` projections.idp_templates.is_auto_creation,` +
|
` projections.idp_templates.is_auto_creation,` +
|
||||||
` projections.idp_templates.is_auto_update,` +
|
` projections.idp_templates.is_auto_update,` +
|
||||||
|
` projections.idp_templates_google.idp_id,` +
|
||||||
|
` projections.idp_templates_google.client_id,` +
|
||||||
|
` projections.idp_templates_google.client_secret,` +
|
||||||
|
` projections.idp_templates_google.scopes,` +
|
||||||
` projections.idp_templates_ldap.idp_id,` +
|
` projections.idp_templates_ldap.idp_id,` +
|
||||||
` projections.idp_templates_ldap.host,` +
|
` projections.idp_templates_ldap.host,` +
|
||||||
` projections.idp_templates_ldap.port,` +
|
` projections.idp_templates_ldap.port,` +
|
||||||
@ -126,6 +141,7 @@ var (
|
|||||||
` projections.idp_templates_ldap.profile_attribute,` +
|
` projections.idp_templates_ldap.profile_attribute,` +
|
||||||
` COUNT(*) OVER ()` +
|
` COUNT(*) OVER ()` +
|
||||||
` FROM projections.idp_templates` +
|
` FROM projections.idp_templates` +
|
||||||
|
` 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`
|
` 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{
|
idpTemplatesCols = []string{
|
||||||
"id",
|
"id",
|
||||||
@ -141,6 +157,12 @@ var (
|
|||||||
"is_linking_allowed",
|
"is_linking_allowed",
|
||||||
"is_auto_creation",
|
"is_auto_creation",
|
||||||
"is_auto_update",
|
"is_auto_update",
|
||||||
|
// google config
|
||||||
|
"idp_id",
|
||||||
|
"client_id",
|
||||||
|
"client_secret",
|
||||||
|
"scopes",
|
||||||
|
// ldap config
|
||||||
"idp_id",
|
"idp_id",
|
||||||
"host",
|
"host",
|
||||||
"port",
|
"port",
|
||||||
@ -196,6 +218,81 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
},
|
},
|
||||||
object: (*IDPTemplate)(nil),
|
object: (*IDPTemplate)(nil),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "prepareIDPTemplateByIDQuery google 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.IDPTypeGoogle,
|
||||||
|
domain.IdentityProviderTypeOrg,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
// google
|
||||||
|
"idp-id",
|
||||||
|
"client_id",
|
||||||
|
nil,
|
||||||
|
database.StringArray{"profile"},
|
||||||
|
// 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.IDPTypeGoogle,
|
||||||
|
OwnerType: domain.IdentityProviderTypeOrg,
|
||||||
|
IsCreationAllowed: true,
|
||||||
|
IsLinkingAllowed: true,
|
||||||
|
IsAutoCreation: true,
|
||||||
|
IsAutoUpdate: true,
|
||||||
|
GoogleIDPTemplate: &GoogleIDPTemplate{
|
||||||
|
IDPID: "idp-id",
|
||||||
|
ClientID: "client_id",
|
||||||
|
ClientSecret: nil,
|
||||||
|
Scopes: []string{"profile"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "prepareIDPTemplateByIDQuery ldap idp",
|
name: "prepareIDPTemplateByIDQuery ldap idp",
|
||||||
prepare: prepareIDPTemplateByIDQuery,
|
prepare: prepareIDPTemplateByIDQuery,
|
||||||
@ -217,6 +314,11 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
// google
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
// ldap config
|
// ldap config
|
||||||
"idp-id",
|
"idp-id",
|
||||||
"host",
|
"host",
|
||||||
@ -305,6 +407,11 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
// google config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
// ldap config
|
// ldap config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@ -404,6 +511,11 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
// google config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
// ldap config
|
// ldap config
|
||||||
"idp-id",
|
"idp-id",
|
||||||
"host",
|
"host",
|
||||||
@ -501,6 +613,11 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
// google config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
// ldap config
|
// ldap config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@ -560,7 +677,7 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
idpTemplatesCols,
|
idpTemplatesCols,
|
||||||
[][]driver.Value{
|
[][]driver.Value{
|
||||||
{
|
{
|
||||||
"idp-id-1",
|
"idp-id-ldap",
|
||||||
"ro",
|
"ro",
|
||||||
testNow,
|
testNow,
|
||||||
testNow,
|
testNow,
|
||||||
@ -573,8 +690,13 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
// google config
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
// ldap config
|
// ldap config
|
||||||
"idp-id",
|
"idp-id-ldap",
|
||||||
"host",
|
"host",
|
||||||
"port",
|
"port",
|
||||||
true,
|
true,
|
||||||
@ -598,19 +720,24 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
"profile",
|
"profile",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idp-id-2",
|
"idp-id-google",
|
||||||
"ro",
|
"ro",
|
||||||
testNow,
|
testNow,
|
||||||
testNow,
|
testNow,
|
||||||
uint64(20211109),
|
uint64(20211109),
|
||||||
domain.IDPConfigStateActive,
|
domain.IDPConfigStateActive,
|
||||||
"idp-name",
|
"idp-name",
|
||||||
domain.IDPTypeLDAP,
|
domain.IDPTypeGoogle,
|
||||||
domain.IdentityProviderTypeOrg,
|
domain.IdentityProviderTypeOrg,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
// google
|
||||||
|
"idp-id-google",
|
||||||
|
"client_id",
|
||||||
|
nil,
|
||||||
|
database.StringArray{"profile"},
|
||||||
// ldap config
|
// ldap config
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@ -648,7 +775,7 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
ChangeDate: testNow,
|
ChangeDate: testNow,
|
||||||
Sequence: 20211109,
|
Sequence: 20211109,
|
||||||
ResourceOwner: "ro",
|
ResourceOwner: "ro",
|
||||||
ID: "idp-id-1",
|
ID: "idp-id-ldap",
|
||||||
State: domain.IDPStateActive,
|
State: domain.IDPStateActive,
|
||||||
Name: "idp-name",
|
Name: "idp-name",
|
||||||
Type: domain.IDPTypeLDAP,
|
Type: domain.IDPTypeLDAP,
|
||||||
@ -658,7 +785,7 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
IsAutoCreation: true,
|
IsAutoCreation: true,
|
||||||
IsAutoUpdate: true,
|
IsAutoUpdate: true,
|
||||||
LDAPIDPTemplate: &LDAPIDPTemplate{
|
LDAPIDPTemplate: &LDAPIDPTemplate{
|
||||||
IDPID: "idp-id",
|
IDPID: "idp-id-ldap",
|
||||||
Host: "host",
|
Host: "host",
|
||||||
Port: "port",
|
Port: "port",
|
||||||
TLS: true,
|
TLS: true,
|
||||||
@ -688,15 +815,21 @@ func Test_IDPTemplateTemplatesPrepares(t *testing.T) {
|
|||||||
ChangeDate: testNow,
|
ChangeDate: testNow,
|
||||||
Sequence: 20211109,
|
Sequence: 20211109,
|
||||||
ResourceOwner: "ro",
|
ResourceOwner: "ro",
|
||||||
ID: "idp-id-2",
|
ID: "idp-id-google",
|
||||||
State: domain.IDPStateActive,
|
State: domain.IDPStateActive,
|
||||||
Name: "idp-name",
|
Name: "idp-name",
|
||||||
Type: domain.IDPTypeLDAP,
|
Type: domain.IDPTypeGoogle,
|
||||||
OwnerType: domain.IdentityProviderTypeOrg,
|
OwnerType: domain.IdentityProviderTypeOrg,
|
||||||
IsCreationAllowed: true,
|
IsCreationAllowed: true,
|
||||||
IsLinkingAllowed: true,
|
IsLinkingAllowed: true,
|
||||||
IsAutoCreation: true,
|
IsAutoCreation: true,
|
||||||
IsAutoUpdate: true,
|
IsAutoUpdate: true,
|
||||||
|
GoogleIDPTemplate: &GoogleIDPTemplate{
|
||||||
|
IDPID: "idp-id-google",
|
||||||
|
ClientID: "client_id",
|
||||||
|
ClientSecret: nil,
|
||||||
|
Scopes: []string{"profile"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,9 @@ package projection
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
@ -14,10 +16,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IDPTemplateTable = "projections.idp_templates"
|
IDPTemplateTable = "projections.idp_templates"
|
||||||
IDPTemplateLDAPTable = IDPTemplateTable + "_" + IDPTemplateLDAPSuffix
|
IDPTemplateGoogleTable = IDPTemplateTable + "_" + IDPTemplateGoogleSuffix
|
||||||
|
IDPTemplateLDAPTable = IDPTemplateTable + "_" + IDPTemplateLDAPSuffix
|
||||||
|
|
||||||
IDPTemplateLDAPSuffix = "ldap"
|
IDPTemplateGoogleSuffix = "google"
|
||||||
|
IDPTemplateLDAPSuffix = "ldap"
|
||||||
|
|
||||||
IDPTemplateIDCol = "id"
|
IDPTemplateIDCol = "id"
|
||||||
IDPTemplateCreationDateCol = "creation_date"
|
IDPTemplateCreationDateCol = "creation_date"
|
||||||
@ -35,6 +39,12 @@ const (
|
|||||||
IDPTemplateIsAutoCreationCol = "is_auto_creation"
|
IDPTemplateIsAutoCreationCol = "is_auto_creation"
|
||||||
IDPTemplateIsAutoUpdateCol = "is_auto_update"
|
IDPTemplateIsAutoUpdateCol = "is_auto_update"
|
||||||
|
|
||||||
|
GoogleIDCol = "idp_id"
|
||||||
|
GoogleInstanceIDCol = "instance_id"
|
||||||
|
GoogleClientIDCol = "client_id"
|
||||||
|
GoogleClientSecretCol = "client_secret"
|
||||||
|
GoogleScopesCol = "scopes"
|
||||||
|
|
||||||
LDAPIDCol = "idp_id"
|
LDAPIDCol = "idp_id"
|
||||||
LDAPInstanceIDCol = "instance_id"
|
LDAPInstanceIDCol = "instance_id"
|
||||||
LDAPHostCol = "host"
|
LDAPHostCol = "host"
|
||||||
@ -90,6 +100,17 @@ func newIDPTemplateProjection(ctx context.Context, config crdb.StatementHandlerC
|
|||||||
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{IDPTemplateResourceOwnerCol})),
|
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{IDPTemplateResourceOwnerCol})),
|
||||||
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{IDPTemplateOwnerRemovedCol})),
|
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{IDPTemplateOwnerRemovedCol})),
|
||||||
),
|
),
|
||||||
|
crdb.NewSuffixedTable([]*crdb.Column{
|
||||||
|
crdb.NewColumn(GoogleIDCol, crdb.ColumnTypeText),
|
||||||
|
crdb.NewColumn(GoogleInstanceIDCol, crdb.ColumnTypeText),
|
||||||
|
crdb.NewColumn(GoogleClientIDCol, crdb.ColumnTypeText),
|
||||||
|
crdb.NewColumn(GoogleClientSecretCol, crdb.ColumnTypeJSONB),
|
||||||
|
crdb.NewColumn(GoogleScopesCol, crdb.ColumnTypeTextArray, crdb.Nullable()),
|
||||||
|
},
|
||||||
|
crdb.NewPrimaryKey(GoogleInstanceIDCol, GoogleIDCol),
|
||||||
|
IDPTemplateGoogleSuffix,
|
||||||
|
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
|
||||||
|
),
|
||||||
crdb.NewSuffixedTable([]*crdb.Column{
|
crdb.NewSuffixedTable([]*crdb.Column{
|
||||||
crdb.NewColumn(LDAPIDCol, crdb.ColumnTypeText),
|
crdb.NewColumn(LDAPIDCol, crdb.ColumnTypeText),
|
||||||
crdb.NewColumn(LDAPInstanceIDCol, crdb.ColumnTypeText),
|
crdb.NewColumn(LDAPInstanceIDCol, crdb.ColumnTypeText),
|
||||||
@ -129,6 +150,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
|||||||
{
|
{
|
||||||
Aggregate: instance.AggregateType,
|
Aggregate: instance.AggregateType,
|
||||||
EventRedusers: []handler.EventReducer{
|
EventRedusers: []handler.EventReducer{
|
||||||
|
{
|
||||||
|
Event: instance.GoogleIDPAddedEventType,
|
||||||
|
Reduce: p.reduceGoogleIDPAdded,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: instance.GoogleIDPChangedEventType,
|
||||||
|
Reduce: p.reduceGoogleIDPChanged,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Event: instance.LDAPIDPAddedEventType,
|
Event: instance.LDAPIDPAddedEventType,
|
||||||
Reduce: p.reduceLDAPIDPAdded,
|
Reduce: p.reduceLDAPIDPAdded,
|
||||||
@ -150,6 +179,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
|||||||
{
|
{
|
||||||
Aggregate: org.AggregateType,
|
Aggregate: org.AggregateType,
|
||||||
EventRedusers: []handler.EventReducer{
|
EventRedusers: []handler.EventReducer{
|
||||||
|
{
|
||||||
|
Event: org.GoogleIDPAddedEventType,
|
||||||
|
Reduce: p.reduceGoogleIDPAdded,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: org.GoogleIDPChangedEventType,
|
||||||
|
Reduce: p.reduceGoogleIDPChanged,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Event: org.LDAPIDPAddedEventType,
|
Event: org.LDAPIDPAddedEventType,
|
||||||
Reduce: p.reduceLDAPIDPAdded,
|
Reduce: p.reduceLDAPIDPAdded,
|
||||||
@ -171,6 +208,94 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *idpTemplateProjection) reduceGoogleIDPAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
var idpEvent idp.GoogleIDPAddedEvent
|
||||||
|
var idpOwnerType domain.IdentityProviderType
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *org.GoogleIDPAddedEvent:
|
||||||
|
idpEvent = e.GoogleIDPAddedEvent
|
||||||
|
idpOwnerType = domain.IdentityProviderTypeOrg
|
||||||
|
case *instance.GoogleIDPAddedEvent:
|
||||||
|
idpEvent = e.GoogleIDPAddedEvent
|
||||||
|
idpOwnerType = domain.IdentityProviderTypeSystem
|
||||||
|
default:
|
||||||
|
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ap9ihb", "reduce.wrong.event.type %v", []eventstore.EventType{org.GoogleIDPAddedEventType, instance.GoogleIDPAddedEventType})
|
||||||
|
}
|
||||||
|
|
||||||
|
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.IDPTypeGoogle),
|
||||||
|
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(GoogleIDCol, idpEvent.ID),
|
||||||
|
handler.NewCol(GoogleInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||||
|
handler.NewCol(GoogleClientIDCol, idpEvent.ClientID),
|
||||||
|
handler.NewCol(GoogleClientSecretCol, idpEvent.ClientSecret),
|
||||||
|
handler.NewCol(GoogleScopesCol, database.StringArray(idpEvent.Scopes)),
|
||||||
|
},
|
||||||
|
crdb.WithTableSuffix(IDPTemplateGoogleSuffix),
|
||||||
|
),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *idpTemplateProjection) reduceGoogleIDPChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
var idpEvent idp.GoogleIDPChangedEvent
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *org.GoogleIDPChangedEvent:
|
||||||
|
idpEvent = e.GoogleIDPChangedEvent
|
||||||
|
case *instance.GoogleIDPChangedEvent:
|
||||||
|
idpEvent = e.GoogleIDPChangedEvent
|
||||||
|
default:
|
||||||
|
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-p1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.GoogleIDPChangedEventType, instance.GoogleIDPChangedEventType})
|
||||||
|
}
|
||||||
|
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
googleCols := reduceGoogleIDPChangedColumns(idpEvent)
|
||||||
|
if len(googleCols) > 0 {
|
||||||
|
ops = append(ops,
|
||||||
|
crdb.AddUpdateStatement(
|
||||||
|
googleCols,
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(GoogleIDCol, idpEvent.ID),
|
||||||
|
handler.NewCond(GoogleInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||||
|
},
|
||||||
|
crdb.WithTableSuffix(IDPTemplateGoogleSuffix),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return crdb.NewMultiStatement(
|
||||||
|
&idpEvent,
|
||||||
|
ops...,
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *idpTemplateProjection) reduceLDAPIDPAdded(event eventstore.Event) (*handler.Statement, error) {
|
func (p *idpTemplateProjection) reduceLDAPIDPAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||||
var idpEvent idp.LDAPIDPAddedEvent
|
var idpEvent idp.LDAPIDPAddedEvent
|
||||||
var idpOwnerType domain.IdentityProviderType
|
var idpOwnerType domain.IdentityProviderType
|
||||||
@ -247,13 +372,10 @@ func (p *idpTemplateProjection) reduceLDAPIDPChanged(event eventstore.Event) (*h
|
|||||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-p1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.LDAPIDPChangedEventType, instance.LDAPIDPChangedEventType})
|
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-p1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.LDAPIDPChangedEventType, instance.LDAPIDPChangedEventType})
|
||||||
}
|
}
|
||||||
|
|
||||||
cols := reduceLDAPIDPChangedTemplateColumns(idpEvent)
|
|
||||||
ldapCols := reduceLDAPIDPChangedLDAPColumns(idpEvent)
|
|
||||||
|
|
||||||
ops := make([]func(eventstore.Event) crdb.Exec, 0, 2)
|
ops := make([]func(eventstore.Event) crdb.Exec, 0, 2)
|
||||||
ops = append(ops,
|
ops = append(ops,
|
||||||
crdb.AddUpdateStatement(
|
crdb.AddUpdateStatement(
|
||||||
cols,
|
reduceIDPChangedTemplateColumns(idpEvent.Name, idpEvent.CreationDate(), idpEvent.Sequence(), idpEvent.OptionChanges),
|
||||||
[]handler.Condition{
|
[]handler.Condition{
|
||||||
handler.NewCond(IDPTemplateIDCol, idpEvent.ID),
|
handler.NewCond(IDPTemplateIDCol, idpEvent.ID),
|
||||||
handler.NewCond(IDPTemplateInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
handler.NewCond(IDPTemplateInstanceIDCol, idpEvent.Aggregate().InstanceID),
|
||||||
@ -261,6 +383,7 @@ func (p *idpTemplateProjection) reduceLDAPIDPChanged(event eventstore.Event) (*h
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ldapCols := reduceLDAPIDPChangedColumns(idpEvent)
|
||||||
if len(ldapCols) > 0 {
|
if len(ldapCols) > 0 {
|
||||||
ops = append(ops,
|
ops = append(ops,
|
||||||
crdb.AddUpdateStatement(
|
crdb.AddUpdateStatement(
|
||||||
@ -320,30 +443,44 @@ func (p *idpTemplateProjection) reduceOwnerRemoved(event eventstore.Event) (*han
|
|||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func reduceLDAPIDPChangedTemplateColumns(idpEvent idp.LDAPIDPChangedEvent) []handler.Column {
|
func reduceIDPChangedTemplateColumns(name *string, creationDate time.Time, sequence uint64, optionChanges idp.OptionChanges) []handler.Column {
|
||||||
cols := make([]handler.Column, 0, 7)
|
cols := make([]handler.Column, 0, 7)
|
||||||
if idpEvent.Name != nil {
|
if name != nil {
|
||||||
cols = append(cols, handler.NewCol(IDPTemplateNameCol, *idpEvent.Name))
|
cols = append(cols, handler.NewCol(IDPTemplateNameCol, *name))
|
||||||
}
|
}
|
||||||
if idpEvent.IsCreationAllowed != nil {
|
if optionChanges.IsCreationAllowed != nil {
|
||||||
cols = append(cols, handler.NewCol(IDPTemplateIsCreationAllowedCol, *idpEvent.IsCreationAllowed))
|
cols = append(cols, handler.NewCol(IDPTemplateIsCreationAllowedCol, *optionChanges.IsCreationAllowed))
|
||||||
}
|
}
|
||||||
if idpEvent.IsLinkingAllowed != nil {
|
if optionChanges.IsLinkingAllowed != nil {
|
||||||
cols = append(cols, handler.NewCol(IDPTemplateIsLinkingAllowedCol, *idpEvent.IsLinkingAllowed))
|
cols = append(cols, handler.NewCol(IDPTemplateIsLinkingAllowedCol, *optionChanges.IsLinkingAllowed))
|
||||||
}
|
}
|
||||||
if idpEvent.IsAutoCreation != nil {
|
if optionChanges.IsAutoCreation != nil {
|
||||||
cols = append(cols, handler.NewCol(IDPTemplateIsAutoCreationCol, *idpEvent.IsAutoCreation))
|
cols = append(cols, handler.NewCol(IDPTemplateIsAutoCreationCol, *optionChanges.IsAutoCreation))
|
||||||
}
|
}
|
||||||
if idpEvent.IsAutoUpdate != nil {
|
if optionChanges.IsAutoUpdate != nil {
|
||||||
cols = append(cols, handler.NewCol(IDPTemplateIsAutoUpdateCol, *idpEvent.IsAutoUpdate))
|
cols = append(cols, handler.NewCol(IDPTemplateIsAutoUpdateCol, *optionChanges.IsAutoUpdate))
|
||||||
}
|
}
|
||||||
return append(cols,
|
return append(cols,
|
||||||
handler.NewCol(IDPTemplateChangeDateCol, idpEvent.CreationDate()),
|
handler.NewCol(IDPTemplateChangeDateCol, creationDate),
|
||||||
handler.NewCol(IDPTemplateSequenceCol, idpEvent.Sequence()),
|
handler.NewCol(IDPTemplateSequenceCol, sequence),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func reduceLDAPIDPChangedLDAPColumns(idpEvent idp.LDAPIDPChangedEvent) []handler.Column {
|
func reduceGoogleIDPChangedColumns(idpEvent idp.GoogleIDPChangedEvent) []handler.Column {
|
||||||
|
googleCols := make([]handler.Column, 0, 3)
|
||||||
|
if idpEvent.ClientID != nil {
|
||||||
|
googleCols = append(googleCols, handler.NewCol(GoogleClientIDCol, *idpEvent.ClientID))
|
||||||
|
}
|
||||||
|
if idpEvent.ClientSecret != nil {
|
||||||
|
googleCols = append(googleCols, handler.NewCol(GoogleClientSecretCol, *idpEvent.ClientSecret))
|
||||||
|
}
|
||||||
|
if idpEvent.Scopes != nil {
|
||||||
|
googleCols = append(googleCols, handler.NewCol(GoogleScopesCol, database.StringArray(idpEvent.Scopes)))
|
||||||
|
}
|
||||||
|
return googleCols
|
||||||
|
}
|
||||||
|
|
||||||
|
func reduceLDAPIDPChangedColumns(idpEvent idp.LDAPIDPChangedEvent) []handler.Column {
|
||||||
ldapCols := make([]handler.Column, 0, 4)
|
ldapCols := make([]handler.Column, 0, 4)
|
||||||
if idpEvent.Host != nil {
|
if idpEvent.Host != nil {
|
||||||
ldapCols = append(ldapCols, handler.NewCol(LDAPHostCol, *idpEvent.Host))
|
ldapCols = append(ldapCols, handler.NewCol(LDAPHostCol, *idpEvent.Host))
|
||||||
|
@ -3,6 +3,7 @@ package projection
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
@ -124,6 +125,254 @@ func TestIDPTemplateProjection_reducesRemove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(instance.GoogleIDPAddedEventType),
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "idp-id",
|
||||||
|
"clientID": "client_id",
|
||||||
|
"clientSecret": {
|
||||||
|
"cryptoType": 0,
|
||||||
|
"algorithm": "RSA-265",
|
||||||
|
"keyId": "key-id"
|
||||||
|
},
|
||||||
|
"scopes": ["profile"],
|
||||||
|
"isCreationAllowed": true,
|
||||||
|
"isLinkingAllowed": true,
|
||||||
|
"isAutoCreation": true,
|
||||||
|
"isAutoUpdate": true
|
||||||
|
}`),
|
||||||
|
), instance.GoogleIDPAddedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: (&idpTemplateProjection{}).reduceGoogleIDPAdded,
|
||||||
|
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,
|
||||||
|
"",
|
||||||
|
domain.IdentityProviderTypeSystem,
|
||||||
|
domain.IDPTypeGoogle,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "INSERT INTO projections.idp_templates_google (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"idp-id",
|
||||||
|
"instance-id",
|
||||||
|
"client_id",
|
||||||
|
anyArg{},
|
||||||
|
database.StringArray{"profile"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "org reduceGoogleIDPAdded",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(org.GoogleIDPAddedEventType),
|
||||||
|
org.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "idp-id",
|
||||||
|
"clientID": "client_id",
|
||||||
|
"clientSecret": {
|
||||||
|
"cryptoType": 0,
|
||||||
|
"algorithm": "RSA-265",
|
||||||
|
"keyId": "key-id"
|
||||||
|
},
|
||||||
|
"scopes": ["profile"],
|
||||||
|
"isCreationAllowed": true,
|
||||||
|
"isLinkingAllowed": true,
|
||||||
|
"isAutoCreation": true,
|
||||||
|
"isAutoUpdate": true
|
||||||
|
}`),
|
||||||
|
), org.GoogleIDPAddedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: (&idpTemplateProjection{}).reduceGoogleIDPAdded,
|
||||||
|
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,
|
||||||
|
"",
|
||||||
|
domain.IdentityProviderTypeOrg,
|
||||||
|
domain.IDPTypeGoogle,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "INSERT INTO projections.idp_templates_google (idp_id, instance_id, client_id, client_secret, scopes) VALUES ($1, $2, $3, $4, $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"idp-id",
|
||||||
|
"instance-id",
|
||||||
|
"client_id",
|
||||||
|
anyArg{},
|
||||||
|
database.StringArray{"profile"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceGoogleIDPChanged minimal",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(instance.GoogleIDPChangedEventType),
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "idp-id",
|
||||||
|
"isCreationAllowed": true,
|
||||||
|
"clientID": "id"
|
||||||
|
}`),
|
||||||
|
), instance.GoogleIDPChangedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: (&idpTemplateProjection{}).reduceGoogleIDPChanged,
|
||||||
|
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_google SET client_id = $1 WHERE (idp_id = $2) AND (instance_id = $3)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"id",
|
||||||
|
"idp-id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance reduceGoogleIDPChanged",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(instance.GoogleIDPChangedEventType),
|
||||||
|
instance.AggregateType,
|
||||||
|
[]byte(`{
|
||||||
|
"id": "idp-id",
|
||||||
|
"clientID": "client_id",
|
||||||
|
"clientSecret": {
|
||||||
|
"cryptoType": 0,
|
||||||
|
"algorithm": "RSA-265",
|
||||||
|
"keyId": "key-id"
|
||||||
|
},
|
||||||
|
"scopes": ["profile"],
|
||||||
|
"isCreationAllowed": true,
|
||||||
|
"isLinkingAllowed": true,
|
||||||
|
"isAutoCreation": true,
|
||||||
|
"isAutoUpdate": true
|
||||||
|
}`),
|
||||||
|
), instance.GoogleIDPChangedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: (&idpTemplateProjection{}).reduceGoogleIDPChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
previousSequence: 10,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.idp_templates SET (is_creation_allowed, is_linking_allowed, is_auto_creation, is_auto_update, change_date, sequence) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (instance_id = $8)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
"idp-id",
|
||||||
|
"instance-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE projections.idp_templates_google SET (client_id, client_secret, scopes) = ($1, $2, $3) WHERE (idp_id = $4) AND (instance_id = $5)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"client_id",
|
||||||
|
anyArg{},
|
||||||
|
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_reducesLDAP(t *testing.T) {
|
func TestIDPTemplateProjection_reducesLDAP(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
event func(t *testing.T) eventstore.Event
|
event func(t *testing.T) eventstore.Event
|
||||||
|
143
internal/repository/idp/google.go
Normal file
143
internal/repository/idp/google.go
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
package idp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoogleIDPAddedEvent struct {
|
||||||
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
ClientID string `json:"clientID"`
|
||||||
|
ClientSecret *crypto.CryptoValue `json:"clientSecret"`
|
||||||
|
Scopes []string `json:"scopes,omitempty"`
|
||||||
|
Options
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleIDPAddedEvent(
|
||||||
|
base *eventstore.BaseEvent,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID string,
|
||||||
|
clientSecret *crypto.CryptoValue,
|
||||||
|
scopes []string,
|
||||||
|
options Options,
|
||||||
|
) *GoogleIDPAddedEvent {
|
||||||
|
return &GoogleIDPAddedEvent{
|
||||||
|
BaseEvent: *base,
|
||||||
|
ID: id,
|
||||||
|
Name: name,
|
||||||
|
ClientID: clientID,
|
||||||
|
ClientSecret: clientSecret,
|
||||||
|
Scopes: scopes,
|
||||||
|
Options: options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *GoogleIDPAddedEvent) Data() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *GoogleIDPAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoogleIDPAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e := &GoogleIDPAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(event.Data, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "IDP-SAff1", "unable to unmarshal event")
|
||||||
|
}
|
||||||
|
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoogleIDPChangedEvent struct {
|
||||||
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
ClientID *string `json:"clientID,omitempty"`
|
||||||
|
ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"`
|
||||||
|
Scopes []string `json:"scopes,omitempty"`
|
||||||
|
OptionChanges
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleIDPChangedEvent(
|
||||||
|
base *eventstore.BaseEvent,
|
||||||
|
id string,
|
||||||
|
changes []GoogleIDPChanges,
|
||||||
|
) (*GoogleIDPChangedEvent, error) {
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "IDP-Dg3qs", "Errors.NoChangesFound")
|
||||||
|
}
|
||||||
|
changedEvent := &GoogleIDPChangedEvent{
|
||||||
|
BaseEvent: *base,
|
||||||
|
ID: id,
|
||||||
|
}
|
||||||
|
for _, change := range changes {
|
||||||
|
change(changedEvent)
|
||||||
|
}
|
||||||
|
return changedEvent, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoogleIDPChanges func(*GoogleIDPChangedEvent)
|
||||||
|
|
||||||
|
func ChangeGoogleName(name string) func(*GoogleIDPChangedEvent) {
|
||||||
|
return func(e *GoogleIDPChangedEvent) {
|
||||||
|
e.Name = &name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func ChangeGoogleClientID(clientID string) func(*GoogleIDPChangedEvent) {
|
||||||
|
return func(e *GoogleIDPChangedEvent) {
|
||||||
|
e.ClientID = &clientID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeGoogleClientSecret(clientSecret *crypto.CryptoValue) func(*GoogleIDPChangedEvent) {
|
||||||
|
return func(e *GoogleIDPChangedEvent) {
|
||||||
|
e.ClientSecret = clientSecret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeGoogleScopes(scopes []string) func(*GoogleIDPChangedEvent) {
|
||||||
|
return func(e *GoogleIDPChangedEvent) {
|
||||||
|
e.Scopes = scopes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeGoogleOptions(options OptionChanges) func(*GoogleIDPChangedEvent) {
|
||||||
|
return func(e *GoogleIDPChangedEvent) {
|
||||||
|
e.OptionChanges = options
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *GoogleIDPChangedEvent) Data() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *GoogleIDPChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoogleIDPChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e := &GoogleIDPChangedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(event.Data, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "IDP-SF3t2", "unable to unmarshal event")
|
||||||
|
}
|
||||||
|
|
||||||
|
return e, nil
|
||||||
|
}
|
@ -70,6 +70,8 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
|||||||
RegisterFilterEventMapper(AggregateType, IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, IDPJWTConfigAddedEventType, IDPJWTConfigAddedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPJWTConfigAddedEventType, IDPJWTConfigAddedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, IDPJWTConfigChangedEventType, IDPJWTConfigChangedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPJWTConfigChangedEventType, IDPJWTConfigChangedEventMapper).
|
||||||
|
RegisterFilterEventMapper(AggregateType, GoogleIDPAddedEventType, GoogleIDPAddedEventMapper).
|
||||||
|
RegisterFilterEventMapper(AggregateType, GoogleIDPChangedEventType, GoogleIDPChangedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, LDAPIDPAddedEventType, LDAPIDPAddedEventMapper).
|
RegisterFilterEventMapper(AggregateType, LDAPIDPAddedEventType, LDAPIDPAddedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, LDAPIDPChangedEventType, LDAPIDPChangedEventMapper).
|
RegisterFilterEventMapper(AggregateType, LDAPIDPChangedEventType, LDAPIDPChangedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, IDPRemovedEventType, IDPRemovedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPRemovedEventType, IDPRemovedEventMapper).
|
||||||
|
@ -10,11 +10,89 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LDAPIDPAddedEventType eventstore.EventType = "instance.idp.ldap.added"
|
GoogleIDPAddedEventType eventstore.EventType = "instance.idp.google.added"
|
||||||
LDAPIDPChangedEventType eventstore.EventType = "instance.idp.ldap.changed"
|
GoogleIDPChangedEventType eventstore.EventType = "instance.idp.google.changed"
|
||||||
IDPRemovedEventType eventstore.EventType = "instance.idp.removed"
|
LDAPIDPAddedEventType eventstore.EventType = "instance.idp.ldap.added"
|
||||||
|
LDAPIDPChangedEventType eventstore.EventType = "instance.idp.ldap.changed"
|
||||||
|
IDPRemovedEventType eventstore.EventType = "instance.idp.removed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GoogleIDPAddedEvent struct {
|
||||||
|
idp.GoogleIDPAddedEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleIDPAddedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID string,
|
||||||
|
clientSecret *crypto.CryptoValue,
|
||||||
|
scopes []string,
|
||||||
|
options idp.Options,
|
||||||
|
) *GoogleIDPAddedEvent {
|
||||||
|
|
||||||
|
return &GoogleIDPAddedEvent{
|
||||||
|
GoogleIDPAddedEvent: *idp.NewGoogleIDPAddedEvent(
|
||||||
|
eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
GoogleIDPAddedEventType,
|
||||||
|
),
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID,
|
||||||
|
clientSecret,
|
||||||
|
scopes,
|
||||||
|
options,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoogleIDPAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e, err := idp.GoogleIDPAddedEventMapper(event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GoogleIDPAddedEvent{GoogleIDPAddedEvent: *e.(*idp.GoogleIDPAddedEvent)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoogleIDPChangedEvent struct {
|
||||||
|
idp.GoogleIDPChangedEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleIDPChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id string,
|
||||||
|
changes []idp.GoogleIDPChanges,
|
||||||
|
) (*GoogleIDPChangedEvent, error) {
|
||||||
|
|
||||||
|
changedEvent, err := idp.NewGoogleIDPChangedEvent(
|
||||||
|
eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
GoogleIDPChangedEventType,
|
||||||
|
),
|
||||||
|
id,
|
||||||
|
changes,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &GoogleIDPChangedEvent{GoogleIDPChangedEvent: *changedEvent}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoogleIDPChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e, err := idp.GoogleIDPChangedEventMapper(event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GoogleIDPChangedEvent{GoogleIDPChangedEvent: *e.(*idp.GoogleIDPChangedEvent)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
type LDAPIDPAddedEvent struct {
|
type LDAPIDPAddedEvent struct {
|
||||||
idp.LDAPIDPAddedEvent
|
idp.LDAPIDPAddedEvent
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,8 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
|||||||
RegisterFilterEventMapper(AggregateType, IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, IDPJWTConfigAddedEventType, IDPJWTConfigAddedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPJWTConfigAddedEventType, IDPJWTConfigAddedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, IDPJWTConfigChangedEventType, IDPJWTConfigChangedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPJWTConfigChangedEventType, IDPJWTConfigChangedEventMapper).
|
||||||
|
RegisterFilterEventMapper(AggregateType, GoogleIDPAddedEventType, GoogleIDPAddedEventMapper).
|
||||||
|
RegisterFilterEventMapper(AggregateType, GoogleIDPChangedEventType, GoogleIDPChangedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, LDAPIDPAddedEventType, LDAPIDPAddedEventMapper).
|
RegisterFilterEventMapper(AggregateType, LDAPIDPAddedEventType, LDAPIDPAddedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, LDAPIDPChangedEventType, LDAPIDPChangedEventMapper).
|
RegisterFilterEventMapper(AggregateType, LDAPIDPChangedEventType, LDAPIDPChangedEventMapper).
|
||||||
RegisterFilterEventMapper(AggregateType, IDPRemovedEventType, IDPRemovedEventMapper).
|
RegisterFilterEventMapper(AggregateType, IDPRemovedEventType, IDPRemovedEventMapper).
|
||||||
|
@ -10,11 +10,89 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LDAPIDPAddedEventType eventstore.EventType = "org.idp.ldap.added"
|
GoogleIDPAddedEventType eventstore.EventType = "org.idp.google.added"
|
||||||
LDAPIDPChangedEventType eventstore.EventType = "org.idp.ldap.changed"
|
GoogleIDPChangedEventType eventstore.EventType = "org.idp.google.changed"
|
||||||
IDPRemovedEventType eventstore.EventType = "org.idp.removed"
|
LDAPIDPAddedEventType eventstore.EventType = "org.idp.ldap.added"
|
||||||
|
LDAPIDPChangedEventType eventstore.EventType = "org.idp.ldap.changed"
|
||||||
|
IDPRemovedEventType eventstore.EventType = "org.idp.removed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GoogleIDPAddedEvent struct {
|
||||||
|
idp.GoogleIDPAddedEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleIDPAddedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID string,
|
||||||
|
clientSecret *crypto.CryptoValue,
|
||||||
|
scopes []string,
|
||||||
|
options idp.Options,
|
||||||
|
) *GoogleIDPAddedEvent {
|
||||||
|
|
||||||
|
return &GoogleIDPAddedEvent{
|
||||||
|
GoogleIDPAddedEvent: *idp.NewGoogleIDPAddedEvent(
|
||||||
|
eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
GoogleIDPAddedEventType,
|
||||||
|
),
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
clientID,
|
||||||
|
clientSecret,
|
||||||
|
scopes,
|
||||||
|
options,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoogleIDPAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e, err := idp.GoogleIDPAddedEventMapper(event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GoogleIDPAddedEvent{GoogleIDPAddedEvent: *e.(*idp.GoogleIDPAddedEvent)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoogleIDPChangedEvent struct {
|
||||||
|
idp.GoogleIDPChangedEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoogleIDPChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
id string,
|
||||||
|
changes []idp.GoogleIDPChanges,
|
||||||
|
) (*GoogleIDPChangedEvent, error) {
|
||||||
|
|
||||||
|
changedEvent, err := idp.NewGoogleIDPChangedEvent(
|
||||||
|
eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
GoogleIDPChangedEventType,
|
||||||
|
),
|
||||||
|
id,
|
||||||
|
changes,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &GoogleIDPChangedEvent{GoogleIDPChangedEvent: *changedEvent}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoogleIDPChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e, err := idp.GoogleIDPChangedEventMapper(event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GoogleIDPChangedEvent{GoogleIDPChangedEvent: *e.(*idp.GoogleIDPChangedEvent)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
type LDAPIDPAddedEvent struct {
|
type LDAPIDPAddedEvent struct {
|
||||||
idp.LDAPIDPAddedEvent
|
idp.LDAPIDPAddedEvent
|
||||||
}
|
}
|
||||||
|
@ -1033,7 +1033,31 @@ service AdminService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new ldap identity provider on the instance
|
// Add a new Google identity provider on the instance
|
||||||
|
rpc AddGoogleProvider(AddGoogleProviderRequest) returns (AddGoogleProviderResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/idps/google"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.idp.write"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change an existing Google identity provider on the instance
|
||||||
|
rpc UpdateGoogleProvider(UpdateGoogleProviderRequest) returns (UpdateGoogleProviderResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put: "/idps/google/{id}"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.idp.write"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new LDAP identity provider on the instance
|
||||||
rpc AddLDAPProvider(AddLDAPProviderRequest) returns (AddLDAPProviderResponse) {
|
rpc AddLDAPProvider(AddLDAPProviderRequest) returns (AddLDAPProviderResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/idps/ldap"
|
post: "/idps/ldap"
|
||||||
@ -1045,7 +1069,7 @@ service AdminService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change an existing ldap identity provider on the instance
|
// Change an existing LDAP identity provider on the instance
|
||||||
rpc UpdateLDAPProvider(UpdateLDAPProviderRequest) returns (UpdateLDAPProviderResponse) {
|
rpc UpdateLDAPProvider(UpdateLDAPProviderRequest) returns (UpdateLDAPProviderResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
put: "/idps/ldap/{id}"
|
put: "/idps/ldap/{id}"
|
||||||
@ -3710,6 +3734,34 @@ message GetProviderByIDResponse {
|
|||||||
zitadel.idp.v1.Provider idp = 1;
|
zitadel.idp.v1.Provider idp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message AddGoogleProviderRequest {
|
||||||
|
// Google will be used as default, if no name is provided
|
||||||
|
string name = 1 [(validate.rules).string = {max_len: 200}];
|
||||||
|
string client_id = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
string client_secret = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
repeated string scopes = 4 [(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}}];
|
||||||
|
zitadel.idp.v1.Options provider_options = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddGoogleProviderResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
string id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateGoogleProviderRequest {
|
||||||
|
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
string name = 2 [(validate.rules).string = {max_len: 200}];
|
||||||
|
string client_id = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
// client_secret will only be updated if provided
|
||||||
|
string client_secret = 4 [(validate.rules).string = {max_len: 200}];
|
||||||
|
repeated string scopes = 5 [(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}}];
|
||||||
|
zitadel.idp.v1.Options provider_options = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateGoogleProviderResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message AddLDAPProviderRequest {
|
message AddLDAPProviderRequest {
|
||||||
string name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
string host = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string host = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
@ -262,9 +262,15 @@ message ProviderConfig {
|
|||||||
Options options = 1;
|
Options options = 1;
|
||||||
oneof config {
|
oneof config {
|
||||||
LDAPConfig ldap = 2;
|
LDAPConfig ldap = 2;
|
||||||
|
GoogleConfig google = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GoogleConfig {
|
||||||
|
string client_id = 1;
|
||||||
|
repeated string scopes = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message LDAPConfig {
|
message LDAPConfig {
|
||||||
string host = 1;
|
string host = 1;
|
||||||
string port = 2;
|
string port = 2;
|
||||||
|
@ -3031,7 +3031,32 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new ldap identity provider in the organisation
|
|
||||||
|
// Add a new Google identity provider in the organisation
|
||||||
|
rpc AddGoogleProvider(AddGoogleProviderRequest) returns (AddGoogleProviderResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/idps/google"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "org.idp.write"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change an existing Google identity provider in the organisation
|
||||||
|
rpc UpdateGoogleProvider(UpdateGoogleProviderRequest) returns (UpdateGoogleProviderResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put: "/idps/google/{id}"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "org.idp.write"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new LDAP identity provider in the organisation
|
||||||
rpc AddLDAPProvider(AddLDAPProviderRequest) returns (AddLDAPProviderResponse) {
|
rpc AddLDAPProvider(AddLDAPProviderRequest) returns (AddLDAPProviderResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/idps/ldap"
|
post: "/idps/ldap"
|
||||||
@ -3043,7 +3068,7 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change an existing ldap identity provider in the organisation
|
// Change an existing LDAP identity provider in the organisation
|
||||||
rpc UpdateLDAPProvider(UpdateLDAPProviderRequest) returns (UpdateLDAPProviderResponse) {
|
rpc UpdateLDAPProvider(UpdateLDAPProviderRequest) returns (UpdateLDAPProviderResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
put: "/idps/ldap/{id}"
|
put: "/idps/ldap/{id}"
|
||||||
@ -6008,6 +6033,34 @@ message GetProviderByIDResponse {
|
|||||||
zitadel.idp.v1.Provider idp = 1;
|
zitadel.idp.v1.Provider idp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message AddGoogleProviderRequest {
|
||||||
|
// Google will be used as default, if no name is provided
|
||||||
|
string name = 1 [(validate.rules).string = {max_len: 200}];
|
||||||
|
string client_id = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
string client_secret = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
repeated string scopes = 4 [(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}}];
|
||||||
|
zitadel.idp.v1.Options provider_options = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddGoogleProviderResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
string id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateGoogleProviderRequest {
|
||||||
|
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
string name = 2 [(validate.rules).string = {max_len: 200}];
|
||||||
|
string client_id = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
// client_secret will only be updated if provided
|
||||||
|
string client_secret = 4 [(validate.rules).string = {max_len: 200}];
|
||||||
|
repeated string scopes = 5 [(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}}];
|
||||||
|
zitadel.idp.v1.Options provider_options = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateGoogleProviderResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message AddLDAPProviderRequest {
|
message AddLDAPProviderRequest {
|
||||||
string name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
string host = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string host = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user