From 9107f6e1b5be64242d42540d8dae35e0d69c2598 Mon Sep 17 00:00:00 2001 From: Nirav Parikh Date: Tue, 14 Jun 2022 20:15:46 +0530 Subject: [PATCH 1/3] changes to fix project updates for namespaces --- .../proto/rpc/system/project.swagger.json | 7 +- internal/dao/project.go | 23 ++- pkg/service/project.go | 180 ++++++++++++++---- proto/types/userpb/v3/user.pb.go | 56 +++--- proto/types/userpb/v3/user.proto | 7 +- 5 files changed, 205 insertions(+), 68 deletions(-) diff --git a/gen/openapi/proto/rpc/system/project.swagger.json b/gen/openapi/proto/rpc/system/project.swagger.json index edeab09..943aeda 100644 --- a/gen/openapi/proto/rpc/system/project.swagger.json +++ b/gen/openapi/proto/rpc/system/project.swagger.json @@ -957,9 +957,14 @@ "type": "string", "description": "Role", "title": "Role" + }, + "namespace": { + "type": "string", + "description": "Namespace", + "title": "Namespace" } }, - "description": "User, role pairing for permission", + "description": "User, role, namespace pairing for permission", "title": "UserRole" } }, diff --git a/internal/dao/project.go b/internal/dao/project.go index 672505e..2b31598 100644 --- a/internal/dao/project.go +++ b/internal/dao/project.go @@ -81,6 +81,7 @@ func GetProjectGroupRoles(ctx context.Context, db bun.IDB, id uuid.UUID) ([]*use Join(`JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id`). Join(`JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id`). Where("authsrv_projectgrouprole.project_id = ?", id). + Where("authsrv_projectgrouprole.trash = ?", false). Scan(ctx, &pr) if err != nil { return nil, err @@ -91,8 +92,9 @@ func GetProjectGroupRoles(ctx context.Context, db bun.IDB, id uuid.UUID) ([]*use ColumnExpr("distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group, namespace"). Join(`JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgroupnamespacerole.role_id`). Join(`JOIN authsrv_project ON authsrv_project.id=authsrv_projectgroupnamespacerole.project_id`). - Join(`JOIN authsrv_group ON authsrv_group.id=authsrv_projectgroupnamespacerole.group_id`). // also need a namespace join + Join(`JOIN authsrv_group ON authsrv_group.id=authsrv_projectgroupnamespacerole.group_id`). Where("authsrv_projectgroupnamespacerole.project_id = ?", id). + Where("authsrv_projectgroupnamespacerole.trash = ?", false). Scan(ctx, &pnr) if err != nil { return nil, err @@ -103,16 +105,29 @@ func GetProjectGroupRoles(ctx context.Context, db bun.IDB, id uuid.UUID) ([]*use func GetProjectUserRoles(ctx context.Context, db bun.IDB, id uuid.UUID) ([]*userv3.UserRole, error) { - var pr = []*userv3.UserRole{} + var ur = []*userv3.UserRole{} err := db.NewSelect().Table("authsrv_projectaccountresourcerole"). ColumnExpr("distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user"). Join(`JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id`). Join(`JOIN identities ON identities.id=authsrv_projectaccountresourcerole.account_id`). Where("authsrv_projectaccountresourcerole.project_id = ?", id). - Scan(ctx, &pr) + Where("authsrv_projectaccountresourcerole.trash = ?", false). + Scan(ctx, &ur) if err != nil { return nil, err } - return pr, err + var unr = []*userv3.UserRole{} + err = db.NewSelect().Table("authsrv_projectaccountnamespacerole"). + ColumnExpr("distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user, namespace"). + Join(`JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id`). + Join(`JOIN identities ON identities.id=authsrv_projectaccountnamespacerole.account_id`). + Where("authsrv_projectaccountnamespacerole.project_id = ?", id). + Where("authsrv_projectaccountnamespacerole.trash = ?", false). + Scan(ctx, &unr) + if err != nil { + return nil, err + } + + return append(ur, unr...), err } diff --git a/pkg/service/project.go b/pkg/service/project.go index db8be51..c357259 100644 --- a/pkg/service/project.go +++ b/pkg/service/project.go @@ -445,16 +445,21 @@ func (s *projectService) createGroupRoleRelations(ctx context.Context, db bun.ID projectNamespaceRoles := project.GetSpec().GetProjectNamespaceRoles() var pgrs []models.ProjectGroupRole + var pgnr []models.ProjectGroupNamespaceRole var ps []*authzv1.Policy for _, pnr := range projectNamespaceRoles { role := pnr.GetRole() - entity, err := dao.GetIdByName(ctx, db, role, &models.Role{}) + entity, err := dao.GetByName(ctx, db, role, &models.Role{}) if err != nil { return &systemv3.Project{}, fmt.Errorf("unable to find role '%v'", role) } var roleId uuid.UUID + var scope string + var roleName string if rle, ok := entity.(*models.Role); ok { roleId = rle.ID + scope = rle.Scope + roleName = rle.Name } else { return &systemv3.Project{}, fmt.Errorf("unable to find role '%v'", role) } @@ -474,24 +479,63 @@ func (s *projectService) createGroupRoleRelations(ctx context.Context, db bun.ID } org := project.Metadata.Organization - pgr := models.ProjectGroupRole{ - Trash: false, - RoleId: roleId, - PartnerId: ids.Partner, - OrganizationId: ids.Organization, - GroupId: grpId, - ProjectId: ids.Id, - Active: true, + switch scope { + case "project": + if org == "" { + return &systemv3.Project{}, fmt.Errorf("no org name provided for role '%v'", roleName) + } + + pgr := models.ProjectGroupRole{ + Trash: false, + RoleId: roleId, + PartnerId: ids.Partner, + OrganizationId: ids.Organization, + GroupId: grpId, + ProjectId: ids.Id, + Active: true, + } + pgrs = append(pgrs, pgr) + + ps = append(ps, &authzv1.Policy{ + Sub: "g:" + grpName, + Ns: "*", + Proj: project.Metadata.Name, + Org: org, + Obj: role, + }) + case "namespace": + if org == "" { + return &systemv3.Project{}, fmt.Errorf("no org name provided for role '%v'", roleName) + } + + namespace := pnr.GetNamespace() + pgnrObj := models.ProjectGroupNamespaceRole{ + CreatedAt: time.Now(), + ModifiedAt: time.Now(), + Trash: false, + PartnerId: ids.Partner, + OrganizationId: ids.Organization, + RoleId: roleId, + GroupId: grpId, + ProjectId: ids.Id, + Namespace: namespace, + Active: true, + } + pgnr = append(pgnr, pgnrObj) + + ps = append(ps, &authzv1.Policy{ + Sub: "g:" + grpName, + Ns: namespace, + Proj: project.Metadata.Name, + Org: org, + Obj: role, + }) + default: + if err != nil { + return project, fmt.Errorf("other scoped roles are not handled") + } } - pgrs = append(pgrs, pgr) - ps = append(ps, &authzv1.Policy{ - Sub: "g:" + grpName, - Ns: "*", - Proj: project.Metadata.Name, - Org: org, - Obj: role, - }) } if len(pgrs) > 0 { _, err := dao.Create(ctx, db, &pgrs) @@ -499,6 +543,12 @@ func (s *projectService) createGroupRoleRelations(ctx context.Context, db bun.ID return &systemv3.Project{}, err } } + if len(pgnr) > 0 { + _, err := dao.Create(ctx, db, &pgnr) + if err != nil { + return &systemv3.Project{}, err + } + } if len(ps) > 0 { success, err := s.azc.CreatePolicies(ctx, &authzv1.Policies{Policies: ps}) @@ -517,6 +567,12 @@ func (s *projectService) deleteGroupRoleRelations(ctx context.Context, db bun.ID return &systemv3.Project{}, err } + pgnr := []models.ProjectGroupNamespaceRole{} + err = dao.DeleteXR(ctx, db, "project_id", projectId, &pgnr) + if err != nil { + return &systemv3.Project{}, err + } + _, err = s.azc.DeletePolicies(ctx, &authzv1.Policy{Proj: project.GetMetadata().GetName()}) if err != nil { return &systemv3.Project{}, fmt.Errorf("unable to delete project group-role relations from authz; %v", err) @@ -530,6 +586,12 @@ func (s *projectService) deleteProjectAccountRelations(ctx context.Context, db b return &systemv3.Project{}, fmt.Errorf("unable to delete project; %v", err) } + pgnr := []models.ProjectAccountNamespaceRole{} + err = dao.DeleteXR(ctx, db, "project_id", projectId, &pgnr) + if err != nil { + return &systemv3.Project{}, err + } + _, err = s.azc.DeletePolicies(ctx, &authzv1.Policy{Proj: project.GetMetadata().GetName()}) if err != nil { return &systemv3.Project{}, fmt.Errorf("unable to delete project user-role relations from authz; %v", err) @@ -540,6 +602,7 @@ func (s *projectService) deleteProjectAccountRelations(ctx context.Context, db b // Update the users(account) mapped to each project func (s *projectService) createProjectAccountRelations(ctx context.Context, db bun.IDB, projectId uuid.UUID, project *systemv3.Project) (*systemv3.Project, error) { var parrs []models.ProjectAccountResourcerole + var panrs []models.ProjectAccountNamespaceRole var ugs []*authzv1.Policy for _, ur := range project.GetSpec().GetUserRoles() { @@ -555,39 +618,76 @@ func (s *projectService) createProjectAccountRelations(ctx context.Context, db b if acc, ok := entity.(*models.KratosIdentities); ok { if role, ok := rentity.(*models.Role); ok { - parr := models.ProjectAccountResourcerole{ - CreatedAt: time.Now(), - ModifiedAt: time.Now(), - Trash: false, - AccountId: acc.ID, - ProjectId: projectId, - RoleId: role.ID, - OrganizationId: role.OrganizationId, - PartnerId: role.PartnerId, - Active: true, + switch role.Scope { + case "project": + parr := models.ProjectAccountResourcerole{ + CreatedAt: time.Now(), + ModifiedAt: time.Now(), + Trash: false, + AccountId: acc.ID, + ProjectId: projectId, + RoleId: role.ID, + OrganizationId: role.OrganizationId, + PartnerId: role.PartnerId, + Active: true, + } + parrs = append(parrs, parr) + ugs = append(ugs, &authzv1.Policy{ + Sub: "u:" + ur.User, + Proj: project.Metadata.Name, + Org: project.Metadata.Organization, + Ns: "*", + Obj: role.Name, + }) + case "namespace": + panrObj := models.ProjectAccountNamespaceRole{ + CreatedAt: time.Now(), + ModifiedAt: time.Now(), + Trash: false, + AccountId: acc.ID, + PartnerId: role.PartnerId, + OrganizationId: role.OrganizationId, + RoleId: role.ID, + ProjectId: projectId, + Namespace: ur.GetNamespace(), + Active: true, + } + panrs = append(panrs, panrObj) + + ugs = append(ugs, &authzv1.Policy{ + Sub: "u:" + ur.User, + Proj: project.Metadata.Name, + Org: project.Metadata.Organization, + Ns: ur.GetNamespace(), + Obj: role.Name, + }) + default: + if err != nil { + return project, fmt.Errorf("other scoped roles are not handled") + } } - parrs = append(parrs, parr) - ugs = append(ugs, &authzv1.Policy{ - Sub: "u:" + ur.User, - Proj: project.Metadata.Name, - Org: project.Metadata.Organization, - Ns: "*", - Obj: role.Name, - }) } } } - if len(parrs) == 0 { + if len(parrs) == 0 && len(panrs) == 0 { return project, nil } - _, err := dao.Create(ctx, db, &parrs) - if err != nil { - return &systemv3.Project{}, err + if len(parrs) > 0 { + _, err := dao.Create(ctx, db, &parrs) + if err != nil { + return &systemv3.Project{}, err + } + } + if len(panrs) > 0 { + _, err := dao.Create(ctx, db, &panrs) + if err != nil { + return &systemv3.Project{}, err + } } // TODO: revert our db inserts if this fails // Just FYI, the succcess can be false if we delete the db directly but casbin has it available internally - _, err = s.azc.CreatePolicies(ctx, &authzv1.Policies{Policies: ugs}) + _, err := s.azc.CreatePolicies(ctx, &authzv1.Policies{Policies: ugs}) if err != nil { return &systemv3.Project{}, fmt.Errorf("unable to create mapping in authz; %v", err) } diff --git a/proto/types/userpb/v3/user.pb.go b/proto/types/userpb/v3/user.pb.go index 315e198..9746e48 100644 --- a/proto/types/userpb/v3/user.pb.go +++ b/proto/types/userpb/v3/user.pb.go @@ -479,8 +479,9 @@ type UserRole struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` - Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` } func (x *UserRole) Reset() { @@ -529,6 +530,13 @@ func (x *UserRole) GetRole() string { return "" } +func (x *UserRole) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + var File_proto_types_userpb_v3_user_proto protoreflect.FileDescriptor var file_proto_types_userpb_v3_user_proto_rawDesc = []byte{ @@ -755,31 +763,35 @@ var file_proto_types_userpb_v3_user_proto_rawDesc = []byte{ 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x40, 0x01, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x1c, 0x92, 0x41, 0x19, 0x0a, 0x17, 0x2a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x32, 0x09, 0x55, 0x73, - 0x65, 0x72, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x40, 0x01, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x55, 0x73, + 0x65, 0x72, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x40, 0x01, 0x22, 0xcc, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0x92, 0x41, 0x0c, 0x2a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x32, 0x04, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0x92, 0x41, 0x0c, 0x2a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x32, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, - 0x3a, 0x32, 0x92, 0x41, 0x2f, 0x0a, 0x2d, 0x2a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, - 0x65, 0x32, 0x21, 0x55, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, - 0x69, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x72, - 0x61, 0x6c, 0x75, 0x73, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x70, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, - 0x70, 0x62, 0x2f, 0x76, 0x33, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x33, 0xa2, 0x02, 0x04, 0x50, - 0x44, 0x54, 0x55, 0xaa, 0x02, 0x19, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x2e, 0x44, 0x65, - 0x76, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x33, 0xca, - 0x02, 0x19, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x33, 0xe2, 0x02, 0x25, 0x50, 0x61, - 0x72, 0x61, 0x6c, 0x75, 0x73, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, - 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x33, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x3a, 0x3a, 0x44, - 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x3a, 0x55, 0x73, 0x65, 0x72, 0x3a, - 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x37, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x19, 0x92, 0x41, 0x16, 0x2a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x32, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x3d, 0x92, 0x41, 0x3a, 0x0a, 0x38, + 0x2a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x32, 0x2c, 0x55, 0x73, 0x65, 0x72, + 0x2c, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x20, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, + 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x2f, 0x70, 0x61, 0x72, 0x61, + 0x6c, 0x75, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, + 0x75, 0x73, 0x65, 0x72, 0x70, 0x62, 0x2f, 0x76, 0x33, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x33, + 0xa2, 0x02, 0x04, 0x50, 0x44, 0x54, 0x55, 0xaa, 0x02, 0x19, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, + 0x73, 0x2e, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x2e, 0x56, 0x33, 0xca, 0x02, 0x19, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x5c, 0x44, 0x65, + 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x33, 0xe2, + 0x02, 0x25, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, 0x73, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x33, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x75, + 0x73, 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x3a, 0x55, + 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/types/userpb/v3/user.proto b/proto/types/userpb/v3/user.proto index 13c595d..8634e05 100644 --- a/proto/types/userpb/v3/user.proto +++ b/proto/types/userpb/v3/user.proto @@ -244,7 +244,7 @@ message UserRole { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { json_schema : { title : "UserRole" - description : "User, role pairing for permission" + description : "User, role, namespace pairing for permission" } }; string user = 1 @@ -257,4 +257,9 @@ message UserRole { title : "Role" description : "Role" } ]; + string namespace = 3 + [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + title : "Namespace" + description : "Namespace" + } ]; } From e0afe7b31510184266f9fc91e7b07f6eeb02c5fc Mon Sep 17 00:00:00 2001 From: Nirav Parikh Date: Wed, 15 Jun 2022 11:31:01 +0530 Subject: [PATCH 2/3] fixing test cases --- pkg/service/project_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/service/project_test.go b/pkg/service/project_test.go index 5b3cff4..0fe8873 100644 --- a/pkg/service/project_test.go +++ b/pkg/service/project_test.go @@ -81,7 +81,11 @@ func TestProjectDelete(t *testing.T) { WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "project-"+puuid)) mock.ExpectBegin() mock.ExpectExec(`UPDATE "authsrv_projectgrouprole" AS "projectgrouprole" SET trash = TRUE WHERE`).WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectQuery(`UPDATE "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" SET trash = TRUE WHERE ."project_id" = '` + puuid + `'. AND .trash = false. RETURNING *`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectExec(`UPDATE "authsrv_projectaccountresourcerole" AS "projectaccountresourcerole" SET trash = TRUE WHERE`).WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectQuery(`UPDATE "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" SET trash = TRUE WHERE ."project_id" = '` + puuid + `'. AND .trash = false. RETURNING *`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectExec(`UPDATE "authsrv_project"`). WillReturnResult(sqlmock.NewResult(1, 1)) @@ -152,6 +156,10 @@ func TestProjectGetByName(t *testing.T) { FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN identities ON identities.id=authsrv_projectaccountresourcerole.account_id WHERE`).WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("ADMIN")) + mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user, namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole + ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN identities + ON identities.id=authsrv_projectaccountnamespacerole.account_id WHERE`).WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("ADMIN")) + project := &systemv3.Project{ Metadata: &v3.Metadata{Id: puuid, Name: "project-" + puuid}, } @@ -196,7 +204,11 @@ func TestProjectUpdate(t *testing.T) { WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(puuid, "project-"+puuid)) mock.ExpectBegin() mock.ExpectExec(`UPDATE "authsrv_projectgrouprole" AS "projectgrouprole" SET trash = TRUE WHERE`).WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectQuery(`UPDATE "authsrv_projectgroupnamespacerole" AS "projectgroupnamespacerole" SET trash = TRUE WHERE ."project_id" = '` + puuid + `'. AND .trash = false. RETURNING *`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectExec(`UPDATE "authsrv_projectaccountresourcerole" AS "projectaccountresourcerole" SET trash = TRUE WHERE`).WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectQuery(`UPDATE "authsrv_projectaccountnamespacerole" AS "projectaccountnamespacerole" SET trash = TRUE WHERE ."project_id" = '` + puuid + `'. AND .trash = false. RETURNING *`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectExec(`UPDATE "authsrv_project"`). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group @@ -211,6 +223,9 @@ func TestProjectUpdate(t *testing.T) { mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN identities ON identities.id=authsrv_projectaccountresourcerole.account_id WHERE`).WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "user"}).AddRow("ADMIN", "user@email.com")) + mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, identities.traits ->> 'email' as user, namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole + ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN identities + ON identities.id=authsrv_projectaccountnamespacerole.account_id WHERE`).WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("ADMIN")) mock.ExpectCommit() project := &systemv3.Project{ From 7d04220d3aab9294787b9169da6d5e4f67798061 Mon Sep 17 00:00:00 2001 From: Nirav Parikh Date: Wed, 15 Jun 2022 12:37:50 +0530 Subject: [PATCH 3/3] fixes for cli config download --- main.go | 4 ++-- .../000021_sentry_account_permission.up.sql | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index d4fb6f4..55594b8 100644 --- a/main.go +++ b/main.go @@ -326,8 +326,8 @@ func setup() { // users and role management services cc := common.CliConfigDownloadData{ - RestEndpoint: apiAddr, - OpsEndpoint: apiAddr, + RestEndpoint: sentryBootstrapAddr, + OpsEndpoint: sentryBootstrapAddr, } if dev { cc.Profile = "staging" diff --git a/persistence/migrations/admindb/000021_sentry_account_permission.up.sql b/persistence/migrations/admindb/000021_sentry_account_permission.up.sql index 89f1ca7..9b30c87 100644 --- a/persistence/migrations/admindb/000021_sentry_account_permission.up.sql +++ b/persistence/migrations/admindb/000021_sentry_account_permission.up.sql @@ -27,6 +27,22 @@ FROM ( ga.trash = FALSE AND gr.trash = FALSE UNION + SELECT + ga.account_id, + gr.group_id, + p.id, + gr.role_id, + gr.organization_id, + gr.partner_id + FROM + authsrv_groupaccount ga + INNER JOIN authsrv_grouprole gr ON ga.group_id = gr.group_id + INNER JOIN authsrv_resourcerole rr ON rr.id = gr.role_id AND rr.scope = 'organization' + INNER JOIN authsrv_project p ON p.organization_id = gr.organization_id AND p.partner_id = gr.partner_id + WHERE + ga.trash = FALSE + AND gr.trash = FALSE + UNION SELECT account_id, uuid_nil() as group_id,