mirror of
https://github.com/zitadel/zitadel.git
synced 2025-05-28 17:18:21 +00:00
fix: handle default org id (#3769)
This commit is contained in:
parent
ebb73186b6
commit
0baaaf8a05
@ -272,6 +272,30 @@ Checks whether an organisation exists by the given parameters
|
|||||||
GET: /orgs/_is_unique
|
GET: /orgs/_is_unique
|
||||||
|
|
||||||
|
|
||||||
|
### SetDefaultOrg
|
||||||
|
|
||||||
|
> **rpc** SetDefaultOrg([SetDefaultOrgRequest](#setdefaultorgrequest))
|
||||||
|
[SetDefaultOrgResponse](#setdefaultorgresponse)
|
||||||
|
|
||||||
|
Set the default org
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PUT: /orgs/default/{org_id}
|
||||||
|
|
||||||
|
|
||||||
|
### GetDefaultOrg
|
||||||
|
|
||||||
|
> **rpc** GetDefaultOrg([GetDefaultOrgRequest](#getdefaultorgrequest))
|
||||||
|
[GetDefaultOrgResponse](#getdefaultorgresponse)
|
||||||
|
|
||||||
|
Set the default org
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GET: /orgs/default
|
||||||
|
|
||||||
|
|
||||||
### ListOrgs
|
### ListOrgs
|
||||||
|
|
||||||
> **rpc** ListOrgs([ListOrgsRequest](#listorgsrequest))
|
> **rpc** ListOrgs([ListOrgsRequest](#listorgsrequest))
|
||||||
@ -1964,6 +1988,23 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetDefaultOrgRequest
|
||||||
|
This is an empty request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetDefaultOrgResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| org | zitadel.org.v1.Org | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetDefaultPasswordResetMessageTextRequest
|
### GetDefaultPasswordResetMessageTextRequest
|
||||||
|
|
||||||
|
|
||||||
@ -3256,6 +3297,28 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### SetDefaultOrgRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| org_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### SetDefaultOrgResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### SetDefaultPasswordResetMessageTextRequest
|
### SetDefaultPasswordResetMessageTextRequest
|
||||||
|
|
||||||
|
|
||||||
|
@ -4701,8 +4701,9 @@ This is an empty request
|
|||||||
|
|
||||||
| Field | Type | Description | Validation |
|
| Field | Type | Description | Validation |
|
||||||
| ----- | ---- | ----------- | ----------- |
|
| ----- | ---- | ----------- | ----------- |
|
||||||
| global_org_id | string | - | |
|
| global_org_id | string | deprecated: use default_org_id instead | |
|
||||||
| iam_project_id | string | - | |
|
| iam_project_id | string | - | |
|
||||||
|
| default_org_id | string | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ type Instance interface {
|
|||||||
RequestedDomain() string
|
RequestedDomain() string
|
||||||
RequestedHost() string
|
RequestedHost() string
|
||||||
DefaultLanguage() language.Tag
|
DefaultLanguage() language.Tag
|
||||||
|
DefaultOrganisationID() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type InstanceVerifier interface {
|
type InstanceVerifier interface {
|
||||||
@ -25,15 +26,16 @@ type InstanceVerifier interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type instance struct {
|
type instance struct {
|
||||||
ID string
|
id string
|
||||||
Domain string
|
domain string
|
||||||
projectID string
|
projectID string
|
||||||
appID string
|
appID string
|
||||||
clientID string
|
clientID string
|
||||||
|
orgID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *instance) InstanceID() string {
|
func (i *instance) InstanceID() string {
|
||||||
return i.ID
|
return i.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *instance) ProjectID() string {
|
func (i *instance) ProjectID() string {
|
||||||
@ -49,17 +51,21 @@ func (i *instance) ConsoleApplicationID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *instance) RequestedDomain() string {
|
func (i *instance) RequestedDomain() string {
|
||||||
return i.Domain
|
return i.domain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *instance) RequestedHost() string {
|
func (i *instance) RequestedHost() string {
|
||||||
return i.Domain
|
return i.domain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *instance) DefaultLanguage() language.Tag {
|
func (i *instance) DefaultLanguage() language.Tag {
|
||||||
return language.Und
|
return language.Und
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *instance) DefaultOrganisationID() string {
|
||||||
|
return i.orgID
|
||||||
|
}
|
||||||
|
|
||||||
func GetInstance(ctx context.Context) Instance {
|
func GetInstance(ctx context.Context) Instance {
|
||||||
instance, ok := ctx.Value(instanceKey).(Instance)
|
instance, ok := ctx.Value(instanceKey).(Instance)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -73,7 +79,7 @@ func WithInstance(ctx context.Context, instance Instance) context.Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WithInstanceID(ctx context.Context, id string) context.Context {
|
func WithInstanceID(ctx context.Context, id string) context.Context {
|
||||||
return context.WithValue(ctx, instanceKey, &instance{ID: id})
|
return context.WithValue(ctx, instanceKey, &instance{id: id})
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRequestedDomain(ctx context.Context, domain string) context.Context {
|
func WithRequestedDomain(ctx context.Context, domain string) context.Context {
|
||||||
@ -82,7 +88,7 @@ func WithRequestedDomain(ctx context.Context, domain string) context.Context {
|
|||||||
i = new(instance)
|
i = new(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
i.Domain = domain
|
i.domain = domain
|
||||||
return context.WithValue(ctx, instanceKey, i)
|
return context.WithValue(ctx, instanceKey, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,10 @@ func (m *mockInstance) DefaultLanguage() language.Tag {
|
|||||||
return language.English
|
return language.English
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockInstance) DefaultOrganisationID() string {
|
||||||
|
return "orgID"
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockInstance) RequestedDomain() string {
|
func (m *mockInstance) RequestedDomain() string {
|
||||||
return "zitadel.cloud"
|
return "zitadel.cloud"
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,21 @@ func (s *Server) IsOrgUnique(ctx context.Context, req *admin_pb.IsOrgUniqueReque
|
|||||||
return &admin_pb.IsOrgUniqueResponse{IsUnique: isUnique}, err
|
return &admin_pb.IsOrgUniqueResponse{IsUnique: isUnique}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) SetDefaultOrg(ctx context.Context, req *admin_pb.SetDefaultOrgRequest) (*admin_pb.SetDefaultOrgResponse, error) {
|
||||||
|
details, err := s.command.SetDefaultOrg(ctx, req.OrgId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.SetDefaultOrgResponse{
|
||||||
|
Details: object.DomainToChangeDetailsPb(details),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetDefaultOrg(ctx context.Context, _ *admin_pb.GetDefaultOrgRequest) (*admin_pb.GetDefaultOrgResponse, error) {
|
||||||
|
org, err := s.query.OrgByID(ctx, authz.GetInstance(ctx).DefaultOrganisationID())
|
||||||
|
return &admin_pb.GetDefaultOrgResponse{Org: org_grpc.OrgToPb(org)}, err
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) GetOrgByID(ctx context.Context, req *admin_pb.GetOrgByIDRequest) (*admin_pb.GetOrgByIDResponse, error) {
|
func (s *Server) GetOrgByID(ctx context.Context, req *admin_pb.GetOrgByIDRequest) (*admin_pb.GetOrgByIDResponse, error) {
|
||||||
org, err := s.query.OrgByID(ctx, req.Id)
|
org, err := s.query.OrgByID(ctx, req.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,7 +12,8 @@ func (s *Server) GetIAM(ctx context.Context, _ *mgmt_pb.GetIAMRequest) (*mgmt_pb
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.GetIAMResponse{
|
return &mgmt_pb.GetIAMResponse{
|
||||||
GlobalOrgId: iam.GlobalOrgID,
|
GlobalOrgId: iam.DefaultOrgID,
|
||||||
|
DefaultOrgId: iam.DefaultOrgID,
|
||||||
IamProjectId: iam.IAMProjectID,
|
IamProjectId: iam.IAMProjectID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ func (s *Server) ListOrgMemberRoles(ctx context.Context, _ *mgmt_pb.ListOrgMembe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
roles := s.query.GetOrgMemberRoles(authz.GetCtxData(ctx).OrgID == iam.GlobalOrgID)
|
roles := s.query.GetOrgMemberRoles(authz.GetCtxData(ctx).OrgID == iam.DefaultOrgID)
|
||||||
return &mgmt_pb.ListOrgMemberRolesResponse{
|
return &mgmt_pb.ListOrgMemberRolesResponse{
|
||||||
Result: roles,
|
Result: roles,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -182,6 +182,10 @@ func (m *mockInstance) DefaultLanguage() language.Tag {
|
|||||||
return language.English
|
return language.English
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockInstance) DefaultOrganisationID() string {
|
||||||
|
return "orgID"
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockInstance) RequestedDomain() string {
|
func (m *mockInstance) RequestedDomain() string {
|
||||||
return "localhost"
|
return "localhost"
|
||||||
}
|
}
|
||||||
|
@ -266,6 +266,10 @@ func (m *mockInstance) DefaultLanguage() language.Tag {
|
|||||||
return language.English
|
return language.English
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockInstance) DefaultOrganisationID() string {
|
||||||
|
return "orgID"
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockInstance) RequestedDomain() string {
|
func (m *mockInstance) RequestedDomain() string {
|
||||||
return "zitadel.cloud"
|
return "zitadel.cloud"
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,9 @@ func (l *Login) customExternalUserMapping(ctx context.Context, user *domain.Exte
|
|||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
resourceOwner = config.AggregateID
|
resourceOwner = config.AggregateID
|
||||||
}
|
}
|
||||||
if resourceOwner == authz.GetInstance(ctx).InstanceID() {
|
instance := authz.GetInstance(ctx)
|
||||||
iam, err := l.query.Instance(ctx)
|
if resourceOwner == instance.InstanceID() {
|
||||||
if err != nil {
|
resourceOwner = instance.DefaultOrganisationID()
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resourceOwner = iam.GlobalOrgID
|
|
||||||
}
|
}
|
||||||
triggerActions, err := l.query.GetActiveActionsByFlowAndTriggerType(ctx, domain.FlowTypeExternalAuthentication, domain.TriggerTypePostAuthentication, resourceOwner)
|
triggerActions, err := l.query.GetActiveActionsByFlowAndTriggerType(ctx, domain.FlowTypeExternalAuthentication, domain.TriggerTypePostAuthentication, resourceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v2/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
|
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
@ -204,32 +205,26 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R
|
|||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
iam, err := l.query.Instance(r.Context())
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
if err != nil {
|
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceOwner := iam.GlobalOrgID
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
|
|
||||||
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID {
|
|
||||||
resourceOwner = authReq.RequestedOrgID
|
resourceOwner = authReq.RequestedOrgID
|
||||||
}
|
}
|
||||||
|
|
||||||
orgIAMPolicy, err := l.getOrgDomainPolicy(r, resourceOwner)
|
orgIAMPolicy, err := l.getOrgDomainPolicy(r, resourceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
human, idpLinking, _ := l.mapExternalUserToLoginUser(orgIAMPolicy, externalUser, idpConfig)
|
human, idpLinking, _ := l.mapExternalUserToLoginUser(orgIAMPolicy, externalUser, idpConfig)
|
||||||
if !idpConfig.AutoRegister {
|
if !idpConfig.AutoRegister {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, iam, orgIAMPolicy, human, idpLinking, err)
|
l.renderExternalNotFoundOption(w, r, authReq, orgIAMPolicy, human, idpLinking, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
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.renderExternalNotFoundOption(w, r, authReq, iam, orgIAMPolicy, human, idpLinking, err)
|
l.renderExternalNotFoundOption(w, r, authReq, orgIAMPolicy, human, idpLinking, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.handleAutoRegister(w, r, authReq)
|
l.handleAutoRegister(w, r, authReq)
|
||||||
@ -249,20 +244,15 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R
|
|||||||
l.renderNextStep(w, r, authReq)
|
l.renderNextStep(w, r, authReq)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *query.Instance, orgIAMPolicy *query.DomainPolicy, human *domain.Human, externalIDP *domain.UserIDPLink, err error) {
|
func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, orgIAMPolicy *query.DomainPolicy, human *domain.Human, externalIDP *domain.UserIDPLink, err error) {
|
||||||
var errID, errMessage string
|
var errID, errMessage string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errID, errMessage = l.getErrorMessage(r, err)
|
errID, errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
if orgIAMPolicy == nil {
|
if orgIAMPolicy == nil {
|
||||||
iam, err = l.query.Instance(r.Context())
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
if err != nil {
|
|
||||||
l.renderError(w, r, authReq, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resourceOwner := iam.GlobalOrgID
|
|
||||||
|
|
||||||
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID {
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
resourceOwner = authReq.RequestedOrgID
|
resourceOwner = authReq.RequestedOrgID
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +307,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
|
|||||||
data := new(externalNotFoundOptionFormData)
|
data := new(externalNotFoundOptionFormData)
|
||||||
authReq, err := l.getAuthRequestAndParseData(r, data)
|
authReq, err := l.getAuthRequestAndParseData(r, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if data.Link {
|
if data.Link {
|
||||||
@ -327,7 +317,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
|
|||||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||||
err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID)
|
err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
|
||||||
}
|
}
|
||||||
l.handleLogin(w, r)
|
l.handleLogin(w, r)
|
||||||
return
|
return
|
||||||
@ -336,29 +326,23 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest) {
|
func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest) {
|
||||||
iam, err := l.query.Instance(r.Context())
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
if err != nil {
|
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceOwner := iam.GlobalOrgID
|
|
||||||
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
||||||
|
|
||||||
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID {
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
memberRoles = nil
|
memberRoles = nil
|
||||||
resourceOwner = authReq.RequestedOrgID
|
resourceOwner = authReq.RequestedOrgID
|
||||||
}
|
}
|
||||||
|
|
||||||
orgIamPolicy, err := l.getOrgDomainPolicy(r, resourceOwner)
|
orgIamPolicy, err := l.getOrgDomainPolicy(r, resourceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
idpConfig, err := l.authRepo.GetIDPConfigByID(r.Context(), authReq.SelectedIDPConfigID)
|
idpConfig, err := l.authRepo.GetIDPConfigByID(r.Context(), authReq.SelectedIDPConfigID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, orgIamPolicy, nil, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,12 +355,12 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR
|
|||||||
user, externalIDP, metadata := l.mapExternalUserToLoginUser(orgIamPolicy, linkingUser, idpConfig)
|
user, externalIDP, metadata := l.mapExternalUserToLoginUser(orgIamPolicy, linkingUser, idpConfig)
|
||||||
user, metadata, err = l.customExternalUserToLoginUserMapping(user, nil, authReq, idpConfig, metadata, resourceOwner)
|
user, metadata, err = l.customExternalUserToLoginUserMapping(user, nil, authReq, idpConfig, metadata, resourceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, orgIamPolicy, nil, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, memberRoles, authReq.ID, userAgentID, resourceOwner, metadata, domain.BrowserInfoFromRequest(r))
|
err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, memberRoles, authReq.ID, userAgentID, resourceOwner, metadata, domain.BrowserInfoFromRequest(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, user, externalIDP, err)
|
l.renderExternalNotFoundOption(w, r, authReq, orgIamPolicy, user, externalIDP, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID)
|
authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v2/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
|
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
iam_model "github.com/zitadel/zitadel/internal/iam/model"
|
iam_model "github.com/zitadel/zitadel/internal/iam/model"
|
||||||
@ -111,12 +112,7 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, idpConfig *iam_model.IDPConfigView, userAgentID string, tokens *oidc.Tokens) {
|
func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, idpConfig *iam_model.IDPConfigView, userAgentID string, tokens *oidc.Tokens) {
|
||||||
iam, err := l.query.Instance(r.Context())
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
if err != nil {
|
|
||||||
l.renderRegisterOption(w, r, authReq, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resourceOwner := iam.GlobalOrgID
|
|
||||||
if authReq.RequestedOrgID != "" {
|
if authReq.RequestedOrgID != "" {
|
||||||
resourceOwner = authReq.RequestedOrgID
|
resourceOwner = authReq.RequestedOrgID
|
||||||
}
|
}
|
||||||
@ -134,11 +130,11 @@ func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Reques
|
|||||||
l.renderExternalRegisterOverview(w, r, authReq, orgIamPolicy, user, externalIDP, nil)
|
l.renderExternalRegisterOverview(w, r, authReq, orgIamPolicy, user, externalIDP, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.registerExternalUser(w, r, authReq, iam, user, externalIDP)
|
l.registerExternalUser(w, r, authReq, user, externalIDP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) registerExternalUser(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *query.Instance, user *domain.Human, externalIDP *domain.UserIDPLink) {
|
func (l *Login) registerExternalUser(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, user *domain.Human, externalIDP *domain.UserIDPLink) {
|
||||||
resourceOwner := iam.GlobalOrgID
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
||||||
|
|
||||||
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
@ -204,15 +200,10 @@ func (l *Login) handleExternalRegisterCheck(w http.ResponseWriter, r *http.Reque
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
iam, err := l.query.Instance(r.Context())
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
if err != nil {
|
|
||||||
l.renderRegisterOption(w, r, authReq, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resourceOwner := iam.GlobalOrgID
|
|
||||||
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
||||||
|
|
||||||
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID {
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
memberRoles = nil
|
memberRoles = nil
|
||||||
resourceOwner = authReq.RequestedOrgID
|
resourceOwner = authReq.RequestedOrgID
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ func (l *Login) jwtExtractionUserNotFound(w http.ResponseWriter, r *http.Request
|
|||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
if !idpConfig.AutoRegister {
|
if !idpConfig.AutoRegister {
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID)
|
authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID)
|
||||||
|
@ -98,10 +98,13 @@ func (l *Login) renderLogin(w http.ResponseWriter, r *http.Request, authReq *dom
|
|||||||
data := l.getUserData(r, authReq, "Login", errID, errMessage)
|
data := l.getUserData(r, authReq, "Login", errID, errMessage)
|
||||||
funcs := map[string]interface{}{
|
funcs := map[string]interface{}{
|
||||||
"hasUsernamePasswordLogin": func() bool {
|
"hasUsernamePasswordLogin": func() bool {
|
||||||
return authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowUsernamePassword
|
return authReq != nil && authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowUsernamePassword
|
||||||
},
|
},
|
||||||
"hasExternalLogin": func() bool {
|
"hasExternalLogin": func() bool {
|
||||||
return authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowExternalIDP && authReq.AllowedExternalIDPs != nil && len(authReq.AllowedExternalIDPs) > 0
|
return authReq != nil && authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowExternalIDP && authReq.AllowedExternalIDPs != nil && len(authReq.AllowedExternalIDPs) > 0
|
||||||
|
},
|
||||||
|
"hasRegistration": func() bool {
|
||||||
|
return authReq != nil && authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowRegister
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.getTranslator(r.Context(), authReq), l.renderer.Templates[tmplLogin], data, funcs)
|
l.renderer.RenderTemplate(w, r, l.getTranslator(r.Context(), authReq), l.renderer.Templates[tmplLogin], data, funcs)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
|
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
@ -61,16 +62,11 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) {
|
|||||||
l.renderRegister(w, r, authRequest, data, err)
|
l.renderRegister(w, r, authRequest, data, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
iam, err := l.query.Instance(r.Context())
|
|
||||||
if err != nil {
|
|
||||||
l.renderRegister(w, r, authRequest, data, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceOwner := iam.GlobalOrgID
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
memberRoles := []string{domain.RoleSelfManagementGlobal}
|
||||||
|
|
||||||
if authRequest != nil && authRequest.RequestedOrgID != "" && authRequest.RequestedOrgID != iam.GlobalOrgID {
|
if authRequest != nil && authRequest.RequestedOrgID != "" && authRequest.RequestedOrgID != resourceOwner {
|
||||||
memberRoles = nil
|
memberRoles = nil
|
||||||
resourceOwner = authRequest.RequestedOrgID
|
resourceOwner = authRequest.RequestedOrgID
|
||||||
}
|
}
|
||||||
@ -114,10 +110,6 @@ func (l *Login) renderRegister(w http.ResponseWriter, r *http.Request, authReque
|
|||||||
if formData.Language == "" {
|
if formData.Language == "" {
|
||||||
formData.Language = l.renderer.ReqLang(translator, r).String()
|
formData.Language = l.renderer.ReqLang(translator, r).String()
|
||||||
}
|
}
|
||||||
data := registerData{
|
|
||||||
baseData: l.getBaseData(r, authRequest, "Register", errID, errMessage),
|
|
||||||
registerFormData: *formData,
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceOwner string
|
var resourceOwner string
|
||||||
if authRequest != nil {
|
if authRequest != nil {
|
||||||
@ -125,12 +117,12 @@ func (l *Login) renderRegister(w http.ResponseWriter, r *http.Request, authReque
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
iam, err := l.query.Instance(r.Context())
|
resourceOwner = authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
if err != nil {
|
}
|
||||||
l.renderRegister(w, r, authRequest, formData, err)
|
|
||||||
return
|
data := registerData{
|
||||||
}
|
baseData: l.getBaseData(r, authRequest, "Register", errID, errMessage),
|
||||||
resourceOwner = iam.GlobalOrgID
|
registerFormData: *formData,
|
||||||
}
|
}
|
||||||
|
|
||||||
pwPolicy, description, _ := l.getPasswordComplexityPolicy(r, authRequest, resourceOwner)
|
pwPolicy, description, _ := l.getPasswordComplexityPolicy(r, authRequest, resourceOwner)
|
||||||
|
@ -211,6 +211,9 @@ func CreateRenderer(pathPrefix string, staticDir http.FileSystem, staticStorage
|
|||||||
"hasExternalLogin": func() bool {
|
"hasExternalLogin": func() bool {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
|
"hasRegistration": func() bool {
|
||||||
|
return true
|
||||||
|
},
|
||||||
"idpProviderClass": func(stylingType domain.IDPConfigStylingType) string {
|
"idpProviderClass": func(stylingType domain.IDPConfigStylingType) string {
|
||||||
return stylingType.GetCSSClass()
|
return stylingType.GetCSSClass()
|
||||||
},
|
},
|
||||||
@ -299,7 +302,7 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
case *domain.LinkUsersStep:
|
case *domain.LinkUsersStep:
|
||||||
l.linkUsers(w, r, authReq, err)
|
l.linkUsers(w, r, authReq, err)
|
||||||
case *domain.ExternalNotFoundOptionStep:
|
case *domain.ExternalNotFoundOptionStep:
|
||||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
|
||||||
case *domain.ExternalLoginStep:
|
case *domain.ExternalLoginStep:
|
||||||
l.handleExternalLoginStep(w, r, authReq, step.SelectedIDPConfigID)
|
l.handleExternalLoginStep(w, r, authReq, step.SelectedIDPConfigID)
|
||||||
case *domain.GrantRequiredStep:
|
case *domain.GrantRequiredStep:
|
||||||
@ -346,7 +349,7 @@ func (l *Login) getBaseData(r *http.Request, authReq *domain.AuthRequest, title
|
|||||||
PrivateLabelingOrgID: l.getPrivateLabelingID(r, authReq),
|
PrivateLabelingOrgID: l.getPrivateLabelingID(r, authReq),
|
||||||
OrgID: l.getOrgID(r, authReq),
|
OrgID: l.getOrgID(r, authReq),
|
||||||
OrgName: l.getOrgName(authReq),
|
OrgName: l.getOrgName(authReq),
|
||||||
PrimaryDomain: l.getOrgPrimaryDomain(authReq),
|
PrimaryDomain: l.getOrgPrimaryDomain(r, authReq),
|
||||||
DisplayLoginNameSuffix: l.isDisplayLoginNameSuffix(authReq),
|
DisplayLoginNameSuffix: l.isDisplayLoginNameSuffix(authReq),
|
||||||
AuthReqID: getRequestID(authReq, r),
|
AuthReqID: getRequestID(authReq, r),
|
||||||
CSRF: csrf.TemplateField(r),
|
CSRF: csrf.TemplateField(r),
|
||||||
@ -490,11 +493,17 @@ func (l *Login) getOrgName(authReq *domain.AuthRequest) string {
|
|||||||
return authReq.RequestedOrgName
|
return authReq.RequestedOrgName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) getOrgPrimaryDomain(authReq *domain.AuthRequest) string {
|
func (l *Login) getOrgPrimaryDomain(r *http.Request, authReq *domain.AuthRequest) string {
|
||||||
if authReq == nil {
|
orgID := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
|
if authReq != nil && authReq.RequestedPrimaryDomain != "" {
|
||||||
|
return authReq.RequestedPrimaryDomain
|
||||||
|
}
|
||||||
|
org, err := l.query.OrgByID(r.Context(), orgID)
|
||||||
|
if err != nil {
|
||||||
|
logging.New().WithError(err).Error("cannot get default org")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return authReq.RequestedPrimaryDomain
|
return org.Domain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) isDisplayLoginNameSuffix(authReq *domain.AuthRequest) bool {
|
func (l *Login) isDisplayLoginNameSuffix(authReq *domain.AuthRequest) bool {
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<div class="lgn-suffix-wrapper">
|
<div class="lgn-suffix-wrapper">
|
||||||
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username"
|
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username"
|
||||||
value="{{ .Username }}" required>
|
value="{{ .Username }}" required>
|
||||||
{{if .DisplayLoginNameSuffix}}
|
{{if .ShowUsername}}
|
||||||
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
|
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<div class="lgn-suffix-wrapper">
|
<div class="lgn-suffix-wrapper">
|
||||||
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username"
|
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username"
|
||||||
value="{{ .Username }}" required>
|
value="{{ .Username }}" required>
|
||||||
{{if .DisplayLoginNameSuffix}}
|
{{if .ShowUsername}}
|
||||||
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
|
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
<div class="lgn-actions lgn-reverse-order">
|
<div class="lgn-actions lgn-reverse-order">
|
||||||
<button class="lgn-raised-button lgn-primary lgn-initial-focus" id="submit-button" type="submit">{{t "Login.NextButtonText"}}</button>
|
<button class="lgn-raised-button lgn-primary lgn-initial-focus" id="submit-button" type="submit">{{t "Login.NextButtonText"}}</button>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
{{if .LoginPolicy.AllowRegister}}
|
{{if hasRegistration}}
|
||||||
<button class="lgn-stroked-button" name="register" value="true" formnovalidate>{{t "Login.RegisterButtonText"}}</button>
|
<button class="lgn-stroked-button" name="register" value="true" formnovalidate>{{t "Login.RegisterButtonText"}}</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@ -60,4 +60,4 @@
|
|||||||
<script src="{{ resourceUrl "scripts/default_form_validation.js" }}"></script>
|
<script src="{{ resourceUrl "scripts/default_form_validation.js" }}"></script>
|
||||||
<script src="{{ resourceUrl "scripts/input_suffix_offset.js" }}"></script>
|
<script src="{{ resourceUrl "scripts/input_suffix_offset.js" }}"></script>
|
||||||
|
|
||||||
{{template "main-bottom" .}}
|
{{template "main-bottom" .}}
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<label class="lgn-label" for="username">{{t "RegistrationUser.UsernameLabel"}}</label>
|
<label class="lgn-label" for="username">{{t "RegistrationUser.UsernameLabel"}}</label>
|
||||||
<div class="lgn-suffix-wrapper">
|
<div class="lgn-suffix-wrapper">
|
||||||
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username" autocomplete="email" value="{{ .Email }}" required>
|
<input class="lgn-input lgn-suffix-input" type="text" id="username" name="username" autocomplete="email" value="{{ .Email }}" required>
|
||||||
{{if .DisplayLoginNameSuffix}}
|
{{if .ShowUsername}}
|
||||||
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
|
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -114,7 +114,7 @@ func (i *IDPConfig) processIdpConfig(providerType iam_model.IDPProviderType, eve
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
idp, err = i.view.IDPConfigByID(idp.IDPConfigID, idp.InstanceID)
|
idp, err = i.view.IDPConfigByID(idp.IDPConfigID, event.InstanceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ func (i *IDPConfig) processIdpConfig(providerType iam_model.IDPProviderType, eve
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
idp, err = i.view.IDPConfigByID(idp.IDPConfigID, idp.InstanceID)
|
idp, err = i.view.IDPConfigByID(idp.IDPConfigID, event.InstanceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,7 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
|||||||
|
|
||||||
validations = append(validations,
|
validations = append(validations,
|
||||||
AddOrgCommand(ctx, orgAgg, setup.Org.Name),
|
AddOrgCommand(ctx, orgAgg, setup.Org.Name),
|
||||||
|
c.prepareSetDefaultOrg(instanceAgg, orgAgg.ID),
|
||||||
AddHumanCommand(userAgg, &setup.Org.Human, c.userPasswordAlg, c.userEncryption),
|
AddHumanCommand(userAgg, &setup.Org.Human, c.userPasswordAlg, c.userEncryption),
|
||||||
c.AddOrgMemberCommand(orgAgg, userID, domain.RoleOrgOwner),
|
c.AddOrgMemberCommand(orgAgg, userID, domain.RoleOrgOwner),
|
||||||
c.AddInstanceMemberCommand(instanceAgg, userID, domain.RoleIAMOwner),
|
c.AddInstanceMemberCommand(instanceAgg, userID, domain.RoleIAMOwner),
|
||||||
@ -379,6 +380,24 @@ func (c *Commands) SetDefaultLanguage(ctx context.Context, defaultLanguage langu
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) SetDefaultOrg(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
|
||||||
|
instanceAgg := instance.NewAggregate(authz.GetInstance(ctx).InstanceID())
|
||||||
|
validation := c.prepareSetDefaultOrg(instanceAgg, orgID)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.ObjectDetails{
|
||||||
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
|
ResourceOwner: events[len(events)-1].Aggregate().InstanceID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func prepareAddInstance(a *instance.Aggregate, instanceName string, defaultLanguage language.Tag) preparation.Validation {
|
func prepareAddInstance(a *instance.Aggregate, instanceName string, defaultLanguage language.Tag) preparation.Validation {
|
||||||
return func() (preparation.CreateCommands, error) {
|
return func() (preparation.CreateCommands, error) {
|
||||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
@ -412,15 +431,25 @@ func SetIAMConsoleID(a *instance.Aggregate, clientID, appID *string) preparation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) setGlobalOrg(ctx context.Context, iamAgg *eventstore.Aggregate, iamWriteModel *InstanceWriteModel, orgID string) (eventstore.Command, error) {
|
func (c *Commands) prepareSetDefaultOrg(a *instance.Aggregate, orgID string) preparation.Validation {
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, iamWriteModel)
|
return func() (preparation.CreateCommands, error) {
|
||||||
if err != nil {
|
if orgID == "" {
|
||||||
return nil, err
|
return nil, errors.ThrowInvalidArgument(nil, "INST-SWffe", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
writeModel, err := getInstanceWriteModel(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if writeModel.DefaultOrgID == orgID {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "INST-SDfw2", "Errors.Instance.NotChanged")
|
||||||
|
}
|
||||||
|
if exists, err := ExistsOrg(ctx, filter, orgID); err != nil || !exists {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(err, "INSTA-Wfe21", "Errors.Org.NotFound")
|
||||||
|
}
|
||||||
|
return []eventstore.Command{instance.NewDefaultOrgSetEventEvent(ctx, &a.Aggregate, orgID)}, nil
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
if iamWriteModel.GlobalOrgID != "" {
|
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "IAM-HGG24", "Errors.IAM.GlobalOrgAlreadySet")
|
|
||||||
}
|
|
||||||
return instance.NewGlobalOrgSetEventEvent(ctx, iamAgg, orgID), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) setIAMProject(ctx context.Context, iamAgg *eventstore.Aggregate, iamWriteModel *InstanceWriteModel, projectID string) (eventstore.Command, error) {
|
func (c *Commands) setIAMProject(ctx context.Context, iamAgg *eventstore.Aggregate, iamWriteModel *InstanceWriteModel, projectID string) (eventstore.Command, error) {
|
||||||
|
@ -15,7 +15,7 @@ type InstanceWriteModel struct {
|
|||||||
State domain.InstanceState
|
State domain.InstanceState
|
||||||
GeneratedDomain string
|
GeneratedDomain string
|
||||||
|
|
||||||
GlobalOrgID string
|
DefaultOrgID string
|
||||||
ProjectID string
|
ProjectID string
|
||||||
DefaultLanguage language.Tag
|
DefaultLanguage language.Tag
|
||||||
}
|
}
|
||||||
@ -46,8 +46,8 @@ func (wm *InstanceWriteModel) Reduce() error {
|
|||||||
wm.GeneratedDomain = e.Domain
|
wm.GeneratedDomain = e.Domain
|
||||||
case *instance.ProjectSetEvent:
|
case *instance.ProjectSetEvent:
|
||||||
wm.ProjectID = e.ProjectID
|
wm.ProjectID = e.ProjectID
|
||||||
case *instance.GlobalOrgSetEvent:
|
case *instance.DefaultOrgSetEvent:
|
||||||
wm.GlobalOrgID = e.OrgID
|
wm.DefaultOrgID = e.OrgID
|
||||||
case *instance.DefaultLanguageSetEvent:
|
case *instance.DefaultLanguageSetEvent:
|
||||||
wm.DefaultLanguage = e.Language
|
wm.DefaultLanguage = e.Language
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ func (wm *InstanceWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
instance.InstanceDomainAddedEventType,
|
instance.InstanceDomainAddedEventType,
|
||||||
instance.InstanceDomainRemovedEventType,
|
instance.InstanceDomainRemovedEventType,
|
||||||
instance.ProjectSetEventType,
|
instance.ProjectSetEventType,
|
||||||
instance.GlobalOrgSetEventType,
|
instance.DefaultOrgSetEventType,
|
||||||
instance.DefaultLanguageSetEventType).
|
instance.DefaultLanguageSetEventType).
|
||||||
Builder()
|
Builder()
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,10 @@ func (m *mockInstance) DefaultLanguage() language.Tag {
|
|||||||
return language.English
|
return language.English
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockInstance) DefaultOrganisationID() string {
|
||||||
|
return "orgID"
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockInstance) RequestedDomain() string {
|
func (m *mockInstance) RequestedDomain() string {
|
||||||
return "zitadel.cloud"
|
return "zitadel.cloud"
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,35 @@ func (c *Commands) ReactivateOrg(ctx context.Context, orgID string) (*domain.Obj
|
|||||||
return writeModelToObjectDetails(&orgWriteModel.WriteModel), nil
|
return writeModelToObjectDetails(&orgWriteModel.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExistsOrg(ctx context.Context, filter preparation.FilterToQueryReducer, id string) (exists bool, err error) {
|
||||||
|
events, err := filter(ctx, eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
ResourceOwner(id).
|
||||||
|
OrderAsc().
|
||||||
|
AddQuery().
|
||||||
|
AggregateTypes(org.AggregateType).
|
||||||
|
AggregateIDs(id).
|
||||||
|
EventTypes(
|
||||||
|
org.OrgAddedEventType,
|
||||||
|
org.OrgDeactivatedEventType,
|
||||||
|
org.OrgReactivatedEventType,
|
||||||
|
org.OrgRemovedEventType,
|
||||||
|
).Builder())
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, event := range events {
|
||||||
|
switch event.(type) {
|
||||||
|
case *org.OrgAddedEvent, *org.OrgReactivatedEvent:
|
||||||
|
exists = true
|
||||||
|
case *org.OrgDeactivatedEvent, *org.OrgRemovedEvent:
|
||||||
|
exists = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exists, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) setUpOrg(
|
func (c *Commands) setUpOrg(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organisation *domain.Org,
|
organisation *domain.Org,
|
||||||
|
@ -24,7 +24,7 @@ const (
|
|||||||
|
|
||||||
type IAM struct {
|
type IAM struct {
|
||||||
es_models.ObjectRoot
|
es_models.ObjectRoot
|
||||||
GlobalOrgID string
|
DefaultOrgID string
|
||||||
IAMProjectID string
|
IAMProjectID string
|
||||||
SetUpDone domain.Step
|
SetUpDone domain.Step
|
||||||
SetUpStarted domain.Step
|
SetUpStarted domain.Step
|
||||||
|
@ -39,8 +39,8 @@ var (
|
|||||||
name: projection.InstanceColumnSequence,
|
name: projection.InstanceColumnSequence,
|
||||||
table: instanceTable,
|
table: instanceTable,
|
||||||
}
|
}
|
||||||
InstanceColumnGlobalOrgID = Column{
|
InstanceColumnDefaultOrgID = Column{
|
||||||
name: projection.InstanceColumnGlobalOrgID,
|
name: projection.InstanceColumnDefaultOrgID,
|
||||||
table: instanceTable,
|
table: instanceTable,
|
||||||
}
|
}
|
||||||
InstanceColumnProjectID = Column{
|
InstanceColumnProjectID = Column{
|
||||||
@ -68,7 +68,7 @@ type Instance struct {
|
|||||||
Sequence uint64
|
Sequence uint64
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
GlobalOrgID string
|
DefaultOrgID string
|
||||||
IAMProjectID string
|
IAMProjectID string
|
||||||
ConsoleID string
|
ConsoleID string
|
||||||
ConsoleAppID string
|
ConsoleAppID string
|
||||||
@ -110,6 +110,10 @@ func (i *Instance) DefaultLanguage() language.Tag {
|
|||||||
return i.DefaultLang
|
return i.DefaultLang
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Instance) DefaultOrganisationID() string {
|
||||||
|
return i.DefaultOrgID
|
||||||
|
}
|
||||||
|
|
||||||
type InstanceSearchQueries struct {
|
type InstanceSearchQueries struct {
|
||||||
SearchRequest
|
SearchRequest
|
||||||
Queries []SearchQuery
|
Queries []SearchQuery
|
||||||
@ -196,7 +200,7 @@ func prepareInstanceQuery(host string) (sq.SelectBuilder, func(*sql.Row) (*Insta
|
|||||||
InstanceColumnCreationDate.identifier(),
|
InstanceColumnCreationDate.identifier(),
|
||||||
InstanceColumnChangeDate.identifier(),
|
InstanceColumnChangeDate.identifier(),
|
||||||
InstanceColumnSequence.identifier(),
|
InstanceColumnSequence.identifier(),
|
||||||
InstanceColumnGlobalOrgID.identifier(),
|
InstanceColumnDefaultOrgID.identifier(),
|
||||||
InstanceColumnProjectID.identifier(),
|
InstanceColumnProjectID.identifier(),
|
||||||
InstanceColumnConsoleID.identifier(),
|
InstanceColumnConsoleID.identifier(),
|
||||||
InstanceColumnConsoleAppID.identifier(),
|
InstanceColumnConsoleAppID.identifier(),
|
||||||
@ -211,7 +215,7 @@ func prepareInstanceQuery(host string) (sq.SelectBuilder, func(*sql.Row) (*Insta
|
|||||||
&instance.CreationDate,
|
&instance.CreationDate,
|
||||||
&instance.ChangeDate,
|
&instance.ChangeDate,
|
||||||
&instance.Sequence,
|
&instance.Sequence,
|
||||||
&instance.GlobalOrgID,
|
&instance.DefaultOrgID,
|
||||||
&instance.IAMProjectID,
|
&instance.IAMProjectID,
|
||||||
&instance.ConsoleID,
|
&instance.ConsoleID,
|
||||||
&instance.ConsoleAppID,
|
&instance.ConsoleAppID,
|
||||||
@ -235,7 +239,7 @@ func prepareInstancesQuery() (sq.SelectBuilder, func(*sql.Rows) (*Instances, err
|
|||||||
InstanceColumnChangeDate.identifier(),
|
InstanceColumnChangeDate.identifier(),
|
||||||
InstanceColumnSequence.identifier(),
|
InstanceColumnSequence.identifier(),
|
||||||
InstanceColumnName.identifier(),
|
InstanceColumnName.identifier(),
|
||||||
InstanceColumnGlobalOrgID.identifier(),
|
InstanceColumnDefaultOrgID.identifier(),
|
||||||
InstanceColumnProjectID.identifier(),
|
InstanceColumnProjectID.identifier(),
|
||||||
InstanceColumnConsoleID.identifier(),
|
InstanceColumnConsoleID.identifier(),
|
||||||
InstanceColumnConsoleAppID.identifier(),
|
InstanceColumnConsoleAppID.identifier(),
|
||||||
@ -254,7 +258,7 @@ func prepareInstancesQuery() (sq.SelectBuilder, func(*sql.Rows) (*Instances, err
|
|||||||
&instance.ChangeDate,
|
&instance.ChangeDate,
|
||||||
&instance.Sequence,
|
&instance.Sequence,
|
||||||
&instance.Name,
|
&instance.Name,
|
||||||
&instance.GlobalOrgID,
|
&instance.DefaultOrgID,
|
||||||
&instance.IAMProjectID,
|
&instance.IAMProjectID,
|
||||||
&instance.ConsoleID,
|
&instance.ConsoleID,
|
||||||
&instance.ConsoleAppID,
|
&instance.ConsoleAppID,
|
||||||
@ -288,7 +292,7 @@ func prepareInstanceDomainQuery(host string) (sq.SelectBuilder, func(*sql.Rows)
|
|||||||
InstanceColumnChangeDate.identifier(),
|
InstanceColumnChangeDate.identifier(),
|
||||||
InstanceColumnSequence.identifier(),
|
InstanceColumnSequence.identifier(),
|
||||||
InstanceColumnName.identifier(),
|
InstanceColumnName.identifier(),
|
||||||
InstanceColumnGlobalOrgID.identifier(),
|
InstanceColumnDefaultOrgID.identifier(),
|
||||||
InstanceColumnProjectID.identifier(),
|
InstanceColumnProjectID.identifier(),
|
||||||
InstanceColumnConsoleID.identifier(),
|
InstanceColumnConsoleID.identifier(),
|
||||||
InstanceColumnConsoleAppID.identifier(),
|
InstanceColumnConsoleAppID.identifier(),
|
||||||
@ -324,7 +328,7 @@ func prepareInstanceDomainQuery(host string) (sq.SelectBuilder, func(*sql.Rows)
|
|||||||
&instance.ChangeDate,
|
&instance.ChangeDate,
|
||||||
&instance.Sequence,
|
&instance.Sequence,
|
||||||
&instance.Name,
|
&instance.Name,
|
||||||
&instance.GlobalOrgID,
|
&instance.DefaultOrgID,
|
||||||
&instance.IAMProjectID,
|
&instance.IAMProjectID,
|
||||||
&instance.ConsoleID,
|
&instance.ConsoleID,
|
||||||
&instance.ConsoleAppID,
|
&instance.ConsoleAppID,
|
||||||
|
@ -36,7 +36,7 @@ func Test_InstancePrepares(t *testing.T) {
|
|||||||
` projections.instances.creation_date,`+
|
` projections.instances.creation_date,`+
|
||||||
` projections.instances.change_date,`+
|
` projections.instances.change_date,`+
|
||||||
` projections.instances.sequence,`+
|
` projections.instances.sequence,`+
|
||||||
` projections.instances.global_org_id,`+
|
` projections.instances.default_org_id,`+
|
||||||
` projections.instances.iam_project_id,`+
|
` projections.instances.iam_project_id,`+
|
||||||
` projections.instances.console_client_id,`+
|
` projections.instances.console_client_id,`+
|
||||||
` projections.instances.console_app_id,`+
|
` projections.instances.console_app_id,`+
|
||||||
@ -65,7 +65,7 @@ func Test_InstancePrepares(t *testing.T) {
|
|||||||
` projections.instances.creation_date,`+
|
` projections.instances.creation_date,`+
|
||||||
` projections.instances.change_date,`+
|
` projections.instances.change_date,`+
|
||||||
` projections.instances.sequence,`+
|
` projections.instances.sequence,`+
|
||||||
` projections.instances.global_org_id,`+
|
` projections.instances.default_org_id,`+
|
||||||
` projections.instances.iam_project_id,`+
|
` projections.instances.iam_project_id,`+
|
||||||
` projections.instances.console_client_id,`+
|
` projections.instances.console_client_id,`+
|
||||||
` projections.instances.console_app_id,`+
|
` projections.instances.console_app_id,`+
|
||||||
@ -76,7 +76,7 @@ func Test_InstancePrepares(t *testing.T) {
|
|||||||
"creation_date",
|
"creation_date",
|
||||||
"change_date",
|
"change_date",
|
||||||
"sequence",
|
"sequence",
|
||||||
"global_org_id",
|
"default_org_id",
|
||||||
"iam_project_id",
|
"iam_project_id",
|
||||||
"console_client_id",
|
"console_client_id",
|
||||||
"console_app_id",
|
"console_app_id",
|
||||||
@ -100,7 +100,7 @@ func Test_InstancePrepares(t *testing.T) {
|
|||||||
CreationDate: testNow,
|
CreationDate: testNow,
|
||||||
ChangeDate: testNow,
|
ChangeDate: testNow,
|
||||||
Sequence: 20211108,
|
Sequence: 20211108,
|
||||||
GlobalOrgID: "global-org-id",
|
DefaultOrgID: "global-org-id",
|
||||||
IAMProjectID: "project-id",
|
IAMProjectID: "project-id",
|
||||||
ConsoleID: "client-id",
|
ConsoleID: "client-id",
|
||||||
ConsoleAppID: "app-id",
|
ConsoleAppID: "app-id",
|
||||||
@ -118,7 +118,7 @@ func Test_InstancePrepares(t *testing.T) {
|
|||||||
` projections.instances.creation_date,`+
|
` projections.instances.creation_date,`+
|
||||||
` projections.instances.change_date,`+
|
` projections.instances.change_date,`+
|
||||||
` projections.instances.sequence,`+
|
` projections.instances.sequence,`+
|
||||||
` projections.instances.global_org_id,`+
|
` projections.instances.default_org_id,`+
|
||||||
` projections.instances.iam_project_id,`+
|
` projections.instances.iam_project_id,`+
|
||||||
` projections.instances.console_client_id,`+
|
` projections.instances.console_client_id,`+
|
||||||
` projections.instances.console_app_id,`+
|
` projections.instances.console_app_id,`+
|
||||||
|
@ -37,7 +37,7 @@ func (q *Queries) GetProjectMemberRoles(ctx context.Context) ([]string, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
roles := make([]string, 0)
|
roles := make([]string, 0)
|
||||||
global := authz.GetCtxData(ctx).OrgID == iam.GlobalOrgID
|
global := authz.GetCtxData(ctx).OrgID == iam.DefaultOrgID
|
||||||
for _, roleMap := range q.zitadelRoles {
|
for _, roleMap := range q.zitadelRoles {
|
||||||
if strings.HasPrefix(roleMap.Role, "PROJECT") && !strings.HasPrefix(roleMap.Role, "PROJECT_GRANT") {
|
if strings.HasPrefix(roleMap.Role, "PROJECT") && !strings.HasPrefix(roleMap.Role, "PROJECT_GRANT") {
|
||||||
if global && !strings.HasSuffix(roleMap.Role, "GLOBAL") {
|
if global && !strings.HasSuffix(roleMap.Role, "GLOBAL") {
|
||||||
|
@ -17,7 +17,7 @@ const (
|
|||||||
InstanceColumnName = "name"
|
InstanceColumnName = "name"
|
||||||
InstanceColumnChangeDate = "change_date"
|
InstanceColumnChangeDate = "change_date"
|
||||||
InstanceColumnCreationDate = "creation_date"
|
InstanceColumnCreationDate = "creation_date"
|
||||||
InstanceColumnGlobalOrgID = "global_org_id"
|
InstanceColumnDefaultOrgID = "default_org_id"
|
||||||
InstanceColumnProjectID = "iam_project_id"
|
InstanceColumnProjectID = "iam_project_id"
|
||||||
InstanceColumnConsoleID = "console_client_id"
|
InstanceColumnConsoleID = "console_client_id"
|
||||||
InstanceColumnConsoleAppID = "console_app_id"
|
InstanceColumnConsoleAppID = "console_app_id"
|
||||||
@ -39,7 +39,7 @@ func NewInstanceProjection(ctx context.Context, config crdb.StatementHandlerConf
|
|||||||
crdb.NewColumn(InstanceColumnName, crdb.ColumnTypeText, crdb.Default("")),
|
crdb.NewColumn(InstanceColumnName, crdb.ColumnTypeText, crdb.Default("")),
|
||||||
crdb.NewColumn(InstanceColumnChangeDate, crdb.ColumnTypeTimestamp),
|
crdb.NewColumn(InstanceColumnChangeDate, crdb.ColumnTypeTimestamp),
|
||||||
crdb.NewColumn(InstanceColumnCreationDate, crdb.ColumnTypeTimestamp),
|
crdb.NewColumn(InstanceColumnCreationDate, crdb.ColumnTypeTimestamp),
|
||||||
crdb.NewColumn(InstanceColumnGlobalOrgID, crdb.ColumnTypeText, crdb.Default("")),
|
crdb.NewColumn(InstanceColumnDefaultOrgID, crdb.ColumnTypeText, crdb.Default("")),
|
||||||
crdb.NewColumn(InstanceColumnProjectID, crdb.ColumnTypeText, crdb.Default("")),
|
crdb.NewColumn(InstanceColumnProjectID, crdb.ColumnTypeText, crdb.Default("")),
|
||||||
crdb.NewColumn(InstanceColumnConsoleID, crdb.ColumnTypeText, crdb.Default("")),
|
crdb.NewColumn(InstanceColumnConsoleID, crdb.ColumnTypeText, crdb.Default("")),
|
||||||
crdb.NewColumn(InstanceColumnConsoleAppID, crdb.ColumnTypeText, crdb.Default("")),
|
crdb.NewColumn(InstanceColumnConsoleAppID, crdb.ColumnTypeText, crdb.Default("")),
|
||||||
@ -63,8 +63,8 @@ func (p *InstanceProjection) reducers() []handler.AggregateReducer {
|
|||||||
Reduce: p.reduceInstanceAdded,
|
Reduce: p.reduceInstanceAdded,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Event: instance.GlobalOrgSetEventType,
|
Event: instance.DefaultOrgSetEventType,
|
||||||
Reduce: p.reduceGlobalOrgSet,
|
Reduce: p.reduceDefaultOrgSet,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Event: instance.ProjectSetEventType,
|
Event: instance.ProjectSetEventType,
|
||||||
@ -100,17 +100,17 @@ func (p *InstanceProjection) reduceInstanceAdded(event eventstore.Event) (*handl
|
|||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *InstanceProjection) reduceGlobalOrgSet(event eventstore.Event) (*handler.Statement, error) {
|
func (p *InstanceProjection) reduceDefaultOrgSet(event eventstore.Event) (*handler.Statement, error) {
|
||||||
e, ok := event.(*instance.GlobalOrgSetEvent)
|
e, ok := event.(*instance.DefaultOrgSetEvent)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-2n9f2", "reduce.wrong.event.type %s", instance.GlobalOrgSetEventType)
|
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-2n9f2", "reduce.wrong.event.type %s", instance.DefaultOrgSetEventType)
|
||||||
}
|
}
|
||||||
return crdb.NewUpdateStatement(
|
return crdb.NewUpdateStatement(
|
||||||
e,
|
e,
|
||||||
[]handler.Column{
|
[]handler.Column{
|
||||||
handler.NewCol(InstanceColumnChangeDate, e.CreationDate()),
|
handler.NewCol(InstanceColumnChangeDate, e.CreationDate()),
|
||||||
handler.NewCol(InstanceColumnSequence, e.Sequence()),
|
handler.NewCol(InstanceColumnSequence, e.Sequence()),
|
||||||
handler.NewCol(InstanceColumnGlobalOrgID, e.OrgID),
|
handler.NewCol(InstanceColumnDefaultOrgID, e.OrgID),
|
||||||
},
|
},
|
||||||
[]handler.Condition{
|
[]handler.Condition{
|
||||||
handler.NewCond(InstanceColumnID, e.Aggregate().InstanceID),
|
handler.NewCond(InstanceColumnID, e.Aggregate().InstanceID),
|
||||||
|
@ -51,15 +51,15 @@ func TestInstanceProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "reduceGlobalOrgSet",
|
name: "reduceDefaultOrgSet",
|
||||||
args: args{
|
args: args{
|
||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.GlobalOrgSetEventType),
|
repository.EventType(instance.DefaultOrgSetEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"globalOrgId": "orgid"}`),
|
[]byte(`{"orgId": "orgid"}`),
|
||||||
), instance.GlobalOrgSetMapper),
|
), instance.DefaultOrgSetMapper),
|
||||||
},
|
},
|
||||||
reduce: (&InstanceProjection{}).reduceGlobalOrgSet,
|
reduce: (&InstanceProjection{}).reduceDefaultOrgSet,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
projection: InstanceProjectionTable,
|
projection: InstanceProjectionTable,
|
||||||
aggregateType: eventstore.AggregateType("instance"),
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
@ -68,7 +68,7 @@ func TestInstanceProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.instances SET (change_date, sequence, global_org_id) = ($1, $2, $3) WHERE (id = $4)",
|
expectedStmt: "UPDATE projections.instances SET (change_date, sequence, default_org_id) = ($1, $2, $3) WHERE (id = $4)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
uint64(15),
|
uint64(15),
|
||||||
|
@ -11,45 +11,45 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GlobalOrgSetEventType eventstore.EventType = "iam.global.org.set"
|
DefaultOrgSetEventType eventstore.EventType = "instance.default.org.set"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GlobalOrgSetEvent struct {
|
type DefaultOrgSetEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
OrgID string `json:"globalOrgId"`
|
OrgID string `json:"orgId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *GlobalOrgSetEvent) Data() interface{} {
|
func (e *DefaultOrgSetEvent) Data() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *GlobalOrgSetEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
func (e *DefaultOrgSetEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGlobalOrgSetEventEvent(
|
func NewDefaultOrgSetEventEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
orgID string,
|
orgID string,
|
||||||
) *GlobalOrgSetEvent {
|
) *DefaultOrgSetEvent {
|
||||||
return &GlobalOrgSetEvent{
|
return &DefaultOrgSetEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
GlobalOrgSetEventType,
|
DefaultOrgSetEventType,
|
||||||
),
|
),
|
||||||
OrgID: orgID,
|
OrgID: orgID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GlobalOrgSetMapper(event *repository.Event) (eventstore.Event, error) {
|
func DefaultOrgSetMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
e := &GlobalOrgSetEvent{
|
e := &DefaultOrgSetEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(event.Data, e)
|
err := json.Unmarshal(event.Data, e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.ThrowInternal(err, "IAM-cdFZH", "unable to unmarshal global org set")
|
return nil, errors.ThrowInternal(err, "IAM-cdFZH", "unable to unmarshal default org set")
|
||||||
}
|
}
|
||||||
|
|
||||||
return e, nil
|
return e, nil
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func RegisterEventMappers(es *eventstore.Eventstore) {
|
func RegisterEventMappers(es *eventstore.Eventstore) {
|
||||||
es.RegisterFilterEventMapper(GlobalOrgSetEventType, GlobalOrgSetMapper).
|
es.RegisterFilterEventMapper(DefaultOrgSetEventType, DefaultOrgSetMapper).
|
||||||
RegisterFilterEventMapper(ProjectSetEventType, ProjectSetMapper).
|
RegisterFilterEventMapper(ProjectSetEventType, ProjectSetMapper).
|
||||||
RegisterFilterEventMapper(ConsoleSetEventType, ConsoleSetMapper).
|
RegisterFilterEventMapper(ConsoleSetEventType, ConsoleSetMapper).
|
||||||
RegisterFilterEventMapper(DefaultLanguageSetEventType, DefaultLanguageSetMapper).
|
RegisterFilterEventMapper(DefaultLanguageSetEventType, DefaultLanguageSetMapper).
|
||||||
|
@ -271,8 +271,6 @@ Errors:
|
|||||||
MemberAlreadyExisting: Member existiert bereits
|
MemberAlreadyExisting: Member existiert bereits
|
||||||
MemberNotExisting: Member existiert nicht
|
MemberNotExisting: Member existiert nicht
|
||||||
IDMissing: ID fehlt
|
IDMissing: ID fehlt
|
||||||
GlobalOrgMissing: Globale Organisation fehlt
|
|
||||||
GlobalOrgAlreadySet: Globale Organisation wurde bereits gesetzt
|
|
||||||
IAMProjectIDMissing: IAM Project ID fehlt
|
IAMProjectIDMissing: IAM Project ID fehlt
|
||||||
IamProjectAlreadySet: IAM Project ID wurde bereits gesetzt
|
IamProjectAlreadySet: IAM Project ID wurde bereits gesetzt
|
||||||
IdpInvalid: IDP Konfiguration ist ungültig
|
IdpInvalid: IDP Konfiguration ist ungültig
|
||||||
|
@ -271,8 +271,6 @@ Errors:
|
|||||||
MemberAlreadyExisting: Member already exists
|
MemberAlreadyExisting: Member already exists
|
||||||
MemberNotExisting: Member does not exist
|
MemberNotExisting: Member does not exist
|
||||||
IDMissing: Id missing
|
IDMissing: Id missing
|
||||||
GlobalOrgMissing: Global organization missing
|
|
||||||
GlobalOrgAlreadySet: Global organization has already been set
|
|
||||||
IAMProjectIDMissing: IAM project id missing
|
IAMProjectIDMissing: IAM project id missing
|
||||||
IamProjectAlreadySet: IAM project id has already been set
|
IamProjectAlreadySet: IAM project id has already been set
|
||||||
IdpInvalid: IDP configuration is invalid
|
IdpInvalid: IDP configuration is invalid
|
||||||
|
@ -269,8 +269,6 @@ Errors:
|
|||||||
MemberAlreadyExisting: Il membro già esistente
|
MemberAlreadyExisting: Il membro già esistente
|
||||||
MemberNotExisting: Il membro non esistente
|
MemberNotExisting: Il membro non esistente
|
||||||
IDMissing: ID mancante
|
IDMissing: ID mancante
|
||||||
GlobalOrgMissing: Manca un'organizzazione globale
|
|
||||||
GlobalOrgAlreadySet: L'organizzazione globale è già stata impostata
|
|
||||||
IAMProjectIDMissing: Manca l'ID del progetto IAM
|
IAMProjectIDMissing: Manca l'ID del progetto IAM
|
||||||
IamProjectAlreadySet: L'ID del progetto IAM è già stato impostato
|
IamProjectAlreadySet: L'ID del progetto IAM è già stato impostato
|
||||||
IdpInvalid: La configurazione dell'IDP non è valida
|
IdpInvalid: La configurazione dell'IDP non è valida
|
||||||
|
@ -423,6 +423,28 @@ service AdminService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the default org
|
||||||
|
rpc SetDefaultOrg(SetDefaultOrgRequest) returns (SetDefaultOrgResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put: "/orgs/default/{org_id}";
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.write";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the default org
|
||||||
|
rpc GetDefaultOrg(GetDefaultOrgRequest) returns (GetDefaultOrgResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/orgs/default";
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.read";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//Returns all organisations matching the request
|
//Returns all organisations matching the request
|
||||||
// all queries need to match (AND)
|
// all queries need to match (AND)
|
||||||
rpc ListOrgs(ListOrgsRequest) returns (ListOrgsResponse) {
|
rpc ListOrgs(ListOrgsRequest) returns (ListOrgsResponse) {
|
||||||
@ -2569,6 +2591,21 @@ message GetDefaultLanguageResponse {
|
|||||||
string language = 1;
|
string language = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SetDefaultOrgRequest {
|
||||||
|
string org_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
|
}
|
||||||
|
|
||||||
|
message SetDefaultOrgResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This is an empty request
|
||||||
|
message GetDefaultOrgRequest {}
|
||||||
|
|
||||||
|
message GetDefaultOrgResponse {
|
||||||
|
zitadel.org.v1.Org org = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message ListInstanceDomainsRequest {
|
message ListInstanceDomainsRequest {
|
||||||
zitadel.v1.ListQuery query = 1;
|
zitadel.v1.ListQuery query = 1;
|
||||||
// the field the result is sorted
|
// the field the result is sorted
|
||||||
|
@ -2877,8 +2877,10 @@ message GetOIDCInformationResponse {
|
|||||||
message GetIAMRequest {}
|
message GetIAMRequest {}
|
||||||
|
|
||||||
message GetIAMResponse {
|
message GetIAMResponse {
|
||||||
|
//deprecated: use default_org_id instead
|
||||||
string global_org_id = 1;
|
string global_org_id = 1;
|
||||||
string iam_project_id = 2;
|
string iam_project_id = 2;
|
||||||
|
string default_org_id = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is an empty request
|
//This is an empty request
|
||||||
|
Loading…
x
Reference in New Issue
Block a user