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) }) } }