fix: correct permissions for projects on v2 api (#9973)

# Which Problems Are Solved

Permission checks in project v2beta API did not cover projects and
granted projects correctly.

# How the Problems Are Solved

Add permission checks v1 correctly to the list queries, add correct
permission checks v2 for projects.

# Additional Changes

Correct Pre-Checks for project grants that the right resource owner is
used.

# Additional Context

Permission checks v2 for project grants is still outstanding under
#9972.
This commit is contained in:
Stefan Benz
2025-06-04 13:46:10 +02:00
committed by GitHub
parent 6aeaa89c25
commit 85e3b7449c
15 changed files with 950 additions and 102 deletions

View File

@@ -16,13 +16,14 @@ type ProjectGrantWriteModel struct {
State domain.ProjectGrantState
}
func NewProjectGrantWriteModel(grantID, projectID, resourceOwner string) *ProjectGrantWriteModel {
func NewProjectGrantWriteModel(grantID, grantedOrgID, projectID, resourceOwner string) *ProjectGrantWriteModel {
return &ProjectGrantWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
GrantID: grantID,
GrantID: grantID,
GrantedOrgID: grantedOrgID,
}
}
@@ -30,27 +31,28 @@ func (wm *ProjectGrantWriteModel) AppendEvents(events ...eventstore.Event) {
for _, event := range events {
switch e := event.(type) {
case *project.GrantAddedEvent:
if e.GrantID == wm.GrantID {
if (wm.GrantID != "" && e.GrantID == wm.GrantID) ||
(wm.GrantedOrgID != "" && e.GrantedOrgID == wm.GrantedOrgID) {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantChangedEvent:
if e.GrantID == wm.GrantID {
if wm.GrantID != "" && e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantCascadeChangedEvent:
if e.GrantID == wm.GrantID {
if wm.GrantID != "" && e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantDeactivateEvent:
if e.GrantID == wm.GrantID {
if wm.GrantID != "" && e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantReactivatedEvent:
if e.GrantID == wm.GrantID {
if wm.GrantID != "" && e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantRemovedEvent:
if e.GrantID == wm.GrantID {
if wm.GrantID != "" && e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.ProjectRemovedEvent:
@@ -114,18 +116,20 @@ func (wm *ProjectGrantWriteModel) Query() *eventstore.SearchQueryBuilder {
type ProjectGrantPreConditionReadModel struct {
eventstore.WriteModel
ProjectID string
GrantedOrgID string
ProjectExists bool
GrantedOrgExists bool
ExistingRoleKeys []string
ProjectResourceOwner string
ProjectID string
GrantedOrgID string
ProjectExists bool
GrantedOrgExists bool
ExistingRoleKeys []string
}
func NewProjectGrantPreConditionReadModel(projectID, grantedOrgID, resourceOwner string) *ProjectGrantPreConditionReadModel {
return &ProjectGrantPreConditionReadModel{
WriteModel: eventstore.WriteModel{ResourceOwner: resourceOwner},
ProjectID: projectID,
GrantedOrgID: grantedOrgID,
WriteModel: eventstore.WriteModel{},
ProjectResourceOwner: resourceOwner,
ProjectID: projectID,
GrantedOrgID: grantedOrgID,
}
}
@@ -133,26 +137,26 @@ func (wm *ProjectGrantPreConditionReadModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.ProjectAddedEvent:
if wm.ResourceOwner == "" {
wm.ResourceOwner = e.Aggregate().ResourceOwner
if wm.ProjectResourceOwner == "" {
wm.ProjectResourceOwner = e.Aggregate().ResourceOwner
}
if wm.ResourceOwner != e.Aggregate().ResourceOwner {
if wm.ProjectResourceOwner != e.Aggregate().ResourceOwner {
continue
}
wm.ProjectExists = true
case *project.ProjectRemovedEvent:
if wm.ResourceOwner != e.Aggregate().ResourceOwner {
if wm.ProjectResourceOwner != e.Aggregate().ResourceOwner {
continue
}
wm.ResourceOwner = ""
wm.ProjectResourceOwner = ""
wm.ProjectExists = false
case *project.RoleAddedEvent:
if e.Aggregate().ResourceOwner != wm.ResourceOwner {
if e.Aggregate().ResourceOwner != wm.ProjectResourceOwner {
continue
}
wm.ExistingRoleKeys = append(wm.ExistingRoleKeys, e.Key)
case *project.RoleRemovedEvent:
if e.Aggregate().ResourceOwner != wm.ResourceOwner {
if e.Aggregate().ResourceOwner != wm.ProjectResourceOwner {
continue
}
for i, key := range wm.ExistingRoleKeys {
@@ -175,12 +179,6 @@ func (wm *ProjectGrantPreConditionReadModel) Reduce() error {
func (wm *ProjectGrantPreConditionReadModel) Query() *eventstore.SearchQueryBuilder {
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
AddQuery().
AggregateTypes(org.AggregateType).
AggregateIDs(wm.GrantedOrgID).
EventTypes(
org.OrgAddedEventType,
org.OrgRemovedEventType).
Or().
AggregateTypes(project.AggregateType).
AggregateIDs(wm.ProjectID).
EventTypes(
@@ -188,6 +186,12 @@ func (wm *ProjectGrantPreConditionReadModel) Query() *eventstore.SearchQueryBuil
project.ProjectRemovedType,
project.RoleAddedType,
project.RoleRemovedType).
Or().
AggregateTypes(org.AggregateType).
AggregateIDs(wm.GrantedOrgID).
EventTypes(
org.OrgAddedEventType,
org.OrgRemovedEventType).
Builder()
return query