mirror of
https://github.com/zitadel/zitadel.git
synced 2025-06-03 03:20:40 +00:00
feat: select idp and auto register (#2336)
* faet: auto regsiter config on idp * feat: auto register on login * feat: auto register on register * feat: redirect to selected identity provider * fix: test * fix: test * fix: user by id request org id * fix: migration version and test Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
parent
79fb8aa37a
commit
e4bdaf26b0
@ -30,5 +30,6 @@ In addition to the standard compliant scopes we utilize the following scopes.
|
|||||||
| `urn:zitadel:iam:org:project:id:{projectid}:aud` | ZITADEL's Project id is `urn:zitadel:iam:org:project:id:69234237810729019:aud` | By adding this scope, the requested projectid will be added to the audience of the access and id token |
|
| `urn:zitadel:iam:org:project:id:{projectid}:aud` | ZITADEL's Project id is `urn:zitadel:iam:org:project:id:69234237810729019:aud` | By adding this scope, the requested projectid will be added to the audience of the access and id token |
|
||||||
| urn:zitadel:iam:user:metadata | `urn:zitadel:iam:user:metadata` | By adding this scope, the metadata of the user will be included in the token. The values are base64 encoded. |
|
| urn:zitadel:iam:user:metadata | `urn:zitadel:iam:user:metadata` | By adding this scope, the metadata of the user will be included in the token. The values are base64 encoded. |
|
||||||
| urn:zitadel:iam:user:resourceowner | `urn:zitadel:iam:user:resourceowner` | By adding this scope, the resourceowner (id, name, primary_domain) of the user will be included in the token. |
|
| urn:zitadel:iam:user:resourceowner | `urn:zitadel:iam:user:resourceowner` | By adding this scope, the resourceowner (id, name, primary_domain) of the user will be included in the token. |
|
||||||
|
| urn:zitadel:iam:org:idp:id:{idp_id} | `urn:zitadel:iam:org:idp:id:76625965177954913` | By adding this scope the user will directly be redirected to the identity provider to authenticate. Make sure you also send the primary domain scope if a custom login policy is configured. Otherwise the system will not be able to identify the identity provider. |
|
||||||
|
|
||||||
> If access to ZITADEL's API's is needed with a service user the scope `urn:zitadel:iam:org:project:id:69234237810729019:aud` needs to be used with the JWT Profile request
|
> If access to ZITADEL's API's is needed with a service user the scope `urn:zitadel:iam:org:project:id:69234237810729019:aud` needs to be used with the JWT Profile request
|
||||||
|
@ -1201,6 +1201,7 @@ This is an empty request
|
|||||||
| scopes | repeated string | - | |
|
| scopes | repeated string | - | |
|
||||||
| display_name_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
| display_name_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
||||||
| username_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
| username_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
||||||
|
| auto_register | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2887,6 +2888,7 @@ This is an empty request
|
|||||||
| idp_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
| idp_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
| styling_type | zitadel.idp.v1.IDPStylingType | - | enum.defined_only: true<br /> |
|
| styling_type | zitadel.idp.v1.IDPStylingType | - | enum.defined_only: true<br /> |
|
||||||
|
| auto_register | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ title: zitadel/idp.proto
|
|||||||
| styling_type | IDPStylingType | - | |
|
| styling_type | IDPStylingType | - | |
|
||||||
| owner | IDPOwnerType | - | |
|
| owner | IDPOwnerType | - | |
|
||||||
| [**oneof**](https://developers.google.com/protocol-buffers/docs/proto3#oneof) config.oidc_config | OIDCConfig | - | |
|
| [**oneof**](https://developers.google.com/protocol-buffers/docs/proto3#oneof) config.oidc_config | OIDCConfig | - | |
|
||||||
|
| auto_register | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3154,6 +3154,7 @@ This is an empty request
|
|||||||
| scopes | repeated string | - | |
|
| scopes | repeated string | - | |
|
||||||
| display_name_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
| display_name_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
||||||
| username_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
| username_mapping | zitadel.idp.v1.OIDCMappingField | - | enum.defined_only: true<br /> |
|
||||||
|
| auto_register | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -7379,6 +7380,7 @@ This is an empty request
|
|||||||
| idp_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
| idp_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
| styling_type | zitadel.idp.v1.IDPStylingType | - | enum.defined_only: true<br /> |
|
| styling_type | zitadel.idp.v1.IDPStylingType | - | enum.defined_only: true<br /> |
|
||||||
|
| auto_register | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,10 +12,11 @@ import (
|
|||||||
|
|
||||||
func addOIDCIDPRequestToDomain(req *admin_pb.AddOIDCIDPRequest) *domain.IDPConfig {
|
func addOIDCIDPRequestToDomain(req *admin_pb.AddOIDCIDPRequest) *domain.IDPConfig {
|
||||||
return &domain.IDPConfig{
|
return &domain.IDPConfig{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
OIDCConfig: addOIDCIDPRequestToDomainOIDCIDPConfig(req),
|
OIDCConfig: addOIDCIDPRequestToDomainOIDCIDPConfig(req),
|
||||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||||
Type: domain.IDPConfigTypeOIDC,
|
Type: domain.IDPConfigTypeOIDC,
|
||||||
|
AutoRegister: req.AutoRegister,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,9 +33,10 @@ func addOIDCIDPRequestToDomainOIDCIDPConfig(req *admin_pb.AddOIDCIDPRequest) *do
|
|||||||
|
|
||||||
func updateIDPToDomain(req *admin_pb.UpdateIDPRequest) *domain.IDPConfig {
|
func updateIDPToDomain(req *admin_pb.UpdateIDPRequest) *domain.IDPConfig {
|
||||||
return &domain.IDPConfig{
|
return &domain.IDPConfig{
|
||||||
IDPConfigID: req.IdpId,
|
IDPConfigID: req.IdpId,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||||
|
AutoRegister: req.AutoRegister,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ func Test_addOIDCIDPRequestToDomain(t *testing.T) {
|
|||||||
Scopes: []string{"email", "profile"},
|
Scopes: []string{"email", "profile"},
|
||||||
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
||||||
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -98,9 +99,10 @@ func Test_updateIDPToDomain(t *testing.T) {
|
|||||||
name: "all fields filled",
|
name: "all fields filled",
|
||||||
args: args{
|
args: args{
|
||||||
req: &admin_pb.UpdateIDPRequest{
|
req: &admin_pb.UpdateIDPRequest{
|
||||||
IdpId: "13523",
|
IdpId: "13523",
|
||||||
Name: "new name",
|
Name: "new name",
|
||||||
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
|
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -18,29 +18,31 @@ func IDPViewsToPb(idps []*iam_model.IDPConfigView) []*idp_pb.IDP {
|
|||||||
|
|
||||||
func ModelIDPViewToPb(idp *iam_model.IDPConfigView) *idp_pb.IDP {
|
func ModelIDPViewToPb(idp *iam_model.IDPConfigView) *idp_pb.IDP {
|
||||||
return &idp_pb.IDP{
|
return &idp_pb.IDP{
|
||||||
Id: idp.IDPConfigID,
|
Id: idp.IDPConfigID,
|
||||||
State: ModelIDPStateToPb(idp.State),
|
State: ModelIDPStateToPb(idp.State),
|
||||||
Name: idp.Name,
|
Name: idp.Name,
|
||||||
StylingType: ModelIDPStylingTypeToPb(idp.StylingType),
|
StylingType: ModelIDPStylingTypeToPb(idp.StylingType),
|
||||||
Owner: ModelIDPProviderTypeToPb(idp.IDPProviderType),
|
AutoRegister: idp.AutoRegister,
|
||||||
Config: ModelIDPViewToConfigPb(idp),
|
Owner: ModelIDPProviderTypeToPb(idp.IDPProviderType),
|
||||||
|
Config: ModelIDPViewToConfigPb(idp),
|
||||||
Details: obj_grpc.ToViewDetailsPb(
|
Details: obj_grpc.ToViewDetailsPb(
|
||||||
idp.Sequence,
|
idp.Sequence,
|
||||||
idp.CreationDate,
|
idp.CreationDate,
|
||||||
idp.ChangeDate,
|
idp.ChangeDate,
|
||||||
"", //TODO: backend
|
idp.AggregateID,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func IDPViewToPb(idp *domain.IDPConfigView) *idp_pb.IDP {
|
func IDPViewToPb(idp *domain.IDPConfigView) *idp_pb.IDP {
|
||||||
mapped := &idp_pb.IDP{
|
mapped := &idp_pb.IDP{
|
||||||
Id: idp.AggregateID,
|
Id: idp.AggregateID,
|
||||||
State: IDPStateToPb(idp.State),
|
State: IDPStateToPb(idp.State),
|
||||||
Name: idp.Name,
|
Name: idp.Name,
|
||||||
StylingType: IDPStylingTypeToPb(idp.StylingType),
|
StylingType: IDPStylingTypeToPb(idp.StylingType),
|
||||||
Config: IDPViewToConfigPb(idp),
|
AutoRegister: idp.AutoRegister,
|
||||||
Details: obj_grpc.ToViewDetailsPb(idp.Sequence, idp.CreationDate, idp.ChangeDate, ""), //TODO: resource owner in view
|
Config: IDPViewToConfigPb(idp),
|
||||||
|
Details: obj_grpc.ToViewDetailsPb(idp.Sequence, idp.CreationDate, idp.ChangeDate, idp.AggregateID),
|
||||||
}
|
}
|
||||||
return mapped
|
return mapped
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,10 @@ func addOIDCIDPRequestToDomainOIDCIDPConfig(req *mgmt_pb.AddOrgOIDCIDPRequest) *
|
|||||||
|
|
||||||
func updateIDPToDomain(req *mgmt_pb.UpdateOrgIDPRequest) *domain.IDPConfig {
|
func updateIDPToDomain(req *mgmt_pb.UpdateOrgIDPRequest) *domain.IDPConfig {
|
||||||
return &domain.IDPConfig{
|
return &domain.IDPConfig{
|
||||||
IDPConfigID: req.IdpId,
|
IDPConfigID: req.IdpId,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||||
|
AutoRegister: req.AutoRegister,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ func Test_addOIDCIDPRequestToDomain(t *testing.T) {
|
|||||||
Scopes: []string{"email", "profile"},
|
Scopes: []string{"email", "profile"},
|
||||||
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
|
||||||
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -45,6 +46,7 @@ func Test_addOIDCIDPRequestToDomain(t *testing.T) {
|
|||||||
"OIDCConfig.AuthorizationEndpoint",
|
"OIDCConfig.AuthorizationEndpoint",
|
||||||
"OIDCConfig.TokenEndpoint",
|
"OIDCConfig.TokenEndpoint",
|
||||||
"Type", //TODO: default (0) is oidc
|
"Type", //TODO: default (0) is oidc
|
||||||
|
"AutoRegister",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -98,9 +100,10 @@ func Test_updateIDPToDomain(t *testing.T) {
|
|||||||
name: "all fields filled",
|
name: "all fields filled",
|
||||||
args: args{
|
args: args{
|
||||||
req: &mgmt_pb.UpdateOrgIDPRequest{
|
req: &mgmt_pb.UpdateOrgIDPRequest{
|
||||||
IdpId: "13523",
|
IdpId: "13523",
|
||||||
Name: "new name",
|
Name: "new name",
|
||||||
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
|
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ package oidc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/caos/oidc/pkg/oidc"
|
"github.com/caos/oidc/pkg/oidc"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
http_utils "github.com/caos/zitadel/internal/api/http"
|
http_utils "github.com/caos/zitadel/internal/api/http"
|
||||||
|
model2 "github.com/caos/zitadel/internal/auth_request/model"
|
||||||
"github.com/caos/zitadel/internal/domain"
|
"github.com/caos/zitadel/internal/domain"
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/user/model"
|
"github.com/caos/zitadel/internal/user/model"
|
||||||
@ -113,18 +115,19 @@ func AuthRequestFromBusiness(authReq *domain.AuthRequest) (_ op.AuthRequest, err
|
|||||||
|
|
||||||
func CreateAuthRequestToBusiness(ctx context.Context, authReq *oidc.AuthRequest, userAgentID, userID string) *domain.AuthRequest {
|
func CreateAuthRequestToBusiness(ctx context.Context, authReq *oidc.AuthRequest, userAgentID, userID string) *domain.AuthRequest {
|
||||||
return &domain.AuthRequest{
|
return &domain.AuthRequest{
|
||||||
CreationDate: time.Now(),
|
CreationDate: time.Now(),
|
||||||
AgentID: userAgentID,
|
AgentID: userAgentID,
|
||||||
BrowserInfo: ParseBrowserInfoFromContext(ctx),
|
BrowserInfo: ParseBrowserInfoFromContext(ctx),
|
||||||
ApplicationID: authReq.ClientID,
|
ApplicationID: authReq.ClientID,
|
||||||
CallbackURI: authReq.RedirectURI,
|
CallbackURI: authReq.RedirectURI,
|
||||||
TransferState: authReq.State,
|
TransferState: authReq.State,
|
||||||
Prompt: PromptToBusiness(authReq.Prompt),
|
Prompt: PromptToBusiness(authReq.Prompt),
|
||||||
PossibleLOAs: ACRValuesToBusiness(authReq.ACRValues),
|
PossibleLOAs: ACRValuesToBusiness(authReq.ACRValues),
|
||||||
UiLocales: UILocalesToBusiness(authReq.UILocales),
|
UiLocales: UILocalesToBusiness(authReq.UILocales),
|
||||||
LoginHint: authReq.LoginHint,
|
LoginHint: authReq.LoginHint,
|
||||||
MaxAuthAge: MaxAgeToBusiness(authReq.MaxAge),
|
SelectedIDPConfigID: GetSelectedIDPIDFromScopes(authReq.Scopes),
|
||||||
UserID: userID,
|
MaxAuthAge: MaxAgeToBusiness(authReq.MaxAge),
|
||||||
|
UserID: userID,
|
||||||
Request: &domain.AuthRequestOIDC{
|
Request: &domain.AuthRequestOIDC{
|
||||||
Scopes: authReq.Scopes,
|
Scopes: authReq.Scopes,
|
||||||
ResponseType: ResponseTypeToBusiness(authReq.ResponseType),
|
ResponseType: ResponseTypeToBusiness(authReq.ResponseType),
|
||||||
@ -196,6 +199,15 @@ func UILocalesToBusiness(tags []language.Tag) []string {
|
|||||||
return locales
|
return locales
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSelectedIDPIDFromScopes(scopes oidc.SpaceDelimitedArray) string {
|
||||||
|
for _, scope := range scopes {
|
||||||
|
if strings.HasPrefix(scope, model2.SelectIDPScope) {
|
||||||
|
return strings.TrimPrefix(scope, model2.SelectIDPScope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func MaxAgeToBusiness(maxAge *uint) *time.Duration {
|
func MaxAgeToBusiness(maxAge *uint) *time.Duration {
|
||||||
if maxAge == nil {
|
if maxAge == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -106,6 +106,9 @@ func (c *Client) IsScopeAllowed(scope string) bool {
|
|||||||
if strings.HasPrefix(scope, authreq_model.ProjectIDScope) {
|
if strings.HasPrefix(scope, authreq_model.ProjectIDScope) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(scope, authreq_model.SelectIDPScope) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if strings.HasPrefix(scope, ScopeUserMetaData) {
|
if strings.HasPrefix(scope, ScopeUserMetaData) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ func (repo *AuthRequestRepo) CreateAuthRequest(ctx context.Context, request *dom
|
|||||||
err = repo.checkLoginName(ctx, request, request.LoginHint)
|
err = repo.checkLoginName(ctx, request, request.LoginHint)
|
||||||
logging.LogWithFields("EVENT-aG311", "login name", request.LoginHint, "id", request.ID, "applicationID", request.ApplicationID, "traceID", tracing.TraceIDFromCtx(ctx)).OnError(err).Debug("login hint invalid")
|
logging.LogWithFields("EVENT-aG311", "login name", request.LoginHint, "id", request.ID, "applicationID", request.ApplicationID, "traceID", tracing.TraceIDFromCtx(ctx)).OnError(err).Debug("login hint invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.AuthRequests.SaveAuthRequest(ctx, request)
|
err = repo.AuthRequests.SaveAuthRequest(ctx, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -642,7 +643,13 @@ func (repo *AuthRequestRepo) nextSteps(ctx context.Context, request *domain.Auth
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(users) > 0 || domain.IsPrompt(request.Prompt, domain.PromptSelectAccount) {
|
if domain.IsPrompt(request.Prompt, domain.PromptSelectAccount) {
|
||||||
|
steps = append(steps, &domain.SelectUserStep{Users: users})
|
||||||
|
}
|
||||||
|
if request.SelectedIDPConfigID != "" {
|
||||||
|
steps = append(steps, &domain.RedirectToExternalIDPStep{})
|
||||||
|
}
|
||||||
|
if len(request.Prompt) == 0 && len(users) > 0 {
|
||||||
steps = append(steps, &domain.SelectUserStep{Users: users})
|
steps = append(steps, &domain.SelectUserStep{Users: users})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,6 +305,15 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
[]domain.NextStep{&domain.ExternalNotFoundOptionStep{}},
|
[]domain.NextStep{&domain.ExternalNotFoundOptionStep{}},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"user not set no active session selected idp, redirect to external idp step",
|
||||||
|
fields{
|
||||||
|
userSessionViewProvider: &mockViewNoUserSession{},
|
||||||
|
},
|
||||||
|
args{&domain.AuthRequest{SelectedIDPConfigID: "id"}, false},
|
||||||
|
[]domain.NextStep{&domain.LoginStep{}, &domain.RedirectToExternalIDPStep{}},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"user not set, prompt select account and internal error, internal error",
|
"user not set, prompt select account and internal error, internal error",
|
||||||
fields{
|
fields{
|
||||||
|
@ -23,6 +23,7 @@ const (
|
|||||||
OrgDomainPrimaryClaim = "urn:zitadel:iam:org:domain:primary"
|
OrgDomainPrimaryClaim = "urn:zitadel:iam:org:domain:primary"
|
||||||
ProjectIDScope = "urn:zitadel:iam:org:project:id:"
|
ProjectIDScope = "urn:zitadel:iam:org:project:id:"
|
||||||
AudSuffix = ":aud"
|
AudSuffix = ":aud"
|
||||||
|
SelectIDPScope = "urn:zitadel:iam:org:idp:id:"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthRequestOIDC struct {
|
type AuthRequestOIDC struct {
|
||||||
|
@ -130,11 +130,12 @@ func writeModelToPrivacyPolicy(wm *PrivacyPolicyWriteModel) *domain.PrivacyPolic
|
|||||||
|
|
||||||
func writeModelToIDPConfig(wm *IDPConfigWriteModel) *domain.IDPConfig {
|
func writeModelToIDPConfig(wm *IDPConfigWriteModel) *domain.IDPConfig {
|
||||||
return &domain.IDPConfig{
|
return &domain.IDPConfig{
|
||||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||||
IDPConfigID: wm.ConfigID,
|
IDPConfigID: wm.ConfigID,
|
||||||
Name: wm.Name,
|
Name: wm.Name,
|
||||||
State: wm.State,
|
State: wm.State,
|
||||||
StylingType: wm.StylingType,
|
StylingType: wm.StylingType,
|
||||||
|
AutoRegister: wm.AutoRegister,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ func (c *Commands) AddDefaultIDPConfig(ctx context.Context, config *domain.IDPCo
|
|||||||
config.Name,
|
config.Name,
|
||||||
config.Type,
|
config.Type,
|
||||||
config.StylingType,
|
config.StylingType,
|
||||||
|
config.AutoRegister,
|
||||||
),
|
),
|
||||||
iam_repo.NewIDPOIDCConfigAddedEvent(
|
iam_repo.NewIDPOIDCConfigAddedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
@ -73,11 +74,11 @@ func (c *Commands) ChangeDefaultIDPConfig(ctx context.Context, config *domain.ID
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-4M9so", "Errors.IDPConfig.NotExisting")
|
return nil, caos_errs.ThrowNotFound(nil, "IAM-m0e3r", "Errors.IDPConfig.NotExisting")
|
||||||
}
|
}
|
||||||
|
|
||||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||||
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, iamAgg, config.IDPConfigID, config.Name, config.StylingType)
|
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, iamAgg, config.IDPConfigID, config.Name, config.StylingType, config.AutoRegister)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||||
}
|
}
|
||||||
@ -98,7 +99,7 @@ func (c *Commands) DeactivateDefaultIDPConfig(ctx context.Context, idpID string)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingIDP.State != domain.IDPConfigStateActive {
|
if existingIDP.State != domain.IDPConfigStateActive {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotActive")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-2n0fs", "Errors.IAM.IDPConfig.NotActive")
|
||||||
}
|
}
|
||||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||||
pushedEvents, err := c.eventstore.PushEvents(ctx, iam_repo.NewIDPConfigDeactivatedEvent(ctx, iamAgg, idpID))
|
pushedEvents, err := c.eventstore.PushEvents(ctx, iam_repo.NewIDPConfigDeactivatedEvent(ctx, iamAgg, idpID))
|
||||||
@ -173,7 +174,7 @@ func (c *Commands) getIAMIDPConfigByID(ctx context.Context, idpID string) (*doma
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !config.State.Exists() {
|
if !config.State.Exists() {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-4M9so", "Errors.IDPConfig.NotExisting")
|
return nil, caos_errs.ThrowNotFound(nil, "IAM-p0pFF", "Errors.IDPConfig.NotExisting")
|
||||||
}
|
}
|
||||||
return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil
|
return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@ func (wm *IAMIDPConfigWriteModel) NewChangedEvent(
|
|||||||
configID,
|
configID,
|
||||||
name string,
|
name string,
|
||||||
stylingType domain.IDPConfigStylingType,
|
stylingType domain.IDPConfigStylingType,
|
||||||
|
autoRegister bool,
|
||||||
) (*iam.IDPConfigChangedEvent, bool) {
|
) (*iam.IDPConfigChangedEvent, bool) {
|
||||||
|
|
||||||
changes := make([]idpconfig.IDPConfigChanges, 0)
|
changes := make([]idpconfig.IDPConfigChanges, 0)
|
||||||
@ -111,6 +112,9 @@ func (wm *IAMIDPConfigWriteModel) NewChangedEvent(
|
|||||||
if stylingType.Valid() && wm.StylingType != stylingType {
|
if stylingType.Valid() && wm.StylingType != stylingType {
|
||||||
changes = append(changes, idpconfig.ChangeStyleType(stylingType))
|
changes = append(changes, idpconfig.ChangeStyleType(stylingType))
|
||||||
}
|
}
|
||||||
|
if wm.AutoRegister != autoRegister {
|
||||||
|
changes = append(changes, idpconfig.ChangeAutoRegister(autoRegister))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ func TestCommandSide_AddDefaultIDPConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -99,8 +100,9 @@ func TestCommandSide_AddDefaultIDPConfig(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
config: &domain.IDPConfig{
|
config: &domain.IDPConfig{
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
StylingType: domain.IDPConfigStylingTypeGoogle,
|
StylingType: domain.IDPConfigStylingTypeGoogle,
|
||||||
|
AutoRegister: true,
|
||||||
OIDCConfig: &domain.OIDCIDPConfig{
|
OIDCConfig: &domain.OIDCIDPConfig{
|
||||||
ClientID: "clientid1",
|
ClientID: "clientid1",
|
||||||
Issuer: "issuer",
|
Issuer: "issuer",
|
||||||
@ -119,10 +121,11 @@ func TestCommandSide_AddDefaultIDPConfig(t *testing.T) {
|
|||||||
AggregateID: "IAM",
|
AggregateID: "IAM",
|
||||||
ResourceOwner: "IAM",
|
ResourceOwner: "IAM",
|
||||||
},
|
},
|
||||||
IDPConfigID: "config1",
|
IDPConfigID: "config1",
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
StylingType: domain.IDPConfigStylingTypeGoogle,
|
StylingType: domain.IDPConfigStylingTypeGoogle,
|
||||||
State: domain.IDPConfigStateActive,
|
State: domain.IDPConfigStateActive,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -212,6 +215,7 @@ func TestCommandSide_ChangeDefaultIDPConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -237,7 +241,7 @@ func TestCommandSide_ChangeDefaultIDPConfig(t *testing.T) {
|
|||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
newDefaultIDPConfigChangedEvent(context.Background(), "config1", "name1", "name2", domain.IDPConfigStylingTypeUnspecified),
|
newDefaultIDPConfigChangedEvent(context.Background(), "config1", "name1", "name2", domain.IDPConfigStylingTypeUnspecified, false),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
uniqueConstraintsFromEventConstraint(idpconfig.NewRemoveIDPConfigNameUniqueConstraint("name1", "IAM")),
|
uniqueConstraintsFromEventConstraint(idpconfig.NewRemoveIDPConfigNameUniqueConstraint("name1", "IAM")),
|
||||||
@ -248,9 +252,10 @@ func TestCommandSide_ChangeDefaultIDPConfig(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
config: &domain.IDPConfig{
|
config: &domain.IDPConfig{
|
||||||
IDPConfigID: "config1",
|
IDPConfigID: "config1",
|
||||||
Name: "name2",
|
Name: "name2",
|
||||||
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
AutoRegister: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -259,10 +264,11 @@ func TestCommandSide_ChangeDefaultIDPConfig(t *testing.T) {
|
|||||||
AggregateID: "IAM",
|
AggregateID: "IAM",
|
||||||
ResourceOwner: "IAM",
|
ResourceOwner: "IAM",
|
||||||
},
|
},
|
||||||
IDPConfigID: "config1",
|
IDPConfigID: "config1",
|
||||||
Name: "name2",
|
Name: "name2",
|
||||||
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
||||||
State: domain.IDPConfigStateActive,
|
State: domain.IDPConfigStateActive,
|
||||||
|
AutoRegister: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -286,7 +292,7 @@ func TestCommandSide_ChangeDefaultIDPConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDefaultIDPConfigChangedEvent(ctx context.Context, configID, oldName, newName string, stylingType domain.IDPConfigStylingType) *iam.IDPConfigChangedEvent {
|
func newDefaultIDPConfigChangedEvent(ctx context.Context, configID, oldName, newName string, stylingType domain.IDPConfigStylingType, autoRegister bool) *iam.IDPConfigChangedEvent {
|
||||||
event, _ := iam.NewIDPConfigChangedEvent(ctx,
|
event, _ := iam.NewIDPConfigChangedEvent(ctx,
|
||||||
&iam.NewAggregate().Aggregate,
|
&iam.NewAggregate().Aggregate,
|
||||||
configID,
|
configID,
|
||||||
@ -294,6 +300,7 @@ func newDefaultIDPConfigChangedEvent(ctx context.Context, configID, oldName, new
|
|||||||
[]idpconfig.IDPConfigChanges{
|
[]idpconfig.IDPConfigChanges{
|
||||||
idpconfig.ChangeName(newName),
|
idpconfig.ChangeName(newName),
|
||||||
idpconfig.ChangeStyleType(stylingType),
|
idpconfig.ChangeStyleType(stylingType),
|
||||||
|
idpconfig.ChangeAutoRegister(autoRegister),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return event
|
return event
|
||||||
|
@ -84,6 +84,7 @@ func TestCommandSide_ChangeDefaultIDPOIDCConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -138,6 +139,7 @@ func TestCommandSide_ChangeDefaultIDPOIDCConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -193,6 +195,7 @@ func TestCommandSide_ChangeDefaultIDPOIDCConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
|
@ -344,6 +344,7 @@ func TestCommandSide_AddIDPProviderDefaultLoginPolicy(t *testing.T) {
|
|||||||
"name",
|
"name",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeUnspecified,
|
domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -391,6 +392,7 @@ func TestCommandSide_AddIDPProviderDefaultLoginPolicy(t *testing.T) {
|
|||||||
"name",
|
"name",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeUnspecified,
|
domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -11,9 +11,10 @@ type IDPConfigWriteModel struct {
|
|||||||
|
|
||||||
State domain.IDPConfigState
|
State domain.IDPConfigState
|
||||||
|
|
||||||
ConfigID string
|
ConfigID string
|
||||||
Name string
|
Name string
|
||||||
StylingType domain.IDPConfigStylingType
|
AutoRegister bool
|
||||||
|
StylingType domain.IDPConfigStylingType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
func (rm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
@ -42,6 +43,7 @@ func (rm *IDPConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.IDPConfigAdde
|
|||||||
rm.ConfigID = e.ConfigID
|
rm.ConfigID = e.ConfigID
|
||||||
rm.Name = e.Name
|
rm.Name = e.Name
|
||||||
rm.StylingType = e.StylingType
|
rm.StylingType = e.StylingType
|
||||||
|
rm.AutoRegister = e.AutoRegister
|
||||||
rm.State = domain.IDPConfigStateActive
|
rm.State = domain.IDPConfigStateActive
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +54,9 @@ func (rm *IDPConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigCh
|
|||||||
if e.StylingType != nil && e.StylingType.Valid() {
|
if e.StylingType != nil && e.StylingType.Valid() {
|
||||||
rm.StylingType = *e.StylingType
|
rm.StylingType = *e.StylingType
|
||||||
}
|
}
|
||||||
|
if e.AutoRegister != nil {
|
||||||
|
rm.AutoRegister = *e.AutoRegister
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *IDPConfigWriteModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) {
|
func (rm *IDPConfigWriteModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) {
|
||||||
|
@ -40,6 +40,7 @@ func (c *Commands) AddIDPConfig(ctx context.Context, config *domain.IDPConfig, r
|
|||||||
config.Name,
|
config.Name,
|
||||||
config.Type,
|
config.Type,
|
||||||
config.StylingType,
|
config.StylingType,
|
||||||
|
config.AutoRegister,
|
||||||
),
|
),
|
||||||
org_repo.NewIDPOIDCConfigAddedEvent(
|
org_repo.NewIDPOIDCConfigAddedEvent(
|
||||||
ctx,
|
ctx,
|
||||||
@ -69,12 +70,12 @@ func (c *Commands) ChangeIDPConfig(ctx context.Context, config *domain.IDPConfig
|
|||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-Gh8ds", "Errors.ResourceOwnerMissing")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-Gh8ds", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
existingIDP, err := c.orgIDPConfigWriteModelByID(ctx, config.IDPConfigID, config.AggregateID)
|
existingIDP, err := c.orgIDPConfigWriteModelByID(ctx, config.IDPConfigID, resourceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotExisting")
|
return nil, caos_errs.ThrowNotFound(nil, "Org-1J9fs", "Errors.Org.IDPConfig.NotExisting")
|
||||||
}
|
}
|
||||||
|
|
||||||
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||||
@ -83,7 +84,8 @@ func (c *Commands) ChangeIDPConfig(ctx context.Context, config *domain.IDPConfig
|
|||||||
orgAgg,
|
orgAgg,
|
||||||
config.IDPConfigID,
|
config.IDPConfigID,
|
||||||
config.Name,
|
config.Name,
|
||||||
config.StylingType)
|
config.StylingType,
|
||||||
|
config.AutoRegister)
|
||||||
|
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged")
|
||||||
@ -105,7 +107,7 @@ func (c *Commands) DeactivateIDPConfig(ctx context.Context, idpID, orgID string)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingIDP.State != domain.IDPConfigStateActive {
|
if existingIDP.State != domain.IDPConfigStateActive {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotActive")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-BBmd0", "Errors.Org.IDPConfig.NotActive")
|
||||||
}
|
}
|
||||||
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||||
pushedEvents, err := c.eventstore.PushEvents(ctx, org_repo.NewIDPConfigDeactivatedEvent(ctx, orgAgg, idpID))
|
pushedEvents, err := c.eventstore.PushEvents(ctx, org_repo.NewIDPConfigDeactivatedEvent(ctx, orgAgg, idpID))
|
||||||
@ -185,7 +187,7 @@ func (c *Commands) getOrgIDPConfigByID(ctx context.Context, idpID, orgID string)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !config.State.Exists() {
|
if !config.State.Exists() {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "ORG-4M9so", "Errors.Org.IDPConfig.NotExisting")
|
return nil, caos_errs.ThrowNotFound(nil, "ORG-2m90f", "Errors.Org.IDPConfig.NotExisting")
|
||||||
}
|
}
|
||||||
return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil
|
return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@ func (wm *OrgIDPConfigWriteModel) NewChangedEvent(
|
|||||||
configID,
|
configID,
|
||||||
name string,
|
name string,
|
||||||
stylingType domain.IDPConfigStylingType,
|
stylingType domain.IDPConfigStylingType,
|
||||||
|
autoRegister bool,
|
||||||
) (*org.IDPConfigChangedEvent, bool) {
|
) (*org.IDPConfigChangedEvent, bool) {
|
||||||
|
|
||||||
changes := make([]idpconfig.IDPConfigChanges, 0)
|
changes := make([]idpconfig.IDPConfigChanges, 0)
|
||||||
@ -111,6 +112,9 @@ func (wm *OrgIDPConfigWriteModel) NewChangedEvent(
|
|||||||
if stylingType.Valid() && wm.StylingType != stylingType {
|
if stylingType.Valid() && wm.StylingType != stylingType {
|
||||||
changes = append(changes, idpconfig.ChangeStyleType(stylingType))
|
changes = append(changes, idpconfig.ChangeStyleType(stylingType))
|
||||||
}
|
}
|
||||||
|
if wm.AutoRegister != autoRegister {
|
||||||
|
changes = append(changes, idpconfig.ChangeAutoRegister(autoRegister))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,9 @@ func TestCommandSide_AddIDPConfig(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
config: &domain.IDPConfig{
|
config: &domain.IDPConfig{
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
StylingType: domain.IDPConfigStylingTypeGoogle,
|
StylingType: domain.IDPConfigStylingTypeGoogle,
|
||||||
|
AutoRegister: true,
|
||||||
OIDCConfig: &domain.OIDCIDPConfig{
|
OIDCConfig: &domain.OIDCIDPConfig{
|
||||||
ClientID: "clientid1",
|
ClientID: "clientid1",
|
||||||
Issuer: "issuer",
|
Issuer: "issuer",
|
||||||
@ -96,6 +97,7 @@ func TestCommandSide_AddIDPConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -128,8 +130,9 @@ func TestCommandSide_AddIDPConfig(t *testing.T) {
|
|||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
config: &domain.IDPConfig{
|
config: &domain.IDPConfig{
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
StylingType: domain.IDPConfigStylingTypeGoogle,
|
StylingType: domain.IDPConfigStylingTypeGoogle,
|
||||||
|
AutoRegister: true,
|
||||||
OIDCConfig: &domain.OIDCIDPConfig{
|
OIDCConfig: &domain.OIDCIDPConfig{
|
||||||
ClientID: "clientid1",
|
ClientID: "clientid1",
|
||||||
Issuer: "issuer",
|
Issuer: "issuer",
|
||||||
@ -148,10 +151,11 @@ func TestCommandSide_AddIDPConfig(t *testing.T) {
|
|||||||
AggregateID: "org1",
|
AggregateID: "org1",
|
||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
},
|
},
|
||||||
IDPConfigID: "config1",
|
IDPConfigID: "config1",
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
StylingType: domain.IDPConfigStylingTypeGoogle,
|
StylingType: domain.IDPConfigStylingTypeGoogle,
|
||||||
State: domain.IDPConfigStateActive,
|
State: domain.IDPConfigStateActive,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -260,6 +264,7 @@ func TestCommandSide_ChangeIDPConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -297,9 +302,10 @@ func TestCommandSide_ChangeIDPConfig(t *testing.T) {
|
|||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
config: &domain.IDPConfig{
|
config: &domain.IDPConfig{
|
||||||
IDPConfigID: "config1",
|
IDPConfigID: "config1",
|
||||||
Name: "name2",
|
Name: "name2",
|
||||||
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -308,10 +314,11 @@ func TestCommandSide_ChangeIDPConfig(t *testing.T) {
|
|||||||
AggregateID: "org1",
|
AggregateID: "org1",
|
||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
},
|
},
|
||||||
IDPConfigID: "config1",
|
IDPConfigID: "config1",
|
||||||
Name: "name2",
|
Name: "name2",
|
||||||
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
StylingType: domain.IDPConfigStylingTypeUnspecified,
|
||||||
State: domain.IDPConfigStateActive,
|
State: domain.IDPConfigStateActive,
|
||||||
|
AutoRegister: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -104,6 +104,7 @@ func TestCommandSide_ChangeIDPOIDCConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -159,6 +160,7 @@ func TestCommandSide_ChangeIDPOIDCConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -215,6 +217,7 @@ func TestCommandSide_ChangeIDPOIDCConfig(t *testing.T) {
|
|||||||
"name1",
|
"name1",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeGoogle,
|
domain.IDPConfigStylingTypeGoogle,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
|
@ -659,6 +659,7 @@ func TestCommandSide_AddIDPProviderLoginPolicy(t *testing.T) {
|
|||||||
"name",
|
"name",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeUnspecified,
|
domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -710,6 +711,7 @@ func TestCommandSide_AddIDPProviderLoginPolicy(t *testing.T) {
|
|||||||
"name",
|
"name",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeUnspecified,
|
domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -164,6 +164,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
|||||||
"name",
|
"name",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeUnspecified,
|
domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -213,6 +214,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
|||||||
"name",
|
"name",
|
||||||
domain.IDPConfigTypeOIDC,
|
domain.IDPConfigTypeOIDC,
|
||||||
domain.IDPConfigStylingTypeUnspecified,
|
domain.IDPConfigStylingTypeUnspecified,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -9,12 +9,13 @@ import (
|
|||||||
|
|
||||||
type IDPConfig struct {
|
type IDPConfig struct {
|
||||||
es_models.ObjectRoot
|
es_models.ObjectRoot
|
||||||
IDPConfigID string
|
IDPConfigID string
|
||||||
Type IDPConfigType
|
Type IDPConfigType
|
||||||
Name string
|
Name string
|
||||||
StylingType IDPConfigStylingType
|
StylingType IDPConfigStylingType
|
||||||
State IDPConfigState
|
State IDPConfigState
|
||||||
OIDCConfig *OIDCIDPConfig
|
OIDCConfig *OIDCIDPConfig
|
||||||
|
AutoRegister bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type IDPConfigView struct {
|
type IDPConfigView struct {
|
||||||
@ -27,6 +28,7 @@ type IDPConfigView struct {
|
|||||||
ChangeDate time.Time
|
ChangeDate time.Time
|
||||||
Sequence uint64
|
Sequence uint64
|
||||||
IDPProviderType IdentityProviderType
|
IDPProviderType IdentityProviderType
|
||||||
|
AutoRegister bool
|
||||||
|
|
||||||
IsOIDC bool
|
IsOIDC bool
|
||||||
OIDCClientID string
|
OIDCClientID string
|
||||||
|
@ -27,6 +27,7 @@ const (
|
|||||||
NextStepPasswordlessRegistrationPrompt
|
NextStepPasswordlessRegistrationPrompt
|
||||||
NextStepRegistration
|
NextStepRegistration
|
||||||
NextStepProjectRequired
|
NextStepProjectRequired
|
||||||
|
NextStepRedirectToExternalIDP
|
||||||
)
|
)
|
||||||
|
|
||||||
type LoginStep struct{}
|
type LoginStep struct{}
|
||||||
@ -67,6 +68,12 @@ const (
|
|||||||
UserSessionStateTerminated
|
UserSessionStateTerminated
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type RedirectToExternalIDPStep struct{}
|
||||||
|
|
||||||
|
func (s *RedirectToExternalIDPStep) Type() NextStepType {
|
||||||
|
return NextStepRedirectToExternalIDP
|
||||||
|
}
|
||||||
|
|
||||||
type InitUserStep struct {
|
type InitUserStep struct {
|
||||||
PasswordSet bool
|
PasswordSet bool
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ type IDPConfigView struct {
|
|||||||
IDPConfigID string
|
IDPConfigID string
|
||||||
Name string
|
Name string
|
||||||
StylingType IDPStylingType
|
StylingType IDPStylingType
|
||||||
|
AutoRegister bool
|
||||||
State IDPConfigState
|
State IDPConfigState
|
||||||
CreationDate time.Time
|
CreationDate time.Time
|
||||||
ChangeDate time.Time
|
ChangeDate time.Time
|
||||||
|
@ -33,6 +33,7 @@ type IDPConfigView struct {
|
|||||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||||
IDPState int32 `json:"-" gorm:"column:idp_state"`
|
IDPState int32 `json:"-" gorm:"column:idp_state"`
|
||||||
IDPProviderType int32 `json:"-" gorm:"column:idp_provider_type"`
|
IDPProviderType int32 `json:"-" gorm:"column:idp_provider_type"`
|
||||||
|
AutoRegister bool `json:"autoRegister" gorm:"column:auto_register"`
|
||||||
|
|
||||||
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
|
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
|
||||||
OIDCClientID string `json:"clientId" gorm:"column:oidc_client_id"`
|
OIDCClientID string `json:"clientId" gorm:"column:oidc_client_id"`
|
||||||
@ -54,6 +55,7 @@ func IDPConfigViewToModel(idp *IDPConfigView) *model.IDPConfigView {
|
|||||||
State: model.IDPConfigState(idp.IDPState),
|
State: model.IDPConfigState(idp.IDPState),
|
||||||
Name: idp.Name,
|
Name: idp.Name,
|
||||||
StylingType: model.IDPStylingType(idp.StylingType),
|
StylingType: model.IDPStylingType(idp.StylingType),
|
||||||
|
AutoRegister: idp.AutoRegister,
|
||||||
Sequence: idp.Sequence,
|
Sequence: idp.Sequence,
|
||||||
CreationDate: idp.CreationDate,
|
CreationDate: idp.CreationDate,
|
||||||
ChangeDate: idp.ChangeDate,
|
ChangeDate: idp.ChangeDate,
|
||||||
|
@ -12,6 +12,7 @@ type IDPConfigReadModel struct {
|
|||||||
State domain.IDPConfigState
|
State domain.IDPConfigState
|
||||||
ConfigID string
|
ConfigID string
|
||||||
Name string
|
Name string
|
||||||
|
AutoRegister bool
|
||||||
StylingType domain.IDPConfigStylingType
|
StylingType domain.IDPConfigStylingType
|
||||||
ProviderType domain.IdentityProviderType
|
ProviderType domain.IdentityProviderType
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ func (rm *IDPConfigReadModel) reduceConfigAddedEvent(e *idpconfig.IDPConfigAdded
|
|||||||
rm.Name = e.Name
|
rm.Name = e.Name
|
||||||
rm.StylingType = e.StylingType
|
rm.StylingType = e.StylingType
|
||||||
rm.State = domain.IDPConfigStateActive
|
rm.State = domain.IDPConfigStateActive
|
||||||
|
rm.AutoRegister = e.AutoRegister
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *IDPConfigReadModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigChangedEvent) {
|
func (rm *IDPConfigReadModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigChangedEvent) {
|
||||||
@ -86,6 +88,9 @@ func (rm *IDPConfigReadModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigCha
|
|||||||
if e.StylingType != nil && e.StylingType.Valid() {
|
if e.StylingType != nil && e.StylingType.Valid() {
|
||||||
rm.StylingType = *e.StylingType
|
rm.StylingType = *e.StylingType
|
||||||
}
|
}
|
||||||
|
if e.AutoRegister != nil {
|
||||||
|
rm.AutoRegister = *e.AutoRegister
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *IDPConfigReadModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) {
|
func (rm *IDPConfigReadModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) {
|
||||||
|
@ -28,6 +28,7 @@ func NewIDPConfigAddedEvent(
|
|||||||
name string,
|
name string,
|
||||||
configType domain.IDPConfigType,
|
configType domain.IDPConfigType,
|
||||||
stylingType domain.IDPConfigStylingType,
|
stylingType domain.IDPConfigStylingType,
|
||||||
|
autoRegister bool,
|
||||||
) *IDPConfigAddedEvent {
|
) *IDPConfigAddedEvent {
|
||||||
|
|
||||||
return &IDPConfigAddedEvent{
|
return &IDPConfigAddedEvent{
|
||||||
@ -41,6 +42,7 @@ func NewIDPConfigAddedEvent(
|
|||||||
name,
|
name,
|
||||||
configType,
|
configType,
|
||||||
stylingType,
|
stylingType,
|
||||||
|
autoRegister,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,11 @@ func NewRemoveIDPConfigNameUniqueConstraint(idpConfigName, resourceOwner string)
|
|||||||
type IDPConfigAddedEvent struct {
|
type IDPConfigAddedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ConfigID string `json:"idpConfigId"`
|
ConfigID string `json:"idpConfigId"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Typ domain.IDPConfigType `json:"idpType,omitempty"`
|
Typ domain.IDPConfigType `json:"idpType,omitempty"`
|
||||||
StylingType domain.IDPConfigStylingType `json:"stylingType,omitempty"`
|
StylingType domain.IDPConfigStylingType `json:"stylingType,omitempty"`
|
||||||
|
AutoRegister bool `json:"autoRegister,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIDPConfigAddedEvent(
|
func NewIDPConfigAddedEvent(
|
||||||
@ -41,13 +42,15 @@ func NewIDPConfigAddedEvent(
|
|||||||
name string,
|
name string,
|
||||||
configType domain.IDPConfigType,
|
configType domain.IDPConfigType,
|
||||||
stylingType domain.IDPConfigStylingType,
|
stylingType domain.IDPConfigStylingType,
|
||||||
|
autoRegister bool,
|
||||||
) *IDPConfigAddedEvent {
|
) *IDPConfigAddedEvent {
|
||||||
return &IDPConfigAddedEvent{
|
return &IDPConfigAddedEvent{
|
||||||
BaseEvent: *base,
|
BaseEvent: *base,
|
||||||
ConfigID: configID,
|
ConfigID: configID,
|
||||||
Name: name,
|
Name: name,
|
||||||
StylingType: stylingType,
|
StylingType: stylingType,
|
||||||
Typ: configType,
|
Typ: configType,
|
||||||
|
AutoRegister: autoRegister,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +78,11 @@ func IDPConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader,
|
|||||||
type IDPConfigChangedEvent struct {
|
type IDPConfigChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ConfigID string `json:"idpConfigId"`
|
ConfigID string `json:"idpConfigId"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
StylingType *domain.IDPConfigStylingType `json:"stylingType,omitempty"`
|
StylingType *domain.IDPConfigStylingType `json:"stylingType,omitempty"`
|
||||||
oldName string `json:"-"`
|
AutoRegister *bool `json:"autoRegister,omitempty"`
|
||||||
|
oldName string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *IDPConfigChangedEvent) Data() interface{} {
|
func (e *IDPConfigChangedEvent) Data() interface{} {
|
||||||
@ -129,6 +133,12 @@ func ChangeStyleType(styleType domain.IDPConfigStylingType) func(*IDPConfigChang
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeAutoRegister(autoRegister bool) func(*IDPConfigChangedEvent) {
|
||||||
|
return func(e *IDPConfigChangedEvent) {
|
||||||
|
e.AutoRegister = &autoRegister
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func IDPConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func IDPConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e := &IDPConfigChangedEvent{
|
e := &IDPConfigChangedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
@ -28,6 +28,7 @@ func NewIDPConfigAddedEvent(
|
|||||||
name string,
|
name string,
|
||||||
configType domain.IDPConfigType,
|
configType domain.IDPConfigType,
|
||||||
stylingType domain.IDPConfigStylingType,
|
stylingType domain.IDPConfigStylingType,
|
||||||
|
autoRegister bool,
|
||||||
) *IDPConfigAddedEvent {
|
) *IDPConfigAddedEvent {
|
||||||
|
|
||||||
return &IDPConfigAddedEvent{
|
return &IDPConfigAddedEvent{
|
||||||
@ -41,6 +42,7 @@ func NewIDPConfigAddedEvent(
|
|||||||
name,
|
name,
|
||||||
configType,
|
configType,
|
||||||
stylingType,
|
stylingType,
|
||||||
|
autoRegister,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,16 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R
|
|||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
if !idpConfig.AutoRegister {
|
||||||
|
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID)
|
||||||
|
if err != nil {
|
||||||
|
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l.handleAutoRegister(w, r, authReq)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.renderNextStep(w, r, authReq)
|
l.renderNextStep(w, r, authReq)
|
||||||
|
@ -119,7 +119,27 @@ func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Reques
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
user, externalIDP := l.mapTokenToLoginHumanAndExternalIDP(orgIamPolicy, tokens, idpConfig)
|
user, externalIDP := l.mapTokenToLoginHumanAndExternalIDP(orgIamPolicy, tokens, idpConfig)
|
||||||
l.renderExternalRegisterOverview(w, r, authReq, orgIamPolicy, user, externalIDP, nil)
|
if !idpConfig.AutoRegister {
|
||||||
|
l.renderExternalRegisterOverview(w, r, authReq, orgIamPolicy, user, externalIDP, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l.registerExternalUser(w, r, authReq, iam, user, externalIDP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Login) registerExternalUser(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *iam_model.IAM, user *domain.Human, externalIDP *domain.ExternalIDP) {
|
||||||
|
resourceOwner := iam.GlobalOrgID
|
||||||
|
memberRoles := []string{domain.RoleOrgProjectCreator}
|
||||||
|
|
||||||
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
|
memberRoles = nil
|
||||||
|
resourceOwner = authReq.RequestedOrgID
|
||||||
|
}
|
||||||
|
_, err := l.command.RegisterHuman(setContext(r.Context(), resourceOwner), resourceOwner, user, externalIDP, memberRoles)
|
||||||
|
if err != nil {
|
||||||
|
l.renderRegisterOption(w, r, authReq, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l.renderNextStep(w, r, authReq)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) renderExternalRegisterOverview(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, orgIAMPolicy *iam_model.OrgIAMPolicyView, human *domain.Human, idp *domain.ExternalIDP, err error) {
|
func (l *Login) renderExternalRegisterOverview(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, orgIAMPolicy *iam_model.OrgIAMPolicyView, human *domain.Human, idp *domain.ExternalIDP, err error) {
|
||||||
|
@ -223,7 +223,7 @@ func (l *Login) renderNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||||
authReq, err := l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID)
|
authReq, err := l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(err, "APP-sio0W", "could not get authreq"))
|
l.renderInternalError(w, r, authReq, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(authReq.PossibleSteps) == 0 {
|
if len(authReq.PossibleSteps) == 0 {
|
||||||
@ -257,6 +257,8 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
l.renderRegisterOption(w, r, authReq, nil)
|
l.renderRegisterOption(w, r, authReq, nil)
|
||||||
case *domain.SelectUserStep:
|
case *domain.SelectUserStep:
|
||||||
l.renderUserSelection(w, r, authReq, step)
|
l.renderUserSelection(w, r, authReq, step)
|
||||||
|
case *domain.RedirectToExternalIDPStep:
|
||||||
|
l.handleIDP(w, r, authReq, authReq.SelectedIDPConfigID)
|
||||||
case *domain.InitPasswordStep:
|
case *domain.InitPasswordStep:
|
||||||
l.renderInitPassword(w, r, authReq, authReq.UserID, "", err)
|
l.renderInitPassword(w, r, authReq, authReq.UserID, "", err)
|
||||||
case *domain.PasswordStep:
|
case *domain.PasswordStep:
|
||||||
|
3
migrations/cockroach/V1.70__idp.sql
Normal file
3
migrations/cockroach/V1.70__idp.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
ALTER TABLE management.idp_configs ADD COLUMN auto_register BOOLEAN;
|
||||||
|
ALTER TABLE adminapi.idp_configs ADD COLUMN auto_register BOOLEAN;
|
||||||
|
ALTER TABLE auth.idp_configs ADD COLUMN auto_register BOOLEAN;
|
@ -2428,6 +2428,7 @@ message AddOIDCIDPRequest {
|
|||||||
description: "definition which field is mapped to the email of the user";
|
description: "definition which field is mapped to the email of the user";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
bool auto_register = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddOIDCIDPResponse {
|
message AddOIDCIDPResponse {
|
||||||
@ -2458,6 +2459,7 @@ message UpdateIDPRequest {
|
|||||||
description: "some identity providers specify the styling of the button to their login";
|
description: "some identity providers specify the styling of the button to their login";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
bool auto_register = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateIDPResponse {
|
message UpdateIDPResponse {
|
||||||
|
@ -38,6 +38,7 @@ message IDP {
|
|||||||
oneof config {
|
oneof config {
|
||||||
OIDCConfig oidc_config = 7;
|
OIDCConfig oidc_config = 7;
|
||||||
}
|
}
|
||||||
|
bool auto_register = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IDPUserLink {
|
message IDPUserLink {
|
||||||
|
@ -4884,6 +4884,7 @@ message AddOrgOIDCIDPRequest {
|
|||||||
description: "definition which field is mapped to the email of the user";
|
description: "definition which field is mapped to the email of the user";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
bool auto_register = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddOrgOIDCIDPResponse {
|
message AddOrgOIDCIDPResponse {
|
||||||
@ -4928,6 +4929,7 @@ message UpdateOrgIDPRequest {
|
|||||||
description: "some identity providers specify the styling of the button to their login";
|
description: "some identity providers specify the styling of the button to their login";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
bool auto_register = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateOrgIDPResponse {
|
message UpdateOrgIDPResponse {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user