diff --git a/internal/api/grpc/management/user_grant_converter.go b/internal/api/grpc/management/user_grant_converter.go index fe3bf4c5c1..576e2a27f2 100644 --- a/internal/api/grpc/management/user_grant_converter.go +++ b/internal/api/grpc/management/user_grant_converter.go @@ -79,8 +79,8 @@ func userGrantSearchQueryToModel(query *management.UserGrantSearchQuery) *grant_ func userGrantSearchKeyToModel(key management.UserGrantSearchKey) grant_model.UserGrantSearchKey { switch key { - case management.UserGrantSearchKey_USERGRANTSEARCHKEY_ORG_ID: - return grant_model.UserGrantSearchKeyResourceOwner + case management.UserGrantSearchKey_USERGRANTSEARCHKEY_WITH_GRANTED: + return grant_model.UserGrantSearchKeyWithGranted case management.UserGrantSearchKey_USERGRANTSEARCHKEY_PROJECT_ID: return grant_model.UserGrantSearchKeyProjectID case management.UserGrantSearchKey_USERGRANTSEARCHKEY_USER_ID: diff --git a/internal/auth/repository/eventsourcing/handler/user_grant.go b/internal/auth/repository/eventsourcing/handler/user_grant.go index 34e85537bd..d9ded99e7f 100644 --- a/internal/auth/repository/eventsourcing/handler/user_grant.go +++ b/internal/auth/repository/eventsourcing/handler/user_grant.go @@ -350,6 +350,7 @@ func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_mode func (u *UserGrant) fillProjectData(grant *view_model.UserGrantView, project *proj_model.Project) { grant.ProjectName = project.Name + grant.ProjectOwner = project.ResourceOwner } func (u *UserGrant) fillOrgData(grant *view_model.UserGrantView, org *org_model.Org) { diff --git a/internal/management/repository/eventsourcing/eventstore/user_grant.go b/internal/management/repository/eventsourcing/eventstore/user_grant.go index 944ccf32a6..ddcfedb81d 100644 --- a/internal/management/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/management/repository/eventsourcing/eventstore/user_grant.go @@ -2,6 +2,7 @@ package eventstore import ( "context" + "github.com/caos/logging" "github.com/caos/zitadel/internal/api/authz" caos_errors "github.com/caos/zitadel/internal/errors" diff --git a/internal/management/repository/eventsourcing/handler/user_grant.go b/internal/management/repository/eventsourcing/handler/user_grant.go index 9bd28c3dd7..e95b153299 100644 --- a/internal/management/repository/eventsourcing/handler/user_grant.go +++ b/internal/management/repository/eventsourcing/handler/user_grant.go @@ -176,6 +176,7 @@ func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_mode func (u *UserGrant) fillProjectData(grant *view_model.UserGrantView, project *proj_model.Project) { grant.ProjectName = project.Name + grant.ProjectOwner = project.ResourceOwner } func (u *UserGrant) fillOrgData(grant *view_model.UserGrantView, org *org_model.Org) { diff --git a/internal/usergrant/model/user_grant_view.go b/internal/usergrant/model/user_grant_view.go index 903a5a63b8..b5dd342433 100644 --- a/internal/usergrant/model/user_grant_view.go +++ b/internal/usergrant/model/user_grant_view.go @@ -56,6 +56,7 @@ const ( UserGrantSearchKeyOrgDomain UserGrantSearchKeyProjectName UserGrantSearchKeyDisplayName + UserGrantSearchKeyWithGranted ) type UserGrantSearchQuery struct { diff --git a/internal/usergrant/repository/view/model/user_grant.go b/internal/usergrant/repository/view/model/user_grant.go index 6e2c3c7dde..626ab0e616 100644 --- a/internal/usergrant/repository/view/model/user_grant.go +++ b/internal/usergrant/repository/view/model/user_grant.go @@ -43,6 +43,7 @@ type UserGrantView struct { DisplayName string `json:"-" gorm:"column:display_name"` Email string `json:"-" gorm:"column:email"` ProjectName string `json:"-" gorm:"column:project_name"` + ProjectOwner string `json:"-" gorm:"column:project_owner"` OrgName string `json:"-" gorm:"column:org_name"` OrgPrimaryDomain string `json:"-" gorm:"column:org_primary_domain"` RoleKeys pq.StringArray `json:"roleKeys" gorm:"column:role_keys"` diff --git a/internal/usergrant/repository/view/model/user_grant_test.go b/internal/usergrant/repository/view/model/user_grant_test.go index 40f5edb1af..ca2cd75b40 100644 --- a/internal/usergrant/repository/view/model/user_grant_test.go +++ b/internal/usergrant/repository/view/model/user_grant_test.go @@ -2,12 +2,13 @@ package model import ( "encoding/json" + "reflect" + "testing" + es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/usergrant/model" es_model "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" "github.com/lib/pq" - "reflect" - "testing" ) func mockUserGrantData(grant *es_model.UserGrant) []byte { diff --git a/internal/usergrant/repository/view/user_grant_view.go b/internal/usergrant/repository/view/user_grant_view.go index c09bdda08b..68d5e65384 100644 --- a/internal/usergrant/repository/view/user_grant_view.go +++ b/internal/usergrant/repository/view/user_grant_view.go @@ -34,13 +34,39 @@ func UserGrantByIDs(db *gorm.DB, table, resourceOwnerID, projectID, userID strin } func SearchUserGrants(db *gorm.DB, table string, req *grant_model.UserGrantSearchRequest) ([]*model.UserGrantView, uint64, error) { - users := make([]*model.UserGrantView, 0) + grants := make([]*model.UserGrantView, 0) + + var orgID string + var withGranted bool + + for i := len(req.Queries) - 1; i >= 0; i-- { + shouldRemove := false + if req.Queries[i].Key == grant_model.UserGrantSearchKeyResourceOwner { + orgID = req.Queries[i].Value.(string) + shouldRemove = true + } + if req.Queries[i].Key == grant_model.UserGrantSearchKeyWithGranted { + withGranted = true + shouldRemove = true + } + if shouldRemove { + req.Queries[i] = req.Queries[len(req.Queries)-1] + req.Queries[len(req.Queries)-1] = nil + req.Queries = req.Queries[:len(req.Queries)-1] + } + } + + if withGranted { + db = db.Where("grant_owner = ? OR project_owner = ?", orgID, orgID) + } else { + db = db.Where("grant_owner = ?", orgID) + } query := repository.PrepareSearchQuery(table, model.UserGrantSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &users) + count, err := query(db, &grants) if err != nil { return nil, 0, err } - return users, count, nil + return grants, count, nil } func UserGrantsByUserID(db *gorm.DB, table, userID string) ([]*model.UserGrantView, error) { diff --git a/internal/view/repository/query.go b/internal/view/repository/query.go index 6623b5687a..8205cda518 100644 --- a/internal/view/repository/query.go +++ b/internal/view/repository/query.go @@ -2,6 +2,7 @@ package repository import ( "fmt" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/model" "github.com/jinzhu/gorm" @@ -37,6 +38,7 @@ func PrepareSearchQuery(table string, request SearchRequest) func(db *gorm.DB, r } query = query.Order(fmt.Sprintf("%s %s", column.ToColumnName(), order)) } + for _, q := range request.GetQueries() { var err error query, err = SetQuery(query, q.GetKey(), q.GetValue(), q.GetMethod()) diff --git a/migrations/cockroach/V1.22__user_grant_owners.sql b/migrations/cockroach/V1.22__user_grant_owners.sql new file mode 100644 index 0000000000..07a11eaa08 --- /dev/null +++ b/migrations/cockroach/V1.22__user_grant_owners.sql @@ -0,0 +1,5 @@ +ALTER TABLE management.user_grants ADD COLUMN project_owner STRING; + +ALTER TABLE auth.user_grants ADD COLUMN project_owner STRING; + +ALTER TABLE authz.user_grants ADD COLUMN project_owner STRING; diff --git a/pkg/grpc/management/proto/management.proto b/pkg/grpc/management/proto/management.proto index 0297b4fa03..19eac49b24 100644 --- a/pkg/grpc/management/proto/management.proto +++ b/pkg/grpc/management/proto/management.proto @@ -2863,7 +2863,7 @@ message UserGrantSearchRequest { message UserGrantSearchQuery { UserGrantSearchKey key = 1 [(validate.rules).enum = {not_in: [0]}]; - SearchMethod method = 2 [(validate.rules).enum = {in: [0]}]; + SearchMethod method = 2 [(validate.rules).enum.defined_only = true]; string value = 3; } @@ -2871,7 +2871,7 @@ enum UserGrantSearchKey { USERGRANTSEARCHKEY_UNSPECIFIED = 0; USERGRANTSEARCHKEY_PROJECT_ID = 1; USERGRANTSEARCHKEY_USER_ID = 2; - USERGRANTSEARCHKEY_ORG_ID = 3; + USERGRANTSEARCHKEY_WITH_GRANTED = 3; USERGRANTSEARCHKEY_ROLE_KEY = 4; USERGRANTSEARCHKEY_GRANT_ID = 5; USERGRANTSEARCHKEY_USER_NAME = 6;