From 847ca1cc78ba93aff6d62e1c5006d31f984ab0ea Mon Sep 17 00:00:00 2001 From: Todd Knight Date: Fri, 10 Jul 2020 17:42:47 -0700 Subject: [PATCH] Grant management added to Roles API and SDK (#185) * Adding grants related methods to Roles. * Adding grants back after the merge of Principals. * Adding tests for Grant related custom methods. * Improving api handler methods. * Fixing tests and sdk field. * Adding todos for adding principals and grants to List and Update Role responses. * Fix up Set* tests and fix SetPrincipals bug. * Making AddPrincipals and RemovePrincipals similar to the tests for AddGrants and RemoveGrants. * Add JSON grants to output (#187) I also changed canonical_grants to grants_canonical and used grants_json. I believe that when members are simply different formats of other members this is the preferred way to have it in the API. Let me know if you disagree and we can dig in more. * Regenerate the API role resource. Co-authored-by: Jeff Mitchell --- api/roles/custom.go | 96 ++ api/roles/role.gen.go | 6 + api/roles/role_test.go | 21 + internal/gen/controller.swagger.json | 367 +++++ .../controller/api/resources/roles/role.pb.go | 40 +- .../api/services/role_service.pb.go | 814 ++++++++++- .../api/services/role_service.pb.gw.go | 936 ++++++++++++ internal/iam/repository_role.go | 13 +- internal/iam/repository_role_grant.go | 21 +- internal/iam/repository_role_test.go | 6 +- internal/iam/role_grant.go | 19 +- internal/perms/acl_test.go | 38 +- internal/perms/grants.go | 23 +- internal/perms/grants_test.go | 82 +- .../api/resources/roles/v1/role.proto | 8 + .../api/services/v1/role_service.proto | 105 ++ internal/servers/controller/handler_test.go | 6 + .../controller/handlers/roles/role_service.go | 202 ++- .../handlers/roles/role_service_test.go | 1250 +++++++++-------- 19 files changed, 3321 insertions(+), 732 deletions(-) diff --git a/api/roles/custom.go b/api/roles/custom.go index 4f340f0fd..86152eda8 100644 --- a/api/roles/custom.go +++ b/api/roles/custom.go @@ -105,3 +105,99 @@ func (s Role) RemovePrincipals(ctx context.Context, groups, users []string) (*Ro return target, apiErr, nil } + +func (s Role) AddGrants(ctx context.Context, grants []string) (*Role, *api.Error, error) { + if s.Client == nil { + return nil, nil, fmt.Errorf("nil client in AddGrants request") + } + // We assume that the client provided has the org and optionally the project id of the request. + + body := map[string]interface{}{ + "grants": grants, + "version": s.Version, + } + + req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:add-grants", s.Id), body) + if err != nil { + return nil, nil, fmt.Errorf("error creating AddGrants request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during AddGrants call: %w", err) + } + + target := new(Role) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding AddGrants repsonse: %w", err) + } + + target.Client = s.Client + + return target, apiErr, nil +} + +func (s Role) SetGrants(ctx context.Context, grants []string) (*Role, *api.Error, error) { + if s.Client == nil { + return nil, nil, fmt.Errorf("nil client in SetGrants request") + } + // We assume that the client provided has the org and optionally the project id of the request. + + body := map[string]interface{}{ + "grants": grants, + "version": s.Version, + } + + req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:set-grants", s.Id), body) + if err != nil { + return nil, nil, fmt.Errorf("error creating SetGrants request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during SetGrants call: %w", err) + } + + target := new(Role) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding SetGrants repsonse: %w", err) + } + + target.Client = s.Client + + return target, apiErr, nil +} + +func (s Role) RemoveGrants(ctx context.Context, grants []string) (*Role, *api.Error, error) { + if s.Client == nil { + return nil, nil, fmt.Errorf("nil client in RemoveGrants request") + } + // We assume that the client provided has the org and optionally the project id of the request. + + body := map[string]interface{}{ + "grants": grants, + "version": s.Version, + } + + req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:remove-grants", s.Id), body) + if err != nil { + return nil, nil, fmt.Errorf("error creating RemoveGrants request: %w", err) + } + + resp, err := s.Client.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("error performing client request during RemoveGrants call: %w", err) + } + + target := new(Role) + apiErr, err := resp.Decode(target) + if err != nil { + return nil, nil, fmt.Errorf("error decoding RemoveGrants repsonse: %w", err) + } + + target.Client = s.Client + + return target, apiErr, nil +} diff --git a/api/roles/role.gen.go b/api/roles/role.gen.go index 13d13cf3b..2147acac7 100644 --- a/api/roles/role.gen.go +++ b/api/roles/role.gen.go @@ -49,6 +49,12 @@ type Role struct { // The grants that this role provides for it's principals. // Output only. Grants []string `json:"grants,omitempty"` + // The canonical version of the grants in the grants field with the same index. + // Output only. + GrantsCanonical []string `json:"grants_canonical,omitempty"` + // The JSON version of the grants in the grants field with the same index. + // Output only. + GrantsJson []string `json:"grants_json,omitempty"` } func (s *Role) SetDefault(key string) { diff --git a/api/roles/role_test.go b/api/roles/role_test.go index 2be07f783..02288cb5a 100644 --- a/api/roles/role_test.go +++ b/api/roles/role_test.go @@ -92,6 +92,27 @@ func TestCustom(t *testing.T) { assert.Equal(t, *updatedRole.Version, (*r.Version)+1) assert.Empty(t, updatedRole.GroupIds) assert.Empty(t, updatedRole.UserIds) + + r = updatedRole + updatedRole, apiErr, err = r.AddGrants(ctx, []string{"id=*;actions=read"}) + require.NoError(err) + require.Nil(apiErr, "Got error ", errorMessage(apiErr)) + assert.Equal(t, *updatedRole.Version, (*r.Version)+1) + assert.Contains(t, updatedRole.Grants, "id=*;actions=read") + + r = updatedRole + updatedRole, apiErr, err = r.SetGrants(ctx, []string{"id=*;actions=*"}) + require.NoError(err) + require.Nil(apiErr, "Got error ", errorMessage(apiErr)) + assert.Equal(t, *updatedRole.Version, (*r.Version)+1) + assert.Contains(t, updatedRole.Grants, "id=*;actions=*") + + r = updatedRole + updatedRole, apiErr, err = r.RemoveGrants(ctx, []string{"id=*;actions=*"}) + require.NoError(err) + require.Nil(apiErr, "Got error ", errorMessage(apiErr)) + assert.Equal(t, *updatedRole.Version, (*r.Version)+1) + assert.Empty(t, updatedRole.Grants) }) } } diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json index 87e22abf2..b7495a498 100644 --- a/internal/gen/controller.swagger.json +++ b/internal/gen/controller.swagger.json @@ -2199,6 +2199,51 @@ ] } }, + "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:add-grants": { + "post": { + "summary": "Adds grants to a role", + "operationId": "RoleService_AddRoleGrants2", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "project_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "role_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.AddRoleGrantsRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:add-principals": { "post": { "summary": "Adds Users and/or Groups to a Role", @@ -2244,6 +2289,51 @@ ] } }, + "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:remove-grants": { + "post": { + "summary": "Removes grants from a role.", + "operationId": "RoleService_RemoveRoleGrants2", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "project_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "role_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.RemoveRoleGrantsRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:remove-principals": { "post": { "summary": "Removes the specified Users and/or Groups from a Role.", @@ -2289,6 +2379,51 @@ ] } }, + "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:set-grants": { + "post": { + "summary": "Set grants for a role, removing any grants that are not specified in the request.", + "operationId": "RoleService_SetRoleGrants2", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "project_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "role_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.SetRoleGrantsRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:set-principals": { "post": { "summary": "Set Users and/or Groups to a Role, removing any principals that are not specified in the request.", @@ -2517,6 +2652,45 @@ ] } }, + "/v1/orgs/{org_id}/roles/{role_id}:add-grants": { + "post": { + "summary": "Adds grants to a role", + "operationId": "RoleService_AddRoleGrants", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "role_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.AddRoleGrantsRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/roles/{role_id}:add-principals": { "post": { "summary": "Adds Users and/or Groups to a Role", @@ -2556,6 +2730,45 @@ ] } }, + "/v1/orgs/{org_id}/roles/{role_id}:remove-grants": { + "post": { + "summary": "Removes grants from a role.", + "operationId": "RoleService_RemoveRoleGrants", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "role_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.RemoveRoleGrantsRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/roles/{role_id}:remove-principals": { "post": { "summary": "Removes the specified Users and/or Groups from a Role.", @@ -2595,6 +2808,45 @@ ] } }, + "/v1/orgs/{org_id}/roles/{role_id}:set-grants": { + "post": { + "summary": "Set grants for a role, removing any grants that are not specified in the request.", + "operationId": "RoleService_SetRoleGrants", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, + "parameters": [ + { + "name": "org_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "role_id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.api.services.v1.SetRoleGrantsRequest" + } + } + ], + "tags": [ + "controller.api.services.v1.RoleService" + ] + } + }, "/v1/orgs/{org_id}/roles/{role_id}:set-principals": { "post": { "summary": "Set Users and/or Groups to a Role, removing any principals that are not specified in the request.", @@ -3153,6 +3405,22 @@ }, "description": "The grants that this role provides for it's principals.\nOutput only.", "readOnly": true + }, + "grants_canonical": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The canonical version of the grants in the grants field with the same index.\nOutput only.", + "readOnly": true + }, + "grants_json": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The JSON version of the grants in the grants field with the same index.\nOutput only.", + "readOnly": true } }, "title": "Role contains all fields related to a Role resource" @@ -3260,6 +3528,39 @@ }, "title": "User contains all fields related to a User resource" }, + "controller.api.services.v1.AddRoleGrantsRequest": { + "type": "object", + "properties": { + "org_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "role_id": { + "type": "string" + }, + "version": { + "type": "integer", + "format": "int64", + "description": "The version ensures the role hasn't changed since it was last retrieved and if\nit has the request will fail." + }, + "grants": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "controller.api.services.v1.AddRoleGrantsResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, "controller.api.services.v1.AddRolePrincipalsRequest": { "type": "object", "properties": { @@ -3638,6 +3939,39 @@ "controller.api.services.v1.RemoveFromHostSetResponse": { "type": "object" }, + "controller.api.services.v1.RemoveRoleGrantsRequest": { + "type": "object", + "properties": { + "org_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "role_id": { + "type": "string" + }, + "version": { + "type": "integer", + "format": "int64", + "description": "The version ensures the role hasn't changed since it was last retrieved and if\nit has the request will fail." + }, + "grants": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "controller.api.services.v1.RemoveRoleGrantsResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, "controller.api.services.v1.RemoveRolePrincipalsRequest": { "type": "object", "properties": { @@ -3677,6 +4011,39 @@ } } }, + "controller.api.services.v1.SetRoleGrantsRequest": { + "type": "object", + "properties": { + "org_id": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "role_id": { + "type": "string" + }, + "version": { + "type": "integer", + "format": "int64", + "description": "The version ensures the role hasn't changed since it was last retrieved and if\nit has the request will fail." + }, + "grants": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "controller.api.services.v1.SetRoleGrantsResponse": { + "type": "object", + "properties": { + "item": { + "$ref": "#/definitions/controller.api.resources.roles.v1.Role" + } + } + }, "controller.api.services.v1.SetRolePrincipalsRequest": { "type": "object", "properties": { diff --git a/internal/gen/controller/api/resources/roles/role.pb.go b/internal/gen/controller/api/resources/roles/role.pb.go index 697e81b35..a9307e2a7 100644 --- a/internal/gen/controller/api/resources/roles/role.pb.go +++ b/internal/gen/controller/api/resources/roles/role.pb.go @@ -66,6 +66,12 @@ type Role struct { // The grants that this role provides for it's principals. // Output only. Grants []string `protobuf:"bytes,11,rep,name=grants,proto3" json:"grants,omitempty"` + // The canonical version of the grants in the grants field with the same index. + // Output only. + GrantsCanonical []string `protobuf:"bytes,12,rep,name=grants_canonical,json=grantsCanonical,proto3" json:"grants_canonical,omitempty"` + // The JSON version of the grants in the grants field with the same index. + // Output only. + GrantsJson []string `protobuf:"bytes,13,rep,name=grants_json,json=grantsJson,proto3" json:"grants_json,omitempty"` } func (x *Role) Reset() { @@ -177,6 +183,20 @@ func (x *Role) GetGrants() []string { return nil } +func (x *Role) GetGrantsCanonical() []string { + if x != nil { + return x.GrantsCanonical + } + return nil +} + +func (x *Role) GetGrantsJson() []string { + if x != nil { + return x.GrantsJson + } + return nil +} + var File_controller_api_resources_roles_v1_role_proto protoreflect.FileDescriptor var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{ @@ -189,7 +209,7 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{ 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xf0, 0x03, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x74, 0x6f, 0x22, 0xbc, 0x04, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, @@ -220,13 +240,17 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{ 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, - 0x72, 0x61, 0x6e, 0x74, 0x73, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, - 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, - 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f, + 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, + 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x4a, 0x73, 0x6f, + 0x6e, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, + 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, + 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/internal/gen/controller/api/services/role_service.pb.go b/internal/gen/controller/api/services/role_service.pb.go index 18f4a9d6f..837f52c4c 100644 --- a/internal/gen/controller/api/services/role_service.pb.go +++ b/internal/gen/controller/api/services/role_service.pb.go @@ -1025,6 +1025,390 @@ func (x *RemoveRolePrincipalsResponse) GetItem() *roles.Role { return nil } +type AddRoleGrantsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + RoleId string `protobuf:"bytes,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + // The version ensures the role hasn't changed since it was last retrieved and if + // it has the request will fail. + Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + Grants []string `protobuf:"bytes,5,rep,name=grants,proto3" json:"grants,omitempty"` +} + +func (x *AddRoleGrantsRequest) Reset() { + *x = AddRoleGrantsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddRoleGrantsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddRoleGrantsRequest) ProtoMessage() {} + +func (x *AddRoleGrantsRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[16] + 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 AddRoleGrantsRequest.ProtoReflect.Descriptor instead. +func (*AddRoleGrantsRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{16} +} + +func (x *AddRoleGrantsRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *AddRoleGrantsRequest) GetProjectId() string { + if x != nil { + return x.ProjectId + } + return "" +} + +func (x *AddRoleGrantsRequest) GetRoleId() string { + if x != nil { + return x.RoleId + } + return "" +} + +func (x *AddRoleGrantsRequest) GetVersion() *wrappers.UInt32Value { + if x != nil { + return x.Version + } + return nil +} + +func (x *AddRoleGrantsRequest) GetGrants() []string { + if x != nil { + return x.Grants + } + return nil +} + +type AddRoleGrantsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *AddRoleGrantsResponse) Reset() { + *x = AddRoleGrantsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddRoleGrantsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddRoleGrantsResponse) ProtoMessage() {} + +func (x *AddRoleGrantsResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[17] + 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 AddRoleGrantsResponse.ProtoReflect.Descriptor instead. +func (*AddRoleGrantsResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{17} +} + +func (x *AddRoleGrantsResponse) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +type SetRoleGrantsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + RoleId string `protobuf:"bytes,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + // The version ensures the role hasn't changed since it was last retrieved and if + // it has the request will fail. + Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + Grants []string `protobuf:"bytes,5,rep,name=grants,proto3" json:"grants,omitempty"` +} + +func (x *SetRoleGrantsRequest) Reset() { + *x = SetRoleGrantsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetRoleGrantsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetRoleGrantsRequest) ProtoMessage() {} + +func (x *SetRoleGrantsRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[18] + 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 SetRoleGrantsRequest.ProtoReflect.Descriptor instead. +func (*SetRoleGrantsRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{18} +} + +func (x *SetRoleGrantsRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *SetRoleGrantsRequest) GetProjectId() string { + if x != nil { + return x.ProjectId + } + return "" +} + +func (x *SetRoleGrantsRequest) GetRoleId() string { + if x != nil { + return x.RoleId + } + return "" +} + +func (x *SetRoleGrantsRequest) GetVersion() *wrappers.UInt32Value { + if x != nil { + return x.Version + } + return nil +} + +func (x *SetRoleGrantsRequest) GetGrants() []string { + if x != nil { + return x.Grants + } + return nil +} + +type SetRoleGrantsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *SetRoleGrantsResponse) Reset() { + *x = SetRoleGrantsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetRoleGrantsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetRoleGrantsResponse) ProtoMessage() {} + +func (x *SetRoleGrantsResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[19] + 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 SetRoleGrantsResponse.ProtoReflect.Descriptor instead. +func (*SetRoleGrantsResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{19} +} + +func (x *SetRoleGrantsResponse) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + +type RemoveRoleGrantsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"` + ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + RoleId string `protobuf:"bytes,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"` + // The version ensures the role hasn't changed since it was last retrieved and if + // it has the request will fail. + Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + Grants []string `protobuf:"bytes,5,rep,name=grants,proto3" json:"grants,omitempty"` +} + +func (x *RemoveRoleGrantsRequest) Reset() { + *x = RemoveRoleGrantsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRoleGrantsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRoleGrantsRequest) ProtoMessage() {} + +func (x *RemoveRoleGrantsRequest) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[20] + 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 RemoveRoleGrantsRequest.ProtoReflect.Descriptor instead. +func (*RemoveRoleGrantsRequest) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{20} +} + +func (x *RemoveRoleGrantsRequest) GetOrgId() string { + if x != nil { + return x.OrgId + } + return "" +} + +func (x *RemoveRoleGrantsRequest) GetProjectId() string { + if x != nil { + return x.ProjectId + } + return "" +} + +func (x *RemoveRoleGrantsRequest) GetRoleId() string { + if x != nil { + return x.RoleId + } + return "" +} + +func (x *RemoveRoleGrantsRequest) GetVersion() *wrappers.UInt32Value { + if x != nil { + return x.Version + } + return nil +} + +func (x *RemoveRoleGrantsRequest) GetGrants() []string { + if x != nil { + return x.Grants + } + return nil +} + +type RemoveRoleGrantsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *roles.Role `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *RemoveRoleGrantsResponse) Reset() { + *x = RemoveRoleGrantsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRoleGrantsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRoleGrantsResponse) ProtoMessage() {} + +func (x *RemoveRoleGrantsResponse) ProtoReflect() protoreflect.Message { + mi := &file_controller_api_services_v1_role_service_proto_msgTypes[21] + 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 RemoveRoleGrantsResponse.ProtoReflect.Descriptor instead. +func (*RemoveRoleGrantsResponse) Descriptor() ([]byte, []int) { + return file_controller_api_services_v1_role_service_proto_rawDescGZIP(), []int{21} +} + +func (x *RemoveRoleGrantsResponse) GetItem() *roles.Role { + if x != nil { + return x.Item + } + return nil +} + var File_controller_api_services_v1_role_service_proto protoreflect.FileDescriptor var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{ @@ -1168,7 +1552,58 @@ var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, - 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xb0, 0x11, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xb5, 0x01, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, + 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, + 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a, + 0x15, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, + 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, + 0x74, 0x65, 0x6d, 0x22, 0xb5, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, + 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, + 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x15, 0x53, + 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, + 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, + 0x6d, 0x22, 0xb8, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, + 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, + 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x57, 0x0a, 0x18, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xe4, 0x18, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xe1, 0x01, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, @@ -1307,13 +1742,72 @@ var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{ 0x12, 0x36, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, - 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x12, 0x9e, 0x02, 0x0a, 0x0d, 0x41, 0x64, 0x64, + 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, + 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xa7, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x86, 0x01, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, + 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, + 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x4d, 0x22, 0x42, 0x2f, 0x76, + 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, + 0x41, 0x17, 0x12, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0xda, 0x02, 0x0a, 0x0d, 0x53, 0x65, + 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, + 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xe3, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x86, 0x01, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x2f, + 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, + 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, + 0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x4d, 0x22, 0x42, 0x2f, + 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, + 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, + 0x92, 0x41, 0x53, 0x12, 0x51, 0x53, 0x65, 0x74, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x12, 0xb3, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, + 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8c, 0x01, + 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x50, 0x22, 0x45, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, + 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, + 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x1d, 0x12, + 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x42, 0x4f, 0x5a, 0x4d, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1328,7 +1822,7 @@ func file_controller_api_services_v1_role_service_proto_rawDescGZIP() []byte { return file_controller_api_services_v1_role_service_proto_rawDescData } -var file_controller_api_services_v1_role_service_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_controller_api_services_v1_role_service_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_controller_api_services_v1_role_service_proto_goTypes = []interface{}{ (*GetRoleRequest)(nil), // 0: controller.api.services.v1.GetRoleRequest (*GetRoleResponse)(nil), // 1: controller.api.services.v1.GetRoleResponse @@ -1346,45 +1840,63 @@ var file_controller_api_services_v1_role_service_proto_goTypes = []interface{}{ (*SetRolePrincipalsResponse)(nil), // 13: controller.api.services.v1.SetRolePrincipalsResponse (*RemoveRolePrincipalsRequest)(nil), // 14: controller.api.services.v1.RemoveRolePrincipalsRequest (*RemoveRolePrincipalsResponse)(nil), // 15: controller.api.services.v1.RemoveRolePrincipalsResponse - (*roles.Role)(nil), // 16: controller.api.resources.roles.v1.Role - (*field_mask.FieldMask)(nil), // 17: google.protobuf.FieldMask - (*wrappers.UInt32Value)(nil), // 18: google.protobuf.UInt32Value + (*AddRoleGrantsRequest)(nil), // 16: controller.api.services.v1.AddRoleGrantsRequest + (*AddRoleGrantsResponse)(nil), // 17: controller.api.services.v1.AddRoleGrantsResponse + (*SetRoleGrantsRequest)(nil), // 18: controller.api.services.v1.SetRoleGrantsRequest + (*SetRoleGrantsResponse)(nil), // 19: controller.api.services.v1.SetRoleGrantsResponse + (*RemoveRoleGrantsRequest)(nil), // 20: controller.api.services.v1.RemoveRoleGrantsRequest + (*RemoveRoleGrantsResponse)(nil), // 21: controller.api.services.v1.RemoveRoleGrantsResponse + (*roles.Role)(nil), // 22: controller.api.resources.roles.v1.Role + (*field_mask.FieldMask)(nil), // 23: google.protobuf.FieldMask + (*wrappers.UInt32Value)(nil), // 24: google.protobuf.UInt32Value } var file_controller_api_services_v1_role_service_proto_depIdxs = []int32{ - 16, // 0: controller.api.services.v1.GetRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role - 16, // 1: controller.api.services.v1.ListRolesResponse.items:type_name -> controller.api.resources.roles.v1.Role - 16, // 2: controller.api.services.v1.CreateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role - 16, // 3: controller.api.services.v1.CreateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role - 16, // 4: controller.api.services.v1.UpdateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role - 17, // 5: controller.api.services.v1.UpdateRoleRequest.update_mask:type_name -> google.protobuf.FieldMask - 16, // 6: controller.api.services.v1.UpdateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role - 18, // 7: controller.api.services.v1.AddRolePrincipalsRequest.version:type_name -> google.protobuf.UInt32Value - 16, // 8: controller.api.services.v1.AddRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role - 18, // 9: controller.api.services.v1.SetRolePrincipalsRequest.version:type_name -> google.protobuf.UInt32Value - 16, // 10: controller.api.services.v1.SetRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role - 18, // 11: controller.api.services.v1.RemoveRolePrincipalsRequest.version:type_name -> google.protobuf.UInt32Value - 16, // 12: controller.api.services.v1.RemoveRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role - 0, // 13: controller.api.services.v1.RoleService.GetRole:input_type -> controller.api.services.v1.GetRoleRequest - 2, // 14: controller.api.services.v1.RoleService.ListRoles:input_type -> controller.api.services.v1.ListRolesRequest - 4, // 15: controller.api.services.v1.RoleService.CreateRole:input_type -> controller.api.services.v1.CreateRoleRequest - 6, // 16: controller.api.services.v1.RoleService.UpdateRole:input_type -> controller.api.services.v1.UpdateRoleRequest - 8, // 17: controller.api.services.v1.RoleService.DeleteRole:input_type -> controller.api.services.v1.DeleteRoleRequest - 10, // 18: controller.api.services.v1.RoleService.AddRolePrincipals:input_type -> controller.api.services.v1.AddRolePrincipalsRequest - 12, // 19: controller.api.services.v1.RoleService.SetRolePrincipals:input_type -> controller.api.services.v1.SetRolePrincipalsRequest - 14, // 20: controller.api.services.v1.RoleService.RemoveRolePrincipals:input_type -> controller.api.services.v1.RemoveRolePrincipalsRequest - 1, // 21: controller.api.services.v1.RoleService.GetRole:output_type -> controller.api.services.v1.GetRoleResponse - 3, // 22: controller.api.services.v1.RoleService.ListRoles:output_type -> controller.api.services.v1.ListRolesResponse - 5, // 23: controller.api.services.v1.RoleService.CreateRole:output_type -> controller.api.services.v1.CreateRoleResponse - 7, // 24: controller.api.services.v1.RoleService.UpdateRole:output_type -> controller.api.services.v1.UpdateRoleResponse - 9, // 25: controller.api.services.v1.RoleService.DeleteRole:output_type -> controller.api.services.v1.DeleteRoleResponse - 11, // 26: controller.api.services.v1.RoleService.AddRolePrincipals:output_type -> controller.api.services.v1.AddRolePrincipalsResponse - 13, // 27: controller.api.services.v1.RoleService.SetRolePrincipals:output_type -> controller.api.services.v1.SetRolePrincipalsResponse - 15, // 28: controller.api.services.v1.RoleService.RemoveRolePrincipals:output_type -> controller.api.services.v1.RemoveRolePrincipalsResponse - 21, // [21:29] is the sub-list for method output_type - 13, // [13:21] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 22, // 0: controller.api.services.v1.GetRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role + 22, // 1: controller.api.services.v1.ListRolesResponse.items:type_name -> controller.api.resources.roles.v1.Role + 22, // 2: controller.api.services.v1.CreateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role + 22, // 3: controller.api.services.v1.CreateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role + 22, // 4: controller.api.services.v1.UpdateRoleRequest.item:type_name -> controller.api.resources.roles.v1.Role + 23, // 5: controller.api.services.v1.UpdateRoleRequest.update_mask:type_name -> google.protobuf.FieldMask + 22, // 6: controller.api.services.v1.UpdateRoleResponse.item:type_name -> controller.api.resources.roles.v1.Role + 24, // 7: controller.api.services.v1.AddRolePrincipalsRequest.version:type_name -> google.protobuf.UInt32Value + 22, // 8: controller.api.services.v1.AddRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role + 24, // 9: controller.api.services.v1.SetRolePrincipalsRequest.version:type_name -> google.protobuf.UInt32Value + 22, // 10: controller.api.services.v1.SetRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role + 24, // 11: controller.api.services.v1.RemoveRolePrincipalsRequest.version:type_name -> google.protobuf.UInt32Value + 22, // 12: controller.api.services.v1.RemoveRolePrincipalsResponse.item:type_name -> controller.api.resources.roles.v1.Role + 24, // 13: controller.api.services.v1.AddRoleGrantsRequest.version:type_name -> google.protobuf.UInt32Value + 22, // 14: controller.api.services.v1.AddRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role + 24, // 15: controller.api.services.v1.SetRoleGrantsRequest.version:type_name -> google.protobuf.UInt32Value + 22, // 16: controller.api.services.v1.SetRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role + 24, // 17: controller.api.services.v1.RemoveRoleGrantsRequest.version:type_name -> google.protobuf.UInt32Value + 22, // 18: controller.api.services.v1.RemoveRoleGrantsResponse.item:type_name -> controller.api.resources.roles.v1.Role + 0, // 19: controller.api.services.v1.RoleService.GetRole:input_type -> controller.api.services.v1.GetRoleRequest + 2, // 20: controller.api.services.v1.RoleService.ListRoles:input_type -> controller.api.services.v1.ListRolesRequest + 4, // 21: controller.api.services.v1.RoleService.CreateRole:input_type -> controller.api.services.v1.CreateRoleRequest + 6, // 22: controller.api.services.v1.RoleService.UpdateRole:input_type -> controller.api.services.v1.UpdateRoleRequest + 8, // 23: controller.api.services.v1.RoleService.DeleteRole:input_type -> controller.api.services.v1.DeleteRoleRequest + 10, // 24: controller.api.services.v1.RoleService.AddRolePrincipals:input_type -> controller.api.services.v1.AddRolePrincipalsRequest + 12, // 25: controller.api.services.v1.RoleService.SetRolePrincipals:input_type -> controller.api.services.v1.SetRolePrincipalsRequest + 14, // 26: controller.api.services.v1.RoleService.RemoveRolePrincipals:input_type -> controller.api.services.v1.RemoveRolePrincipalsRequest + 16, // 27: controller.api.services.v1.RoleService.AddRoleGrants:input_type -> controller.api.services.v1.AddRoleGrantsRequest + 18, // 28: controller.api.services.v1.RoleService.SetRoleGrants:input_type -> controller.api.services.v1.SetRoleGrantsRequest + 20, // 29: controller.api.services.v1.RoleService.RemoveRoleGrants:input_type -> controller.api.services.v1.RemoveRoleGrantsRequest + 1, // 30: controller.api.services.v1.RoleService.GetRole:output_type -> controller.api.services.v1.GetRoleResponse + 3, // 31: controller.api.services.v1.RoleService.ListRoles:output_type -> controller.api.services.v1.ListRolesResponse + 5, // 32: controller.api.services.v1.RoleService.CreateRole:output_type -> controller.api.services.v1.CreateRoleResponse + 7, // 33: controller.api.services.v1.RoleService.UpdateRole:output_type -> controller.api.services.v1.UpdateRoleResponse + 9, // 34: controller.api.services.v1.RoleService.DeleteRole:output_type -> controller.api.services.v1.DeleteRoleResponse + 11, // 35: controller.api.services.v1.RoleService.AddRolePrincipals:output_type -> controller.api.services.v1.AddRolePrincipalsResponse + 13, // 36: controller.api.services.v1.RoleService.SetRolePrincipals:output_type -> controller.api.services.v1.SetRolePrincipalsResponse + 15, // 37: controller.api.services.v1.RoleService.RemoveRolePrincipals:output_type -> controller.api.services.v1.RemoveRolePrincipalsResponse + 17, // 38: controller.api.services.v1.RoleService.AddRoleGrants:output_type -> controller.api.services.v1.AddRoleGrantsResponse + 19, // 39: controller.api.services.v1.RoleService.SetRoleGrants:output_type -> controller.api.services.v1.SetRoleGrantsResponse + 21, // 40: controller.api.services.v1.RoleService.RemoveRoleGrants:output_type -> controller.api.services.v1.RemoveRoleGrantsResponse + 30, // [30:41] is the sub-list for method output_type + 19, // [19:30] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name } func init() { file_controller_api_services_v1_role_service_proto_init() } @@ -1585,6 +2097,78 @@ func file_controller_api_services_v1_role_service_proto_init() { return nil } } + file_controller_api_services_v1_role_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddRoleGrantsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddRoleGrantsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetRoleGrantsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetRoleGrantsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveRoleGrantsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_api_services_v1_role_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveRoleGrantsResponse); 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{ @@ -1592,7 +2176,7 @@ func file_controller_api_services_v1_role_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_api_services_v1_role_service_proto_rawDesc, NumEnums: 0, - NumMessages: 16, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, @@ -1666,6 +2250,23 @@ type RoleServiceClient interface { // existing organization, an error is returned. It is not an error to have duplicate // user/group ids. RemoveRolePrincipals(ctx context.Context, in *RemoveRolePrincipalsRequest, opts ...grpc.CallOption) (*RemoveRolePrincipalsResponse, error) + // AddRoleGrants adds grants to a role. The provided request must include + // the org id and the role id which the grants will be added to. If the + // org id is missing, malformed or references a non existing organization, + // an error is returned. It is not an error to have duplicate grants. + AddRoleGrants(ctx context.Context, in *AddRoleGrantsRequest, opts ...grpc.CallOption) (*AddRoleGrantsResponse, error) + // SetRoleGrants sets the role's grants. Any existing grants on the role are + // deleted if they are not included in this request. The provided request must + // include the org id and the role id which the grants will be set to. If the + // org id is missing, malformed or references a non existing organization, an + // error is returned. It is not an error to have duplicate grants. + SetRoleGrants(ctx context.Context, in *SetRoleGrantsRequest, opts ...grpc.CallOption) (*SetRoleGrantsResponse, error) + // RemoveRoleGrants removes the users and/or groups from the specified role. + // The provided request must include the org id and the role id which the users + // and/or groups will be removed from. If the org id is missing, malformed or references a non + // existing organization, an error is returned. It is not an error to have duplicate + // user/group ids. + RemoveRoleGrants(ctx context.Context, in *RemoveRoleGrantsRequest, opts ...grpc.CallOption) (*RemoveRoleGrantsResponse, error) } type roleServiceClient struct { @@ -1748,6 +2349,33 @@ func (c *roleServiceClient) RemoveRolePrincipals(ctx context.Context, in *Remove return out, nil } +func (c *roleServiceClient) AddRoleGrants(ctx context.Context, in *AddRoleGrantsRequest, opts ...grpc.CallOption) (*AddRoleGrantsResponse, error) { + out := new(AddRoleGrantsResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/AddRoleGrants", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) SetRoleGrants(ctx context.Context, in *SetRoleGrantsRequest, opts ...grpc.CallOption) (*SetRoleGrantsResponse, error) { + out := new(SetRoleGrantsResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/SetRoleGrants", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *roleServiceClient) RemoveRoleGrants(ctx context.Context, in *RemoveRoleGrantsRequest, opts ...grpc.CallOption) (*RemoveRoleGrantsResponse, error) { + out := new(RemoveRoleGrantsResponse) + err := c.cc.Invoke(ctx, "/controller.api.services.v1.RoleService/RemoveRoleGrants", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RoleServiceServer is the server API for RoleService service. type RoleServiceServer interface { // GetRole returns a stored Role if present. The provided request @@ -1798,6 +2426,23 @@ type RoleServiceServer interface { // existing organization, an error is returned. It is not an error to have duplicate // user/group ids. RemoveRolePrincipals(context.Context, *RemoveRolePrincipalsRequest) (*RemoveRolePrincipalsResponse, error) + // AddRoleGrants adds grants to a role. The provided request must include + // the org id and the role id which the grants will be added to. If the + // org id is missing, malformed or references a non existing organization, + // an error is returned. It is not an error to have duplicate grants. + AddRoleGrants(context.Context, *AddRoleGrantsRequest) (*AddRoleGrantsResponse, error) + // SetRoleGrants sets the role's grants. Any existing grants on the role are + // deleted if they are not included in this request. The provided request must + // include the org id and the role id which the grants will be set to. If the + // org id is missing, malformed or references a non existing organization, an + // error is returned. It is not an error to have duplicate grants. + SetRoleGrants(context.Context, *SetRoleGrantsRequest) (*SetRoleGrantsResponse, error) + // RemoveRoleGrants removes the users and/or groups from the specified role. + // The provided request must include the org id and the role id which the users + // and/or groups will be removed from. If the org id is missing, malformed or references a non + // existing organization, an error is returned. It is not an error to have duplicate + // user/group ids. + RemoveRoleGrants(context.Context, *RemoveRoleGrantsRequest) (*RemoveRoleGrantsResponse, error) } // UnimplementedRoleServiceServer can be embedded to have forward compatible implementations. @@ -1828,6 +2473,15 @@ func (*UnimplementedRoleServiceServer) SetRolePrincipals(context.Context, *SetRo func (*UnimplementedRoleServiceServer) RemoveRolePrincipals(context.Context, *RemoveRolePrincipalsRequest) (*RemoveRolePrincipalsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RemoveRolePrincipals not implemented") } +func (*UnimplementedRoleServiceServer) AddRoleGrants(context.Context, *AddRoleGrantsRequest) (*AddRoleGrantsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddRoleGrants not implemented") +} +func (*UnimplementedRoleServiceServer) SetRoleGrants(context.Context, *SetRoleGrantsRequest) (*SetRoleGrantsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetRoleGrants not implemented") +} +func (*UnimplementedRoleServiceServer) RemoveRoleGrants(context.Context, *RemoveRoleGrantsRequest) (*RemoveRoleGrantsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveRoleGrants not implemented") +} func RegisterRoleServiceServer(s *grpc.Server, srv RoleServiceServer) { s.RegisterService(&_RoleService_serviceDesc, srv) @@ -1977,6 +2631,60 @@ func _RoleService_RemoveRolePrincipals_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } +func _RoleService_AddRoleGrants_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddRoleGrantsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).AddRoleGrants(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/AddRoleGrants", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).AddRoleGrants(ctx, req.(*AddRoleGrantsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_SetRoleGrants_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetRoleGrantsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).SetRoleGrants(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/SetRoleGrants", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).SetRoleGrants(ctx, req.(*SetRoleGrantsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoleService_RemoveRoleGrants_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveRoleGrantsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoleServiceServer).RemoveRoleGrants(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/controller.api.services.v1.RoleService/RemoveRoleGrants", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoleServiceServer).RemoveRoleGrants(ctx, req.(*RemoveRoleGrantsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _RoleService_serviceDesc = grpc.ServiceDesc{ ServiceName: "controller.api.services.v1.RoleService", HandlerType: (*RoleServiceServer)(nil), @@ -2013,6 +2721,18 @@ var _RoleService_serviceDesc = grpc.ServiceDesc{ MethodName: "RemoveRolePrincipals", Handler: _RoleService_RemoveRolePrincipals_Handler, }, + { + MethodName: "AddRoleGrants", + Handler: _RoleService_AddRoleGrants_Handler, + }, + { + MethodName: "SetRoleGrants", + Handler: _RoleService_SetRoleGrants_Handler, + }, + { + MethodName: "RemoveRoleGrants", + Handler: _RoleService_RemoveRoleGrants_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "controller/api/services/v1/role_service.proto", diff --git a/internal/gen/controller/api/services/role_service.pb.gw.go b/internal/gen/controller/api/services/role_service.pb.gw.go index 11a1529ef..af4ea7d2d 100644 --- a/internal/gen/controller/api/services/role_service.pb.gw.go +++ b/internal/gen/controller/api/services/role_service.pb.gw.go @@ -1671,6 +1671,624 @@ func local_request_RoleService_RemoveRolePrincipals_1(ctx context.Context, marsh } +func request_RoleService_AddRoleGrants_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AddRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := client.AddRoleGrants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_AddRoleGrants_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AddRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := server.AddRoleGrants(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_AddRoleGrants_1(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AddRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["project_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id") + } + + protoReq.ProjectId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := client.AddRoleGrants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_AddRoleGrants_1(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AddRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["project_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id") + } + + protoReq.ProjectId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := server.AddRoleGrants(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_SetRoleGrants_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := client.SetRoleGrants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_SetRoleGrants_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := server.SetRoleGrants(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_SetRoleGrants_1(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["project_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id") + } + + protoReq.ProjectId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := client.SetRoleGrants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_SetRoleGrants_1(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["project_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id") + } + + protoReq.ProjectId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := server.SetRoleGrants(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_RemoveRoleGrants_0(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RemoveRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := client.RemoveRoleGrants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_RemoveRoleGrants_0(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RemoveRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := server.RemoveRoleGrants(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RoleService_RemoveRoleGrants_1(ctx context.Context, marshaler runtime.Marshaler, client RoleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RemoveRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["project_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id") + } + + protoReq.ProjectId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := client.RemoveRoleGrants(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RoleService_RemoveRoleGrants_1(ctx context.Context, marshaler runtime.Marshaler, server RoleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RemoveRoleGrantsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["org_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id") + } + + protoReq.OrgId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err) + } + + val, ok = pathParams["project_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id") + } + + protoReq.ProjectId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err) + } + + val, ok = pathParams["role_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "role_id") + } + + protoReq.RoleId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "role_id", err) + } + + msg, err := server.RemoveRoleGrants(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterRoleServiceHandlerServer registers the http handlers for service RoleService to "mux". // UnaryRPC :call RoleServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1996,6 +2614,126 @@ func RegisterRoleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("POST", pattern_RoleService_AddRoleGrants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_AddRoleGrants_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_AddRoleGrants_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_AddRoleGrants_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_AddRoleGrants_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_AddRoleGrants_1(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_AddRoleGrants_1(ctx, mux, outboundMarshaler, w, req, response_RoleService_AddRoleGrants_1{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_SetRoleGrants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_SetRoleGrants_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_SetRoleGrants_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_SetRoleGrants_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_SetRoleGrants_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_SetRoleGrants_1(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_SetRoleGrants_1(ctx, mux, outboundMarshaler, w, req, response_RoleService_SetRoleGrants_1{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_RemoveRoleGrants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_RemoveRoleGrants_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_RemoveRoleGrants_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_RemoveRoleGrants_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_RemoveRoleGrants_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RoleService_RemoveRoleGrants_1(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_RemoveRoleGrants_1(ctx, mux, outboundMarshaler, w, req, response_RoleService_RemoveRoleGrants_1{resp}, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2357,6 +3095,126 @@ func RegisterRoleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("POST", pattern_RoleService_AddRoleGrants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_AddRoleGrants_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_AddRoleGrants_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_AddRoleGrants_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_AddRoleGrants_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_AddRoleGrants_1(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_AddRoleGrants_1(ctx, mux, outboundMarshaler, w, req, response_RoleService_AddRoleGrants_1{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_SetRoleGrants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_SetRoleGrants_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_SetRoleGrants_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_SetRoleGrants_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_SetRoleGrants_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_SetRoleGrants_1(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_SetRoleGrants_1(ctx, mux, outboundMarshaler, w, req, response_RoleService_SetRoleGrants_1{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_RemoveRoleGrants_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_RemoveRoleGrants_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_RemoveRoleGrants_0(ctx, mux, outboundMarshaler, w, req, response_RoleService_RemoveRoleGrants_0{resp}, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RoleService_RemoveRoleGrants_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RoleService_RemoveRoleGrants_1(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RoleService_RemoveRoleGrants_1(ctx, mux, outboundMarshaler, w, req, response_RoleService_RemoveRoleGrants_1{resp}, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2468,6 +3326,60 @@ func (m response_RoleService_RemoveRolePrincipals_1) XXX_ResponseBody() interfac return response.Item } +type response_RoleService_AddRoleGrants_0 struct { + proto.Message +} + +func (m response_RoleService_AddRoleGrants_0) XXX_ResponseBody() interface{} { + response := m.Message.(*AddRoleGrantsResponse) + return response.Item +} + +type response_RoleService_AddRoleGrants_1 struct { + proto.Message +} + +func (m response_RoleService_AddRoleGrants_1) XXX_ResponseBody() interface{} { + response := m.Message.(*AddRoleGrantsResponse) + return response.Item +} + +type response_RoleService_SetRoleGrants_0 struct { + proto.Message +} + +func (m response_RoleService_SetRoleGrants_0) XXX_ResponseBody() interface{} { + response := m.Message.(*SetRoleGrantsResponse) + return response.Item +} + +type response_RoleService_SetRoleGrants_1 struct { + proto.Message +} + +func (m response_RoleService_SetRoleGrants_1) XXX_ResponseBody() interface{} { + response := m.Message.(*SetRoleGrantsResponse) + return response.Item +} + +type response_RoleService_RemoveRoleGrants_0 struct { + proto.Message +} + +func (m response_RoleService_RemoveRoleGrants_0) XXX_ResponseBody() interface{} { + response := m.Message.(*RemoveRoleGrantsResponse) + return response.Item +} + +type response_RoleService_RemoveRoleGrants_1 struct { + proto.Message +} + +func (m response_RoleService_RemoveRoleGrants_1) XXX_ResponseBody() interface{} { + response := m.Message.(*RemoveRoleGrantsResponse) + return response.Item +} + var ( pattern_RoleService_GetRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "id"}, "", runtime.AssumeColonVerbOpt(true))) @@ -2500,6 +3412,18 @@ var ( pattern_RoleService_RemoveRolePrincipals_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "role_id"}, "remove-principals", runtime.AssumeColonVerbOpt(true))) pattern_RoleService_RemoveRolePrincipals_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"v1", "orgs", "org_id", "projects", "project_id", "roles", "role_id"}, "remove-principals", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_AddRoleGrants_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "role_id"}, "add-grants", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_AddRoleGrants_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"v1", "orgs", "org_id", "projects", "project_id", "roles", "role_id"}, "add-grants", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_SetRoleGrants_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "role_id"}, "set-grants", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_SetRoleGrants_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"v1", "orgs", "org_id", "projects", "project_id", "roles", "role_id"}, "set-grants", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_RemoveRoleGrants_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "roles", "role_id"}, "remove-grants", runtime.AssumeColonVerbOpt(true))) + + pattern_RoleService_RemoveRoleGrants_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6}, []string{"v1", "orgs", "org_id", "projects", "project_id", "roles", "role_id"}, "remove-grants", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -2534,4 +3458,16 @@ var ( forward_RoleService_RemoveRolePrincipals_0 = runtime.ForwardResponseMessage forward_RoleService_RemoveRolePrincipals_1 = runtime.ForwardResponseMessage + + forward_RoleService_AddRoleGrants_0 = runtime.ForwardResponseMessage + + forward_RoleService_AddRoleGrants_1 = runtime.ForwardResponseMessage + + forward_RoleService_SetRoleGrants_0 = runtime.ForwardResponseMessage + + forward_RoleService_SetRoleGrants_1 = runtime.ForwardResponseMessage + + forward_RoleService_RemoveRoleGrants_0 = runtime.ForwardResponseMessage + + forward_RoleService_RemoveRoleGrants_1 = runtime.ForwardResponseMessage ) diff --git a/internal/iam/repository_role.go b/internal/iam/repository_role.go index 02b473da8..9b29b2de9 100644 --- a/internal/iam/repository_role.go +++ b/internal/iam/repository_role.go @@ -89,13 +89,14 @@ func (r *Repository) UpdateRole(ctx context.Context, role *Role, fieldMaskPaths // LookupRole will look up a role in the repository. If the role is not // found, it will return nil, nil. -func (r *Repository) LookupRole(ctx context.Context, withPublicId string, opt ...Option) (*Role, []PrincipalRole, error) { +func (r *Repository) LookupRole(ctx context.Context, withPublicId string, opt ...Option) (*Role, []PrincipalRole, []*RoleGrant, error) { if withPublicId == "" { - return nil, nil, fmt.Errorf("lookup role: missing public id %w", db.ErrNilParameter) + return nil, nil, nil, fmt.Errorf("lookup role: missing public id %w", db.ErrNilParameter) } role := allocRole() role.PublicId = withPublicId var pr []PrincipalRole + var rg []*RoleGrant _, err := r.writer.DoTx( ctx, db.StdRetryCnt, @@ -112,13 +113,17 @@ func (r *Repository) LookupRole(ctx context.Context, withPublicId string, opt .. if err != nil { return fmt.Errorf("lookup role: listing principal roles: %w for %s", err, withPublicId) } + rg, err = repo.ListRoleGrants(ctx, withPublicId) + if err != nil { + return fmt.Errorf("lookup role: listing principal roles: %w for %s", err, withPublicId) + } return nil }, ) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return &role, pr, nil + return &role, pr, rg, nil } // DeleteRole will delete a role from the repository. diff --git a/internal/iam/repository_role_grant.go b/internal/iam/repository_role_grant.go index c19c80371..6f45cf4a5 100644 --- a/internal/iam/repository_role_grant.go +++ b/internal/iam/repository_role_grant.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/watchtower/internal/db" "github.com/hashicorp/watchtower/internal/oplog" "github.com/hashicorp/watchtower/internal/perms" - "github.com/hashicorp/watchtower/internal/types/scope" ) // AddRoleGrant will add role grants associated with the role ID in the @@ -140,14 +139,7 @@ func (r *Repository) DeleteRoleGrants(ctx context.Context, roleId string, roleVe deleteRoleGrants := make([]interface{}, 0, len(grants)) for _, grant := range grants { // Use a fake scope, just want to get out a canonical string - perm, err := perms.Parse( - perms.Scope{ - Id: "s_abcd1234", - Type: scope.Organization, - }, - "", - grant, - ) + perm, err := perms.Parse("o_abcd1234", "", grant) if err != nil { return fmt.Errorf("delete role grants: error parsing grant string: %w", err) } @@ -237,14 +229,7 @@ func (r *Repository) SetRoleGrants(ctx context.Context, roleId string, roleVersi deleteRoleGrants := make([]interface{}, 0, len(grants)) for _, grant := range grants { // Use a fake scope, just want to get out a canonical string - perm, err := perms.Parse( - perms.Scope{ - Id: "s_abcd1234", - Type: scope.Organization, - }, - "", - grant, - ) + perm, err := perms.Parse("o_abcd1234", "", grant) if err != nil { return nil, 0, fmt.Errorf("set role grants: error parsing grant string: %w", err) } @@ -291,7 +276,7 @@ func (r *Repository) SetRoleGrants(ctx context.Context, roleId string, roleVersi } updatedRole := allocRole() updatedRole.PublicId = roleId - updatedRole.Version = uint32(roleVersion) + 1 + updatedRole.Version = roleVersion + 1 var roleOplogMsg oplog.Message rowsUpdated, err := w.Update(ctx, &updatedRole, []string{"Version"}, nil, db.NewOplogMsg(&roleOplogMsg), db.WithVersion(roleVersion)) if err != nil { diff --git a/internal/iam/repository_role_test.go b/internal/iam/repository_role_test.go index 2c2599584..e35a2d192 100644 --- a/internal/iam/repository_role_test.go +++ b/internal/iam/repository_role_test.go @@ -160,7 +160,7 @@ func TestRepository_CreateRole(t *testing.T) { assert.NotNil(grp.CreateTime) assert.NotNil(grp.UpdateTime) - foundGrp, _, err := repo.LookupRole(context.Background(), grp.PublicId) + foundGrp, _, _, err := repo.LookupRole(context.Background(), grp.PublicId) assert.NoError(err) assert.True(proto.Equal(foundGrp, grp)) @@ -422,7 +422,7 @@ func TestRepository_UpdateRole(t *testing.T) { default: assert.NotEqual(r.UpdateTime, roleAfterUpdate.UpdateTime) } - foundRole, _, err := repo.LookupRole(context.Background(), r.PublicId) + foundRole, _, _, err := repo.LookupRole(context.Background(), r.PublicId) assert.NoError(err) assert.True(proto.Equal(roleAfterUpdate, foundRole)) dbassert := dbassert.New(t, rw) @@ -512,7 +512,7 @@ func TestRepository_DeleteRole(t *testing.T) { } assert.NoError(err) assert.Equal(tt.wantRowsDeleted, deletedRows) - foundRole, _, err := repo.LookupRole(context.Background(), tt.args.role.PublicId) + foundRole, _, _, err := repo.LookupRole(context.Background(), tt.args.role.PublicId) assert.Error(err) assert.Nil(foundRole) assert.True(errors.Is(err, db.ErrRecordNotFound)) diff --git a/internal/iam/role_grant.go b/internal/iam/role_grant.go index 6aba03a60..6efc8104d 100644 --- a/internal/iam/role_grant.go +++ b/internal/iam/role_grant.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/watchtower/internal/iam/store" "github.com/hashicorp/watchtower/internal/perms" "github.com/hashicorp/watchtower/internal/types/resource" - "github.com/hashicorp/watchtower/internal/types/scope" "google.golang.org/protobuf/proto" ) @@ -36,14 +35,7 @@ func NewRoleGrant(roleId string, grant string, opt ...Option) (*RoleGrant, error // Validate that the grant parses successfully. Note that we fake the scope // here to avoid a lookup as the scope is only relevant at actual ACL // checking time and we just care that it parses correctly. - perm, err := perms.Parse( - perms.Scope{ - Id: "s_abcd1234", - Type: scope.Organization, - }, - "", - grant, - ) + perm, err := perms.Parse("o_abcd1234", "", grant) if err != nil { return nil, fmt.Errorf("new role grant: error parsing grant string: %w", err) } @@ -82,14 +74,7 @@ func (g *RoleGrant) VetForWrite(ctx context.Context, r db.Reader, opType db.OpTy // checking time and we just care that it parses correctly. We may have // already done this in NewRoleGrant, but we re-check and set it here // anyways because it should still be part of the vetting process. - perm, err := perms.Parse( - perms.Scope{ - Id: "s_abcd1234", - Type: scope.Organization, - }, - "", - g.RawGrant, - ) + perm, err := perms.Parse("o_abcd1234", "", g.RawGrant) if err != nil { return fmt.Errorf("vet role grant for writing: error parsing grant string: %w", err) } diff --git a/internal/perms/acl_test.go b/internal/perms/acl_test.go index 154ae4798..a1272e896 100644 --- a/internal/perms/acl_test.go +++ b/internal/perms/acl_test.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/watchtower/internal/types/action" "github.com/hashicorp/watchtower/internal/types/resource" - "github.com/hashicorp/watchtower/internal/types/scope" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -14,7 +13,7 @@ func Test_ACLAllowed(t *testing.T) { t.Parallel() type scopeGrant struct { - scope Scope + scope string grants []string } type actionAllowed struct { @@ -32,7 +31,7 @@ func Test_ACLAllowed(t *testing.T) { // A set of common grants to use in the following tests commonGrants := []scopeGrant{ { - scope: Scope{Type: scope.Organization, Id: "org_a"}, + scope: "o_a", grants: []string{ "id=a_bar;actions=read,update", "id=a_foo;type=host-catalog;actions=update,delete", @@ -40,7 +39,7 @@ func Test_ACLAllowed(t *testing.T) { }, }, { - scope: Scope{Type: scope.Organization, Id: "org_b"}, + scope: "o_b", grants: []string{ "type=host-set;actions=list,create", "type=host;actions=*", @@ -48,7 +47,7 @@ func Test_ACLAllowed(t *testing.T) { }, }, { - scope: Scope{Type: scope.Organization, Id: "org_c"}, + scope: "o_c", grants: []string{ "id={{user.id }};actions=create,update", }, @@ -77,7 +76,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope and id no matching action", - resource: Resource{ScopeId: "org_a", Id: "a_foo"}, + resource: Resource{ScopeId: "o_a", Id: "a_foo"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Update}, @@ -86,7 +85,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope and id and matching action", - resource: Resource{ScopeId: "org_a", Id: "a_bar"}, + resource: Resource{ScopeId: "o_a", Id: "a_bar"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Read, allowed: true}, @@ -96,7 +95,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope and id and all action", - resource: Resource{ScopeId: "org_b", Type: resource.Host}, + resource: Resource{ScopeId: "o_b", Type: resource.Host}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Read, allowed: true}, @@ -106,7 +105,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope and id and all action but bad specifier", - resource: Resource{ScopeId: "org_b", Id: "id_g"}, + resource: Resource{ScopeId: "o_b", Id: "id_g"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Read}, @@ -116,7 +115,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope and not matching type", - resource: Resource{ScopeId: "org_a", Type: resource.HostCatalog}, + resource: Resource{ScopeId: "o_a", Type: resource.HostCatalog}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Update}, @@ -125,7 +124,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope and matching type", - resource: Resource{ScopeId: "org_a", Type: resource.HostSet}, + resource: Resource{ScopeId: "o_a", Type: resource.HostSet}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.List, allowed: true}, @@ -135,7 +134,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope, type, action, bad pin", - resource: Resource{ScopeId: "org_a", Id: "a_foo", Type: resource.HostCatalog}, + resource: Resource{ScopeId: "o_a", Id: "a_foo", Type: resource.HostCatalog}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Update}, @@ -145,7 +144,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope, type, action, random id and bad pin", - resource: Resource{ScopeId: "org_a", Id: "anything", Type: resource.HostCatalog, Pin: "a_bar"}, + resource: Resource{ScopeId: "o_a", Id: "anything", Type: resource.HostCatalog, Pin: "a_bar"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Update}, @@ -155,7 +154,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "matching scope, type, action, random id and good pin", - resource: Resource{ScopeId: "org_a", Id: "anything", Type: resource.HostCatalog, Pin: "a_foo"}, + resource: Resource{ScopeId: "o_a", Id: "anything", Type: resource.HostCatalog, Pin: "a_foo"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Update, allowed: true}, @@ -165,7 +164,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "wrong scope and matching type", - resource: Resource{ScopeId: "org_bad", Type: resource.HostSet}, + resource: Resource{ScopeId: "o_bad", Type: resource.HostSet}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.List}, @@ -175,7 +174,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "any id", - resource: Resource{ScopeId: "org_b", Type: resource.AuthMethod}, + resource: Resource{ScopeId: "o_b", Type: resource.AuthMethod}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.List}, @@ -185,7 +184,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "bad templated user id", - resource: Resource{ScopeId: "org_c"}, + resource: Resource{ScopeId: "o_c"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.List}, @@ -196,7 +195,7 @@ func Test_ACLAllowed(t *testing.T) { }, { name: "good templated user id", - resource: Resource{ScopeId: "org_c", Id: "u_abcd1234"}, + resource: Resource{ScopeId: "o_c", Id: "u_abcd1234"}, scopeGrants: commonGrants, actionsAllowed: []actionAllowed{ {action: action.Create, allowed: true}, @@ -210,9 +209,8 @@ func Test_ACLAllowed(t *testing.T) { t.Run(test.name, func(t *testing.T) { var grants []Grant for _, sg := range test.scopeGrants { - scope := sg.scope for _, g := range sg.grants { - grant, err := Parse(scope, test.userId, g) + grant, err := Parse(sg.scope, test.userId, g) require.NoError(t, err) grants = append(grants, grant) } diff --git a/internal/perms/grants.go b/internal/perms/grants.go index 76b44eeb8..ec8e37b40 100644 --- a/internal/perms/grants.go +++ b/internal/perms/grants.go @@ -198,23 +198,28 @@ func (g *Grant) unmarshalText(grantString string) error { // // The scope must be the org and project where this grant originated, not the // request. -func Parse(s Scope, userId, grantString string) (Grant, error) { +func Parse(scopeId, userId, grantString string) (Grant, error) { if len(grantString) == 0 { return Grant{}, errors.New("grant string is empty") } - switch s.Type { - case scope.Project, scope.Organization: - default: - return Grant{}, errors.New("invalid scope type") - } - - if s.Id == "" { + if scopeId == "" { return Grant{}, errors.New("no scope ID provided") } grant := Grant{ - scope: s, + scope: Scope{Id: scopeId}, + } + + switch { + case scopeId == "global": + grant.scope.Type = scope.Global + case strings.HasPrefix(scopeId, scope.Organization.Prefix()): + grant.scope.Type = scope.Organization + case strings.HasPrefix(scopeId, scope.Project.Prefix()): + grant.scope.Type = scope.Project + default: + return Grant{}, errors.New("invalid scope type") } switch { diff --git a/internal/perms/grants_test.go b/internal/perms/grants_test.go index d11f013d7..c8898d1fa 100644 --- a/internal/perms/grants_test.go +++ b/internal/perms/grants_test.go @@ -320,11 +320,12 @@ func Test_Parse(t *testing.T) { t.Parallel() type input struct { - name string - input string - userId string - err string - expected Grant + name string + input string + userId string + err string + scopeOverride string + expected Grant } tests := []input{ @@ -362,7 +363,7 @@ func Test_Parse(t *testing.T) { input: `{"id":"foobar","type":"host-catalog","actions":["create","read"]}`, expected: Grant{ scope: Scope{ - Id: "scope", + Id: "o_scope", Type: scope.Organization, }, id: "foobar", @@ -378,7 +379,7 @@ func Test_Parse(t *testing.T) { input: `id=foobar;type=host-catalog;actions=create,read`, expected: Grant{ scope: Scope{ - Id: "scope", + Id: "o_scope", Type: scope.Organization, }, id: "foobar", @@ -389,6 +390,57 @@ func Test_Parse(t *testing.T) { }, }, }, + { + name: "default project scope", + input: `id=foobar;type=host-catalog;actions=create,read`, + scopeOverride: "p_1234", + expected: Grant{ + scope: Scope{ + Id: "p_1234", + Type: scope.Project, + }, + id: "foobar", + typ: resource.HostCatalog, + actions: map[action.Type]bool{ + action.Create: true, + action.Read: true, + }, + }, + }, + { + name: "default org scope", + input: `id=foobar;type=host-catalog;actions=create,read`, + scopeOverride: "o_1234", + expected: Grant{ + scope: Scope{ + Id: "o_1234", + Type: scope.Organization, + }, + id: "foobar", + typ: resource.HostCatalog, + actions: map[action.Type]bool{ + action.Create: true, + action.Read: true, + }, + }, + }, + { + name: "default global scope", + input: `id=foobar;type=host-catalog;actions=create,read`, + scopeOverride: "global", + expected: Grant{ + scope: Scope{ + Id: "global", + Type: scope.Global, + }, + id: "foobar", + typ: resource.HostCatalog, + actions: map[action.Type]bool{ + action.Create: true, + action.Read: true, + }, + }, + }, { name: "bad user id template", input: `id={{superman}};actions=create,read`, @@ -401,7 +453,7 @@ func Test_Parse(t *testing.T) { userId: "u_abcd1234", expected: Grant{ scope: Scope{ - Id: "scope", + Id: "o_scope", Type: scope.Organization, }, id: "u_abcd1234", @@ -413,15 +465,11 @@ func Test_Parse(t *testing.T) { }, } - _, err := Parse(Scope{}, "", "") + _, err := Parse("", "", "") require.Error(t, err) assert.Equal(t, "grant string is empty", err.Error()) - _, err = Parse(Scope{}, "", "{}") - require.Error(t, err) - assert.Equal(t, "invalid scope type", err.Error()) - - _, err = Parse(Scope{Type: scope.Organization}, "", "{}") + _, err = Parse("", "", "{}") require.Error(t, err) assert.Equal(t, "no scope ID provided", err.Error()) @@ -429,7 +477,11 @@ func Test_Parse(t *testing.T) { t.Run(test.name, func(t *testing.T) { assert := assert.New(t) require := require.New(t) - grant, err := Parse(Scope{Id: "scope", Type: scope.Organization}, test.userId, test.input) + scope := "o_scope" + if test.scopeOverride != "" { + scope = test.scopeOverride + } + grant, err := Parse(scope, test.userId, test.input) if test.err != "" { require.Error(err) assert.True(strings.Contains(err.Error(), test.err)) diff --git a/internal/proto/local/controller/api/resources/roles/v1/role.proto b/internal/proto/local/controller/api/resources/roles/v1/role.proto index d5af6e09b..0b1da0ee8 100644 --- a/internal/proto/local/controller/api/resources/roles/v1/role.proto +++ b/internal/proto/local/controller/api/resources/roles/v1/role.proto @@ -51,4 +51,12 @@ message Role { // The grants that this role provides for it's principals. // Output only. repeated string grants = 11; + + // The canonical version of the grants in the grants field with the same index. + // Output only. + repeated string grants_canonical = 12; + + // The JSON version of the grants in the grants field with the same index. + // Output only. + repeated string grants_json = 13; } diff --git a/internal/proto/local/controller/api/services/v1/role_service.proto b/internal/proto/local/controller/api/services/v1/role_service.proto index 6e99876b9..6c4cab3b1 100644 --- a/internal/proto/local/controller/api/services/v1/role_service.proto +++ b/internal/proto/local/controller/api/services/v1/role_service.proto @@ -169,6 +169,69 @@ service RoleService { summary: "Removes the specified Users and/or Groups from a Role." }; } + + // AddRoleGrants adds grants to a role. The provided request must include + // the org id and the role id which the grants will be added to. If the + // org id is missing, malformed or references a non existing organization, + // an error is returned. It is not an error to have duplicate grants. + rpc AddRoleGrants(AddRoleGrantsRequest) returns (AddRoleGrantsResponse) { + option (google.api.http) = { + post: "/v1/orgs/{org_id}/roles/{role_id}:add-grants" + body: "*" + response_body: "item" + additional_bindings { + post: "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:add-grants" + body: "*" + response_body: "item" + } + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Adds grants to a role" + }; + } + + // SetRoleGrants sets the role's grants. Any existing grants on the role are + // deleted if they are not included in this request. The provided request must + // include the org id and the role id which the grants will be set to. If the + // org id is missing, malformed or references a non existing organization, an + // error is returned. It is not an error to have duplicate grants. + rpc SetRoleGrants(SetRoleGrantsRequest) returns (SetRoleGrantsResponse) { + option (google.api.http) = { + post: "/v1/orgs/{org_id}/roles/{role_id}:set-grants" + body: "*" + response_body: "item" + additional_bindings { + post: "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:set-grants" + body: "*" + response_body: "item" + } + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Set grants for a role, removing any grants that are not specified in the request." + }; + } + + // RemoveRoleGrants removes the users and/or groups from the specified role. + // The provided request must include the org id and the role id which the users + // and/or groups will be removed from. If the org id is missing, malformed or references a non + // existing organization, an error is returned. It is not an error to have duplicate + // user/group ids. + rpc RemoveRoleGrants(RemoveRoleGrantsRequest) returns (RemoveRoleGrantsResponse) { + option (google.api.http) = { + post: "/v1/orgs/{org_id}/roles/{role_id}:remove-grants" + body: "*" + response_body: "item" + additional_bindings { + post: "/v1/orgs/{org_id}/projects/{project_id}/roles/{role_id}:remove-grants" + body: "*" + response_body: "item" + } + }; + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Removes grants from a role." + }; + } + } message GetRoleRequest { @@ -269,4 +332,46 @@ message RemoveRolePrincipalsRequest { message RemoveRolePrincipalsResponse { resources.roles.v1.Role item = 1; +} + +message AddRoleGrantsRequest { + string org_id = 1; + string project_id = 2; + string role_id = 3; + // The version ensures the role hasn't changed since it was last retrieved and if + // it has the request will fail. + google.protobuf.UInt32Value version = 4; + repeated string grants = 5 [json_name="grants"]; +} + +message AddRoleGrantsResponse { + resources.roles.v1.Role item = 1; +} + +message SetRoleGrantsRequest { + string org_id = 1; + string project_id = 2; + string role_id = 3; + // The version ensures the role hasn't changed since it was last retrieved and if + // it has the request will fail. + google.protobuf.UInt32Value version = 4; + repeated string grants = 5 [json_name="grants"]; +} + +message SetRoleGrantsResponse { + resources.roles.v1.Role item = 1; +} + +message RemoveRoleGrantsRequest { + string org_id = 1; + string project_id = 2; + string role_id = 3; + // The version ensures the role hasn't changed since it was last retrieved and if + // it has the request will fail. + google.protobuf.UInt32Value version = 4; + repeated string grants = 5 [json_name="grants"]; +} + +message RemoveRoleGrantsResponse { + resources.roles.v1.Role item = 1; } \ No newline at end of file diff --git a/internal/servers/controller/handler_test.go b/internal/servers/controller/handler_test.go index a4a14976e..95d18bc1a 100644 --- a/internal/servers/controller/handler_test.go +++ b/internal/servers/controller/handler_test.go @@ -141,6 +141,12 @@ func TestGrpcGatewayRouting_CustomActions(t *testing.T) { "v1/orgs/someid/projects/p_something/roles/r_anotherid:add-principals", "v1/orgs/someid/projects/p_something/roles/r_anotherid:set-principals", "v1/orgs/someid/projects/p_something/roles/r_anotherid:remove-principals", + "v1/orgs/someid/roles/r_anotherid:add-grants", + "v1/orgs/someid/roles/r_anotherid:set-grants", + "v1/orgs/someid/roles/r_anotherid:remove-grants", + "v1/orgs/someid/projects/p_something/roles/r_anotherid:add-grants", + "v1/orgs/someid/projects/p_something/roles/r_anotherid:set-grants", + "v1/orgs/someid/projects/p_something/roles/r_anotherid:remove-grants", }, }, } diff --git a/internal/servers/controller/handlers/roles/role_service.go b/internal/servers/controller/handlers/roles/role_service.go index 7a912bd77..9b575a0bb 100644 --- a/internal/servers/controller/handlers/roles/role_service.go +++ b/internal/servers/controller/handlers/roles/role_service.go @@ -11,6 +11,7 @@ import ( pb "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/roles" pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services" "github.com/hashicorp/watchtower/internal/iam" + "github.com/hashicorp/watchtower/internal/perms" "github.com/hashicorp/watchtower/internal/servers/controller/handlers" "github.com/hashicorp/watchtower/internal/types/scope" "google.golang.org/grpc/codes" @@ -164,12 +165,54 @@ func (s Service) RemoveRolePrincipals(ctx context.Context, req *pbs.RemoveRolePr return &pbs.RemoveRolePrincipalsResponse{Item: r}, nil } +// AddRoleGrants implements the interface pbs.RoleServiceServer. +func (s Service) AddRoleGrants(ctx context.Context, req *pbs.AddRoleGrantsRequest) (*pbs.AddRoleGrantsResponse, error) { + auth := handlers.ToTokenMetadata(ctx) + _ = auth + if err := validateAddRoleGrantsRequest(req); err != nil { + return nil, err + } + r, err := s.addGrantsInRepo(ctx, req.GetRoleId(), req.GetGrants(), req.GetVersion().GetValue()) + if err != nil { + return nil, err + } + return &pbs.AddRoleGrantsResponse{Item: r}, nil +} + +// SetRoleGrants implements the interface pbs.RoleServiceServer. +func (s Service) SetRoleGrants(ctx context.Context, req *pbs.SetRoleGrantsRequest) (*pbs.SetRoleGrantsResponse, error) { + auth := handlers.ToTokenMetadata(ctx) + _ = auth + if err := validateSetRoleGrantsRequest(req); err != nil { + return nil, err + } + r, err := s.setGrantsInRepo(ctx, req.GetRoleId(), req.GetGrants(), req.GetVersion().GetValue()) + if err != nil { + return nil, err + } + return &pbs.SetRoleGrantsResponse{Item: r}, nil +} + +// RemoveRoleGrants implements the interface pbs.RoleServiceServer. +func (s Service) RemoveRoleGrants(ctx context.Context, req *pbs.RemoveRoleGrantsRequest) (*pbs.RemoveRoleGrantsResponse, error) { + auth := handlers.ToTokenMetadata(ctx) + _ = auth + if err := validateRemoveRoleGrantsRequest(req); err != nil { + return nil, err + } + r, err := s.removeGrantsInRepo(ctx, req.GetRoleId(), req.GetGrants(), req.GetVersion().GetValue()) + if err != nil { + return nil, err + } + return &pbs.RemoveRoleGrantsResponse{Item: r}, nil +} + func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Role, error) { repo, err := s.repoFn() if err != nil { return nil, err } - out, pr, err := repo.LookupRole(ctx, id) + out, pr, roleGrants, err := repo.LookupRole(ctx, id) if err != nil { if errors.Is(err, db.ErrRecordNotFound) { return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id) @@ -179,7 +222,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Role, error) { if out == nil { return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id) } - return toProto(out, pr), nil + return toProto(out, pr, roleGrants), nil } func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Role) (*pb.Role, error) { @@ -208,7 +251,7 @@ func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Role if out == nil { return nil, status.Error(codes.Internal, "Unable to create role but no error returned from repository.") } - return toProto(out, nil), nil + return toProto(out, nil, nil), nil } func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []string, item *pb.Role) (*pb.Role, error) { @@ -246,7 +289,8 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st if rowsUpdated == 0 { return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id) } - return toProto(out, nil), nil + // TODO: Attach principals and grants to UpdateRole response + return toProto(out, nil, nil), nil } func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) { @@ -275,7 +319,8 @@ func (s Service) listFromRepo(ctx context.Context, scopeId string) ([]*pb.Role, } var outRl []*pb.Role for _, g := range rl { - outRl = append(outRl, toProto(g, nil)) + // TODO: Attach principals and grants to ListRoles response. + outRl = append(outRl, toProto(g, nil, nil)) } return outRl, nil } @@ -289,14 +334,14 @@ func (s Service) addPrinciplesInRepo(ctx context.Context, roleId string, userIds if err != nil { return nil, status.Errorf(codes.Internal, "Unable to add principles to role: %v.", err) } - out, pr, err := repo.LookupRole(ctx, roleId) + out, pr, roleGrants, err := repo.LookupRole(ctx, roleId) if err != nil { return nil, status.Errorf(codes.Internal, "Unable to look up role: %v.", err) } if out == nil { return nil, status.Error(codes.Internal, "Unable to lookup role after adding principles to it.") } - return toProto(out, pr), nil + return toProto(out, pr, roleGrants), nil } func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, userIds []string, groupIds []string, version uint32) (*pb.Role, error) { @@ -308,14 +353,14 @@ func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, userIds if err != nil { return nil, status.Errorf(codes.Internal, "Unable to set principles on role: %v.", err) } - out, pr, err := repo.LookupRole(ctx, roleId) + out, pr, roleGrants, err := repo.LookupRole(ctx, roleId) if err != nil { return nil, status.Errorf(codes.Internal, "Unable to look up role: %v.", err) } if out == nil { return nil, status.Error(codes.Internal, "Unable to lookup role after setting principles for it.") } - return toProto(out, pr), nil + return toProto(out, pr, roleGrants), nil } func (s Service) removePrinciplesInRepo(ctx context.Context, roleId string, userIds []string, groupIds []string, version uint32) (*pb.Role, error) { @@ -327,14 +372,75 @@ func (s Service) removePrinciplesInRepo(ctx context.Context, roleId string, user if err != nil { return nil, status.Errorf(codes.Internal, "Unable to remove principles from role: %v.", err) } - out, pr, err := repo.LookupRole(ctx, roleId) + out, pr, roleGrants, err := repo.LookupRole(ctx, roleId) if err != nil { return nil, status.Errorf(codes.Internal, "Unable to look up role: %v.", err) } if out == nil { return nil, status.Error(codes.Internal, "Unable to lookup role after removing principles from it.") } - return toProto(out, pr), nil + return toProto(out, pr, roleGrants), nil +} + +func (s Service) addGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*pb.Role, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + _, err = repo.AddRoleGrants(ctx, roleId, version, grants) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to add grants to role: %v.", err) + } + out, pr, roleGrants, err := repo.LookupRole(ctx, roleId) + if err != nil { + return nil, status.Error(codes.Internal, "Error looking up role after adding grants to it.") + } + if out == nil { + return nil, status.Error(codes.Internal, "Unable to lookup role after adding grants to it.") + } + return toProto(out, pr, roleGrants), nil +} + +func (s Service) setGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*pb.Role, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + // If no grant was provided, we clear the grants. + if grants == nil { + grants = []string{} + } + _, _, err = repo.SetRoleGrants(ctx, roleId, version, grants) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to set grants on role: %v.", err) + } + out, pr, roleGrants, err := repo.LookupRole(ctx, roleId) + if err != nil { + return nil, status.Error(codes.Internal, "Error looking up role after setting grants on it.") + } + if out == nil { + return nil, status.Error(codes.Internal, "Unable to lookup role after setting grants on it.") + } + return toProto(out, pr, roleGrants), nil +} + +func (s Service) removeGrantsInRepo(ctx context.Context, roleId string, grants []string, version uint32) (*pb.Role, error) { + repo, err := s.repoFn() + if err != nil { + return nil, err + } + _, err = repo.DeleteRoleGrants(ctx, roleId, version, grants) + if err != nil { + return nil, status.Errorf(codes.Internal, "Unable to remove grants from role: %v.", err) + } + out, pr, roleGrants, err := repo.LookupRole(ctx, roleId) + if err != nil { + return nil, status.Error(codes.Internal, "Error looking up role after removing grants from it.") + } + if out == nil { + return nil, status.Error(codes.Internal, "Unable to lookup role after removing grants from it.") + } + return toProto(out, pr, roleGrants), nil } // toDbUpdateMask converts the wire format's FieldMask into a list of strings containing FieldMask paths used @@ -356,7 +462,7 @@ func toDbUpdateMask(paths []string) ([]string, error) { return dbPaths, nil } -func toProto(in *iam.Role, principals []iam.PrincipalRole) *pb.Role { +func toProto(in *iam.Role, principals []iam.PrincipalRole, grants []*iam.RoleGrant) *pb.Role { out := pb.Role{ Id: in.GetPublicId(), CreatedTime: in.GetCreateTime().GetTimestamp(), @@ -377,6 +483,26 @@ func toProto(in *iam.Role, principals []iam.PrincipalRole) *pb.Role { out.GroupIds = append(out.GroupIds, p.GetPrincipalId()) } } + for _, g := range grants { + out.Grants = append(out.Grants, g.GetRawGrant()) + parsed, err := perms.Parse(in.GetGrantScopeId(), "", g.GetRawGrant()) + if err != nil { + // This should never happen as we validate on the way in, but let's + // return what we can since we are still returning the raw grant + out.GrantsCanonical = append(out.GrantsCanonical, "") + out.GrantsJson = append(out.GrantsJson, "") + } else { + out.GrantsCanonical = append(out.GrantsCanonical, parsed.CanonicalString()) + jsonGrant, err := parsed.MarshalJSON() + if err != nil { + // Again, this should never happen, but let's return what we + // have anyways + out.GrantsJson = append(out.GrantsJson, "") + } else { + out.GrantsJson = append(out.GrantsJson, string(jsonGrant)) + } + } + } if in.GetGrantScopeId() != "" { out.GrantScopeId = &wrapperspb.StringValue{Value: in.GetGrantScopeId()} } @@ -503,10 +629,6 @@ func validateSetRolePrincipalsRequest(req *pbs.SetRolePrincipalsRequest) error { if req.GetVersion() == nil { badFields["version"] = "Required field." } - if len(req.GetGroupIds()) == 0 && len(req.GetUserIds()) == 0 { - badFields["user_ids"] = "Either user_ids or group_ids must be non empty." - badFields["group_ids"] = "Either user_ids or group_ids must be non empty." - } if len(badFields) > 0 { return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) } @@ -531,6 +653,54 @@ func validateRemoveRolePrincipalsRequest(req *pbs.RemoveRolePrincipalsRequest) e return nil } +func validateAddRoleGrantsRequest(req *pbs.AddRoleGrantsRequest) error { + badFields := validateAncestors(req) + if !validId(req.GetRoleId(), iam.RolePrefix+"_") { + badFields["id"] = "Incorrectly formatted identifier." + } + if req.GetVersion() == nil { + badFields["version"] = "Required field." + } + if len(req.GetGrants()) == 0 { + badFields["grants"] = "This must be non empty." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) + } + return nil +} + +func validateSetRoleGrantsRequest(req *pbs.SetRoleGrantsRequest) error { + badFields := validateAncestors(req) + if !validId(req.GetRoleId(), iam.RolePrefix+"_") { + badFields["id"] = "Incorrectly formatted identifier." + } + if req.GetVersion() == nil { + badFields["version"] = "Required field." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) + } + return nil +} + +func validateRemoveRoleGrantsRequest(req *pbs.RemoveRoleGrantsRequest) error { + badFields := validateAncestors(req) + if !validId(req.GetRoleId(), iam.RolePrefix+"_") { + badFields["id"] = "Incorrectly formatted identifier." + } + if req.GetVersion() == nil { + badFields["version"] = "Required field." + } + if len(req.GetGrants()) == 0 { + badFields["grants"] = "This must be non empty." + } + if len(badFields) > 0 { + return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields) + } + return nil +} + func validId(id, prefix string) bool { if !strings.HasPrefix(id, prefix) { return false diff --git a/internal/servers/controller/handlers/roles/role_service_test.go b/internal/servers/controller/handlers/roles/role_service_test.go index 10360a1fa..d5a3ccffa 100644 --- a/internal/servers/controller/handlers/roles/role_service_test.go +++ b/internal/servers/controller/handlers/roles/role_service_test.go @@ -3,12 +3,10 @@ package roles_test import ( "context" "fmt" - "sort" "strings" "testing" "github.com/golang/protobuf/ptypes" - "github.com/google/go-cmp/cmp" "github.com/hashicorp/watchtower/internal/db" pb "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/roles" pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services" @@ -19,7 +17,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/wrapperspb" "github.com/stretchr/testify/assert" @@ -826,212 +823,112 @@ func TestAddPrincipal(t *testing.T) { repoFn := func() (*iam.Repository, error) { return iam.NewRepository(rw, rw, wrap) } - o, p := iam.TestScopes(t, conn) - - orUserEmpty := iam.TestRole(t, conn, o.GetPublicId()) - prUserEmpty := iam.TestRole(t, conn, p.GetPublicId()) - orGroupEmpty := iam.TestRole(t, conn, o.GetPublicId()) - prGroupEmpty := iam.TestRole(t, conn, p.GetPublicId()) - - orWithUser := iam.TestRole(t, conn, o.GetPublicId()) - assignedUser := iam.TestUser(t, conn, o.GetPublicId()) - _ = iam.TestUserRole(t, conn, orWithUser.GetPublicId(), assignedUser.GetPublicId()) - - ou1 := iam.TestUser(t, conn, o.GetPublicId()) - ou2 := iam.TestUser(t, conn, o.GetPublicId()) - - orWithGroup := iam.TestRole(t, conn, o.GetPublicId()) - assignedOG := iam.TestGroup(t, conn, o.GetPublicId()) - _ = iam.TestGroupRole(t, conn, orWithGroup.GetPublicId(), assignedOG.GetPublicId()) - - og1 := iam.TestGroup(t, conn, o.GetPublicId()) - og2 := iam.TestGroup(t, conn, o.GetPublicId()) - - prWithUser := iam.TestRole(t, conn, p.GetPublicId()) - _ = iam.TestUserRole(t, conn, prWithUser.GetPublicId(), assignedUser.GetPublicId()) - - prWithGroup := iam.TestRole(t, conn, p.GetPublicId()) - assignedPG := iam.TestGroup(t, conn, p.GetPublicId()) - _ = iam.TestGroupRole(t, conn, prWithGroup.GetPublicId(), assignedPG.GetPublicId()) - - pg1 := iam.TestGroup(t, conn, p.GetPublicId()) - pg2 := iam.TestGroup(t, conn, p.GetPublicId()) - s, err := roles.NewService(repoFn) require.NoError(t, err, "Error when getting new role service.") - cases := []struct { - name string - req *pbs.AddRolePrincipalsRequest - res *pbs.AddRolePrincipalsResponse - errCode codes.Code + o, p := iam.TestScopes(t, conn) + users := []*iam.User{ + iam.TestUser(t, conn, o.GetPublicId()), + iam.TestUser(t, conn, o.GetPublicId()), + iam.TestUser(t, conn, o.GetPublicId()), + } + groups := []*iam.Group{ + iam.TestGroup(t, conn, o.GetPublicId()), + iam.TestGroup(t, conn, o.GetPublicId()), + iam.TestGroup(t, conn, o.GetPublicId()), + } + + addCases := []struct { + name string + setup func(*iam.Role) + addUsers []string + addGroups []string + resultUsers []string + resultGroups []string + wantErr bool }{ { - name: "Add User Empty Org Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: orUserEmpty.GetScopeId(), - RoleId: orUserEmpty.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orUserEmpty.GetVersion()}, - }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orUserEmpty.GetPublicId(), - CreatedTime: orUserEmpty.GetCreateTime().GetTimestamp(), - Version: orUserEmpty.GetVersion() + 1, - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orUserEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, + name: "Add user on empty role", + setup: func(r *iam.Role) {}, + addUsers: []string{users[1].GetPublicId()}, + resultUsers: []string{users[1].GetPublicId()}, }, { - name: "Add User Populated Org Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: orWithUser.GetScopeId(), - RoleId: orWithUser.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orWithUser.GetVersion()}, + name: "Add user on populated role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orWithUser.GetPublicId(), - CreatedTime: orWithUser.GetCreateTime().GetTimestamp(), - Version: orWithUser.GetVersion() + 1, - UserIds: []string{assignedUser.GetPublicId(), ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orWithUser.GetScopeId()}, - }, - }, - errCode: codes.OK, + addUsers: []string{users[1].GetPublicId()}, + resultUsers: []string{users[0].GetPublicId(), users[1].GetPublicId()}, }, { - name: "Add User Empty Project Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prUserEmpty.GetScopeId(), - RoleId: prUserEmpty.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prUserEmpty.GetVersion()}, + name: "Add empty on populated role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) + iam.TestUserRole(t, conn, r.GetPublicId(), users[1].GetPublicId()) }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prUserEmpty.GetPublicId(), - CreatedTime: prUserEmpty.GetCreateTime().GetTimestamp(), - Version: prUserEmpty.GetVersion() + 1, - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prUserEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, + wantErr: true, }, { - name: "Add User Populated Project Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prWithUser.GetScopeId(), - RoleId: prWithUser.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithUser.GetVersion()}, - }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prWithUser.GetPublicId(), - CreatedTime: prWithUser.GetCreateTime().GetTimestamp(), - Version: prWithUser.GetVersion() + 1, - UserIds: []string{assignedUser.GetPublicId(), ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prWithUser.GetScopeId()}, - }, - }, - errCode: codes.OK, + name: "Add group on empty role", + setup: func(r *iam.Role) {}, + addGroups: []string{groups[1].GetPublicId()}, + resultGroups: []string{groups[1].GetPublicId()}, }, { - name: "Add Group Empty Org Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: orGroupEmpty.GetScopeId(), - RoleId: orGroupEmpty.GetPublicId(), - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orGroupEmpty.GetVersion()}, + name: "Add group on populated role", + setup: func(r *iam.Role) { + iam.TestGroupRole(t, conn, r.GetPublicId(), groups[0].GetPublicId()) }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orGroupEmpty.GetPublicId(), - CreatedTime: orGroupEmpty.GetCreateTime().GetTimestamp(), - Version: orGroupEmpty.GetVersion() + 1, - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orGroupEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Add Group Populated Org Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: orWithGroup.GetScopeId(), - RoleId: orWithGroup.GetPublicId(), - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orWithGroup.GetVersion()}, - }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orWithGroup.GetPublicId(), - CreatedTime: orWithGroup.GetCreateTime().GetTimestamp(), - Version: orWithGroup.GetVersion() + 1, - GroupIds: []string{assignedOG.GetPublicId(), og1.GetPublicId(), og2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orWithGroup.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Add Group Empty Project Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prGroupEmpty.GetScopeId(), - RoleId: prGroupEmpty.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prGroupEmpty.GetVersion()}, - }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prGroupEmpty.GetPublicId(), - CreatedTime: prGroupEmpty.GetCreateTime().GetTimestamp(), - Version: prGroupEmpty.GetVersion() + 1, - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prGroupEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Add Group Populated Project Role", - req: &pbs.AddRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prWithGroup.GetScopeId(), - RoleId: prWithGroup.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, - }, - res: &pbs.AddRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prWithGroup.GetPublicId(), - CreatedTime: prWithGroup.GetCreateTime().GetTimestamp(), - Version: prWithGroup.GetVersion() + 1, - GroupIds: []string{assignedPG.GetPublicId(), pg1.GetPublicId(), pg2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prWithGroup.GetScopeId()}, - }, - }, - errCode: codes.OK, + addGroups: []string{groups[1].GetPublicId()}, + resultGroups: []string{groups[0].GetPublicId(), groups[1].GetPublicId()}, }, + } + + for _, tc := range addCases { + for _, scope := range []*iam.Scope{o, p} { + t.Run(tc.name+"_"+scope.GetType(), func(t *testing.T) { + role := iam.TestRole(t, conn, scope.GetPublicId()) + tc.setup(role) + req := &pbs.AddRolePrincipalsRequest{ + OrgId: o.GetPublicId(), + RoleId: role.GetPublicId(), + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + UserIds: tc.addUsers, + GroupIds: tc.addGroups, + } + + got, err := s.AddRolePrincipals(context.Background(), req) + if tc.wantErr { + assert.Error(t, err) + return + } + s, ok := status.FromError(err) + require.True(t, ok) + require.NoError(t, err, "Got error: %v", s) + + assert.ElementsMatch(t, got.GetItem().GetUserIds(), tc.resultUsers) + assert.ElementsMatch(t, got.GetItem().GetGroupIds(), tc.resultGroups) + }) + } + } + + role := iam.TestRole(t, conn, p.GetPublicId()) + + failCases := []struct { + name string + req *pbs.AddRolePrincipalsRequest + errCode codes.Code + }{ { name: "Bad Org Id", req: &pbs.AddRolePrincipalsRequest{ OrgId: "", - ProjectId: prWithGroup.GetScopeId(), - RoleId: prWithGroup.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, + ProjectId: role.GetScopeId(), + RoleId: role.GetPublicId(), + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, { @@ -1039,43 +936,29 @@ func TestAddPrincipal(t *testing.T) { req: &pbs.AddRolePrincipalsRequest{ OrgId: o.GetPublicId(), ProjectId: "bad id", - RoleId: prWithGroup.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, + RoleId: role.GetPublicId(), + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, { name: "Bad Role Id", req: &pbs.AddRolePrincipalsRequest{ OrgId: o.GetPublicId(), - ProjectId: prWithGroup.GetScopeId(), + ProjectId: role.GetScopeId(), RoleId: "bad id", - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, } - for _, tc := range cases { + for _, tc := range failCases { t.Run(tc.name, func(t *testing.T) { assert := assert.New(t) - got, gErr := s.AddRolePrincipals(context.Background(), tc.req) + _, gErr := s.AddRolePrincipals(context.Background(), tc.req) assert.Equal(tc.errCode, status.Code(gErr), "AddRolePrincipals(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) - - if tc.res == nil { - require.Nil(t, got) - return - } - got.Item.UpdatedTime = nil - sort.Strings(got.Item.UserIds) - sort.Strings(got.Item.GroupIds) - sort.Strings(tc.res.Item.UserIds) - sort.Strings(tc.res.Item.GroupIds) - assert.Emptyf(cmp.Diff(tc.res, got, protocmp.Transform()), - "AddRolePrincipals(%+v) got\nresponse\n%v,\nwanted\n%v", tc.req, got, tc.res) }) } } @@ -1087,212 +970,113 @@ func TestSetPrincipal(t *testing.T) { repoFn := func() (*iam.Repository, error) { return iam.NewRepository(rw, rw, wrap) } - o, p := iam.TestScopes(t, conn) - - orUserEmpty := iam.TestRole(t, conn, o.GetPublicId()) - prUserEmpty := iam.TestRole(t, conn, p.GetPublicId()) - orGroupEmpty := iam.TestRole(t, conn, o.GetPublicId()) - prGroupEmpty := iam.TestRole(t, conn, p.GetPublicId()) - - orWithUser := iam.TestRole(t, conn, o.GetPublicId()) - assignedUser := iam.TestUser(t, conn, o.GetPublicId()) - _ = iam.TestUserRole(t, conn, orWithUser.GetPublicId(), assignedUser.GetPublicId()) - - ou1 := iam.TestUser(t, conn, o.GetPublicId()) - ou2 := iam.TestUser(t, conn, o.GetPublicId()) - - orWithGroup := iam.TestRole(t, conn, o.GetPublicId()) - assignedOG := iam.TestGroup(t, conn, o.GetPublicId()) - _ = iam.TestGroupRole(t, conn, orWithGroup.GetPublicId(), assignedOG.GetPublicId()) - - og1 := iam.TestGroup(t, conn, o.GetPublicId()) - og2 := iam.TestGroup(t, conn, o.GetPublicId()) - - prWithUser := iam.TestRole(t, conn, p.GetPublicId()) - _ = iam.TestUserRole(t, conn, prWithUser.GetPublicId(), assignedUser.GetPublicId()) - - prWithGroup := iam.TestRole(t, conn, p.GetPublicId()) - assignedPG := iam.TestGroup(t, conn, p.GetPublicId()) - _ = iam.TestGroupRole(t, conn, prWithGroup.GetPublicId(), assignedPG.GetPublicId()) - - pg1 := iam.TestGroup(t, conn, p.GetPublicId()) - pg2 := iam.TestGroup(t, conn, p.GetPublicId()) - s, err := roles.NewService(repoFn) require.NoError(t, err, "Error when getting new role service.") - cases := []struct { - name string - req *pbs.SetRolePrincipalsRequest - res *pbs.SetRolePrincipalsResponse - errCode codes.Code + o, p := iam.TestScopes(t, conn) + users := []*iam.User{ + iam.TestUser(t, conn, o.GetPublicId()), + iam.TestUser(t, conn, o.GetPublicId()), + iam.TestUser(t, conn, o.GetPublicId()), + } + groups := []*iam.Group{ + iam.TestGroup(t, conn, o.GetPublicId()), + iam.TestGroup(t, conn, o.GetPublicId()), + iam.TestGroup(t, conn, o.GetPublicId()), + } + + setCases := []struct { + name string + setup func(*iam.Role) + setUsers []string + setGroups []string + resultUsers []string + resultGroups []string + wantErr bool }{ { - name: "Set User Empty Org Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: orUserEmpty.GetScopeId(), - RoleId: orUserEmpty.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orUserEmpty.GetVersion()}, - }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orUserEmpty.GetPublicId(), - CreatedTime: orUserEmpty.GetCreateTime().GetTimestamp(), - Version: orUserEmpty.GetVersion() + 1, - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orUserEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, + name: "Set user on empty role", + setup: func(r *iam.Role) {}, + setUsers: []string{users[1].GetPublicId()}, + resultUsers: []string{users[1].GetPublicId()}, }, { - name: "Set User Populated Org Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: orWithUser.GetScopeId(), - RoleId: orWithUser.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orWithUser.GetVersion()}, + name: "Set user on populated role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orWithUser.GetPublicId(), - CreatedTime: orWithUser.GetCreateTime().GetTimestamp(), - Version: orWithUser.GetVersion() + 1, - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orWithUser.GetScopeId()}, - }, - }, - errCode: codes.OK, + setUsers: []string{users[1].GetPublicId()}, + resultUsers: []string{users[1].GetPublicId()}, }, { - name: "Set User Empty Project Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prUserEmpty.GetScopeId(), - RoleId: prUserEmpty.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prUserEmpty.GetVersion()}, + name: "Set empty on populated role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) + iam.TestUserRole(t, conn, r.GetPublicId(), users[1].GetPublicId()) }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prUserEmpty.GetPublicId(), - CreatedTime: prUserEmpty.GetCreateTime().GetTimestamp(), - Version: prUserEmpty.GetVersion() + 1, - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prUserEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, + setUsers: []string{}, + resultUsers: nil, }, { - name: "Set User Populated Project Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prWithUser.GetScopeId(), - RoleId: prWithUser.GetPublicId(), - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithUser.GetVersion()}, - }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prWithUser.GetPublicId(), - CreatedTime: prWithUser.GetCreateTime().GetTimestamp(), - Version: prWithUser.GetVersion() + 1, - UserIds: []string{ou1.GetPublicId(), ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prWithUser.GetScopeId()}, - }, - }, - errCode: codes.OK, + name: "Set group on empty role", + setup: func(r *iam.Role) {}, + setGroups: []string{groups[1].GetPublicId()}, + resultGroups: []string{groups[1].GetPublicId()}, }, { - name: "Set Group Empty Org Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: orGroupEmpty.GetScopeId(), - RoleId: orGroupEmpty.GetPublicId(), - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orGroupEmpty.GetVersion()}, + name: "Set group on populated role", + setup: func(r *iam.Role) { + iam.TestGroupRole(t, conn, r.GetPublicId(), groups[0].GetPublicId()) }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orGroupEmpty.GetPublicId(), - CreatedTime: orGroupEmpty.GetCreateTime().GetTimestamp(), - Version: orGroupEmpty.GetVersion() + 1, - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orGroupEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Set Group Populated Org Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: orWithGroup.GetScopeId(), - RoleId: orWithGroup.GetPublicId(), - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orWithGroup.GetVersion()}, - }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orWithGroup.GetPublicId(), - CreatedTime: orWithGroup.GetCreateTime().GetTimestamp(), - Version: orWithGroup.GetVersion() + 1, - GroupIds: []string{og1.GetPublicId(), og2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orWithGroup.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Set Group Empty Project Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prGroupEmpty.GetScopeId(), - RoleId: prGroupEmpty.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prGroupEmpty.GetVersion()}, - }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prGroupEmpty.GetPublicId(), - CreatedTime: prGroupEmpty.GetCreateTime().GetTimestamp(), - Version: prGroupEmpty.GetVersion() + 1, - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prGroupEmpty.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Set Group Populated Project Role", - req: &pbs.SetRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: prWithGroup.GetScopeId(), - RoleId: prWithGroup.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, - }, - res: &pbs.SetRolePrincipalsResponse{ - Item: &pb.Role{ - Id: prWithGroup.GetPublicId(), - CreatedTime: prWithGroup.GetCreateTime().GetTimestamp(), - Version: prWithGroup.GetVersion() + 1, - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: prWithGroup.GetScopeId()}, - }, - }, - errCode: codes.OK, + setGroups: []string{groups[1].GetPublicId()}, + resultGroups: []string{groups[1].GetPublicId()}, }, + } + + for _, tc := range setCases { + for _, scope := range []*iam.Scope{o, p} { + t.Run(tc.name+"_"+scope.GetType(), func(t *testing.T) { + role := iam.TestRole(t, conn, scope.GetPublicId()) + tc.setup(role) + req := &pbs.SetRolePrincipalsRequest{ + OrgId: o.GetPublicId(), + RoleId: role.GetPublicId(), + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + UserIds: tc.setUsers, + GroupIds: tc.setGroups, + } + + got, err := s.SetRolePrincipals(context.Background(), req) + if tc.wantErr { + assert.Error(t, err) + return + } + s, ok := status.FromError(err) + require.True(t, ok) + require.NoError(t, err, "Got error: %v", s) + + assert.Equal(t, got.GetItem().GetUserIds(), tc.resultUsers) + assert.Equal(t, got.GetItem().GetGroupIds(), tc.resultGroups) + }) + } + } + + role := iam.TestRole(t, conn, p.GetPublicId()) + + failCases := []struct { + name string + req *pbs.SetRolePrincipalsRequest + errCode codes.Code + }{ { name: "Bad Org Id", req: &pbs.SetRolePrincipalsRequest{ OrgId: "", - ProjectId: prWithGroup.GetScopeId(), - RoleId: prWithGroup.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, + ProjectId: role.GetScopeId(), + RoleId: role.GetPublicId(), + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, { @@ -1300,43 +1084,29 @@ func TestSetPrincipal(t *testing.T) { req: &pbs.SetRolePrincipalsRequest{ OrgId: o.GetPublicId(), ProjectId: "bad id", - RoleId: prWithGroup.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, + RoleId: role.GetPublicId(), + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, { name: "Bad Role Id", req: &pbs.SetRolePrincipalsRequest{ OrgId: o.GetPublicId(), - ProjectId: prWithGroup.GetScopeId(), + ProjectId: role.GetScopeId(), RoleId: "bad id", - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: prWithGroup.GetVersion()}, + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, } - for _, tc := range cases { + for _, tc := range failCases { t.Run(tc.name, func(t *testing.T) { assert := assert.New(t) - got, gErr := s.SetRolePrincipals(context.Background(), tc.req) - assert.Equal(tc.errCode, status.Code(gErr), "AddRolePrincipals(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) - - if tc.res == nil { - require.Nil(t, got) - return - } - got.Item.UpdatedTime = nil - sort.Strings(got.Item.UserIds) - sort.Strings(got.Item.GroupIds) - sort.Strings(tc.res.Item.UserIds) - sort.Strings(tc.res.Item.GroupIds) - assert.Emptyf(cmp.Diff(tc.res, got, protocmp.Transform()), - "AddRolePrincipals(%+v) got response %v, wanted %v", tc.req, got, tc.res) + _, gErr := s.SetRolePrincipals(context.Background(), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "SetRolePrincipals(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) }) } } @@ -1348,195 +1118,525 @@ func TestRemovePrincipal(t *testing.T) { repoFn := func() (*iam.Repository, error) { return iam.NewRepository(rw, rw, wrap) } - o, p := iam.TestScopes(t, conn) - - orgEmptyRole := iam.TestRole(t, conn, o.GetPublicId()) - orgUserRoles := iam.TestRole(t, conn, o.GetPublicId()) - orgGroupRoles := iam.TestRole(t, conn, o.GetPublicId()) - projEmptyRole := iam.TestRole(t, conn, p.GetPublicId()) - projUserRoles := iam.TestRole(t, conn, p.GetPublicId()) - projGroupRoles := iam.TestRole(t, conn, p.GetPublicId()) - - ou1 := iam.TestUser(t, conn, o.GetPublicId()) - ou2 := iam.TestUser(t, conn, o.GetPublicId()) - _ = iam.TestUserRole(t, conn, orgUserRoles.GetPublicId(), ou1.GetPublicId()) - _ = iam.TestUserRole(t, conn, orgUserRoles.GetPublicId(), ou2.GetPublicId()) - _ = iam.TestUserRole(t, conn, projUserRoles.GetPublicId(), ou1.GetPublicId()) - _ = iam.TestUserRole(t, conn, projUserRoles.GetPublicId(), ou2.GetPublicId()) - - og1 := iam.TestGroup(t, conn, o.GetPublicId()) - og2 := iam.TestGroup(t, conn, o.GetPublicId()) - _ = iam.TestGroupRole(t, conn, orgGroupRoles.GetPublicId(), og1.GetPublicId()) - _ = iam.TestGroupRole(t, conn, orgGroupRoles.GetPublicId(), og2.GetPublicId()) - - pg1 := iam.TestGroup(t, conn, p.GetPublicId()) - pg2 := iam.TestGroup(t, conn, p.GetPublicId()) - _ = iam.TestGroupRole(t, conn, projGroupRoles.GetPublicId(), pg1.GetPublicId()) - _ = iam.TestGroupRole(t, conn, projGroupRoles.GetPublicId(), pg2.GetPublicId()) - s, err := roles.NewService(repoFn) require.NoError(t, err, "Error when getting new role service.") - cases := []struct { + o, p := iam.TestScopes(t, conn) + users := []*iam.User{ + iam.TestUser(t, conn, o.GetPublicId()), + iam.TestUser(t, conn, o.GetPublicId()), + iam.TestUser(t, conn, o.GetPublicId()), + } + groups := []*iam.Group{ + iam.TestGroup(t, conn, o.GetPublicId()), + iam.TestGroup(t, conn, o.GetPublicId()), + iam.TestGroup(t, conn, o.GetPublicId()), + } + + addCases := []struct { + name string + setup func(*iam.Role) + removeUsers []string + removeGroups []string + resultUsers []string + resultGroups []string + wantErr bool + }{ + { + name: "Remove user on empty role", + setup: func(r *iam.Role) {}, + removeUsers: []string{users[1].GetPublicId()}, + wantErr: true, + }, + { + name: "Remove 1 of 2 users from role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) + iam.TestUserRole(t, conn, r.GetPublicId(), users[1].GetPublicId()) + }, + removeUsers: []string{users[1].GetPublicId()}, + resultUsers: []string{users[0].GetPublicId()}, + }, + { + name: "Remove all users from role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) + iam.TestUserRole(t, conn, r.GetPublicId(), users[1].GetPublicId()) + }, + removeUsers: []string{users[0].GetPublicId(), users[1].GetPublicId()}, + resultUsers: []string{}, + }, + { + name: "Remove empty on populated role", + setup: func(r *iam.Role) { + iam.TestUserRole(t, conn, r.GetPublicId(), users[0].GetPublicId()) + }, + wantErr: true, + }, + { + name: "Remove group on empty role", + setup: func(r *iam.Role) {}, + removeGroups: []string{groups[1].GetPublicId()}, + wantErr: true, + }, + { + name: "Remove 1 of 2 groups from role", + setup: func(r *iam.Role) { + iam.TestGroupRole(t, conn, r.GetPublicId(), groups[0].GetPublicId()) + iam.TestGroupRole(t, conn, r.GetPublicId(), groups[1].GetPublicId()) + }, + removeGroups: []string{groups[1].GetPublicId()}, + resultGroups: []string{groups[0].GetPublicId()}, + }, + { + name: "Remove all groups from role", + setup: func(r *iam.Role) { + iam.TestGroupRole(t, conn, r.GetPublicId(), groups[0].GetPublicId()) + iam.TestGroupRole(t, conn, r.GetPublicId(), groups[1].GetPublicId()) + }, + removeGroups: []string{groups[0].GetPublicId(), groups[1].GetPublicId()}, + resultGroups: []string{}, + }, + } + + for _, tc := range addCases { + for _, scope := range []*iam.Scope{o, p} { + t.Run(tc.name+"_"+scope.GetType(), func(t *testing.T) { + role := iam.TestRole(t, conn, scope.GetPublicId()) + tc.setup(role) + req := &pbs.RemoveRolePrincipalsRequest{ + OrgId: o.GetPublicId(), + RoleId: role.GetPublicId(), + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + UserIds: tc.removeUsers, + GroupIds: tc.removeGroups, + } + + got, err := s.RemoveRolePrincipals(context.Background(), req) + if tc.wantErr { + assert.Error(t, err) + return + } + s, ok := status.FromError(err) + require.True(t, ok) + require.NoError(t, err, "Got error: %v", s) + + assert.ElementsMatch(t, got.GetItem().GetUserIds(), tc.resultUsers) + assert.ElementsMatch(t, got.GetItem().GetGroupIds(), tc.resultGroups) + }) + } + } + + role := iam.TestRole(t, conn, p.GetPublicId()) + + failCases := []struct { name string - req *pbs.RemoveRolePrincipalsRequest - res *pbs.RemoveRolePrincipalsResponse + req *pbs.AddRolePrincipalsRequest errCode codes.Code }{ - { - name: "Remove User From Org Role", - req: &pbs.RemoveRolePrincipalsRequest{ - OrgId: orgUserRoles.GetScopeId(), - RoleId: orgUserRoles.GetPublicId(), - UserIds: []string{ou1.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orgUserRoles.GetVersion()}, - }, - res: &pbs.RemoveRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orgUserRoles.GetPublicId(), - CreatedTime: orgUserRoles.GetCreateTime().GetTimestamp(), - Version: orgUserRoles.GetVersion() + 1, - UserIds: []string{ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orgUserRoles.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Remove User From Proj Role", - req: &pbs.RemoveRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: projUserRoles.GetScopeId(), - RoleId: projUserRoles.GetPublicId(), - UserIds: []string{ou1.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: projUserRoles.GetVersion()}, - }, - res: &pbs.RemoveRolePrincipalsResponse{ - Item: &pb.Role{ - Id: projUserRoles.GetPublicId(), - CreatedTime: projUserRoles.GetCreateTime().GetTimestamp(), - Version: projUserRoles.GetVersion() + 1, - UserIds: []string{ou2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: projUserRoles.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Remove Group From Org Role", - req: &pbs.RemoveRolePrincipalsRequest{ - OrgId: orgGroupRoles.GetScopeId(), - RoleId: orgGroupRoles.GetPublicId(), - GroupIds: []string{og1.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orgGroupRoles.GetVersion()}, - }, - res: &pbs.RemoveRolePrincipalsResponse{ - Item: &pb.Role{ - Id: orgGroupRoles.GetPublicId(), - CreatedTime: orgGroupRoles.GetCreateTime().GetTimestamp(), - Version: orgGroupRoles.GetVersion() + 1, - GroupIds: []string{og2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: orgGroupRoles.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - { - name: "Remove Group From Proj Role", - req: &pbs.RemoveRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: projGroupRoles.GetScopeId(), - RoleId: projGroupRoles.GetPublicId(), - GroupIds: []string{pg1.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: projGroupRoles.GetVersion()}, - }, - res: &pbs.RemoveRolePrincipalsResponse{ - Item: &pb.Role{ - Id: projGroupRoles.GetPublicId(), - CreatedTime: projGroupRoles.GetCreateTime().GetTimestamp(), - Version: projGroupRoles.GetVersion() + 1, - GroupIds: []string{pg2.GetPublicId()}, - GrantScopeId: &wrapperspb.StringValue{Value: projGroupRoles.GetScopeId()}, - }, - }, - errCode: codes.OK, - }, - // TODO: Should it be a silent noop to remove a principal from a role when the principal isn't on the role? - { - name: "Remove From Empty Org Role", - req: &pbs.RemoveRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - RoleId: orgEmptyRole.GetPublicId(), - UserIds: []string{ou1.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: orgEmptyRole.GetVersion()}, - }, - errCode: codes.Internal, - }, - { - name: "Remove From Empty Project Role", - req: &pbs.RemoveRolePrincipalsRequest{ - OrgId: o.GetPublicId(), - ProjectId: projEmptyRole.GetScopeId(), - RoleId: projEmptyRole.GetPublicId(), - UserIds: []string{ou1.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: projEmptyRole.GetVersion()}, - }, - errCode: codes.Internal, - }, { name: "Bad Org Id", - req: &pbs.RemoveRolePrincipalsRequest{ + req: &pbs.AddRolePrincipalsRequest{ OrgId: "", - ProjectId: projGroupRoles.GetScopeId(), - RoleId: projGroupRoles.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: projGroupRoles.GetVersion()}, + ProjectId: role.GetScopeId(), + RoleId: role.GetPublicId(), + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, { name: "Bad Project Id", - req: &pbs.RemoveRolePrincipalsRequest{ + req: &pbs.AddRolePrincipalsRequest{ OrgId: o.GetPublicId(), ProjectId: "bad id", - RoleId: projGroupRoles.GetPublicId(), - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: projGroupRoles.GetVersion()}, + RoleId: role.GetPublicId(), + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, { name: "Bad Role Id", - req: &pbs.RemoveRolePrincipalsRequest{ + req: &pbs.AddRolePrincipalsRequest{ OrgId: o.GetPublicId(), - ProjectId: projGroupRoles.GetScopeId(), + ProjectId: role.GetScopeId(), RoleId: "bad id", - GroupIds: []string{pg1.GetPublicId(), pg2.GetPublicId()}, - Version: &wrapperspb.UInt32Value{Value: projGroupRoles.GetVersion()}, + GroupIds: []string{}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, }, - res: nil, errCode: codes.InvalidArgument, }, } - for _, tc := range cases { + for _, tc := range failCases { t.Run(tc.name, func(t *testing.T) { assert := assert.New(t) - got, gErr := s.RemoveRolePrincipals(context.Background(), tc.req) + _, gErr := s.AddRolePrincipals(context.Background(), tc.req) assert.Equal(tc.errCode, status.Code(gErr), "AddRolePrincipals(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) - - if tc.res == nil { - require.Nil(t, got) - return - } - got.Item.UpdatedTime = nil - sort.Strings(got.Item.UserIds) - sort.Strings(got.Item.GroupIds) - sort.Strings(tc.res.Item.UserIds) - sort.Strings(tc.res.Item.GroupIds) - assert.Emptyf(cmp.Diff(tc.res, got, protocmp.Transform()), - "AddRolePrincipals(%+v) got response %v, wanted %v", tc.req, got, tc.res) + }) + } +} + +func TestAddGrants(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + wrap := db.TestWrapper(t) + repoFn := func() (*iam.Repository, error) { + return iam.NewRepository(rw, rw, wrap) + } + s, err := roles.NewService(repoFn) + require.NoError(t, err, "Error when getting new role service.") + + addCases := []struct { + name string + existing []string + add []string + result []string + wantErr bool + }{ + { + name: "Add grant on empty role", + add: []string{"id=*;actions=delete"}, + result: []string{"id=*;actions=delete"}, + }, + { + name: "Add grant on role with grant", + existing: []string{"id=1;actions=read"}, + add: []string{"id=*;actions=delete"}, + result: []string{"id=1;actions=read", "id=*;actions=delete"}, + }, + { + name: "Add grant matching existing grant", + existing: []string{"id=1;actions=read", "id=*;actions=delete"}, + add: []string{"id=*;actions=delete"}, + wantErr: true, + }, + } + + for _, tc := range addCases { + o, p := iam.TestScopes(t, conn) + for _, scope := range []*iam.Scope{o, p} { + t.Run(tc.name+"_"+scope.Type, func(t *testing.T) { + assert := assert.New(t) + role := iam.TestRole(t, conn, scope.GetPublicId()) + for _, e := range tc.existing { + _ = iam.TestRoleGrant(t, conn, role.GetPublicId(), e) + } + req := &pbs.AddRoleGrantsRequest{ + OrgId: o.GetPublicId(), + RoleId: role.GetPublicId(), + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + } + if o != scope { + req.ProjectId = scope.GetPublicId() + } + req.Grants = append(req.Grants, tc.add...) + got, err := s.AddRoleGrants(context.Background(), req) + if tc.wantErr { + assert.Error(err) + return + } + s, _ := status.FromError(err) + require.NoError(t, err, "Got error %v", s) + assert.Equal(tc.result, got.GetItem().GetGrants()) + }) + } + } + + o, p := iam.TestScopes(t, conn) + role := iam.TestRole(t, conn, p.GetPublicId()) + failCases := []struct { + name string + req *pbs.AddRoleGrantsRequest + errCode codes.Code + }{ + { + name: "Bad Org Id", + req: &pbs.AddRoleGrantsRequest{ + OrgId: "", + ProjectId: role.GetScopeId(), + RoleId: role.GetPublicId(), + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Project Id", + req: &pbs.AddRoleGrantsRequest{ + OrgId: o.GetPublicId(), + ProjectId: "bad id", + RoleId: role.GetPublicId(), + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Role Id", + req: &pbs.AddRoleGrantsRequest{ + OrgId: o.GetPublicId(), + ProjectId: role.GetScopeId(), + RoleId: "bad id", + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range failCases { + t.Run(tc.name, func(t *testing.T) { + assert := assert.New(t) + _, gErr := s.AddRoleGrants(context.Background(), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "AddRoleGrants(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + }) + } +} + +func TestSetGrants(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + wrap := db.TestWrapper(t) + repoFn := func() (*iam.Repository, error) { + return iam.NewRepository(rw, rw, wrap) + } + + s, err := roles.NewService(repoFn) + require.NoError(t, err, "Error when getting new role service.") + + setCases := []struct { + name string + existing []string + set []string + result []string + wantErr bool + }{ + { + name: "Set grant on empty role", + set: []string{"id=*;actions=delete"}, + result: []string{"id=*;actions=delete"}, + }, + { + name: "Set grant on role with grant", + existing: []string{"id=1;actions=read"}, + set: []string{"id=*;actions=delete"}, + result: []string{"id=*;actions=delete"}, + }, + { + name: "Set grant matching existing grant", + existing: []string{"id=1;actions=read", "id=*;actions=delete"}, + set: []string{"id=*;actions=delete"}, + result: []string{"id=*;actions=delete"}, + }, + { + name: "Set empty on role", + existing: []string{"id=1;actions=read", "id=*;actions=delete"}, + set: nil, + result: nil, + }, + } + + for _, tc := range setCases { + o, p := iam.TestScopes(t, conn) + for _, scope := range []*iam.Scope{o, p} { + t.Run(tc.name+"_"+scope.Type, func(t *testing.T) { + assert := assert.New(t) + role := iam.TestRole(t, conn, scope.GetPublicId()) + for _, e := range tc.existing { + _ = iam.TestRoleGrant(t, conn, role.GetPublicId(), e) + } + req := &pbs.SetRoleGrantsRequest{ + OrgId: o.GetPublicId(), + RoleId: role.GetPublicId(), + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + } + if o != scope { + req.ProjectId = scope.GetPublicId() + } + req.Grants = append(req.Grants, tc.set...) + got, err := s.SetRoleGrants(context.Background(), req) + if tc.wantErr { + assert.Error(err) + return + } + s, _ := status.FromError(err) + require.NoError(t, err, "Got error %v", s) + assert.Equal(tc.result, got.GetItem().GetGrants()) + }) + } + } + + o, p := iam.TestScopes(t, conn) + role := iam.TestRole(t, conn, p.GetPublicId()) + + failCases := []struct { + name string + req *pbs.SetRoleGrantsRequest + errCode codes.Code + }{ + { + name: "Bad Org Id", + req: &pbs.SetRoleGrantsRequest{ + OrgId: "", + ProjectId: role.GetScopeId(), + RoleId: role.GetPublicId(), + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Project Id", + req: &pbs.SetRoleGrantsRequest{ + OrgId: o.GetPublicId(), + ProjectId: "bad id", + RoleId: role.GetPublicId(), + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Role Id", + req: &pbs.SetRoleGrantsRequest{ + OrgId: o.GetPublicId(), + ProjectId: role.GetScopeId(), + RoleId: "bad id", + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range failCases { + t.Run(tc.name, func(t *testing.T) { + assert := assert.New(t) + _, gErr := s.SetRoleGrants(context.Background(), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "SetRoleGrants(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) + }) + } +} + +func TestRemoveGrants(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + wrap := db.TestWrapper(t) + repoFn := func() (*iam.Repository, error) { + return iam.NewRepository(rw, rw, wrap) + } + s, err := roles.NewService(repoFn) + require.NoError(t, err, "Error when getting new role service.") + + removeCases := []struct { + name string + existing []string + remove []string + result []string + wantErr bool + }{ + { + name: "Remove all", + existing: []string{"id=1;actions=read"}, + remove: []string{"id=1;actions=read"}, + }, + { + name: "Remove partial", + existing: []string{"id=1;actions=read", "id=2;actions=delete"}, + remove: []string{"id=1;actions=read"}, + result: []string{"id=2;actions=delete"}, + }, + { + name: "Remove non existant", + existing: []string{"id=2;actions=delete"}, + remove: []string{"id=1;actions=read"}, + result: []string{"id=2;actions=delete"}, + }, + { + name: "Remove from empty role", + existing: []string{}, + remove: []string{"id=1;actions=read"}, + result: nil, + }, + } + + for _, tc := range removeCases { + o, p := iam.TestScopes(t, conn) + for _, scope := range []*iam.Scope{o, p} { + t.Run(tc.name+"_"+scope.Type, func(t *testing.T) { + assert := assert.New(t) + role := iam.TestRole(t, conn, scope.GetPublicId()) + for _, e := range tc.existing { + _ = iam.TestRoleGrant(t, conn, role.GetPublicId(), e) + } + req := &pbs.RemoveRoleGrantsRequest{ + OrgId: o.GetPublicId(), + RoleId: role.GetPublicId(), + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + } + if o != scope { + req.ProjectId = scope.GetPublicId() + } + req.Grants = append(req.Grants, tc.remove...) + got, err := s.RemoveRoleGrants(context.Background(), req) + if tc.wantErr { + assert.Error(err) + return + } + s, ok := status.FromError(err) + assert.True(ok) + require.NoError(t, err, "Got error %v", s) + assert.Equal(tc.result, got.GetItem().GetGrants()) + }) + } + } + + o, p := iam.TestScopes(t, conn) + role := iam.TestRole(t, conn, p.GetPublicId()) + failCases := []struct { + name string + req *pbs.RemoveRoleGrantsRequest + + errCode codes.Code + }{ + { + name: "Bad Org Id", + req: &pbs.RemoveRoleGrantsRequest{ + OrgId: "", + ProjectId: role.GetScopeId(), + RoleId: role.GetPublicId(), + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Project Id", + req: &pbs.RemoveRoleGrantsRequest{ + OrgId: o.GetPublicId(), + ProjectId: "bad id", + RoleId: role.GetPublicId(), + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + { + name: "Bad Role Id", + req: &pbs.RemoveRoleGrantsRequest{ + OrgId: o.GetPublicId(), + ProjectId: role.GetScopeId(), + RoleId: "bad id", + Grants: []string{"id=*;actions=create"}, + Version: &wrapperspb.UInt32Value{Value: role.GetVersion()}, + }, + errCode: codes.InvalidArgument, + }, + } + for _, tc := range failCases { + t.Run(tc.name, func(t *testing.T) { + assert := assert.New(t) + _, gErr := s.RemoveRoleGrants(context.Background(), tc.req) + assert.Equal(tc.errCode, status.Code(gErr), "RemoveRoleGrants(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode) }) } }