fix: Remove project (#538)

* Remove project added

* Gemeriert

* corrections

* corrections

* Delete*sByProjectID added

* Correct typos
This commit is contained in:
Michael Waeger
2020-08-05 18:32:25 +02:00
committed by GitHub
parent ade09724a4
commit 41fa434439
39 changed files with 12243 additions and 21919 deletions

View File

@@ -40,6 +40,11 @@ func (s *Server) ReactivateProject(ctx context.Context, in *management.ProjectID
return projectFromModel(project), nil
}
func (s *Server) RemoveProject(ctx context.Context, in *management.ProjectID) (*empty.Empty, error) {
err := s.project.RemoveProject(ctx, in.Id)
return &empty.Empty{}, err
}
func (s *Server) SearchProjects(ctx context.Context, in *management.ProjectSearchRequest) (*management.ProjectSearchResponse, error) {
request := projectSearchRequestsToModel(in)
request.AppendMyResourceOwnerQuery(grpc_util.GetHeader(ctx, http.ZitadelOrgID))

View File

@@ -35,7 +35,7 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder {
}
// Filter mocks base method
func (m *MockRepository) Filter(arg0 context.Context, arg1 *models.SearchQuery) ([]*models.Event, error) {
func (m *MockRepository) Filter(arg0 context.Context, arg1 *models.SearchQueryFactory) ([]*models.Event, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Filter", arg0, arg1)
ret0, _ := ret[0].([]*models.Event)
@@ -63,6 +63,21 @@ func (mr *MockRepositoryMockRecorder) Health(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Health", reflect.TypeOf((*MockRepository)(nil).Health), arg0)
}
// LatestSequence mocks base method
func (m *MockRepository) LatestSequence(arg0 context.Context, arg1 *models.SearchQueryFactory) (uint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "LatestSequence", arg0, arg1)
ret0, _ := ret[0].(uint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// LatestSequence indicates an expected call of LatestSequence
func (mr *MockRepositoryMockRecorder) LatestSequence(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatestSequence", reflect.TypeOf((*MockRepository)(nil).LatestSequence), arg0, arg1)
}
// PushAggregates mocks base method
func (m *MockRepository) PushAggregates(arg0 context.Context, arg1 ...*models.Aggregate) error {
m.ctrl.T.Helper()

View File

@@ -80,6 +80,33 @@ func (repo *ProjectRepo) ReactivateProject(ctx context.Context, id string) (*pro
return repo.ProjectEvents.ReactivateProject(ctx, id)
}
func (repo *ProjectRepo) RemoveProject(ctx context.Context, projectID string) error {
proj := proj_model.NewProject(projectID)
aggregates := make([]*es_models.Aggregate, 0)
project, agg, err := repo.ProjectEvents.PrepareRemoveProject(ctx, proj)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
// remove user_grants
usergrants, err := repo.View.UserGrantsByProjectID(projectID)
if err != nil {
return err
}
for _, grant := range usergrants {
_, aggs, err := repo.UserGrantEvents.PrepareRemoveUserGrant(ctx, grant.ID, true)
if err != nil {
return err
}
for _, agg := range aggs {
aggregates = append(aggregates, agg)
}
}
return es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
}
func (repo *ProjectRepo) SearchProjects(ctx context.Context, request *proj_model.ProjectViewSearchRequest) (*proj_model.ProjectViewSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit)
sequence, err := repo.View.GetLatestProjectSequence()

View File

@@ -57,6 +57,8 @@ func (p *Application) Reduce(event *models.Event) (err error) {
return err
}
return p.view.DeleteApplication(app.ID, event.Sequence)
case es_model.ProjectRemoved:
return p.view.DeleteApplicationsByProjectID(event.AggregateID)
default:
return p.view.ProcessedApplicationSequence(event.Sequence)
}

View File

@@ -45,6 +45,8 @@ func (p *Project) Reduce(event *models.Event) (err error) {
return err
}
err = project.AppendEvent(event)
case es_model.ProjectRemoved:
return p.view.DeleteProject(event.AggregateID, event.Sequence)
default:
return p.view.ProcessedProjectSequence(event.Sequence)
}

View File

@@ -86,6 +86,8 @@ func (p *ProjectGrant) Reduce(event *models.Event) (err error) {
return err
}
return p.view.DeleteProjectGrant(grant.GrantID, event.Sequence)
case es_model.ProjectRemoved:
return p.view.DeleteProjectGrantsByProjectID(event.AggregateID)
default:
return p.view.ProcessedProjectGrantSequence(event.Sequence)
}

View File

@@ -70,6 +70,9 @@ func (p *ProjectGrantMember) processProjectGrantMember(event *models.Event) (err
return err
}
return p.view.DeleteProjectGrantMember(member.GrantID, member.UserID, event.Sequence)
case proj_es_model.ProjectRemoved:
return p.view.DeleteProjectGrantMembersByProjectID(event.AggregateID)
default:
return p.view.ProcessedProjectGrantMemberSequence(event.Sequence)
}

View File

@@ -70,6 +70,8 @@ func (p *ProjectMember) processProjectMember(event *models.Event) (err error) {
return err
}
return p.view.DeleteProjectMember(event.AggregateID, member.UserID, event.Sequence)
case proj_es_model.ProjectRemoved:
return p.view.DeleteProjectMembersByProjectID(event.AggregateID)
default:
return p.view.ProcessedProjectMemberSequence(event.Sequence)
}

View File

@@ -53,6 +53,8 @@ func (p *ProjectRole) Reduce(event *models.Event) (err error) {
return err
}
return p.view.DeleteProjectRole(event.AggregateID, event.ResourceOwner, role.Key, event.Sequence)
case es_model.ProjectRemoved:
return p.view.DeleteProjectRolesByProjectID(event.AggregateID)
default:
return p.view.ProcessedProjectRoleSequence(event.Sequence)
}

View File

@@ -15,6 +15,10 @@ func (v *View) ApplicationByID(appID string) (*model.ApplicationView, error) {
return view.ApplicationByID(v.Db, applicationTable, appID)
}
func (v *View) ApplicationsByProjectID(ProjectID string) ([]*model.ApplicationView, error) {
return view.ApplicationsByProjectID(v.Db, applicationTable, ProjectID)
}
func (v *View) SearchApplications(request *proj_model.ApplicationSearchRequest) ([]*model.ApplicationView, uint64, error) {
return view.SearchApplications(v.Db, applicationTable, request)
}
@@ -35,6 +39,10 @@ func (v *View) DeleteApplication(appID string, eventSequence uint64) error {
return v.ProcessedApplicationSequence(eventSequence)
}
func (v *View) DeleteApplicationsByProjectID(ProjectID string) error {
return view.DeleteApplicationsByProjectID(v.Db, applicationTable, ProjectID)
}
func (v *View) GetLatestApplicationSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(applicationTable)
}

View File

@@ -47,6 +47,10 @@ func (v *View) DeleteProjectGrant(grantID string, eventSequence uint64) error {
return v.ProcessedProjectGrantSequence(eventSequence)
}
func (v *View) DeleteProjectGrantsByProjectID(projectID string) error {
return view.DeleteProjectGrantsByProjectID(v.Db, grantedProjectTable, projectID)
}
func (v *View) GetLatestProjectGrantSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(grantedProjectTable)
}

View File

@@ -15,6 +15,10 @@ func (v *View) ProjectGrantMemberByIDs(projectID, userID string) (*model.Project
return view.ProjectGrantMemberByIDs(v.Db, projectGrantMemberTable, projectID, userID)
}
func (v *View) ProjectGrantMembersByProjectID(projectID string) ([]*model.ProjectGrantMemberView, error) {
return view.ProjectGrantMembersByProjectID(v.Db, projectGrantMemberTable, projectID)
}
func (v *View) SearchProjectGrantMembers(request *proj_model.ProjectGrantMemberSearchRequest) ([]*model.ProjectGrantMemberView, uint64, error) {
return view.SearchProjectGrantMembers(v.Db, projectGrantMemberTable, request)
}
@@ -39,6 +43,10 @@ func (v *View) DeleteProjectGrantMember(grantID, userID string, eventSequence ui
return v.ProcessedProjectGrantMemberSequence(eventSequence)
}
func (v *View) DeleteProjectGrantMembersByProjectID(projectID string) error {
return view.DeleteProjectGrantMembersByProjectID(v.Db, projectGrantMemberTable, projectID)
}
func (v *View) GetLatestProjectGrantMemberSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(projectGrantMemberTable)
}

View File

@@ -15,6 +15,10 @@ func (v *View) ProjectMemberByIDs(projectID, userID string) (*model.ProjectMembe
return view.ProjectMemberByIDs(v.Db, projectMemberTable, projectID, userID)
}
func (v *View) ProjectMembersByProjectID(projectID string) ([]*model.ProjectMemberView, error) {
return view.ProjectMembersByProjectID(v.Db, projectMemberTable, projectID)
}
func (v *View) SearchProjectMembers(request *proj_model.ProjectMemberSearchRequest) ([]*model.ProjectMemberView, uint64, error) {
return view.SearchProjectMembers(v.Db, projectMemberTable, request)
}
@@ -39,6 +43,10 @@ func (v *View) DeleteProjectMember(projectID, userID string, eventSequence uint6
return v.ProcessedProjectMemberSequence(eventSequence)
}
func (v *View) DeleteProjectMembersByProjectID(projectID string) error {
return view.DeleteProjectMembersByProjectID(v.Db, projectMemberTable, projectID)
}
func (v *View) GetLatestProjectMemberSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(projectMemberTable)
}

View File

@@ -15,6 +15,10 @@ func (v *View) ProjectRoleByIDs(projectID, orgID, key string) (*model.ProjectRol
return view.ProjectRoleByIDs(v.Db, projectRoleTable, projectID, orgID, key)
}
func (v *View) ProjectRolesByProjectID(projectID string) ([]*model.ProjectRoleView, error) {
return view.ProjectRolesByProjectID(v.Db, projectRoleTable, projectID)
}
func (v *View) ResourceOwnerProjectRolesByKey(projectID, resourceowner, key string) ([]*model.ProjectRoleView, error) {
return view.ResourceOwnerProjectRolesByKey(v.Db, projectRoleTable, projectID, resourceowner, key)
}
@@ -43,6 +47,10 @@ func (v *View) DeleteProjectRole(projectID, orgID, key string, eventSequence uin
return v.ProcessedProjectRoleSequence(eventSequence)
}
func (v *View) DeleteProjectRolesByProjectID(projectID string) error {
return view.DeleteProjectRolesByProjectID(v.Db, projectRoleTable, projectID)
}
func (v *View) GetLatestProjectRoleSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(projectRoleTable)
}

View File

@@ -12,6 +12,7 @@ type ProjectRepository interface {
UpdateProject(ctx context.Context, project *model.Project) (*model.Project, error)
DeactivateProject(ctx context.Context, id string) (*model.Project, error)
ReactivateProject(ctx context.Context, id string) (*model.Project, error)
RemoveProject(ctx context.Context, id string) error
SearchProjects(ctx context.Context, request *model.ProjectViewSearchRequest) (*model.ProjectViewSearchResponse, error)
SearchProjectGrants(ctx context.Context, request *model.ProjectGrantViewSearchRequest) (*model.ProjectGrantViewSearchResponse, error)
SearchGrantedProjects(ctx context.Context, request *model.ProjectGrantViewSearchRequest) (*model.ProjectGrantViewSearchResponse, error)

View File

@@ -1,8 +1,9 @@
package model
import (
"github.com/caos/zitadel/internal/model"
"time"
"github.com/caos/zitadel/internal/model"
)
type ProjectGrantMemberView struct {
@@ -38,6 +39,7 @@ const (
ProjectGrantMemberSearchKeyLastName
ProjectGrantMemberSearchKeyGrantID
ProjectGrantMemberSearchKeyUserID
ProjectGrantMemberSearchKeyProjectID
)
type ProjectGrantMemberSearchQuery struct {

View File

@@ -163,6 +163,35 @@ func (es *ProjectEventstore) ReactivateProject(ctx context.Context, id string) (
return model.ProjectToModel(repoExisting), nil
}
func (es *ProjectEventstore) RemoveProject(ctx context.Context, proj *proj_model.Project) error {
project, aggregate, err := es.PrepareRemoveProject(ctx, proj)
if err != nil {
return err
}
err = es_sdk.PushAggregates(ctx, es.PushAggregates, project.AppendEvents, aggregate)
if err != nil {
return err
}
es.projectCache.cacheProject(project)
return nil
}
func (es *ProjectEventstore) PrepareRemoveProject(ctx context.Context, proj *proj_model.Project) (*model.Project, *es_models.Aggregate, error) {
if proj.AggregateID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Akbov", "Errors.ProjectInvalid")
}
existing, err := es.ProjectByID(ctx, proj.AggregateID)
if err != nil {
return nil, nil, err
}
repoProject := model.ProjectFromModel(existing)
projectAggregate, err := ProjectRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoProject)
if err != nil {
return nil, nil, err
}
return repoProject, projectAggregate, nil
}
func (es *ProjectEventstore) ProjectMemberByIDs(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
if member.UserID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "Errors.Project.UserIDMissing")
@@ -202,7 +231,7 @@ func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_
if _, m := model.GetProjectMember(repoProject.Members, member.UserID); m != nil {
return model.ProjectMemberToModel(m), nil
}
return nil, caos_errs.ThrowInternal(nil, "EVENT-3udjs", "Errors.Internal")
return nil, caos_errs.ThrowInternal(nil, "EVENT-rfQWv", "Errors.Internal")
}
func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
@@ -229,7 +258,7 @@ func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *pr
if _, m := model.GetProjectMember(repoProject.Members, member.UserID); m != nil {
return model.ProjectMemberToModel(m), nil
}
return nil, caos_errs.ThrowInternal(nil, "EVENT-3udjs", "Errors.Internal")
return nil, caos_errs.ThrowInternal(nil, "EVENT-pLyzi", "Errors.Internal")
}
func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) error {
@@ -255,6 +284,29 @@ func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *pr
return err
}
func (es *ProjectEventstore) PrepareRemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*model.ProjectMember, *es_models.Aggregate, error) {
if member.UserID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-tCXHE", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return nil, nil, err
}
if _, m := existing.GetMember(member.UserID); m == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-wPcg5", "Errors.Project.MemberNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoMember := model.ProjectMemberFromModel(member)
projectAggregate := ProjectMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
agg, err := projectAggregate(ctx)
if err != nil {
return nil, nil, err
}
return repoMember, agg, err
}
func (es *ProjectEventstore) AddProjectRoles(ctx context.Context, roles ...*proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
if roles == nil || len(roles) == 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-uOJAs", "Errors.Project.MinimumOneRoleNeeded")
@@ -487,7 +539,7 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model
converted.OIDCConfig.ClientSecretString = stringPw
return converted, nil
}
return nil, caos_errs.ThrowInternal(nil, "EVENT-3udjs", "Errors.Internal")
return nil, caos_errs.ThrowInternal(nil, "EVENT-GvPct", "Errors.Internal")
}
func (es *ProjectEventstore) ChangeApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
@@ -538,6 +590,27 @@ func (es *ProjectEventstore) RemoveApplication(ctx context.Context, app *proj_mo
return nil
}
func (es *ProjectEventstore) PrepareRemoveApplication(ctx context.Context, app *proj_model.Application) (*model.Application, *es_models.Aggregate, error) {
if app.AppID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-xu0Wy", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil {
return nil, nil, err
}
if _, app := existing.GetApp(app.AppID); app == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gaOD2", "Errors.Project.AppNotExisting")
}
repoProject := model.ProjectFromModel(existing)
appRepo := model.AppFromModel(app)
projectAggregate := ApplicationRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, appRepo)
agg, err := projectAggregate(ctx)
if err != nil {
return nil, nil, err
}
return appRepo, agg, nil
}
func (es *ProjectEventstore) ApplicationChanges(ctx context.Context, projectID string, appID string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ApplicationChanges, error) {
query := ChangesQuery(projectID, lastSequence, limit, sortAscending)
@@ -927,7 +1000,7 @@ func (es *ProjectEventstore) ProjectGrantMemberByIDs(ctx context.Context, member
return m, nil
}
}
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3udjs", "Errors.Project.MemberNotFound")
return nil, caos_errs.ThrowNotFound(nil, "EVENT-LxiBI", "Errors.Project.MemberNotFound")
}
func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) {
@@ -955,7 +1028,7 @@ func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *
return model.GrantMemberToModel(m), nil
}
}
return nil, caos_errs.ThrowInternal(nil, "EVENT-3udjs", "Errors.Internal")
return nil, caos_errs.ThrowInternal(nil, "EVENT-BBcGD", "Errors.Internal")
}
func (es *ProjectEventstore) ChangeProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) {

View File

@@ -345,6 +345,93 @@ func TestReactivateProject(t *testing.T) {
}
}
func TestRemoveProject(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *ProjectEventstore
ctx context.Context
existing *model.Project
}
type res struct {
result *model.Project
wantErr bool
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "remove project, ok",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Name: "Name",
Members: []*model.ProjectMember{&model.ProjectMember{UserID: "UserID", Roles: []string{"Roles"}}},
},
},
res: res{
result: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}},
},
},
{
name: "no projectid",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
ObjectRoot: es_models.ObjectRoot{Sequence: 1},
Name: "Name",
Members: []*model.ProjectMember{&model.ProjectMember{UserID: "UserID", Roles: []string{"Roles"}}},
},
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "project not existing",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{},
},
res: res{
wantErr: true,
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "existing not found",
args: args{
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "OtherAggregateID", Sequence: 1}},
},
res: res{
wantErr: true,
errFunc: caos_errs.IsNotFound,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.args.es.RemoveProject(tt.args.ctx, tt.args.existing)
if !tt.res.wantErr && err != nil {
t.Errorf("should not get err")
}
if tt.res.wantErr && !tt.res.errFunc(err) {
t.Errorf("got wrong err: %v ", err)
}
})
}
}
func TestProjectMemberByIDs(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {

View File

@@ -2,6 +2,7 @@ package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
@@ -99,6 +100,17 @@ func projectStateAggregate(aggCreator *es_models.AggregateCreator, project *mode
}
}
func ProjectRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Project) (*es_models.Aggregate, error) {
if existing == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Cj7lb", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.ProjectRemoved, existing)
}
func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if member == nil {

View File

@@ -19,6 +19,19 @@ func ApplicationByID(db *gorm.DB, table, appID string) (*model.ApplicationView,
return app, err
}
func ApplicationsByProjectID(db *gorm.DB, table, projectID string) ([]*model.ApplicationView, error) {
applications := make([]*model.ApplicationView, 0)
queries := []*proj_model.ApplicationSearchQuery{
&proj_model.ApplicationSearchQuery{Key: proj_model.AppSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
}
query := repository.PrepareSearchQuery(table, model.ApplicationSearchRequest{Queries: queries})
_, err := query(db, &applications)
if err != nil {
return nil, err
}
return applications, nil
}
func ApplicationByOIDCClientID(db *gorm.DB, table, clientID string) (*model.ApplicationView, error) {
app := new(model.ApplicationView)
clientIDQuery := model.ApplicationSearchQuery{Key: proj_model.AppSearchKeyOIDCClientID, Value: clientID, Method: global_model.SearchMethodEquals}
@@ -58,3 +71,8 @@ func DeleteApplication(db *gorm.DB, table, appID string) error {
delete := repository.PrepareDeleteByKey(table, model.ApplicationSearchKey(proj_model.AppSearchKeyAppID), appID)
return delete(db)
}
func DeleteApplicationsByProjectID(db *gorm.DB, table, projectID string) error {
delete := repository.PrepareDeleteByKey(table, model.ApplicationSearchKey(proj_model.AppSearchKeyProjectID), projectID)
return delete(db)
}

View File

@@ -2,18 +2,20 @@ package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/project/model"
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
"github.com/lib/pq"
"time"
)
const (
ProjectGrantMemberKeyUserID = "user_id"
ProjectGrantMemberKeyGrantID = "grant_id"
ProjectGrantMemberKeyProjectID = "project_id"
ProjectGrantMemberKeyUserName = "user_name"
ProjectGrantMemberKeyEmail = "email"
ProjectGrantMemberKeyFirstName = "first_name"

View File

@@ -63,6 +63,8 @@ func (key ProjectGrantMemberSearchKey) ToColumnName() string {
return ProjectGrantMemberKeyUserID
case proj_model.ProjectGrantMemberSearchKeyGrantID:
return ProjectGrantMemberKeyGrantID
case proj_model.ProjectGrantMemberSearchKeyProjectID:
return ProjectGrantMemberKeyProjectID
default:
return ""
}

View File

@@ -22,6 +22,19 @@ func ProjectGrantMemberByIDs(db *gorm.DB, table, grantID, userID string) (*model
return role, err
}
func ProjectGrantMembersByProjectID(db *gorm.DB, table, projectID string) ([]*model.ProjectGrantMemberView, error) {
members := make([]*model.ProjectGrantMemberView, 0)
queries := []*proj_model.ProjectGrantMemberSearchQuery{
&proj_model.ProjectGrantMemberSearchQuery{Key: proj_model.ProjectGrantMemberSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
}
query := repository.PrepareSearchQuery(table, model.ProjectGrantMemberSearchRequest{Queries: queries})
_, err := query(db, &members)
if err != nil {
return nil, err
}
return members, nil
}
func SearchProjectGrantMembers(db *gorm.DB, table string, req *proj_model.ProjectGrantMemberSearchRequest) ([]*model.ProjectGrantMemberView, uint64, error) {
roles := make([]*model.ProjectGrantMemberView, 0)
query := repository.PrepareSearchQuery(table, model.ProjectGrantMemberSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries})
@@ -58,3 +71,8 @@ func DeleteProjectGrantMember(db *gorm.DB, table, grantID, userID string) error
delete := repository.PrepareDeleteByObject(table, role)
return delete(db)
}
func DeleteProjectGrantMembersByProjectID(db *gorm.DB, table, projectID string) error {
delete := repository.PrepareDeleteByKey(table, model.ProjectGrantMemberSearchKey(proj_model.ProjectGrantMemberSearchKeyProjectID), projectID)
return delete(db)
}

View File

@@ -72,3 +72,8 @@ func DeleteProjectGrant(db *gorm.DB, table, grantID string) error {
delete := repository.PrepareDeleteByKey(table, model.ProjectGrantSearchKey(proj_model.GrantedProjectSearchKeyGrantID), grantID)
return delete(db)
}
func DeleteProjectGrantsByProjectID(db *gorm.DB, table, projectID string) error {
delete := repository.PrepareDeleteByKey(table, model.ProjectGrantSearchKey(proj_model.GrantedProjectSearchKeyProjectID), projectID)
return delete(db)
}

View File

@@ -22,6 +22,19 @@ func ProjectMemberByIDs(db *gorm.DB, table, projectID, userID string) (*model.Pr
return role, err
}
func ProjectMembersByProjectID(db *gorm.DB, table, projectID string) ([]*model.ProjectMemberView, error) {
members := make([]*model.ProjectMemberView, 0)
queries := []*proj_model.ProjectMemberSearchQuery{
&proj_model.ProjectMemberSearchQuery{Key: proj_model.ProjectMemberSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
}
query := repository.PrepareSearchQuery(table, model.ProjectMemberSearchRequest{Queries: queries})
_, err := query(db, &members)
if err != nil {
return nil, err
}
return members, nil
}
func SearchProjectMembers(db *gorm.DB, table string, req *proj_model.ProjectMemberSearchRequest) ([]*model.ProjectMemberView, uint64, error) {
roles := make([]*model.ProjectMemberView, 0)
query := repository.PrepareSearchQuery(table, model.ProjectMemberSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries})
@@ -57,3 +70,8 @@ func DeleteProjectMember(db *gorm.DB, table, projectID, userID string) error {
delete := repository.PrepareDeleteByObject(table, role)
return delete(db)
}
func DeleteProjectMembersByProjectID(db *gorm.DB, table, projectID string) error {
delete := repository.PrepareDeleteByKey(table, model.ProjectMemberSearchKey(proj_model.ProjectMemberSearchKeyProjectID), projectID)
return delete(db)
}

View File

@@ -23,6 +23,19 @@ func ProjectRoleByIDs(db *gorm.DB, table, projectID, orgID, key string) (*model.
return role, err
}
func ProjectRolesByProjectID(db *gorm.DB, table, projectID string) ([]*model.ProjectRoleView, error) {
roles := make([]*model.ProjectRoleView, 0)
queries := []*proj_model.ProjectRoleSearchQuery{
&proj_model.ProjectRoleSearchQuery{Key: proj_model.ProjectRoleSearchKeyProjectID, Value: projectID, Method: global_model.SearchMethodEquals},
}
query := repository.PrepareSearchQuery(table, model.ProjectRoleSearchRequest{Queries: queries})
_, err := query(db, &roles)
if err != nil {
return nil, err
}
return roles, nil
}
func ResourceOwnerProjectRolesByKey(db *gorm.DB, table, projectID, resourceOwner, key string) ([]*model.ProjectRoleView, error) {
roles := make([]*model.ProjectRoleView, 0)
queries := []*proj_model.ProjectRoleSearchQuery{
@@ -75,3 +88,9 @@ func DeleteProjectRole(db *gorm.DB, table, projectID, orgID, key string) error {
delete := repository.PrepareDeleteByObject(table, role)
return delete(db)
}
func DeleteProjectRolesByProjectID(db *gorm.DB, table, projectID string) error {
delete := repository.PrepareDeleteByKey(table, model.ProjectRoleSearchKey(proj_model.ProjectRoleSearchKeyProjectID), projectID)
return delete(db)
}

View File

@@ -1,193 +1,105 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.20.1
// protoc v3.11.3
// source: options.proto
package authoption
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
math "math"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type AuthOption struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Permission string `protobuf:"bytes,1,opt,name=permission,proto3" json:"permission,omitempty"`
CheckFieldName string `protobuf:"bytes,2,opt,name=check_field_name,json=checkFieldName,proto3" json:"check_field_name,omitempty"`
Permission string `protobuf:"bytes,1,opt,name=permission,proto3" json:"permission,omitempty"`
CheckFieldName string `protobuf:"bytes,2,opt,name=check_field_name,json=checkFieldName,proto3" json:"check_field_name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (x *AuthOption) Reset() {
*x = AuthOption{}
if protoimpl.UnsafeEnabled {
mi := &file_options_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AuthOption) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthOption) ProtoMessage() {}
func (x *AuthOption) ProtoReflect() protoreflect.Message {
mi := &file_options_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthOption.ProtoReflect.Descriptor instead.
func (m *AuthOption) Reset() { *m = AuthOption{} }
func (m *AuthOption) String() string { return proto.CompactTextString(m) }
func (*AuthOption) ProtoMessage() {}
func (*AuthOption) Descriptor() ([]byte, []int) {
return file_options_proto_rawDescGZIP(), []int{0}
return fileDescriptor_110d40819f1994f9, []int{0}
}
func (x *AuthOption) GetPermission() string {
if x != nil {
return x.Permission
func (m *AuthOption) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AuthOption.Unmarshal(m, b)
}
func (m *AuthOption) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AuthOption.Marshal(b, m, deterministic)
}
func (m *AuthOption) XXX_Merge(src proto.Message) {
xxx_messageInfo_AuthOption.Merge(m, src)
}
func (m *AuthOption) XXX_Size() int {
return xxx_messageInfo_AuthOption.Size(m)
}
func (m *AuthOption) XXX_DiscardUnknown() {
xxx_messageInfo_AuthOption.DiscardUnknown(m)
}
var xxx_messageInfo_AuthOption proto.InternalMessageInfo
func (m *AuthOption) GetPermission() string {
if m != nil {
return m.Permission
}
return ""
}
func (x *AuthOption) GetCheckFieldName() string {
if x != nil {
return x.CheckFieldName
func (m *AuthOption) GetCheckFieldName() string {
if m != nil {
return m.CheckFieldName
}
return ""
}
var file_options_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*descriptor.MethodOptions)(nil),
ExtensionType: (*AuthOption)(nil),
Field: 50000,
Name: "caos.zitadel.utils.v1.auth_option",
Tag: "bytes,50000,opt,name=auth_option",
Filename: "options.proto",
},
var E_AuthOption = &proto.ExtensionDesc{
ExtendedType: (*descriptor.MethodOptions)(nil),
ExtensionType: (*AuthOption)(nil),
Field: 50000,
Name: "caos.zitadel.utils.v1.auth_option",
Tag: "bytes,50000,opt,name=auth_option",
Filename: "options.proto",
}
// Extension fields to descriptor.MethodOptions.
var (
// optional caos.zitadel.utils.v1.AuthOption auth_option = 50000;
E_AuthOption = &file_options_proto_extTypes[0]
)
var File_options_proto protoreflect.FileDescriptor
var file_options_proto_rawDesc = []byte{
0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x15, 0x63, 0x61, 0x6f, 0x73, 0x2e, 0x7a, 0x69, 0x74, 0x61, 0x64, 0x65, 0x6c, 0x2e, 0x75, 0x74,
0x69, 0x6c, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x68,
0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d,
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f,
0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65,
0x3a, 0x64, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x61, 0x6f, 0x73, 0x2e, 0x7a,
0x69, 0x74, 0x61, 0x64, 0x65, 0x6c, 0x2e, 0x75, 0x74, 0x69, 0x6c, 0x73, 0x2e, 0x76, 0x31, 0x2e,
0x41, 0x75, 0x74, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68,
0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x4a, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x6f, 0x73, 0x2f, 0x7a, 0x69, 0x74, 0x61, 0x64, 0x65,
0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
func init() {
proto.RegisterType((*AuthOption)(nil), "caos.zitadel.utils.v1.AuthOption")
proto.RegisterExtension(E_AuthOption)
}
var (
file_options_proto_rawDescOnce sync.Once
file_options_proto_rawDescData = file_options_proto_rawDesc
)
func init() { proto.RegisterFile("options.proto", fileDescriptor_110d40819f1994f9) }
func file_options_proto_rawDescGZIP() []byte {
file_options_proto_rawDescOnce.Do(func() {
file_options_proto_rawDescData = protoimpl.X.CompressGZIP(file_options_proto_rawDescData)
})
return file_options_proto_rawDescData
}
var file_options_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_options_proto_goTypes = []interface{}{
(*AuthOption)(nil), // 0: caos.zitadel.utils.v1.AuthOption
(*descriptor.MethodOptions)(nil), // 1: google.protobuf.MethodOptions
}
var file_options_proto_depIdxs = []int32{
1, // 0: caos.zitadel.utils.v1.auth_option:extendee -> google.protobuf.MethodOptions
0, // 1: caos.zitadel.utils.v1.auth_option:type_name -> caos.zitadel.utils.v1.AuthOption
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
1, // [1:2] is the sub-list for extension type_name
0, // [0:1] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_options_proto_init() }
func file_options_proto_init() {
if File_options_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_options_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AuthOption); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_options_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 1,
NumServices: 0,
},
GoTypes: file_options_proto_goTypes,
DependencyIndexes: file_options_proto_depIdxs,
MessageInfos: file_options_proto_msgTypes,
ExtensionInfos: file_options_proto_extTypes,
}.Build()
File_options_proto = out.File
file_options_proto_rawDesc = nil
file_options_proto_goTypes = nil
file_options_proto_depIdxs = nil
var fileDescriptor_110d40819f1994f9 = []byte{
// 252 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x8f, 0x31, 0x4b, 0xc5, 0x30,
0x14, 0x85, 0x79, 0x0a, 0x82, 0x79, 0x28, 0x52, 0x10, 0x8a, 0x83, 0x54, 0xa7, 0x2e, 0xef, 0x06,
0x75, 0x73, 0xd3, 0x41, 0x44, 0x50, 0xe1, 0x0d, 0x0e, 0x2e, 0x25, 0x4d, 0xef, 0x6b, 0x83, 0x6d,
0x6e, 0x49, 0x6e, 0x1c, 0xfc, 0x01, 0xfe, 0x3e, 0x7f, 0x92, 0x34, 0xa9, 0x3e, 0x07, 0xa7, 0x5c,
0x0e, 0xe7, 0x9c, 0x7c, 0x47, 0x1c, 0xd0, 0xc8, 0x86, 0xac, 0x87, 0xd1, 0x11, 0x53, 0x76, 0xac,
0x15, 0x79, 0xf8, 0x30, 0xac, 0x1a, 0xec, 0x21, 0xb0, 0xe9, 0x3d, 0xbc, 0x5f, 0x9c, 0x14, 0x2d,
0x51, 0xdb, 0xa3, 0x8c, 0xa6, 0x3a, 0x6c, 0x64, 0x83, 0x5e, 0x3b, 0x33, 0x32, 0xb9, 0x14, 0x3c,
0x7f, 0x11, 0xe2, 0x26, 0x70, 0xf7, 0x1c, 0xdb, 0xb2, 0x53, 0x21, 0x46, 0x74, 0x83, 0xf1, 0xde,
0x90, 0xcd, 0x17, 0xc5, 0xa2, 0xdc, 0x5f, 0xff, 0x51, 0xb2, 0x52, 0x1c, 0xe9, 0x0e, 0xf5, 0x5b,
0xb5, 0x31, 0xd8, 0x37, 0x95, 0x55, 0x03, 0xe6, 0x3b, 0xd1, 0x75, 0x18, 0xf5, 0xbb, 0x49, 0x7e,
0x52, 0x03, 0x5e, 0x37, 0x62, 0xa9, 0x02, 0x77, 0x15, 0xcd, 0xc5, 0x90, 0x48, 0xe0, 0x87, 0x04,
0x1e, 0x91, 0x3b, 0x6a, 0xd2, 0xbf, 0x3e, 0xff, 0xfa, 0xdc, 0x2d, 0x16, 0xe5, 0xf2, 0xf2, 0x0c,
0xfe, 0x1d, 0x02, 0x5b, 0xc6, 0xb5, 0x50, 0xbf, 0xf7, 0xed, 0xc3, 0xeb, 0x7d, 0x6b, 0xb8, 0x0b,
0x35, 0x68, 0x1a, 0xe4, 0x14, 0x95, 0x73, 0x54, 0x1a, 0xcb, 0xe8, 0xac, 0xea, 0xd3, 0x76, 0x3d,
0x3f, 0xab, 0x16, 0xed, 0x6a, 0x2a, 0x48, 0x5c, 0x72, 0x7b, 0xd6, 0x7b, 0xd1, 0x71, 0xf5, 0x1d,
0x00, 0x00, 0xff, 0xff, 0xd2, 0xa7, 0xf7, 0xca, 0x5a, 0x01, 0x00, 0x00,
}

View File

@@ -83,7 +83,7 @@ func templatesAuth_method_mappingGoTmpl() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "templates/auth_method_mapping.go.tmpl", size: 828, mode: os.FileMode(420), modTime: time.Unix(1594209794, 0)}
info := bindataFileInfo{name: "templates/auth_method_mapping.go.tmpl", size: 828, mode: os.FileMode(420), modTime: time.Unix(1594709815, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -182,7 +182,6 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
"templates": &bintree{nil, map[string]*bintree{
"auth_method_mapping.go.tmpl": &bintree{templatesAuth_method_mappingGoTmpl, map[string]*bintree{}},
@@ -235,3 +234,4 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}