feat: delete (#243)

* feat: project role remove

* feat: search queries

* feat: search queries

* feat: cascade remove/change project role

* fix: comment in project grant

* fix: remove projecr grant

* fix: only search usergrants of my org

* fix: delete usergrants

* fix: delete usergrants

* fix: check if role exists on project grant

* feat: bulk add project role

* fix: tests

* fix: update user grants on project update

* fix: return roles

* feat: add resourceowner name on project grants

* fix: migration number

* fix: tests

* fix: generate protos

* fix: some unnecessary code
This commit is contained in:
Fabi
2020-06-19 15:32:03 +02:00
committed by GitHub
parent 8f49f2c2d8
commit 710652ef24
55 changed files with 4404 additions and 2668 deletions

View File

@@ -2,6 +2,14 @@ package eventstore
import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
es_int "github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
es_proj_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
usr_grant_model "github.com/caos/zitadel/internal/usergrant/model"
usr_grant_event "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing"
"strings"
"github.com/caos/zitadel/internal/api/auth"
@@ -15,10 +23,12 @@ import (
)
type ProjectRepo struct {
SearchLimit uint64
ProjectEvents *proj_event.ProjectEventstore
View *view.View
Roles []string
es_int.Eventstore
SearchLimit uint64
ProjectEvents *proj_event.ProjectEventstore
UserGrantEvents *usr_grant_event.UserGrantEventStore
View *view.View
Roles []string
}
func (repo *ProjectRepo) ProjectByID(ctx context.Context, id string) (project *proj_model.Project, err error) {
@@ -48,7 +58,7 @@ func (repo *ProjectRepo) SearchProjects(ctx context.Context, request *proj_model
permissions := auth.GetPermissionsFromCtx(ctx)
if !auth.HasGlobalPermission(permissions) {
ids := auth.GetPermissionCtxIDs(permissions)
request.Queries = append(request.Queries, &proj_model.ProjectViewSearchQuery{Key: proj_model.PROJECTSEARCHKEY_PROJECTID, Method: global_model.SEARCHMETHOD_IN, Value: ids})
request.Queries = append(request.Queries, &proj_model.ProjectViewSearchQuery{Key: proj_model.PROJECTSEARCHKEY_PROJECTID, Method: global_model.SEARCHMETHOD_IS_ONE_OF, Value: ids})
}
projects, count, err := repo.View.SearchProjects(request)
@@ -103,8 +113,13 @@ func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj
}, nil
}
func (repo *ProjectRepo) AddProjectRole(ctx context.Context, member *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
return repo.ProjectEvents.AddProjectRole(ctx, member)
func (repo *ProjectRepo) AddProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
return repo.ProjectEvents.AddProjectRoles(ctx, role)
}
func (repo *ProjectRepo) BulkAddProjectRole(ctx context.Context, roles []*proj_model.ProjectRole) error {
_, err := repo.ProjectEvents.AddProjectRoles(ctx, roles...)
return err
}
func (repo *ProjectRepo) ChangeProjectRole(ctx context.Context, member *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
@@ -112,8 +127,40 @@ func (repo *ProjectRepo) ChangeProjectRole(ctx context.Context, member *proj_mod
}
func (repo *ProjectRepo) RemoveProjectRole(ctx context.Context, projectID, key string) error {
member := proj_model.NewProjectRole(projectID, key)
return repo.ProjectEvents.RemoveProjectRole(ctx, member)
role := proj_model.NewProjectRole(projectID, key)
aggregates := make([]*es_models.Aggregate, 0)
project, agg, err := repo.ProjectEvents.PrepareRemoveProjectRole(ctx, role)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
usergrants, err := repo.View.UserGrantsByProjectIDAndRoleKey(projectID, key)
if err != nil {
return err
}
for _, grant := range usergrants {
changed := &usr_grant_model.UserGrant{
ObjectRoot: models.ObjectRoot{AggregateID: grant.ID, Sequence: grant.Sequence, ResourceOwner: grant.ResourceOwner},
RoleKeys: grant.RoleKeys,
ProjectID: grant.ProjectID,
UserID: grant.UserID,
}
changed.RemoveRoleKeyIfExisting(key)
_, agg, err := repo.UserGrantEvents.PrepareChangeUserGrant(ctx, changed, true)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
}
if err != nil {
return err
}
err = es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
if err != nil {
return err
}
return nil
}
func (repo *ProjectRepo) SearchProjectRoles(ctx context.Context, request *proj_model.ProjectRoleSearchRequest) (*proj_model.ProjectRoleSearchResponse, error) {
@@ -211,25 +258,100 @@ func (repo *ProjectRepo) SearchProjectGrants(ctx context.Context, request *proj_
}, nil
}
func (repo *ProjectRepo) AddProjectGrant(ctx context.Context, app *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.AddProjectGrant(ctx, app)
func (repo *ProjectRepo) AddProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.AddProjectGrant(ctx, grant)
}
func (repo *ProjectRepo) ChangeProjectGrant(ctx context.Context, app *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.ChangeProjectGrant(ctx, app)
func (repo *ProjectRepo) ChangeProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
project, aggFunc, removedRoles, err := repo.ProjectEvents.PrepareChangeProjectGrant(ctx, grant)
if err != nil {
return nil, err
}
agg, err := aggFunc(ctx)
if err != nil {
return nil, err
}
aggregates := make([]*es_models.Aggregate, 0)
aggregates = append(aggregates, agg)
usergrants, err := repo.View.UserGrantsByProjectID(grant.AggregateID)
if err != nil {
return nil, err
}
for _, grant := range usergrants {
changed := &usr_grant_model.UserGrant{
ObjectRoot: models.ObjectRoot{AggregateID: grant.ID, Sequence: grant.Sequence, ResourceOwner: grant.ResourceOwner},
RoleKeys: grant.RoleKeys,
ProjectID: grant.ProjectID,
UserID: grant.UserID,
}
existing := changed.RemoveRoleKeysIfExisting(removedRoles)
if existing {
_, agg, err := repo.UserGrantEvents.PrepareChangeUserGrant(ctx, changed, true)
if err != nil {
return nil, err
}
aggregates = append(aggregates, agg)
}
}
if err != nil {
return nil, err
}
err = es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
if err != nil {
return nil, err
}
if _, g := es_proj_model.GetProjectGrant(project.Grants, grant.GrantID); g != nil {
return es_proj_model.GrantToModel(g), nil
}
return nil, caos_errs.ThrowInternal(nil, "EVENT-dksi8", "Could not find app in list")
}
func (repo *ProjectRepo) DeactivateProjectGrant(ctx context.Context, projectID, appID string) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.DeactivateProjectGrant(ctx, projectID, appID)
func (repo *ProjectRepo) DeactivateProjectGrant(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.DeactivateProjectGrant(ctx, projectID, grantID)
}
func (repo *ProjectRepo) ReactivateProjectGrant(ctx context.Context, projectID, appID string) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.ReactivateProjectGrant(ctx, projectID, appID)
func (repo *ProjectRepo) ReactivateProjectGrant(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.ReactivateProjectGrant(ctx, projectID, grantID)
}
func (repo *ProjectRepo) RemoveProjectGrant(ctx context.Context, projectID, appID string) error {
app := proj_model.NewProjectGrant(projectID, appID)
return repo.ProjectEvents.RemoveProjectGrant(ctx, app)
func (repo *ProjectRepo) RemoveProjectGrant(ctx context.Context, projectID, grantID string) error {
grant, err := repo.ProjectEvents.ProjectGrantByIDs(ctx, projectID, grantID)
if err != nil {
return err
}
aggregates := make([]*es_models.Aggregate, 0)
project, aggFunc, err := repo.ProjectEvents.PrepareRemoveProjectGrant(ctx, grant)
if err != nil {
return err
}
agg, err := aggFunc(ctx)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
usergrants, err := repo.View.UserGrantsByOrgIDAndProjectID(grant.GrantedOrgID, projectID)
if err != nil {
return err
}
for _, grant := range usergrants {
_, grantAggregates, err := repo.UserGrantEvents.PrepareRemoveUserGrant(ctx, grant.ID, true)
if err != nil {
return err
}
for _, agg := range grantAggregates {
aggregates = append(aggregates, agg)
}
}
if err != nil {
return err
}
err = es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
if err != nil {
return err
}
return nil
}
func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID, grantID, userID string) (member *proj_model.ProjectGrantMember, err error) {

View File

@@ -38,6 +38,18 @@ func (repo *UserGrantRepo) RemoveUserGrant(ctx context.Context, grantID string)
return repo.UserGrantEvents.RemoveUserGrant(ctx, grantID)
}
func (repo *UserGrantRepo) BulkAddUserGrant(ctx context.Context, grants ...*grant_model.UserGrant) error {
return repo.UserGrantEvents.AddUserGrants(ctx, grants...)
}
func (repo *UserGrantRepo) BulkChangeUserGrant(ctx context.Context, grants ...*grant_model.UserGrant) error {
return repo.UserGrantEvents.ChangeUserGrants(ctx, grants...)
}
func (repo *UserGrantRepo) BulkRemoveUserGrant(ctx context.Context, grantIDs ...string) error {
return repo.UserGrantEvents.RemoveUserGrants(ctx, grantIDs...)
}
func (repo *UserGrantRepo) SearchUserGrants(ctx context.Context, request *grant_model.UserGrantSearchRequest) (*grant_model.UserGrantSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit)
grants, count, err := repo.View.SearchUserGrants(request)

View File

@@ -66,8 +66,12 @@ func (p *ProjectGrant) Process(event *models.Event) (err error) {
if err != nil {
return err
}
p.fillOrgData(grantedProject, org)
case es_model.ProjectGrantChanged:
resourceOwner, err := p.orgEvents.OrgByID(context.TODO(), org_model.NewOrg(grantedProject.ResourceOwner))
if err != nil {
return err
}
p.fillOrgData(grantedProject, org, resourceOwner)
case es_model.ProjectGrantChanged, es_model.ProjectGrantCascadeChanged:
grant := new(view_model.ProjectGrant)
err := grant.SetData(event)
if err != nil {
@@ -94,8 +98,9 @@ func (p *ProjectGrant) Process(event *models.Event) (err error) {
return p.view.PutProjectGrant(grantedProject)
}
func (p *ProjectGrant) fillOrgData(grantedProject *view_model.ProjectGrantView, org *org_model.Org) {
func (p *ProjectGrant) fillOrgData(grantedProject *view_model.ProjectGrantView, org, resourceOwner *org_model.Org) {
grantedProject.OrgName = org.Name
grantedProject.ResourceOwnerName = resourceOwner.Name
}
func (p *ProjectGrant) getProject(projectID string) (*proj_model.Project, error) {

View File

@@ -56,7 +56,7 @@ func (p *ProjectRole) Process(event *models.Event) (err error) {
if err != nil {
return err
}
err = p.removeRoleFromAllResourceowners(event, role)
return p.view.DeleteProjectRole(event.AggregateID, event.ResourceOwner, role.Key, event.Sequence)
case es_model.ProjectGrantAdded:
return p.addGrantRoles(event)
case es_model.ProjectGrantChanged:

View File

@@ -73,6 +73,7 @@ func (u *UserGrant) processUserGrant(event *models.Event) (err error) {
}
err = u.fillData(grant, event.ResourceOwner)
case grant_es_model.UserGrantChanged,
grant_es_model.UserGrantCascadeChanged,
grant_es_model.UserGrantDeactivated,
grant_es_model.UserGrantReactivated:
grant, err = u.view.UserGrantByID(event.AggregateID)
@@ -80,8 +81,8 @@ func (u *UserGrant) processUserGrant(event *models.Event) (err error) {
return err
}
err = grant.AppendEvent(event)
case grant_es_model.UserGrantRemoved:
err = u.view.DeleteUserGrant(event.AggregateID, event.Sequence)
case grant_es_model.UserGrantRemoved, grant_es_model.UserGrantCascadeRemoved:
return u.view.DeleteUserGrant(event.AggregateID, event.Sequence)
default:
return u.view.ProcessedUserGrantSequence(event.Sequence)
}

View File

@@ -96,7 +96,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
return &EsRepository{
spooler: spool,
OrgRepository: eventstore.OrgRepository{conf.SearchLimit, org, view, roles},
ProjectRepo: eventstore.ProjectRepo{conf.SearchLimit, project, view, roles},
ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, project, usergrant, view, roles},
UserRepo: eventstore.UserRepo{conf.SearchLimit, user, policy, org, view},
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
PolicyRepo: eventstore.PolicyRepo{policy},

View File

@@ -23,6 +23,10 @@ func (v *View) ProjectGrantsByProjectID(projectID string) ([]*model.ProjectGrant
return view.ProjectGrantsByProjectID(v.Db, grantedProjectTable, projectID)
}
func (v *View) ProjectGrantsByProjectIDAndRoleKey(projectID, key string) ([]*model.ProjectGrantView, error) {
return view.ProjectGrantsByProjectIDAndRoleKey(v.Db, grantedProjectTable, projectID, key)
}
func (v *View) SearchProjectGrants(request *proj_model.ProjectGrantViewSearchRequest) ([]*model.ProjectGrantView, int, error) {
return view.SearchProjectGrants(v.Db, grantedProjectTable, request)
}
@@ -38,7 +42,7 @@ func (v *View) PutProjectGrant(project *model.ProjectGrantView) error {
func (v *View) DeleteProjectGrant(grantID string, eventSequence uint64) error {
err := view.DeleteProjectGrant(v.Db, grantedProjectTable, grantID)
if err != nil {
return nil
return err
}
return v.ProcessedProjectGrantSequence(eventSequence)
}

View File

@@ -31,6 +31,14 @@ func (v *View) UserGrantsByOrgID(orgID string) ([]*model.UserGrantView, error) {
return view.UserGrantsByOrgID(v.Db, userGrantTable, orgID)
}
func (v *View) UserGrantsByProjectIDAndRoleKey(projectID, roleKey string) ([]*model.UserGrantView, error) {
return view.UserGrantsByProjectIDAndRole(v.Db, userGrantTable, projectID, roleKey)
}
func (v *View) UserGrantsByOrgIDAndProjectID(orgID, projectID string) ([]*model.UserGrantView, error) {
return view.UserGrantsByOrgIDAndProjectID(v.Db, userGrantTable, orgID, projectID)
}
func (v *View) PutUserGrant(grant *model.UserGrantView, sequence uint64) error {
err := view.PutUserGrant(v.Db, userGrantTable, grant)
if err != nil {

View File

@@ -28,6 +28,7 @@ type ProjectRepository interface {
RemoveProjectRole(ctx context.Context, projectID, key string) error
SearchProjectRoles(ctx context.Context, request *model.ProjectRoleSearchRequest) (*model.ProjectRoleSearchResponse, error)
ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64) (*model.ProjectChanges, error)
BulkAddProjectRole(ctx context.Context, role []*model.ProjectRole) error
ApplicationByID(ctx context.Context, projectID, appID string) (*model.Application, error)
AddApplication(ctx context.Context, app *model.Application) (*model.Application, error)
@@ -41,8 +42,8 @@ type ProjectRepository interface {
ApplicationChanges(ctx context.Context, id string, secId string, lastSequence uint64, limit uint64) (*model.ApplicationChanges, error)
ProjectGrantByID(ctx context.Context, projectID, grantID string) (*model.ProjectGrant, error)
AddProjectGrant(ctx context.Context, app *model.ProjectGrant) (*model.ProjectGrant, error)
ChangeProjectGrant(ctx context.Context, app *model.ProjectGrant) (*model.ProjectGrant, error)
AddProjectGrant(ctx context.Context, grant *model.ProjectGrant) (*model.ProjectGrant, error)
ChangeProjectGrant(ctx context.Context, grant *model.ProjectGrant) (*model.ProjectGrant, error)
DeactivateProjectGrant(ctx context.Context, projectID, grantID string) (*model.ProjectGrant, error)
ReactivateProjectGrant(ctx context.Context, projectID, grantID string) (*model.ProjectGrant, error)
RemoveProjectGrant(ctx context.Context, projectID, grantID string) error

View File

@@ -13,4 +13,8 @@ type UserGrantRepository interface {
ReactivateUserGrant(ctx context.Context, grantID string) (*model.UserGrant, error)
RemoveUserGrant(ctx context.Context, grantID string) error
SearchUserGrants(ctx context.Context, request *model.UserGrantSearchRequest) (*model.UserGrantSearchResponse, error)
BulkAddUserGrant(ctx context.Context, grant ...*model.UserGrant) error
BulkChangeUserGrant(ctx context.Context, grant ...*model.UserGrant) error
BulkRemoveUserGrant(ctx context.Context, grantIDs ...string) error
}