diff --git a/gen/openapi/proto/rpc/role/role.swagger.json b/gen/openapi/proto/rpc/role/role.swagger.json index 467e91e..da289a3 100644 --- a/gen/openapi/proto/rpc/role/role.swagger.json +++ b/gen/openapi/proto/rpc/role/role.swagger.json @@ -150,11 +150,18 @@ }, { "name": "spec.scope", - "description": "Scope. Scope of the rol", + "description": "Scope. Scope of role", "in": "query", "required": false, "type": "string" }, + { + "name": "spec.builtin", + "description": "Builtin. Specify if this is a builtin role", + "in": "query", + "required": false, + "type": "boolean" + }, { "name": "status.conditionType", "description": "Condition Type. type of the status condition", @@ -325,11 +332,18 @@ }, { "name": "spec.scope", - "description": "Scope. Scope of the rol", + "description": "Scope. Scope of role", "in": "query", "required": false, "type": "string" }, + { + "name": "spec.builtin", + "description": "Builtin. Specify if this is a builtin role", + "in": "query", + "required": false, + "type": "boolean" + }, { "name": "status.conditionType", "description": "Condition Type. type of the status condition", @@ -560,11 +574,18 @@ }, { "name": "spec.scope", - "description": "Scope. Scope of the rol", + "description": "Scope. Scope of role", "in": "query", "required": false, "type": "string" }, + { + "name": "spec.builtin", + "description": "Builtin. Specify if this is a builtin role", + "in": "query", + "required": false, + "type": "boolean" + }, { "name": "status.conditionType", "description": "Condition Type. type of the status condition", @@ -931,8 +952,14 @@ }, "scope": { "type": "string", - "description": "Scope of the rol", + "description": "Scope of role", "title": "Scope" + }, + "builtin": { + "type": "boolean", + "description": "Specify if this is a builtin role", + "title": "Builtin", + "readOnly": true } }, "description": "Role specification", diff --git a/internal/models/role.go b/internal/models/role.go index 811aac2..d79d544 100644 --- a/internal/models/role.go +++ b/internal/models/role.go @@ -19,5 +19,6 @@ type Role struct { OrganizationId uuid.UUID `bun:"organization_id,type:uuid"` PartnerId uuid.UUID `bun:"partner_id,type:uuid"` IsGlobal bool `bun:"is_global,notnull,default:true"` // does not matter + Builtin bool `bun:"builtin,notnull,default:true"` Scope string `bun:"scope,notnull"` } diff --git a/persistence/migrations/admindb/000007_authsrv_resourcerole.up.sql b/persistence/migrations/admindb/000007_authsrv_resourcerole.up.sql index b746332..3a3df9a 100644 --- a/persistence/migrations/admindb/000007_authsrv_resourcerole.up.sql +++ b/persistence/migrations/admindb/000007_authsrv_resourcerole.up.sql @@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS authsrv_resourcerole ( modified_at timestamp with time zone NOT NULL, trash boolean NOT NULL, is_global boolean NOT NULL, + builtin boolean NOT NULL, scope character varying(256) NOT NULL, organization_id uuid, partner_id uuid @@ -29,4 +30,4 @@ ALTER TABLE ONLY authsrv_resourcerole ALTER TABLE ONLY authsrv_resourcerole ADD CONSTRAINT authsrv_resourcerole_partner_id_de49ca91_fk_authsrv_partner_id FOREIGN KEY (partner_id) - REFERENCES authsrv_partner(id) DEFERRABLE INITIALLY DEFERRED; \ No newline at end of file + REFERENCES authsrv_partner(id) DEFERRABLE INITIALLY DEFERRED; diff --git a/pkg/common/constants.go b/pkg/common/constants.go index 5c51554..11c929a 100644 --- a/pkg/common/constants.go +++ b/pkg/common/constants.go @@ -48,3 +48,4 @@ const ( ) var SessionDataKey contextKey +var SessionInternalKey contextKey diff --git a/pkg/service/role.go b/pkg/service/role.go index 75d4f42..06daac6 100644 --- a/pkg/service/role.go +++ b/pkg/service/role.go @@ -138,6 +138,12 @@ func (s *roleService) Create(ctx context.Context, role *rolev3.Role) (*rolev3.Ro return nil, fmt.Errorf("unknown scope '%v'", scope) } + // Only allow internal call (eg: initialize) to set builtin flag + builtin := role.GetSpec().GetBuiltin() + if builtin { + builtin = IsInternalRequest(ctx) + } + // convert v3 spec to internal models rle := models.Role{ Name: role.GetMetadata().GetName(), @@ -148,6 +154,7 @@ func (s *roleService) Create(ctx context.Context, role *rolev3.Role) (*rolev3.Ro OrganizationId: organizationId, PartnerId: partnerId, IsGlobal: role.GetSpec().GetIsGlobal(), + Builtin: builtin, Scope: strings.ToLower(scope), } @@ -244,6 +251,9 @@ func (s *roleService) Update(ctx context.Context, role *rolev3.Role) (*rolev3.Ro } if rle, ok := entity.(*models.Role); ok { + if rle.Builtin { + return role, fmt.Errorf("builtin role '%v' cannot be updated", name) + } //update role details rle.Name = role.Metadata.Name rle.Description = role.Metadata.Description @@ -364,6 +374,7 @@ func (s *roleService) toV3Role(ctx context.Context, db bun.IDB, role *rolev3.Rol IsGlobal: rle.IsGlobal, Scope: rle.Scope, Rolepermissions: permissions, + Builtin: rle.Builtin, } return role, nil } diff --git a/pkg/service/role_test.go b/pkg/service/role_test.go index 615c6f1..f6a9e08 100644 --- a/pkg/service/role_test.go +++ b/pkg/service/role_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/RafayLabs/rcloud-base/pkg/common" v3 "github.com/RafayLabs/rcloud-base/proto/types/commonpb/v3" rolev3 "github.com/RafayLabs/rcloud-base/proto/types/rolepb/v3" "github.com/google/uuid" @@ -55,13 +56,8 @@ func TestCreateRole(t *testing.T) { rs := NewRoleService(db, &mazc, getLogger()) ruuid := uuid.New().String() - puuid := uuid.New().String() - ouuid := uuid.New().String() - mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) - mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + puuid, ouuid := addParterOrgFetchExpectation(mock) mock.ExpectQuery(`SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). WillReturnError(fmt.Errorf("no data available")) @@ -81,6 +77,67 @@ func TestCreateRole(t *testing.T) { } performRoleBasicChecks(t, role, ruuid) } +func TestCreateRoleNoBuiltinOverride(t *testing.T) { + db, mock := getDB(t) + defer db.Close() + + mazc := mockAuthzClient{} + rs := NewRoleService(db, &mazc, getLogger()) + + ruuid := uuid.New().String() + + puuid, ouuid := addParterOrgFetchExpectation(mock) + mock.ExpectQuery(`SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). + WillReturnError(fmt.Errorf("no data available")) + + mock.ExpectBegin() + // TODO: more precise checks + mock.ExpectQuery(`INSERT INTO "authsrv_resourcerole".* TRUE, FALSE, 'system'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ruuid)) + mock.ExpectCommit() + + role := &rolev3.Role{ + Metadata: &v3.Metadata{Partner: "partner-" + puuid, Organization: "org-" + ouuid, Name: "role-" + ruuid}, + Spec: &rolev3.RoleSpec{IsGlobal: true, Scope: "system", Builtin: true}, + } + role, err := rs.Create(context.Background(), role) + if err != nil { + t.Fatal("could not create group:", err) + } + performRoleBasicChecks(t, role, ruuid) +} + +func TestCreateRoleBuiltinOverride(t *testing.T) { + db, mock := getDB(t) + defer db.Close() + + mazc := mockAuthzClient{} + rs := NewRoleService(db, &mazc, getLogger()) + + ruuid := uuid.New().String() + + puuid, ouuid := addParterOrgFetchExpectation(mock) + mock.ExpectQuery(`SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). + WillReturnError(fmt.Errorf("no data available")) + + mock.ExpectBegin() + // TODO: more precise checks + mock.ExpectQuery(`INSERT INTO "authsrv_resourcerole".* TRUE, TRUE, 'system'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ruuid)) + mock.ExpectCommit() + + role := &rolev3.Role{ + Metadata: &v3.Metadata{Partner: "partner-" + puuid, Organization: "org-" + ouuid, Name: "role-" + ruuid}, + Spec: &rolev3.RoleSpec{IsGlobal: true, Scope: "system", Builtin: true}, + } + + internalCtx := context.WithValue(context.Background(), common.SessionInternalKey, true) + role, err := rs.Create(internalCtx, role) + if err != nil { + t.Fatal("could not create group:", err) + } + performRoleBasicChecks(t, role, ruuid) +} func TestCreateRoleWithPermissions(t *testing.T) { db, mock := getDB(t) @@ -90,13 +147,8 @@ func TestCreateRoleWithPermissions(t *testing.T) { rs := NewRoleService(db, &mazc, getLogger()) ruuid := uuid.New().String() - puuid := uuid.New().String() - ouuid := uuid.New().String() - mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) - mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + puuid, ouuid := addParterOrgFetchExpectation(mock) mock.ExpectQuery(`SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). WillReturnError(fmt.Errorf("no data available")) @@ -129,13 +181,8 @@ func TestCreateRoleDuplicate(t *testing.T) { rs := NewRoleService(db, &mazc, getLogger()) ruuid := uuid.New().String() - puuid := uuid.New().String() - ouuid := uuid.New().String() - mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) - mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + puuid, ouuid := addParterOrgFetchExpectation(mock) mock.ExpectQuery(` SELECT "resourcerole"."id" FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ruuid)) @@ -163,18 +210,13 @@ func TestUpdateRole(t *testing.T) { rs := NewRoleService(db, &mazc, getLogger()) ruuid := uuid.New().String() - puuid := uuid.New().String() - ouuid := uuid.New().String() - mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) - mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + puuid, ouuid := addParterOrgFetchExpectation(mock) mock.ExpectQuery(`SELECT "resourcerole"."id", "resourcerole"."name", .*FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name", "organization_id", "partner_id"}).AddRow(ruuid, "role-"+ruuid, ouuid, puuid)) mock.ExpectBegin() - mock.ExpectExec(`UPDATE "authsrv_resourcerole" AS "resourcerole" SET "name" = 'role-` + ruuid + `', .*"organization_id" = '` + ouuid + `', "partner_id" = '` + puuid + `', "is_global" = TRUE, "scope" = 'system' WHERE .id = '` + ruuid + `'.`). + mock.ExpectExec(`UPDATE "authsrv_resourcerole" AS "resourcerole" SET "name" = 'role-` + ruuid + `', .*"organization_id" = '` + ouuid + `', "partner_id" = '` + puuid + `', "is_global" = TRUE, "builtin" = FALSE, "scope" = 'system' WHERE .id = '` + ruuid + `'.`). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec(`UPDATE "authsrv_resourcerolepermission" AS "resourcerolepermission" SET trash = TRUE WHERE ."resource_role_id" = '` + ruuid + `'.`). WillReturnResult(sqlmock.NewResult(1, 1)) @@ -196,6 +238,28 @@ func TestUpdateRole(t *testing.T) { performRoleBasicChecks(t, role, ruuid) } +func TestUpdateRoleBuiltin(t *testing.T) { + db, mock := getDB(t) + defer db.Close() + + mazc := mockAuthzClient{} + rs := NewRoleService(db, &mazc, getLogger()) + + ruuid := uuid.New().String() + puuid, ouuid := addParterOrgFetchExpectation(mock) + mock.ExpectQuery(`SELECT "resourcerole"."id", "resourcerole"."name", .*FROM "authsrv_resourcerole" AS "resourcerole" WHERE .organization_id = '` + ouuid + `'. AND .partner_id = '` + puuid + `'. AND .name = 'role-` + ruuid + `'.`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name", "organization_id", "partner_id", "builtin"}).AddRow(ruuid, "role-"+ruuid, ouuid, puuid, true)) + + role := &rolev3.Role{ + Metadata: &v3.Metadata{Partner: "partner-" + puuid, Organization: "org-" + ouuid, Name: "role-" + ruuid}, + Spec: &rolev3.RoleSpec{IsGlobal: true, Scope: "system", Rolepermissions: []string{"ops_star.all"}}, + } + _, err := rs.Update(context.Background(), role) + if err == nil { + t.Fatal("builtin roles should not be updated") + } +} + func TestRoleDelete(t *testing.T) { db, mock := getDB(t) defer db.Close() @@ -204,13 +268,8 @@ func TestRoleDelete(t *testing.T) { rs := NewRoleService(db, &mazc, getLogger()) ruuid := uuid.New().String() - puuid := uuid.New().String() - ouuid := uuid.New().String() - mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) - mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + puuid, ouuid := addParterOrgFetchExpectation(mock) mock.ExpectQuery(`SELECT "resourcerole"."id", "resourcerole"."name", .* FROM "authsrv_resourcerole" AS "resourcerole" WHERE`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(ruuid, "role-"+ruuid)) mock.ExpectBegin() diff --git a/pkg/service/utils.go b/pkg/service/utils.go index cd57945..8403069 100644 --- a/pkg/service/utils.go +++ b/pkg/service/utils.go @@ -27,3 +27,9 @@ func GetSessionDataFromContext(ctx context.Context) (*commonv3.SessionData, bool s, ok := ctx.Value(common.SessionDataKey).(*commonv3.SessionData) return s, ok } + +func IsInternalRequest(ctx context.Context) bool { + v := ctx.Value(common.SessionInternalKey) + b, ok := v.(bool) + return ok && b +} diff --git a/proto/types/rolepb/v3/role.pb.go b/proto/types/rolepb/v3/role.pb.go index 37833ee..37cc36b 100644 --- a/proto/types/rolepb/v3/role.pb.go +++ b/proto/types/rolepb/v3/role.pb.go @@ -109,6 +109,7 @@ type RoleSpec struct { Rolepermissions []string `protobuf:"bytes,1,rep,name=rolepermissions,proto3" json:"rolepermissions,omitempty"` IsGlobal bool `protobuf:"varint,2,opt,name=isGlobal,proto3" json:"isGlobal,omitempty"` Scope string `protobuf:"bytes,3,opt,name=scope,proto3" json:"scope,omitempty"` + Builtin bool `protobuf:"varint,4,opt,name=builtin,proto3" json:"builtin,omitempty"` } func (x *RoleSpec) Reset() { @@ -164,6 +165,13 @@ func (x *RoleSpec) GetScope() string { return "" } +func (x *RoleSpec) GetBuiltin() bool { + if x != nil { + return x.Builtin + } + return false +} + type RoleList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -283,7 +291,7 @@ var file_proto_types_rolepb_v3_role_proto_rawDesc = []byte{ 0x92, 0x41, 0x34, 0x0a, 0x32, 0x2a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x32, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0xd2, 0x01, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0xd2, 0x01, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0xd2, 0x01, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xd2, 0x01, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x95, 0x02, 0x0a, 0x08, 0x52, 0x6f, 0x6c, 0x65, + 0xd2, 0x01, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xdf, 0x02, 0x0a, 0x08, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x59, 0x0a, 0x0f, 0x72, 0x6f, 0x6c, 0x65, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x2f, 0x92, 0x41, 0x2c, 0x2a, 0x10, 0x52, 0x6f, 0x6c, 0x65, 0x20, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, @@ -294,54 +302,59 @@ var file_proto_types_rolepb_v3_role_proto_rawDesc = []byte{ 0x08, 0x42, 0x2f, 0x92, 0x41, 0x2c, 0x2a, 0x08, 0x49, 0x73, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x32, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x72, 0x6f, - 0x6c, 0x65, 0x52, 0x08, 0x69, 0x73, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x12, 0x32, 0x0a, 0x05, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1c, 0x92, 0x41, 0x19, - 0x2a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x32, 0x10, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x20, 0x6f, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x3a, 0x2d, 0x92, 0x41, 0x2a, 0x0a, 0x28, 0x2a, 0x12, 0x52, 0x6f, 0x6c, 0x65, 0x20, 0x53, 0x70, - 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x12, 0x52, 0x6f, 0x6c, - 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x99, 0x03, 0x0a, 0x08, 0x52, 0x6f, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x0a, - 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x39, 0x92, 0x41, 0x36, 0x2a, 0x0b, 0x41, 0x50, 0x49, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x32, 0x25, 0x41, 0x50, 0x49, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, - 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, - 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x40, 0x01, 0x52, 0x0a, 0x61, 0x70, 0x69, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0x92, 0x41, 0x28, 0x2a, 0x04, 0x4b, 0x69, 0x6e, 0x64, - 0x32, 0x1e, 0x4b, 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, + 0x6c, 0x65, 0x52, 0x08, 0x69, 0x73, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x12, 0x2f, 0x0a, 0x05, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0x92, 0x41, 0x16, + 0x2a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x32, 0x0d, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x4b, 0x0a, + 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x42, 0x31, + 0x92, 0x41, 0x2e, 0x2a, 0x07, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x32, 0x21, 0x53, 0x70, + 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, + 0x20, 0x61, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x40, + 0x01, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x3a, 0x2d, 0x92, 0x41, 0x2a, 0x0a, + 0x28, 0x2a, 0x12, 0x52, 0x6f, 0x6c, 0x65, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x12, 0x52, 0x6f, 0x6c, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x99, 0x03, 0x0a, 0x08, 0x52, 0x6f, + 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x39, 0x92, 0x41, 0x36, 0x2a, + 0x0b, 0x41, 0x50, 0x49, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x25, 0x41, 0x50, + 0x49, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x40, 0x01, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3f, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x2b, 0x92, 0x41, 0x28, 0x2a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x32, 0x1e, 0x4b, 0x69, 0x6e, 0x64, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x40, 0x01, 0x52, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x12, 0x78, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x33, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x33, 0x92, + 0x41, 0x30, 0x2a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0x22, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x40, 0x01, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x78, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x61, 0x66, - 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x42, 0x33, 0x92, 0x41, 0x30, 0x2a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x32, 0x22, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x40, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x59, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x6f, 0x6c, 0x65, - 0x42, 0x24, 0x92, 0x41, 0x21, 0x2a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x32, 0x16, 0x4c, 0x69, - 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x6f, 0x6c, 0x65, 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, 0x52, 0x6f, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x32, 0x09, - 0x52, 0x6f, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x40, 0x01, 0x42, 0xe8, 0x01, 0x0a, 0x1b, - 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x76, 0x33, 0x42, 0x09, 0x52, 0x6f, 0x6c, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x52, 0x61, 0x66, 0x61, 0x79, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x72, - 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x70, 0x62, 0x2f, 0x76, 0x33, - 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x76, 0x33, 0xa2, 0x02, 0x04, 0x52, 0x44, 0x54, 0x52, 0xaa, 0x02, - 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, - 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x52, 0x6f, 0x6c, 0x65, 0x5c, - 0x56, 0x33, 0xe2, 0x02, 0x23, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x5c, 0x52, 0x6f, 0x6c, 0x65, 0x5c, 0x56, 0x33, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1b, 0x52, 0x61, 0x66, 0x61, 0x79, - 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x3a, 0x52, 0x6f, - 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x40, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x59, 0x0a, 0x05, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x61, + 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x72, 0x6f, + 0x6c, 0x65, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x24, 0x92, 0x41, 0x21, 0x2a, + 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x32, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x72, 0x6f, 0x6c, 0x65, 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, + 0x52, 0x6f, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x32, 0x09, 0x52, 0x6f, 0x6c, 0x65, 0x20, 0x6c, + 0x69, 0x73, 0x74, 0x40, 0x01, 0x42, 0xe8, 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x61, + 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x72, 0x6f, + 0x6c, 0x65, 0x2e, 0x76, 0x33, 0x42, 0x09, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x52, + 0x61, 0x66, 0x61, 0x79, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x72, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, + 0x62, 0x61, 0x73, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x70, 0x62, 0x2f, 0x76, 0x33, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x76, + 0x33, 0xa2, 0x02, 0x04, 0x52, 0x44, 0x54, 0x52, 0xaa, 0x02, 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, + 0x2e, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x2e, + 0x56, 0x33, 0xca, 0x02, 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x5c, 0x52, 0x6f, 0x6c, 0x65, 0x5c, 0x56, 0x33, 0xe2, 0x02, 0x23, 0x52, + 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x52, + 0x6f, 0x6c, 0x65, 0x5c, 0x56, 0x33, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x1b, 0x52, 0x61, 0x66, 0x61, 0x79, 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, + 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x3a, 0x52, 0x6f, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x33, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/types/rolepb/v3/role.proto b/proto/types/rolepb/v3/role.proto index 38142e1..59ae5d8 100644 --- a/proto/types/rolepb/v3/role.proto +++ b/proto/types/rolepb/v3/role.proto @@ -64,7 +64,13 @@ message RoleSpec { string scope = 3 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { title : "Scope" - description : "Scope of the rol" + description : "Scope of role" + } ]; + bool builtin = 4 + [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + title : "Builtin" + description : "Specify if this is a builtin role" + read_only : true } ]; } diff --git a/scripts/initialize/main.go b/scripts/initialize/main.go index 625101e..95f5575 100644 --- a/scripts/initialize/main.go +++ b/scripts/initialize/main.go @@ -216,13 +216,15 @@ func main() { log.Fatal("unable to create organization", err) } + // this is used to figure out if the request originated internally so as to not override `builtin` + internalCtx := context.WithValue(context.Background(), common.SessionInternalKey, true) for scope := range data { for name := range data[scope] { perms := data[scope][name] fmt.Println(scope, name, len(perms)) - _, err := rs.Create(context.Background(), &rolev3.Role{ + _, err := rs.Create(internalCtx, &rolev3.Role{ Metadata: &commonv3.Metadata{Name: name, Partner: *partner, Organization: *org, Description: "..."}, - Spec: &rolev3.RoleSpec{IsGlobal: true, Scope: scope, Rolepermissions: perms}, + Spec: &rolev3.RoleSpec{IsGlobal: true, Scope: scope, Rolepermissions: perms, Builtin: true}, }) if err != nil { log.Fatalf("unable to create rolepermission %s %s: %s", scope, name, err)