mirror of
https://github.com/zitadel/zitadel.git
synced 2025-05-01 06:50:50 +00:00
feat: check has project (#2206)
* feat: define org grant check on project * feat: has project check * feat: has project check * feat: check has project * feat: check has project * feat: add has project check to console * Update internal/auth/repository/eventsourcing/eventstore/auth_request.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/auth/repository/eventsourcing/eventstore/auth_request.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/auth/repository/eventsourcing/eventstore/auth_request.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/auth/repository/eventsourcing/eventstore/auth_request.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/auth/repository/eventsourcing/eventstore/auth_request_test.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/auth/repository/eventsourcing/eventstore/auth_request_test.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/auth/repository/eventsourcing/eventstore/auth_request_test.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update internal/ui/login/static/i18n/en.yaml Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix: add has project tests Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
parent
0b3155b8ab
commit
0ab973b967
@ -89,6 +89,9 @@
|
|||||||
<mat-checkbox [(ngModel)]="project.projectRoleCheck" (change)="saveProject()" color="primary">
|
<mat-checkbox [(ngModel)]="project.projectRoleCheck" (change)="saveProject()" color="primary">
|
||||||
{{'PROJECT.ROLE.CHECK' | translate}}</mat-checkbox>
|
{{'PROJECT.ROLE.CHECK' | translate}}</mat-checkbox>
|
||||||
<p class="desc">{{'PROJECT.ROLE.CHECK_DESCRIPTION' | translate}}</p>
|
<p class="desc">{{'PROJECT.ROLE.CHECK_DESCRIPTION' | translate}}</p>
|
||||||
|
<mat-checkbox [(ngModel)]="project.hasProjectCheck" (change)="saveProject()" color="primary">
|
||||||
|
{{'PROJECT.HAS_PROJECT' | translate}}</mat-checkbox>
|
||||||
|
<p class="desc">{{'PROJECT.HAS_PROJECT_DESCRIPTION' | translate}}</p>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<app-project-roles
|
<app-project-roles
|
||||||
[disabled]="(['project.role.write$', 'project.role.write:'+ project.id]| hasRole | async) == false"
|
[disabled]="(['project.role.write$', 'project.role.write:'+ project.id]| hasRole | async) == false"
|
||||||
|
@ -185,6 +185,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
|||||||
req.setName(this.project.name);
|
req.setName(this.project.name);
|
||||||
req.setProjectRoleAssertion(this.project.projectRoleAssertion);
|
req.setProjectRoleAssertion(this.project.projectRoleAssertion);
|
||||||
req.setProjectRoleCheck(this.project.projectRoleCheck);
|
req.setProjectRoleCheck(this.project.projectRoleCheck);
|
||||||
|
req.setHasProjectCheck(this.project.hasProjectCheck);
|
||||||
|
|
||||||
this.mgmtService.updateProject(req).then(() => {
|
this.mgmtService.updateProject(req).then(() => {
|
||||||
this.toast.showInfo('PROJECT.TOAST.UPDATED', true);
|
this.toast.showInfo('PROJECT.TOAST.UPDATED', true);
|
||||||
|
@ -1034,6 +1034,8 @@
|
|||||||
"CHECK": "Rollen bei Authentisierung prüfen",
|
"CHECK": "Rollen bei Authentisierung prüfen",
|
||||||
"CHECK_DESCRIPTION": "Ist das Attribut gesetzt, kann ein Benutzer nur mit einem entsprechenden Rolle authentifiziert werden."
|
"CHECK_DESCRIPTION": "Ist das Attribut gesetzt, kann ein Benutzer nur mit einem entsprechenden Rolle authentifiziert werden."
|
||||||
},
|
},
|
||||||
|
"HAS_PROJECT": "Projektbesitz bei Authentisierung prüfen",
|
||||||
|
"HAS_PROJECT_DESCRIPTION": "Es wird überprüft, ob die Organisation des Benutzers über dieses Projekt verfügt. Wenn nicht, kann der Benutzer nicht authentifiziert werden.",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"TOTAL": "Einträge gesamt:",
|
"TOTAL": "Einträge gesamt:",
|
||||||
"SELECTION": "ausgewählt",
|
"SELECTION": "ausgewählt",
|
||||||
|
@ -1036,6 +1036,8 @@
|
|||||||
"CHECK": "Check roles on Authentication",
|
"CHECK": "Check roles on Authentication",
|
||||||
"CHECK_DESCRIPTION": "If set, users are only allowed to authenticate if any role is assigned to their account."
|
"CHECK_DESCRIPTION": "If set, users are only allowed to authenticate if any role is assigned to their account."
|
||||||
},
|
},
|
||||||
|
"HAS_PROJECT": "Check for Project on Authentication",
|
||||||
|
"HAS_PROJECT_DESCRIPTION": "It is checked whether the user's organisation has this project. If not, the user cannot be authenticated.",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"TOTAL": "Entries total:",
|
"TOTAL": "Entries total:",
|
||||||
"SELECTION": "Selected Elements",
|
"SELECTION": "Selected Elements",
|
||||||
|
@ -3276,6 +3276,7 @@ This is an empty request
|
|||||||
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
| project_role_assertion | bool | - | |
|
| project_role_assertion | bool | - | |
|
||||||
| project_role_check | bool | - | |
|
| project_role_check | bool | - | |
|
||||||
|
| has_project_check | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -7520,6 +7521,7 @@ This is an empty request
|
|||||||
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
|
||||||
| project_role_assertion | bool | - | |
|
| project_role_assertion | bool | - | |
|
||||||
| project_role_check | bool | - | |
|
| project_role_check | bool | - | |
|
||||||
|
| has_project_check | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ title: zitadel/project.proto
|
|||||||
| state | ProjectState | - | |
|
| state | ProjectState | - | |
|
||||||
| project_role_assertion | bool | describes if roles of user should be added in token | |
|
| project_role_assertion | bool | describes if roles of user should be added in token | |
|
||||||
| project_role_check | bool | ZITADEL checks if the user has at least one on this project | |
|
| project_role_check | bool | ZITADEL checks if the user has at least one on this project | |
|
||||||
|
| has_project_check | bool | ZITADEL checks if the org of the user has permission to this project | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,32 @@ title: zitadel/text.proto
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### ExternalRegistrationUserOverviewScreenText
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| title | string | - | string.max_len: 200<br /> |
|
||||||
|
| description | string | - | string.max_len: 500<br /> |
|
||||||
|
| email_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| username_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| firstname_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| lastname_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| nickname_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| language_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| phone_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_and_privacy_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_confirm | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_link_text | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_confirm_and | string | - | string.max_len: 200<br /> |
|
||||||
|
| privacy_link_text | string | - | string.max_len: 200<br /> |
|
||||||
|
| back_button_text | string | - | string.max_len: 200<br /> |
|
||||||
|
| next_button_text | string | - | string.max_len: 200<br /> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ExternalUserNotFoundScreenText
|
### ExternalUserNotFoundScreenText
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +75,11 @@ title: zitadel/text.proto
|
|||||||
| description | string | - | string.max_len: 500<br /> |
|
| description | string | - | string.max_len: 500<br /> |
|
||||||
| link_button_text | string | - | string.max_len: 100<br /> |
|
| link_button_text | string | - | string.max_len: 100<br /> |
|
||||||
| auto_register_button_text | string | - | string.max_len: 100<br /> |
|
| auto_register_button_text | string | - | string.max_len: 100<br /> |
|
||||||
|
| tos_and_privacy_label | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_confirm | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_link_text | string | - | string.max_len: 200<br /> |
|
||||||
|
| privacy_link_text | string | - | string.max_len: 200<br /> |
|
||||||
|
| tos_confirm_and | string | - | string.max_len: 200<br /> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -246,6 +277,7 @@ title: zitadel/text.proto
|
|||||||
| passwordless_prompt_text | PasswordlessPromptScreenText | - | |
|
| passwordless_prompt_text | PasswordlessPromptScreenText | - | |
|
||||||
| passwordless_registration_text | PasswordlessRegistrationScreenText | - | |
|
| passwordless_registration_text | PasswordlessRegistrationScreenText | - | |
|
||||||
| passwordless_registration_done_text | PasswordlessRegistrationDoneScreenText | - | |
|
| passwordless_registration_done_text | PasswordlessRegistrationDoneScreenText | - | |
|
||||||
|
| external_registration_user_overview_text | ExternalRegistrationUserOverviewScreenText | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -405,6 +437,7 @@ title: zitadel/text.proto
|
|||||||
| title | string | - | string.max_len: 200<br /> |
|
| title | string | - | string.max_len: 200<br /> |
|
||||||
| description | string | - | string.max_len: 500<br /> |
|
| description | string | - | string.max_len: 500<br /> |
|
||||||
| next_button_text | string | - | string.max_len: 100<br /> |
|
| next_button_text | string | - | string.max_len: 100<br /> |
|
||||||
|
| cancel_button_text | string | - | string.max_len: 100<br /> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ func ProjectCreateToDomain(req *mgmt_pb.AddProjectRequest) *domain.Project {
|
|||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
ProjectRoleAssertion: req.ProjectRoleAssertion,
|
ProjectRoleAssertion: req.ProjectRoleAssertion,
|
||||||
ProjectRoleCheck: req.ProjectRoleCheck,
|
ProjectRoleCheck: req.ProjectRoleCheck,
|
||||||
|
HasProjectCheck: req.HasProjectCheck,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ func ProjectUpdateToDomain(req *mgmt_pb.UpdateProjectRequest) *domain.Project {
|
|||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
ProjectRoleAssertion: req.ProjectRoleAssertion,
|
ProjectRoleAssertion: req.ProjectRoleAssertion,
|
||||||
ProjectRoleCheck: req.ProjectRoleCheck,
|
ProjectRoleCheck: req.ProjectRoleCheck,
|
||||||
|
HasProjectCheck: req.HasProjectCheck,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ func ProjectToPb(project *proj_model.ProjectView) *proj_pb.Project {
|
|||||||
State: projectStateToPb(project.State),
|
State: projectStateToPb(project.State),
|
||||||
ProjectRoleAssertion: project.ProjectRoleAssertion,
|
ProjectRoleAssertion: project.ProjectRoleAssertion,
|
||||||
ProjectRoleCheck: project.ProjectRoleCheck,
|
ProjectRoleCheck: project.ProjectRoleCheck,
|
||||||
|
HasProjectCheck: project.HasProjectCheck,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ type AuthRequestRepo struct {
|
|||||||
LockoutPolicyViewProvider lockoutPolicyViewProvider
|
LockoutPolicyViewProvider lockoutPolicyViewProvider
|
||||||
IDPProviderViewProvider idpProviderViewProvider
|
IDPProviderViewProvider idpProviderViewProvider
|
||||||
UserGrantProvider userGrantProvider
|
UserGrantProvider userGrantProvider
|
||||||
|
ProjectProvider projectProvider
|
||||||
|
|
||||||
IdGenerator id.Generator
|
IdGenerator id.Generator
|
||||||
|
|
||||||
@ -96,6 +97,11 @@ type userGrantProvider interface {
|
|||||||
UserGrantsByProjectAndUserID(string, string) ([]*grant_view_model.UserGrantView, error)
|
UserGrantsByProjectAndUserID(string, string) ([]*grant_view_model.UserGrantView, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type projectProvider interface {
|
||||||
|
ApplicationByClientID(context.Context, string) (*project_view_model.ApplicationView, error)
|
||||||
|
OrgProjectMappingByIDs(orgID, projectID string) (*project_view_model.OrgProjectMapping, error)
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *AuthRequestRepo) Health(ctx context.Context) error {
|
func (repo *AuthRequestRepo) Health(ctx context.Context) error {
|
||||||
return repo.AuthRequests.Health(ctx)
|
return repo.AuthRequests.Health(ctx)
|
||||||
}
|
}
|
||||||
@ -680,7 +686,15 @@ func (repo *AuthRequestRepo) nextSteps(ctx context.Context, request *domain.Auth
|
|||||||
}
|
}
|
||||||
//PLANNED: consent step
|
//PLANNED: consent step
|
||||||
|
|
||||||
missing, err := userGrantRequired(ctx, request, user, repo.UserGrantProvider)
|
missing, err := projectRequired(ctx, request, repo.ProjectProvider)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if missing {
|
||||||
|
return append(steps, &domain.ProjectRequiredStep{}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
missing, err = userGrantRequired(ctx, request, user, repo.UserGrantProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1081,6 +1095,7 @@ func linkingIDPConfigExistingInAllowedIDPs(linkingUsers []*domain.ExternalUser,
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func userGrantRequired(ctx context.Context, request *domain.AuthRequest, user *user_model.UserView, userGrantProvider userGrantProvider) (_ bool, err error) {
|
func userGrantRequired(ctx context.Context, request *domain.AuthRequest, user *user_model.UserView, userGrantProvider userGrantProvider) (_ bool, err error) {
|
||||||
var app *project_view_model.ApplicationView
|
var app *project_view_model.ApplicationView
|
||||||
switch request.Request.Type() {
|
switch request.Request.Type() {
|
||||||
@ -1101,3 +1116,27 @@ func userGrantRequired(ctx context.Context, request *domain.AuthRequest, user *u
|
|||||||
}
|
}
|
||||||
return len(grants) == 0, nil
|
return len(grants) == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func projectRequired(ctx context.Context, request *domain.AuthRequest, projectProvider projectProvider) (_ bool, err error) {
|
||||||
|
var app *project_view_model.ApplicationView
|
||||||
|
switch request.Request.Type() {
|
||||||
|
case domain.AuthRequestTypeOIDC:
|
||||||
|
app, err = projectProvider.ApplicationByClientID(ctx, request.ApplicationID)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false, errors.ThrowPreconditionFailed(nil, "EVENT-dfrw2", "Errors.AuthRequest.RequestTypeNotSupported")
|
||||||
|
}
|
||||||
|
if !app.HasProjectCheck {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
_, err = projectProvider.OrgProjectMappingByIDs(request.UserOrgID, app.ProjectID)
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
@ -6,9 +6,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/crypto"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||||
"github.com/caos/zitadel/internal/auth_request/model"
|
"github.com/caos/zitadel/internal/auth_request/model"
|
||||||
"github.com/caos/zitadel/internal/auth_request/repository/cache"
|
"github.com/caos/zitadel/internal/auth_request/repository/cache"
|
||||||
@ -227,6 +228,22 @@ func (m *mockUserGrants) UserGrantsByProjectAndUserID(s string, s2 string) ([]*g
|
|||||||
return grants, nil
|
return grants, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockProject struct {
|
||||||
|
hasProject bool
|
||||||
|
projectCheck bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockProject) ApplicationByClientID(ctx context.Context, s string) (*proj_view_model.ApplicationView, error) {
|
||||||
|
return &proj_view_model.ApplicationView{HasProjectCheck: m.projectCheck}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockProject) OrgProjectMappingByIDs(orgID, projectID string) (*proj_view_model.OrgProjectMapping, error) {
|
||||||
|
if m.hasProject {
|
||||||
|
return &proj_view_model.OrgProjectMapping{OrgID: orgID, ProjectID: projectID}, nil
|
||||||
|
}
|
||||||
|
return nil, errors.ThrowNotFound(nil, "ERROR", "error")
|
||||||
|
}
|
||||||
|
|
||||||
func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
AuthRequests *cache.AuthRequestCache
|
AuthRequests *cache.AuthRequestCache
|
||||||
@ -236,6 +253,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userEventProvider userEventProvider
|
userEventProvider userEventProvider
|
||||||
orgViewProvider orgViewProvider
|
orgViewProvider orgViewProvider
|
||||||
userGrantProvider userGrantProvider
|
userGrantProvider userGrantProvider
|
||||||
|
projectProvider projectProvider
|
||||||
loginPolicyProvider loginPolicyViewProvider
|
loginPolicyProvider loginPolicyViewProvider
|
||||||
lockoutPolicyProvider lockoutPolicyViewProvider
|
lockoutPolicyProvider lockoutPolicyViewProvider
|
||||||
PasswordCheckLifeTime time.Duration
|
PasswordCheckLifeTime time.Duration
|
||||||
@ -684,6 +702,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
projectProvider: &mockProject{},
|
||||||
loginPolicyProvider: &mockLoginPolicy{
|
loginPolicyProvider: &mockLoginPolicy{
|
||||||
policy: &iam_view_model.LoginPolicyView{},
|
policy: &iam_view_model.LoginPolicyView{},
|
||||||
},
|
},
|
||||||
@ -741,6 +760,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
projectProvider: &mockProject{},
|
||||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
policy: &iam_view_model.LockoutPolicyView{
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
@ -971,6 +991,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
projectProvider: &mockProject{},
|
||||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
policy: &iam_view_model.LockoutPolicyView{
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
@ -1004,6 +1025,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
projectProvider: &mockProject{},
|
||||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
policy: &iam_view_model.LockoutPolicyView{
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
@ -1041,6 +1063,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
roleCheck: true,
|
roleCheck: true,
|
||||||
userGrants: 0,
|
userGrants: 0,
|
||||||
},
|
},
|
||||||
|
projectProvider: &mockProject{},
|
||||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
policy: &iam_view_model.LockoutPolicyView{
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
@ -1078,6 +1101,83 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
roleCheck: true,
|
roleCheck: true,
|
||||||
userGrants: 2,
|
userGrants: 2,
|
||||||
},
|
},
|
||||||
|
projectProvider: &mockProject{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
|
},
|
||||||
|
args{&domain.AuthRequest{
|
||||||
|
UserID: "UserID",
|
||||||
|
Prompt: []domain.Prompt{domain.PromptNone},
|
||||||
|
Request: &domain.AuthRequestOIDC{},
|
||||||
|
LoginPolicy: &domain.LoginPolicy{
|
||||||
|
SecondFactors: []domain.SecondFactorType{domain.SecondFactorTypeOTP},
|
||||||
|
},
|
||||||
|
}, true},
|
||||||
|
[]domain.NextStep{&domain.RedirectToCallbackStep{}},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt none, checkLoggedIn true, authenticated and required project missing, project required step",
|
||||||
|
fields{
|
||||||
|
userSessionViewProvider: &mockViewUserSession{
|
||||||
|
PasswordVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||||
|
SecondFactorVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||||
|
},
|
||||||
|
userViewProvider: &mockViewUser{
|
||||||
|
PasswordSet: true,
|
||||||
|
IsEmailVerified: true,
|
||||||
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
|
},
|
||||||
|
userEventProvider: &mockEventUser{},
|
||||||
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
projectProvider: &mockProject{
|
||||||
|
projectCheck: true,
|
||||||
|
hasProject: false,
|
||||||
|
},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
|
},
|
||||||
|
args{&domain.AuthRequest{
|
||||||
|
UserID: "UserID",
|
||||||
|
Prompt: []domain.Prompt{domain.PromptNone},
|
||||||
|
Request: &domain.AuthRequestOIDC{},
|
||||||
|
LoginPolicy: &domain.LoginPolicy{
|
||||||
|
SecondFactors: []domain.SecondFactorType{domain.SecondFactorTypeOTP},
|
||||||
|
},
|
||||||
|
}, true},
|
||||||
|
[]domain.NextStep{&domain.ProjectRequiredStep{}},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt none, checkLoggedIn true, authenticated and required project exist, redirect to callback step",
|
||||||
|
fields{
|
||||||
|
userSessionViewProvider: &mockViewUserSession{
|
||||||
|
PasswordVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||||
|
SecondFactorVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||||
|
},
|
||||||
|
userViewProvider: &mockViewUser{
|
||||||
|
PasswordSet: true,
|
||||||
|
IsEmailVerified: true,
|
||||||
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
|
},
|
||||||
|
userEventProvider: &mockEventUser{},
|
||||||
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
projectProvider: &mockProject{
|
||||||
|
projectCheck: true,
|
||||||
|
hasProject: true,
|
||||||
|
},
|
||||||
lockoutPolicyProvider: &mockLockoutPolicy{
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
policy: &iam_view_model.LockoutPolicyView{
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
@ -1172,6 +1272,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
UserEventProvider: tt.fields.userEventProvider,
|
UserEventProvider: tt.fields.userEventProvider,
|
||||||
OrgViewProvider: tt.fields.orgViewProvider,
|
OrgViewProvider: tt.fields.orgViewProvider,
|
||||||
UserGrantProvider: tt.fields.userGrantProvider,
|
UserGrantProvider: tt.fields.userGrantProvider,
|
||||||
|
ProjectProvider: tt.fields.projectProvider,
|
||||||
LoginPolicyViewProvider: tt.fields.loginPolicyProvider,
|
LoginPolicyViewProvider: tt.fields.loginPolicyProvider,
|
||||||
LockoutPolicyViewProvider: tt.fields.lockoutPolicyProvider,
|
LockoutPolicyViewProvider: tt.fields.lockoutPolicyProvider,
|
||||||
PasswordCheckLifeTime: tt.fields.PasswordCheckLifeTime,
|
PasswordCheckLifeTime: tt.fields.PasswordCheckLifeTime,
|
||||||
|
@ -82,6 +82,7 @@ func (a *Application) Reduce(event *models.Event) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
app.ProjectRoleCheck = project.ProjectRoleCheck
|
app.ProjectRoleCheck = project.ProjectRoleCheck
|
||||||
|
app.HasProjectCheck = project.HasProjectCheck
|
||||||
app.ProjectRoleAssertion = project.ProjectRoleAssertion
|
app.ProjectRoleAssertion = project.ProjectRoleAssertion
|
||||||
|
|
||||||
err = app.AppendEvent(event)
|
err = app.AppendEvent(event)
|
||||||
|
@ -74,6 +74,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
||||||
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
||||||
newLockoutPolicy(handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
newLockoutPolicy(handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||||
|
newOrgProjectMapping(handler{view, bulkLimit, configs.cycleDuration("OrgProjectMapping"), errorCount, es}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/logging"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
|
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||||
|
"github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||||
|
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||||
|
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
orgProjectMappingTable = "auth.org_project_mapping"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrgProjectMapping struct {
|
||||||
|
handler
|
||||||
|
subscription *v1.Subscription
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOrgProjectMapping(
|
||||||
|
handler handler,
|
||||||
|
) *OrgProjectMapping {
|
||||||
|
h := &OrgProjectMapping{
|
||||||
|
handler: handler,
|
||||||
|
}
|
||||||
|
|
||||||
|
h.subscribe()
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *OrgProjectMapping) subscribe() {
|
||||||
|
k.subscription = k.es.Subscribe(k.AggregateTypes()...)
|
||||||
|
go func() {
|
||||||
|
for event := range k.subscription.Events {
|
||||||
|
query.ReduceEvent(k, event)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) ViewModel() string {
|
||||||
|
return orgProjectMappingTable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) Subscription() *v1.Subscription {
|
||||||
|
return p.subscription
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ *OrgProjectMapping) AggregateTypes() []es_models.AggregateType {
|
||||||
|
return []es_models.AggregateType{model.ProjectAggregate}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) CurrentSequence() (uint64, error) {
|
||||||
|
sequence, err := p.view.GetLatestOrgProjectMappingSequence()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return sequence.CurrentSequence, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) EventQuery() (*es_models.SearchQuery, error) {
|
||||||
|
sequence, err := p.view.GetLatestOrgProjectMappingSequence()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) {
|
||||||
|
mapping := new(view_model.OrgProjectMapping)
|
||||||
|
switch event.Type {
|
||||||
|
case model.ProjectAdded:
|
||||||
|
mapping.OrgID = event.ResourceOwner
|
||||||
|
mapping.ProjectID = event.AggregateID
|
||||||
|
case model.ProjectRemoved:
|
||||||
|
err := p.view.DeleteOrgProjectMappingsByProjectID(event.AggregateID)
|
||||||
|
if err == nil {
|
||||||
|
return p.view.ProcessedOrgProjectMappingSequence(event)
|
||||||
|
}
|
||||||
|
case model.ProjectGrantAdded:
|
||||||
|
projectGrant := new(view_model.ProjectGrant)
|
||||||
|
projectGrant.SetData(event)
|
||||||
|
mapping.OrgID = projectGrant.GrantedOrgID
|
||||||
|
mapping.ProjectID = event.AggregateID
|
||||||
|
mapping.ProjectGrantID = projectGrant.GrantID
|
||||||
|
case model.ProjectGrantRemoved:
|
||||||
|
projectGrant := new(view_model.ProjectGrant)
|
||||||
|
projectGrant.SetData(event)
|
||||||
|
err := p.view.DeleteOrgProjectMappingsByProjectGrantID(event.AggregateID)
|
||||||
|
if err == nil {
|
||||||
|
return p.view.ProcessedOrgProjectMappingSequence(event)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return p.view.ProcessedOrgProjectMappingSequence(event)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.view.PutOrgProjectMapping(mapping, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) OnError(event *es_models.Event, err error) error {
|
||||||
|
logging.LogWithFields("SPOOL-2k0fS", "id", event.AggregateID).WithError(err).Warn("something went wrong in org project mapping handler")
|
||||||
|
return spooler.HandleError(event, err, p.view.GetLatestOrgProjectMappingFailedEvent, p.view.ProcessedOrgProjectMappingFailedEvent, p.view.ProcessedOrgProjectMappingSequence, p.errorCountUntilSkip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OrgProjectMapping) OnSuccess() error {
|
||||||
|
return spooler.HandleSuccess(p.view.UpdateOrgProjectMappingSpoolerRunTimestamp)
|
||||||
|
}
|
@ -111,6 +111,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
|||||||
LoginPolicyViewProvider: view,
|
LoginPolicyViewProvider: view,
|
||||||
LockoutPolicyViewProvider: view,
|
LockoutPolicyViewProvider: view,
|
||||||
UserGrantProvider: view,
|
UserGrantProvider: view,
|
||||||
|
ProjectProvider: view,
|
||||||
IdGenerator: idGenerator,
|
IdGenerator: idGenerator,
|
||||||
PasswordCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
PasswordCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
||||||
ExternalLoginCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
ExternalLoginCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
"github.com/caos/zitadel/internal/project/repository/view"
|
||||||
|
"github.com/caos/zitadel/internal/project/repository/view/model"
|
||||||
|
"github.com/caos/zitadel/internal/view/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
orgPrgojectMappingTable = "auth.org_project_mapping"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *View) OrgProjectMappingByIDs(orgID, projectID string) (*model.OrgProjectMapping, error) {
|
||||||
|
return view.OrgProjectMappingByIDs(v.Db, orgPrgojectMappingTable, orgID, projectID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) PutOrgProjectMapping(mapping *model.OrgProjectMapping, event *models.Event) error {
|
||||||
|
err := view.PutOrgProjectMapping(v.Db, orgPrgojectMappingTable, mapping)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedOrgProjectMappingSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteOrgProjectMapping(orgID, projectID string, event *models.Event) error {
|
||||||
|
err := view.DeleteOrgProjectMapping(v.Db, orgPrgojectMappingTable, orgID, projectID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedOrgProjectMappingSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteOrgProjectMappingsByProjectID(projectID string) error {
|
||||||
|
return view.DeleteOrgProjectMappingsByProjectID(v.Db, orgPrgojectMappingTable, projectID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteOrgProjectMappingsByProjectGrantID(projectGrantID string) error {
|
||||||
|
return view.DeleteOrgProjectMappingsByProjectGrantID(v.Db, orgPrgojectMappingTable, projectGrantID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestOrgProjectMappingSequence() (*repository.CurrentSequence, error) {
|
||||||
|
return v.latestSequence(orgPrgojectMappingTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedOrgProjectMappingSequence(event *models.Event) error {
|
||||||
|
return v.saveCurrentSequence(orgPrgojectMappingTable, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) UpdateOrgProjectMappingSpoolerRunTimestamp() error {
|
||||||
|
return v.updateSpoolerRunSequence(orgPrgojectMappingTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestOrgProjectMappingFailedEvent(sequence uint64) (*repository.FailedEvent, error) {
|
||||||
|
return v.latestFailedEvent(orgPrgojectMappingTable, sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedOrgProjectMappingFailedEvent(failedEvent *repository.FailedEvent) error {
|
||||||
|
return v.saveFailedEvent(failedEvent)
|
||||||
|
}
|
@ -45,7 +45,7 @@ func (c *Commands) addProject(ctx context.Context, projectAdd *domain.Project, r
|
|||||||
projectRole = domain.RoleProjectOwnerGlobal
|
projectRole = domain.RoleProjectOwnerGlobal
|
||||||
}
|
}
|
||||||
events := []eventstore.EventPusher{
|
events := []eventstore.EventPusher{
|
||||||
project.NewProjectAddedEvent(ctx, projectAgg, projectAdd.Name),
|
project.NewProjectAddedEvent(ctx, projectAgg, projectAdd.Name, projectAdd.ProjectRoleAssertion, projectAdd.ProjectRoleCheck, projectAdd.HasProjectCheck),
|
||||||
project.NewProjectMemberAddedEvent(ctx, projectAgg, ownerUserID, projectRole),
|
project.NewProjectMemberAddedEvent(ctx, projectAgg, ownerUserID, projectRole),
|
||||||
}
|
}
|
||||||
return events, addedProject, nil
|
return events, addedProject, nil
|
||||||
@ -87,7 +87,13 @@ func (c *Commands) ChangeProject(ctx context.Context, projectChange *domain.Proj
|
|||||||
}
|
}
|
||||||
|
|
||||||
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
|
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
|
||||||
changedEvent, hasChanged, err := existingProject.NewChangedEvent(ctx, projectAgg, projectChange.Name, projectChange.ProjectRoleAssertion, projectChange.ProjectRoleCheck)
|
changedEvent, hasChanged, err := existingProject.NewChangedEvent(
|
||||||
|
ctx,
|
||||||
|
projectAgg,
|
||||||
|
projectChange.Name,
|
||||||
|
projectChange.ProjectRoleAssertion,
|
||||||
|
projectChange.ProjectRoleCheck,
|
||||||
|
projectChange.HasProjectCheck)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -113,7 +113,7 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
@ -180,7 +180,7 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
|
@ -87,7 +87,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -116,7 +116,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
|
@ -10,6 +10,7 @@ func projectWriteModelToProject(writeModel *ProjectWriteModel) *domain.Project {
|
|||||||
Name: writeModel.Name,
|
Name: writeModel.Name,
|
||||||
ProjectRoleAssertion: writeModel.ProjectRoleAssertion,
|
ProjectRoleAssertion: writeModel.ProjectRoleAssertion,
|
||||||
ProjectRoleCheck: writeModel.ProjectRoleCheck,
|
ProjectRoleCheck: writeModel.ProjectRoleCheck,
|
||||||
|
HasProjectCheck: writeModel.HasProjectCheck,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ func TestCommandSide_AddProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -116,7 +116,7 @@ func TestCommandSide_AddProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -152,7 +152,7 @@ func TestCommandSide_AddProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -341,7 +341,7 @@ func TestCommandSide_ChangeProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -379,7 +379,7 @@ func TestCommandSide_ChangeProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -424,7 +424,7 @@ func TestCommandSide_ChangeProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -477,7 +477,7 @@ func TestCommandSide_ChangeProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -556,7 +556,7 @@ func TestCommandSide_ChangeProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -637,7 +637,7 @@ func TestCommandSide_ChangeProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -813,7 +813,7 @@ func TestCommandSide_DeactivateProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -839,7 +839,7 @@ func TestCommandSide_DeactivateProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -876,7 +876,7 @@ func TestCommandSide_DeactivateProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1009,7 +1009,7 @@ func TestCommandSide_ReactivateProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1035,7 +1035,7 @@ func TestCommandSide_ReactivateProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1068,7 +1068,7 @@ func TestCommandSide_ReactivateProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1206,7 +1206,7 @@ func TestCommandSide_RemoveProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1232,7 +1232,7 @@ func TestCommandSide_RemoveProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1277,7 +1277,7 @@ func TestCommandSide_RemoveProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1324,7 +1324,7 @@ func TestCommandSide_RemoveProjectGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -14,6 +14,7 @@ type ProjectWriteModel struct {
|
|||||||
Name string
|
Name string
|
||||||
ProjectRoleAssertion bool
|
ProjectRoleAssertion bool
|
||||||
ProjectRoleCheck bool
|
ProjectRoleCheck bool
|
||||||
|
HasProjectCheck bool
|
||||||
State domain.ProjectState
|
State domain.ProjectState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ func (wm *ProjectWriteModel) Reduce() error {
|
|||||||
wm.Name = e.Name
|
wm.Name = e.Name
|
||||||
wm.ProjectRoleAssertion = e.ProjectRoleAssertion
|
wm.ProjectRoleAssertion = e.ProjectRoleAssertion
|
||||||
wm.ProjectRoleCheck = e.ProjectRoleCheck
|
wm.ProjectRoleCheck = e.ProjectRoleCheck
|
||||||
|
wm.HasProjectCheck = e.HasProjectCheck
|
||||||
wm.State = domain.ProjectStateActive
|
wm.State = domain.ProjectStateActive
|
||||||
case *project.ProjectChangeEvent:
|
case *project.ProjectChangeEvent:
|
||||||
if e.Name != nil {
|
if e.Name != nil {
|
||||||
@ -44,6 +46,9 @@ func (wm *ProjectWriteModel) Reduce() error {
|
|||||||
if e.ProjectRoleCheck != nil {
|
if e.ProjectRoleCheck != nil {
|
||||||
wm.ProjectRoleCheck = *e.ProjectRoleCheck
|
wm.ProjectRoleCheck = *e.ProjectRoleCheck
|
||||||
}
|
}
|
||||||
|
if e.HasProjectCheck != nil {
|
||||||
|
wm.HasProjectCheck = *e.HasProjectCheck
|
||||||
|
}
|
||||||
case *project.ProjectDeactivatedEvent:
|
case *project.ProjectDeactivatedEvent:
|
||||||
if wm.State == domain.ProjectStateRemoved {
|
if wm.State == domain.ProjectStateRemoved {
|
||||||
continue
|
continue
|
||||||
@ -80,7 +85,8 @@ func (wm *ProjectWriteModel) NewChangedEvent(
|
|||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
name string,
|
name string,
|
||||||
projectRoleAssertion,
|
projectRoleAssertion,
|
||||||
projectRoleCheck bool,
|
projectRoleCheck,
|
||||||
|
hasProjectCheck bool,
|
||||||
) (*project.ProjectChangeEvent, bool, error) {
|
) (*project.ProjectChangeEvent, bool, error) {
|
||||||
changes := make([]project.ProjectChanges, 0)
|
changes := make([]project.ProjectChanges, 0)
|
||||||
var err error
|
var err error
|
||||||
@ -96,6 +102,9 @@ func (wm *ProjectWriteModel) NewChangedEvent(
|
|||||||
if wm.ProjectRoleCheck != projectRoleCheck {
|
if wm.ProjectRoleCheck != projectRoleCheck {
|
||||||
changes = append(changes, project.ChangeProjectRoleCheck(projectRoleCheck))
|
changes = append(changes, project.ChangeProjectRoleCheck(projectRoleCheck))
|
||||||
}
|
}
|
||||||
|
if wm.HasProjectCheck != hasProjectCheck {
|
||||||
|
changes = append(changes, project.ChangeHasProjectCheck(hasProjectCheck))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func TestCommandSide_AddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -76,7 +76,7 @@ func TestCommandSide_AddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -104,7 +104,7 @@ func TestCommandSide_AddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -148,7 +148,7 @@ func TestCommandSide_AddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -240,7 +240,7 @@ func TestCommandSide_BulkAddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -277,7 +277,7 @@ func TestCommandSide_BulkAddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -309,7 +309,7 @@ func TestCommandSide_BulkAddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -367,7 +367,7 @@ func TestCommandSide_BulkAddProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -486,7 +486,7 @@ func TestCommandSide_ChangeProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -521,7 +521,7 @@ func TestCommandSide_ChangeProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -568,7 +568,7 @@ func TestCommandSide_ChangeProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -609,7 +609,7 @@ func TestCommandSide_ChangeProjectRole(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -2,6 +2,10 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
"github.com/caos/zitadel/internal/domain"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/eventstore"
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
@ -12,8 +16,6 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/iam"
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
"github.com/caos/zitadel/internal/repository/member"
|
"github.com/caos/zitadel/internal/repository/member"
|
||||||
"github.com/caos/zitadel/internal/repository/project"
|
"github.com/caos/zitadel/internal/repository/project"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommandSide_AddProject(t *testing.T) {
|
func TestCommandSide_AddProject(t *testing.T) {
|
||||||
@ -71,7 +73,7 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
eventFromEventPusher(project.NewProjectAddedEvent(
|
eventFromEventPusher(project.NewProjectAddedEvent(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project",
|
"project", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(project.NewProjectMemberAddedEvent(
|
eventFromEventPusher(project.NewProjectMemberAddedEvent(
|
||||||
@ -91,7 +93,10 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
project: &domain.Project{
|
project: &domain.Project{
|
||||||
Name: "project",
|
Name: "project",
|
||||||
|
ProjectRoleAssertion: true,
|
||||||
|
ProjectRoleCheck: true,
|
||||||
|
HasProjectCheck: true,
|
||||||
},
|
},
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
ownerID: "user1",
|
ownerID: "user1",
|
||||||
@ -118,7 +123,7 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
eventFromEventPusher(project.NewProjectAddedEvent(
|
eventFromEventPusher(project.NewProjectAddedEvent(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&project.NewAggregate("project1", "globalorg").Aggregate,
|
&project.NewAggregate("project1", "globalorg").Aggregate,
|
||||||
"project",
|
"project", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(project.NewProjectMemberAddedEvent(
|
eventFromEventPusher(project.NewProjectMemberAddedEvent(
|
||||||
@ -138,7 +143,10 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
project: &domain.Project{
|
project: &domain.Project{
|
||||||
Name: "project",
|
Name: "project",
|
||||||
|
ProjectRoleAssertion: true,
|
||||||
|
ProjectRoleCheck: true,
|
||||||
|
HasProjectCheck: true,
|
||||||
},
|
},
|
||||||
resourceOwner: "globalorg",
|
resourceOwner: "globalorg",
|
||||||
ownerID: "user1",
|
ownerID: "user1",
|
||||||
@ -149,7 +157,10 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
ResourceOwner: "globalorg",
|
ResourceOwner: "globalorg",
|
||||||
AggregateID: "project1",
|
AggregateID: "project1",
|
||||||
},
|
},
|
||||||
Name: "project",
|
Name: "project",
|
||||||
|
ProjectRoleAssertion: true,
|
||||||
|
ProjectRoleCheck: true,
|
||||||
|
HasProjectCheck: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -171,7 +182,7 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
eventFromEventPusher(project.NewProjectAddedEvent(
|
eventFromEventPusher(project.NewProjectAddedEvent(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project",
|
"project", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(project.NewProjectMemberAddedEvent(
|
eventFromEventPusher(project.NewProjectMemberAddedEvent(
|
||||||
@ -191,7 +202,10 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
project: &domain.Project{
|
project: &domain.Project{
|
||||||
Name: "project",
|
Name: "project",
|
||||||
|
ProjectRoleAssertion: true,
|
||||||
|
ProjectRoleCheck: true,
|
||||||
|
HasProjectCheck: true,
|
||||||
},
|
},
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
ownerID: "user1",
|
ownerID: "user1",
|
||||||
@ -202,7 +216,10 @@ func TestCommandSide_AddProject(t *testing.T) {
|
|||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
AggregateID: "project1",
|
AggregateID: "project1",
|
||||||
},
|
},
|
||||||
Name: "project",
|
Name: "project",
|
||||||
|
ProjectRoleAssertion: true,
|
||||||
|
ProjectRoleCheck: true,
|
||||||
|
HasProjectCheck: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -315,7 +332,7 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectRemovedEvent(context.Background(),
|
project.NewProjectRemovedEvent(context.Background(),
|
||||||
@ -348,7 +365,7 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -359,7 +376,10 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
AggregateID: "project1",
|
AggregateID: "project1",
|
||||||
},
|
},
|
||||||
Name: "project",
|
Name: "project",
|
||||||
|
ProjectRoleAssertion: true,
|
||||||
|
ProjectRoleCheck: true,
|
||||||
|
HasProjectCheck: true,
|
||||||
},
|
},
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
},
|
},
|
||||||
@ -376,7 +396,7 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
@ -387,8 +407,9 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
"org1",
|
"org1",
|
||||||
"project",
|
"project",
|
||||||
"project-new",
|
"project-new",
|
||||||
true,
|
false,
|
||||||
true),
|
false,
|
||||||
|
false),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
uniqueConstraintsFromEventConstraint(project.NewRemoveProjectNameUniqueConstraint("project", "org1")),
|
uniqueConstraintsFromEventConstraint(project.NewRemoveProjectNameUniqueConstraint("project", "org1")),
|
||||||
@ -403,8 +424,9 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
AggregateID: "project1",
|
AggregateID: "project1",
|
||||||
},
|
},
|
||||||
Name: "project-new",
|
Name: "project-new",
|
||||||
ProjectRoleAssertion: true,
|
ProjectRoleAssertion: false,
|
||||||
ProjectRoleCheck: true,
|
ProjectRoleCheck: false,
|
||||||
|
HasProjectCheck: false,
|
||||||
},
|
},
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
},
|
},
|
||||||
@ -415,8 +437,9 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
},
|
},
|
||||||
Name: "project-new",
|
Name: "project-new",
|
||||||
ProjectRoleAssertion: true,
|
ProjectRoleAssertion: false,
|
||||||
ProjectRoleCheck: true,
|
ProjectRoleCheck: false,
|
||||||
|
HasProjectCheck: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -429,7 +452,7 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
@ -440,8 +463,9 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
"org1",
|
"org1",
|
||||||
"project",
|
"project",
|
||||||
"",
|
"",
|
||||||
true,
|
false,
|
||||||
true),
|
false,
|
||||||
|
false),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -454,8 +478,9 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
AggregateID: "project1",
|
AggregateID: "project1",
|
||||||
},
|
},
|
||||||
Name: "project",
|
Name: "project",
|
||||||
ProjectRoleAssertion: true,
|
ProjectRoleAssertion: false,
|
||||||
ProjectRoleCheck: true,
|
ProjectRoleCheck: false,
|
||||||
|
HasProjectCheck: false,
|
||||||
},
|
},
|
||||||
resourceOwner: "org1",
|
resourceOwner: "org1",
|
||||||
},
|
},
|
||||||
@ -466,8 +491,9 @@ func TestCommandSide_ChangeProject(t *testing.T) {
|
|||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
},
|
},
|
||||||
Name: "project",
|
Name: "project",
|
||||||
ProjectRoleAssertion: true,
|
ProjectRoleAssertion: false,
|
||||||
ProjectRoleCheck: true,
|
ProjectRoleCheck: false,
|
||||||
|
HasProjectCheck: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -568,7 +594,7 @@ func TestCommandSide_DeactivateProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectRemovedEvent(context.Background(),
|
project.NewProjectRemovedEvent(context.Background(),
|
||||||
@ -596,7 +622,7 @@ func TestCommandSide_DeactivateProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectDeactivatedEvent(context.Background(),
|
project.NewProjectDeactivatedEvent(context.Background(),
|
||||||
@ -623,7 +649,7 @@ func TestCommandSide_DeactivateProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
@ -744,7 +770,7 @@ func TestCommandSide_ReactivateProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectRemovedEvent(context.Background(),
|
project.NewProjectRemovedEvent(context.Background(),
|
||||||
@ -772,7 +798,7 @@ func TestCommandSide_ReactivateProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -795,7 +821,7 @@ func TestCommandSide_ReactivateProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectDeactivatedEvent(context.Background(),
|
project.NewProjectDeactivatedEvent(context.Background(),
|
||||||
@ -920,7 +946,7 @@ func TestCommandSide_RemoveProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectRemovedEvent(context.Background(),
|
project.NewProjectRemovedEvent(context.Background(),
|
||||||
@ -948,7 +974,7 @@ func TestCommandSide_RemoveProject(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"project"),
|
"project", true, true, true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expectPush(
|
expectPush(
|
||||||
@ -994,10 +1020,11 @@ func TestCommandSide_RemoveProject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProjectChangedEvent(ctx context.Context, projectID, resourceOwner, oldName, newName string, roleAssertion, roleCheck bool) *project.ProjectChangeEvent {
|
func newProjectChangedEvent(ctx context.Context, projectID, resourceOwner, oldName, newName string, roleAssertion, roleCheck, hasProjectCheck bool) *project.ProjectChangeEvent {
|
||||||
changes := []project.ProjectChanges{
|
changes := []project.ProjectChanges{
|
||||||
project.ChangeProjectRoleAssertion(roleAssertion),
|
project.ChangeProjectRoleAssertion(roleAssertion),
|
||||||
project.ChangeProjectRoleCheck(roleCheck),
|
project.ChangeProjectRoleCheck(roleCheck),
|
||||||
|
project.ChangeHasProjectCheck(hasProjectCheck),
|
||||||
}
|
}
|
||||||
if newName != "" {
|
if newName != "" {
|
||||||
changes = append(changes, project.ChangeName(newName))
|
changes = append(changes, project.ChangeName(newName))
|
||||||
|
@ -140,7 +140,7 @@ func TestCommandSide_AddUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -187,7 +187,7 @@ func TestCommandSide_AddUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -229,7 +229,7 @@ func TestCommandSide_AddUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -272,7 +272,7 @@ func TestCommandSide_AddUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -331,7 +331,7 @@ func TestCommandSide_AddUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -403,7 +403,7 @@ func TestCommandSide_AddUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -717,7 +717,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -776,7 +776,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -830,7 +830,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -885,7 +885,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -956,7 +956,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
@ -1043,7 +1043,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
project.NewProjectAddedEvent(context.Background(),
|
project.NewProjectAddedEvent(context.Background(),
|
||||||
&project.NewAggregate("project1", "org1").Aggregate,
|
&project.NewAggregate("project1", "org1").Aggregate,
|
||||||
"projectname1",
|
"projectname1", true, true, true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
|
@ -26,6 +26,7 @@ const (
|
|||||||
NextStepPasswordless
|
NextStepPasswordless
|
||||||
NextStepPasswordlessRegistrationPrompt
|
NextStepPasswordlessRegistrationPrompt
|
||||||
NextStepRegistration
|
NextStepRegistration
|
||||||
|
NextStepProjectRequired
|
||||||
)
|
)
|
||||||
|
|
||||||
type LoginStep struct{}
|
type LoginStep struct{}
|
||||||
@ -161,6 +162,12 @@ func (s *GrantRequiredStep) Type() NextStepType {
|
|||||||
return NextStepGrantRequired
|
return NextStepGrantRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProjectRequiredStep struct{}
|
||||||
|
|
||||||
|
func (s *ProjectRequiredStep) Type() NextStepType {
|
||||||
|
return NextStepProjectRequired
|
||||||
|
}
|
||||||
|
|
||||||
type RedirectToCallbackStep struct{}
|
type RedirectToCallbackStep struct{}
|
||||||
|
|
||||||
func (s *RedirectToCallbackStep) Type() NextStepType {
|
func (s *RedirectToCallbackStep) Type() NextStepType {
|
||||||
|
@ -11,6 +11,7 @@ type Project struct {
|
|||||||
Name string
|
Name string
|
||||||
ProjectRoleAssertion bool
|
ProjectRoleAssertion bool
|
||||||
ProjectRoleCheck bool
|
ProjectRoleCheck bool
|
||||||
|
HasProjectCheck bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectState int32
|
type ProjectState int32
|
||||||
|
@ -84,6 +84,7 @@ func (a *Application) Reduce(event *models.Event) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
app.ProjectRoleCheck = project.ProjectRoleCheck
|
app.ProjectRoleCheck = project.ProjectRoleCheck
|
||||||
|
app.HasProjectCheck = project.HasProjectCheck
|
||||||
app.ProjectRoleAssertion = project.ProjectRoleAssertion
|
app.ProjectRoleAssertion = project.ProjectRoleAssertion
|
||||||
|
|
||||||
err = app.AppendEvent(event)
|
err = app.AppendEvent(event)
|
||||||
|
53
internal/project/model/org_project_mapping_view.go
Normal file
53
internal/project/model/org_project_mapping_view.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrgProjectMapping struct {
|
||||||
|
OrgID string
|
||||||
|
ProjectID string
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrgProjectMappingViewSearchRequest struct {
|
||||||
|
Offset uint64
|
||||||
|
Limit uint64
|
||||||
|
SortingColumn OrgProjectMappingViewSearchKey
|
||||||
|
Asc bool
|
||||||
|
Queries []*OrgProjectMappingViewSearchQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrgProjectMappingViewSearchKey int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
OrgProjectMappingSearchKeyUnspecified OrgProjectMappingViewSearchKey = iota
|
||||||
|
OrgProjectMappingSearchKeyProjectID
|
||||||
|
OrgProjectMappingSearchKeyOrgID
|
||||||
|
OrgProjectMappingSearchKeyProjectGrantID
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrgProjectMappingViewSearchQuery struct {
|
||||||
|
Key OrgProjectMappingViewSearchKey
|
||||||
|
Method domain.SearchMethod
|
||||||
|
Value interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrgProjectMappingViewSearchResponse struct {
|
||||||
|
Offset uint64
|
||||||
|
Limit uint64
|
||||||
|
TotalResult uint64
|
||||||
|
Result []*OrgProjectMapping
|
||||||
|
Sequence uint64
|
||||||
|
Timestamp time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OrgProjectMappingViewSearchRequest) GetSearchQuery(key OrgProjectMappingViewSearchKey) (int, *OrgProjectMappingViewSearchQuery) {
|
||||||
|
for i, q := range r.Queries {
|
||||||
|
if q.Key == key {
|
||||||
|
return i, q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, nil
|
||||||
|
}
|
@ -17,6 +17,7 @@ type Project struct {
|
|||||||
Grants []*ProjectGrant
|
Grants []*ProjectGrant
|
||||||
ProjectRoleAssertion bool
|
ProjectRoleAssertion bool
|
||||||
ProjectRoleCheck bool
|
ProjectRoleCheck bool
|
||||||
|
HasProjectCheck bool
|
||||||
}
|
}
|
||||||
type ProjectChanges struct {
|
type ProjectChanges struct {
|
||||||
Changes []*ProjectChange
|
Changes []*ProjectChange
|
||||||
|
@ -16,6 +16,7 @@ type ProjectView struct {
|
|||||||
ResourceOwner string
|
ResourceOwner string
|
||||||
ProjectRoleAssertion bool
|
ProjectRoleAssertion bool
|
||||||
ProjectRoleCheck bool
|
ProjectRoleCheck bool
|
||||||
|
HasProjectCheck bool
|
||||||
Sequence uint64
|
Sequence uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ type Project struct {
|
|||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
ProjectRoleAssertion bool `json:"projectRoleAssertion,omitempty"`
|
ProjectRoleAssertion bool `json:"projectRoleAssertion,omitempty"`
|
||||||
ProjectRoleCheck bool `json:"projectRoleCheck,omitempty"`
|
ProjectRoleCheck bool `json:"projectRoleCheck,omitempty"`
|
||||||
|
HasProjectCheck bool `json:"hasProjectCheck,omitempty"`
|
||||||
State int32 `json:"-"`
|
State int32 `json:"-"`
|
||||||
Members []*ProjectMember `json:"-"`
|
Members []*ProjectMember `json:"-"`
|
||||||
Roles []*ProjectRole `json:"-"`
|
Roles []*ProjectRole `json:"-"`
|
||||||
@ -25,47 +26,6 @@ type Project struct {
|
|||||||
Grants []*ProjectGrant `json:"-"`
|
Grants []*ProjectGrant `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProject(projects []*Project, id string) (int, *Project) {
|
|
||||||
for i, p := range projects {
|
|
||||||
if p.AggregateID == id {
|
|
||||||
return i, p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Project) Changes(changed *Project) map[string]interface{} {
|
|
||||||
changes := make(map[string]interface{}, 1)
|
|
||||||
if changed.Name != "" && p.Name != changed.Name {
|
|
||||||
changes["name"] = changed.Name
|
|
||||||
}
|
|
||||||
if p.ProjectRoleAssertion != changed.ProjectRoleAssertion {
|
|
||||||
changes["projectRoleAssertion"] = changed.ProjectRoleAssertion
|
|
||||||
}
|
|
||||||
if p.ProjectRoleCheck != changed.ProjectRoleCheck {
|
|
||||||
changes["projectRoleCheck"] = changed.ProjectRoleCheck
|
|
||||||
}
|
|
||||||
return changes
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProjectFromModel(project *model.Project) *Project {
|
|
||||||
members := ProjectMembersFromModel(project.Members)
|
|
||||||
roles := ProjectRolesFromModel(project.Roles)
|
|
||||||
apps := AppsFromModel(project.Applications)
|
|
||||||
grants := GrantsFromModel(project.Grants)
|
|
||||||
return &Project{
|
|
||||||
ObjectRoot: project.ObjectRoot,
|
|
||||||
Name: project.Name,
|
|
||||||
ProjectRoleAssertion: project.ProjectRoleAssertion,
|
|
||||||
ProjectRoleCheck: project.ProjectRoleCheck,
|
|
||||||
State: int32(project.State),
|
|
||||||
Members: members,
|
|
||||||
Roles: roles,
|
|
||||||
Applications: apps,
|
|
||||||
Grants: grants,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProjectToModel(project *Project) *model.Project {
|
func ProjectToModel(project *Project) *model.Project {
|
||||||
members := ProjectMembersToModel(project.Members)
|
members := ProjectMembersToModel(project.Members)
|
||||||
roles := ProjectRolesToModel(project.Roles)
|
roles := ProjectRolesToModel(project.Roles)
|
||||||
|
@ -8,50 +8,6 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/project/model"
|
"github.com/caos/zitadel/internal/project/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestProjectChanges(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
existingProject *Project
|
|
||||||
newProject *Project
|
|
||||||
}
|
|
||||||
type res struct {
|
|
||||||
changesLen int
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
res res
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "project name changes",
|
|
||||||
args: args{
|
|
||||||
existingProject: &Project{Name: "Name"},
|
|
||||||
newProject: &Project{Name: "NameChanged"},
|
|
||||||
},
|
|
||||||
res: res{
|
|
||||||
changesLen: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "no changes",
|
|
||||||
args: args{
|
|
||||||
existingProject: &Project{Name: "Name"},
|
|
||||||
newProject: &Project{Name: "Name"},
|
|
||||||
},
|
|
||||||
res: res{
|
|
||||||
changesLen: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
changes := tt.args.existingProject.Changes(tt.args.newProject)
|
|
||||||
if len(changes) != tt.res.changesLen {
|
|
||||||
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestProjectFromEvents(t *testing.T) {
|
func TestProjectFromEvents(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
event []*es_models.Event
|
event []*es_models.Event
|
||||||
|
@ -31,6 +31,7 @@ type ApplicationView struct {
|
|||||||
State int32 `json:"-" gorm:"column:app_state"`
|
State int32 `json:"-" gorm:"column:app_state"`
|
||||||
ProjectRoleAssertion bool `json:"projectRoleAssertion" gorm:"column:project_role_assertion"`
|
ProjectRoleAssertion bool `json:"projectRoleAssertion" gorm:"column:project_role_assertion"`
|
||||||
ProjectRoleCheck bool `json:"projectRoleCheck" gorm:"column:project_role_check"`
|
ProjectRoleCheck bool `json:"projectRoleCheck" gorm:"column:project_role_check"`
|
||||||
|
HasProjectCheck bool `json:"hasProjectCheck" gorm:"column:has_project_check"`
|
||||||
|
|
||||||
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
|
IsOIDC bool `json:"-" gorm:"column:is_oidc"`
|
||||||
OIDCVersion int32 `json:"oidcVersion" gorm:"column:oidc_version"`
|
OIDCVersion int32 `json:"oidcVersion" gorm:"column:oidc_version"`
|
||||||
@ -234,6 +235,7 @@ func (a *ApplicationView) setProjectChanges(event *models.Event) error {
|
|||||||
changes := struct {
|
changes := struct {
|
||||||
ProjectRoleAssertion *bool `json:"projectRoleAssertion,omitempty"`
|
ProjectRoleAssertion *bool `json:"projectRoleAssertion,omitempty"`
|
||||||
ProjectRoleCheck *bool `json:"projectRoleCheck,omitempty"`
|
ProjectRoleCheck *bool `json:"projectRoleCheck,omitempty"`
|
||||||
|
HasProjectCheck *bool `json:"hasProjectCheck,omitempty"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(event.Data, &changes); err != nil {
|
if err := json.Unmarshal(event.Data, &changes); err != nil {
|
||||||
logging.Log("EVEN-DFbfg").WithError(err).Error("could not unmarshal event data")
|
logging.Log("EVEN-DFbfg").WithError(err).Error("could not unmarshal event data")
|
||||||
@ -245,5 +247,8 @@ func (a *ApplicationView) setProjectChanges(event *models.Event) error {
|
|||||||
if changes.ProjectRoleCheck != nil {
|
if changes.ProjectRoleCheck != nil {
|
||||||
a.ProjectRoleCheck = *changes.ProjectRoleCheck
|
a.ProjectRoleCheck = *changes.ProjectRoleCheck
|
||||||
}
|
}
|
||||||
|
if changes.HasProjectCheck != nil {
|
||||||
|
a.HasProjectCheck = *changes.HasProjectCheck
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
const (
|
||||||
|
OrgProjectMappingKeyProjectID = "project_id"
|
||||||
|
OrgProjectMappingKeyOrgID = "org_id"
|
||||||
|
OrgProjectMappingKeyProjectGrantID = "project_grant_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrgProjectMapping struct {
|
||||||
|
ProjectID string `json:"-" gorm:"column:project_id;primary_key"`
|
||||||
|
OrgID string `json:"-" gorm:"column:org_id;primary_key"`
|
||||||
|
ProjectGrantID string `json:"-" gorm:"column:project_grant_id;"`
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||||
|
"github.com/caos/zitadel/internal/view/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrgProjectMappingSearchRequest proj_model.OrgProjectMappingViewSearchRequest
|
||||||
|
type OrgProjectMappingSearchQuery proj_model.OrgProjectMappingViewSearchQuery
|
||||||
|
type OrgProjectMappingSearchKey proj_model.OrgProjectMappingViewSearchKey
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchRequest) GetLimit() uint64 {
|
||||||
|
return req.Limit
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchRequest) GetOffset() uint64 {
|
||||||
|
return req.Offset
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchRequest) GetSortingColumn() repository.ColumnKey {
|
||||||
|
if req.SortingColumn == proj_model.OrgProjectMappingSearchKeyUnspecified {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return OrgProjectMappingSearchKey(req.SortingColumn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchRequest) GetAsc() bool {
|
||||||
|
return req.Asc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchRequest) GetQueries() []repository.SearchQuery {
|
||||||
|
result := make([]repository.SearchQuery, len(req.Queries))
|
||||||
|
for i, q := range req.Queries {
|
||||||
|
result[i] = OrgProjectMappingSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchQuery) GetKey() repository.ColumnKey {
|
||||||
|
return OrgProjectMappingSearchKey(req.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchQuery) GetMethod() domain.SearchMethod {
|
||||||
|
return req.Method
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req OrgProjectMappingSearchQuery) GetValue() interface{} {
|
||||||
|
return req.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (key OrgProjectMappingSearchKey) ToColumnName() string {
|
||||||
|
switch proj_model.OrgProjectMappingViewSearchKey(key) {
|
||||||
|
case proj_model.OrgProjectMappingSearchKeyOrgID:
|
||||||
|
return OrgProjectMappingKeyOrgID
|
||||||
|
case proj_model.OrgProjectMappingSearchKeyProjectID:
|
||||||
|
return OrgProjectMappingKeyProjectID
|
||||||
|
case proj_model.OrgProjectMappingSearchKeyProjectGrantID:
|
||||||
|
return OrgProjectMappingKeyProjectGrantID
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
@ -27,23 +27,10 @@ type ProjectView struct {
|
|||||||
ResourceOwner string `json:"-" gorm:"column:resource_owner"`
|
ResourceOwner string `json:"-" gorm:"column:resource_owner"`
|
||||||
ProjectRoleAssertion bool `json:"projectRoleAssertion" gorm:"column:project_role_assertion"`
|
ProjectRoleAssertion bool `json:"projectRoleAssertion" gorm:"column:project_role_assertion"`
|
||||||
ProjectRoleCheck bool `json:"projectRoleCheck" gorm:"column:project_role_check"`
|
ProjectRoleCheck bool `json:"projectRoleCheck" gorm:"column:project_role_check"`
|
||||||
|
HasProjectCheck bool `json:"hasProjectCheck" gorm:"column:has_project_check"`
|
||||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectFromModel(project *model.ProjectView) *ProjectView {
|
|
||||||
return &ProjectView{
|
|
||||||
ProjectID: project.ProjectID,
|
|
||||||
Name: project.Name,
|
|
||||||
ChangeDate: project.ChangeDate,
|
|
||||||
CreationDate: project.CreationDate,
|
|
||||||
State: int32(project.State),
|
|
||||||
ResourceOwner: project.ResourceOwner,
|
|
||||||
ProjectRoleAssertion: project.ProjectRoleAssertion,
|
|
||||||
ProjectRoleCheck: project.ProjectRoleCheck,
|
|
||||||
Sequence: project.Sequence,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProjectToModel(project *ProjectView) *model.ProjectView {
|
func ProjectToModel(project *ProjectView) *model.ProjectView {
|
||||||
return &model.ProjectView{
|
return &model.ProjectView{
|
||||||
ProjectID: project.ProjectID,
|
ProjectID: project.ProjectID,
|
||||||
@ -54,6 +41,7 @@ func ProjectToModel(project *ProjectView) *model.ProjectView {
|
|||||||
ResourceOwner: project.ResourceOwner,
|
ResourceOwner: project.ResourceOwner,
|
||||||
ProjectRoleAssertion: project.ProjectRoleAssertion,
|
ProjectRoleAssertion: project.ProjectRoleAssertion,
|
||||||
ProjectRoleCheck: project.ProjectRoleCheck,
|
ProjectRoleCheck: project.ProjectRoleCheck,
|
||||||
|
HasProjectCheck: project.HasProjectCheck,
|
||||||
Sequence: project.Sequence,
|
Sequence: project.Sequence,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
51
internal/project/repository/view/org_project_mapping_view.go
Normal file
51
internal/project/repository/view/org_project_mapping_view.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||||
|
"github.com/caos/zitadel/internal/project/repository/view/model"
|
||||||
|
"github.com/caos/zitadel/internal/view/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OrgProjectMappingByIDs(db *gorm.DB, table, orgID, projectID string) (*model.OrgProjectMapping, error) {
|
||||||
|
orgProjectMapping := new(model.OrgProjectMapping)
|
||||||
|
|
||||||
|
projectIDQuery := model.OrgProjectMappingSearchQuery{Key: proj_model.OrgProjectMappingSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals}
|
||||||
|
orgIDQuery := model.OrgProjectMappingSearchQuery{Key: proj_model.OrgProjectMappingSearchKeyOrgID, Value: orgID, Method: domain.SearchMethodEquals}
|
||||||
|
query := repository.PrepareGetByQuery(table, projectIDQuery, orgIDQuery)
|
||||||
|
err := query(db, orgProjectMapping)
|
||||||
|
if caos_errs.IsNotFound(err) {
|
||||||
|
return nil, caos_errs.ThrowNotFound(nil, "VIEW-fn9fs", "Errors.OrgProjectMapping.NotExisting")
|
||||||
|
}
|
||||||
|
return orgProjectMapping, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func PutOrgProjectMapping(db *gorm.DB, table string, grant *model.OrgProjectMapping) error {
|
||||||
|
save := repository.PrepareSave(table)
|
||||||
|
return save(db, grant)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteOrgProjectMapping(db *gorm.DB, table, orgID, projectID string) error {
|
||||||
|
projectIDSearch := repository.Key{Key: model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectID), Value: projectID}
|
||||||
|
orgIDSearch := repository.Key{Key: model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyOrgID), Value: orgID}
|
||||||
|
delete := repository.PrepareDeleteByKeys(table, projectIDSearch, orgIDSearch)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteOrgProjectMappingsByProjectID(db *gorm.DB, table, projectID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectID), projectID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteOrgProjectMappingsByProjectGrantID(db *gorm.DB, table, projectGrantID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectGrantID), projectGrantID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteOrgProjectMappingsByOrgID(db *gorm.DB, table, orgID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyOrgID), orgID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
@ -38,6 +38,7 @@ type ProjectAddedEvent struct {
|
|||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
ProjectRoleAssertion bool `json:"projectRoleAssertion,omitempty"`
|
ProjectRoleAssertion bool `json:"projectRoleAssertion,omitempty"`
|
||||||
ProjectRoleCheck bool `json:"projectRoleCheck,omitempty"`
|
ProjectRoleCheck bool `json:"projectRoleCheck,omitempty"`
|
||||||
|
HasProjectCheck bool `json:"hasProjectCheck,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ProjectAddedEvent) Data() interface{} {
|
func (e *ProjectAddedEvent) Data() interface{} {
|
||||||
@ -52,6 +53,9 @@ func NewProjectAddedEvent(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
name string,
|
name string,
|
||||||
|
projectRoleAssertion,
|
||||||
|
projectRoleCheck,
|
||||||
|
hasProjectCheck bool,
|
||||||
) *ProjectAddedEvent {
|
) *ProjectAddedEvent {
|
||||||
return &ProjectAddedEvent{
|
return &ProjectAddedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
@ -59,7 +63,10 @@ func NewProjectAddedEvent(
|
|||||||
aggregate,
|
aggregate,
|
||||||
ProjectAddedType,
|
ProjectAddedType,
|
||||||
),
|
),
|
||||||
Name: name,
|
Name: name,
|
||||||
|
ProjectRoleAssertion: projectRoleAssertion,
|
||||||
|
ProjectRoleCheck: projectRoleCheck,
|
||||||
|
HasProjectCheck: hasProjectCheck,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +89,7 @@ type ProjectChangeEvent struct {
|
|||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
ProjectRoleAssertion *bool `json:"projectRoleAssertion,omitempty"`
|
ProjectRoleAssertion *bool `json:"projectRoleAssertion,omitempty"`
|
||||||
ProjectRoleCheck *bool `json:"projectRoleCheck,omitempty"`
|
ProjectRoleCheck *bool `json:"projectRoleCheck,omitempty"`
|
||||||
|
HasProjectCheck *bool `json:"hasProjectCheck,omitempty"`
|
||||||
oldName string
|
oldName string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +150,12 @@ func ChangeProjectRoleCheck(projectRoleCheck bool) func(event *ProjectChangeEven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeHasProjectCheck(ChangeHasProjectCheck bool) func(event *ProjectChangeEvent) {
|
||||||
|
return func(e *ProjectChangeEvent) {
|
||||||
|
e.HasProjectCheck = &ChangeHasProjectCheck
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ProjectChangeEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func ProjectChangeEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e := &ProjectChangeEvent{
|
e := &ProjectChangeEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
@ -291,6 +291,8 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
l.handleExternalLoginStep(w, r, authReq, step.SelectedIDPConfigID)
|
l.handleExternalLoginStep(w, r, authReq, step.SelectedIDPConfigID)
|
||||||
case *domain.GrantRequiredStep:
|
case *domain.GrantRequiredStep:
|
||||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowPreconditionFailed(nil, "APP-asb43", "Errors.User.GrantRequired"))
|
l.renderInternalError(w, r, authReq, caos_errs.ThrowPreconditionFailed(nil, "APP-asb43", "Errors.User.GrantRequired"))
|
||||||
|
case *domain.ProjectRequiredStep:
|
||||||
|
l.renderInternalError(w, r, authReq, caos_errs.ThrowPreconditionFailed(nil, "APP-m92d", "Errors.User.ProjectRequired"))
|
||||||
default:
|
default:
|
||||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(nil, "APP-ds3QF", "step no possible"))
|
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(nil, "APP-ds3QF", "step no possible"))
|
||||||
}
|
}
|
||||||
|
@ -349,6 +349,7 @@ Errors:
|
|||||||
ExternalUserIDEmpty: Externe User ID ist leer
|
ExternalUserIDEmpty: Externe User ID ist leer
|
||||||
UserDisplayNameEmpty: Benutzer Anzeige Name ist leer
|
UserDisplayNameEmpty: Benutzer Anzeige Name ist leer
|
||||||
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
|
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
|
||||||
|
ProjectRequired: Der Login an diese Applikation ist nicht möglich. Die Organisation des Benutzer benötigt Berechtigung auf das Projekt. Bitte melde dich bei deinem Administrator.
|
||||||
IdentityProvider:
|
IdentityProvider:
|
||||||
InvalidConfig: Identitäts Provider Konfiguration ist ungültig
|
InvalidConfig: Identitäts Provider Konfiguration ist ungültig
|
||||||
IAM:
|
IAM:
|
||||||
|
@ -350,6 +350,7 @@ Errors:
|
|||||||
ExternalUserIDEmpty: External User ID is empty
|
ExternalUserIDEmpty: External User ID is empty
|
||||||
UserDisplayNameEmpty: User Display Name is empty
|
UserDisplayNameEmpty: User Display Name is empty
|
||||||
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
|
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
|
||||||
|
ProjectRequired: Login not possible. The organisation of the user must be granted to the project. Please contact your administrator.
|
||||||
IdentityProvider:
|
IdentityProvider:
|
||||||
InvalidConfig: Identity Provider configuration is invalid
|
InvalidConfig: Identity Provider configuration is invalid
|
||||||
IAM:
|
IAM:
|
||||||
|
13
migrations/cockroach/V1.61__has_project.sql
Normal file
13
migrations/cockroach/V1.61__has_project.sql
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
ALTER TABLE management.projects ADD COLUMN has_project_check BOOLEAN;
|
||||||
|
|
||||||
|
ALTER TABLE authz.applications ADD COLUMN has_project_check BOOLEAN;
|
||||||
|
ALTER TABLE auth.applications ADD COLUMN has_project_check BOOLEAN;
|
||||||
|
ALTER TABLE management.applications ADD COLUMN has_project_check BOOLEAN;
|
||||||
|
|
||||||
|
CREATE TABLE auth.org_project_mapping (
|
||||||
|
org_id TEXT,
|
||||||
|
project_id TEXT,
|
||||||
|
project_grant_id TEXT,
|
||||||
|
|
||||||
|
PRIMARY KEY (org_id, project_id)
|
||||||
|
);
|
@ -3452,6 +3452,7 @@ message AddProjectRequest {
|
|||||||
string name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
bool project_role_assertion = 2;
|
bool project_role_assertion = 2;
|
||||||
bool project_role_check = 3;
|
bool project_role_check = 3;
|
||||||
|
bool has_project_check = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddProjectResponse {
|
message AddProjectResponse {
|
||||||
@ -3464,6 +3465,7 @@ message UpdateProjectRequest {
|
|||||||
string name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
string name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
bool project_role_assertion = 3;
|
bool project_role_assertion = 3;
|
||||||
bool project_role_check = 4;
|
bool project_role_check = 4;
|
||||||
|
bool has_project_check = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateProjectResponse {
|
message UpdateProjectResponse {
|
||||||
|
@ -29,6 +29,8 @@ message Project {
|
|||||||
bool project_role_assertion = 5;
|
bool project_role_assertion = 5;
|
||||||
// ZITADEL checks if the user has at least one on this project
|
// ZITADEL checks if the user has at least one on this project
|
||||||
bool project_role_check = 6;
|
bool project_role_check = 6;
|
||||||
|
// ZITADEL checks if the org of the user has permission to this project
|
||||||
|
bool has_project_check = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GrantedProject {
|
message GrantedProject {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user