From 93e941a475498d8fe956103ab419c8ec04b90c70 Mon Sep 17 00:00:00 2001 From: Silvan Date: Thu, 19 Nov 2020 14:13:07 +0100 Subject: [PATCH] fix: Improve search user grants (#988) * fix(management): search user grants with granted * fix(auth): handle user grant project owner * fix: migration --- .../grpc/management/user_grant_converter.go | 4 +-- .../eventsourcing/handler/user_grant.go | 1 + .../eventsourcing/eventstore/user_grant.go | 1 + .../eventsourcing/handler/user_grant.go | 1 + internal/usergrant/model/user_grant_view.go | 1 + .../repository/view/model/user_grant.go | 1 + .../repository/view/model/user_grant_test.go | 5 +-- .../repository/view/user_grant_view.go | 32 +++++++++++++++++-- internal/view/repository/query.go | 2 ++ .../cockroach/V1.22__user_grant_owners.sql | 5 +++ pkg/grpc/management/proto/management.proto | 4 +-- 11 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 migrations/cockroach/V1.22__user_grant_owners.sql diff --git a/internal/api/grpc/management/user_grant_converter.go b/internal/api/grpc/management/user_grant_converter.go index fe3bf4c5c..576e2a27f 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 34e85537b..d9ded99e7 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 944ccf32a..ddcfedb81 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 9bd28c3dd..e95b15329 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 903a5a63b..b5dd34243 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 6e2c3c7dd..626ab0e61 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 40f5edb1a..ca2cd75b4 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 c09bdda08..68d5e6538 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 6623b5687..8205cda51 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 000000000..07a11eaa0 --- /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 0297b4fa0..19eac49b2 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;