-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #91 from code0-tech/assign-abilities-to-roles
Add mutation to assign abilities to roles
- Loading branch information
Showing
16 changed files
with
335 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# frozen_string_literal: true | ||
|
||
module Mutations | ||
module TeamRoles | ||
class AssignAbilities < BaseMutation | ||
description 'Update the abilities a role is granted.' | ||
|
||
field :abilities, [Types::TeamRoleAbilityEnum], description: 'The now granted abilities' | ||
|
||
argument :abilities, [Types::TeamRoleAbilityEnum], | ||
description: 'The abilities that should be granted to the ability' | ||
argument :role_id, Types::GlobalIdType[::TeamRole], | ||
description: 'The id of the role which should be granted the abilities' | ||
|
||
def resolve(role_id:, abilities:) | ||
role = SagittariusSchema.object_from_id(role_id) | ||
|
||
return { abilities: nil, errors: [create_message_error('Invalid role')] } if role.nil? | ||
|
||
::TeamRoles::AssignAbilitiesService.new( | ||
current_user, | ||
role, | ||
abilities | ||
).execute.to_mutation_response(success_key: :abilities) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
|
||
module Types | ||
class TeamRoleAbilityEnum < BaseEnum | ||
description 'Represents abilities that can be granted to roles in teams.' | ||
|
||
TeamRoleAbility::ABILITIES.each do |ability, settings| | ||
value ability.upcase, settings[:description], value: ability, **settings.except(:db, :description) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# frozen_string_literal: true | ||
|
||
module TeamRoles | ||
class AssignAbilitiesService | ||
include Sagittarius::Database::Transactional | ||
|
||
attr_reader :current_user, :role, :abilities | ||
|
||
def initialize(current_user, role, abilities) | ||
@current_user = current_user | ||
@role = role | ||
@abilities = abilities | ||
end | ||
|
||
def execute | ||
team = role.team | ||
unless Ability.allowed?(current_user, :assign_role_abilities, team) | ||
return ServiceResponse.error(message: 'Missing permissions', payload: :missing_permission) | ||
end | ||
|
||
transactional do |t| | ||
current_abilities = role.abilities | ||
old_abilities_for_audit_event = current_abilities.map(&:ability) | ||
|
||
current_abilities.where.not(ability: abilities).delete_all | ||
|
||
(abilities - current_abilities.map(&:ability)).map do |ability| | ||
team_role_ability = TeamRoleAbility.create(team_role: role, ability: ability) | ||
|
||
next if team_role_ability.persisted? | ||
|
||
t.rollback_and_return! ServiceResponse.error( | ||
message: 'Failed to save team role ability', | ||
payload: team_role_ability.errors | ||
) | ||
end | ||
|
||
new_abilities = role.reload.abilities.map(&:ability) | ||
|
||
AuditService.audit( | ||
:team_role_abilities_updated, | ||
author_id: current_user.id, | ||
entity: role, | ||
details: { | ||
old_abilities: old_abilities_for_audit_event, | ||
new_abilities: new_abilities, | ||
}, | ||
target: team | ||
) | ||
|
||
ServiceResponse.success(message: 'Role abilities updated', payload: new_abilities) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
title: TeamRoleAbility | ||
--- | ||
|
||
Represents abilities that can be granted to roles in teams. | ||
|
||
| Value | Description | | ||
|-------|-------------| | ||
| `ASSIGN_MEMBER_ROLES` | Allows to change the roles of a team member | | ||
| `ASSIGN_ROLE_ABILITIES` | Allows to change the abilities of a team role | | ||
| `CREATE_TEAM_ROLE` | Allows the creation of roles in a team | | ||
| `INVITE_MEMBER` | Allows to invite new members to a team | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
title: teamRolesAssignAbilities | ||
--- | ||
|
||
Update the abilities a role is granted. | ||
|
||
## Arguments | ||
|
||
| Name | Type | Description | | ||
|------|------|-------------| | ||
| `abilities` | [`[TeamRoleAbility!]!`](../enum/teamroleability.md) | The abilities that should be granted to the ability | | ||
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. | | ||
| `roleId` | [`TeamRoleID!`](../scalar/teamroleid.md) | The id of the role which should be granted the abilities | | ||
|
||
## Fields | ||
|
||
| Name | Type | Description | | ||
|------|------|-------------| | ||
| `abilities` | [`[TeamRoleAbility!]`](../enum/teamroleability.md) | The now granted abilities | | ||
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. | | ||
| `errors` | [`[Error!]!`](../union/error.md) | Errors encountered during execution of the mutation. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe Mutations::TeamRoles::AssignAbilities do | ||
it { expect(described_class.graphql_name).to eq('TeamRolesAssignAbilities') } | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
id | ||
team | ||
name | ||
abilities | ||
createdAt | ||
updatedAt | ||
] | ||
|
69 changes: 69 additions & 0 deletions
69
spec/requests/graphql/mutation/team_roles/assign_abilities_mutation_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe 'teamRolesAssignAbilities Mutation' do | ||
include GraphqlHelpers | ||
|
||
subject(:mutate!) { post_graphql mutation, variables: variables, current_user: current_user } | ||
|
||
let(:mutation) do | ||
<<~QUERY | ||
mutation($input: TeamRolesAssignAbilitiesInput!) { | ||
teamRolesAssignAbilities(input: $input) { | ||
#{error_query} | ||
abilities | ||
} | ||
} | ||
QUERY | ||
end | ||
|
||
let(:team_role) { create(:team_role) } | ||
let(:input) do | ||
{ | ||
roleId: team_role.to_global_id.to_s, | ||
abilities: ['CREATE_TEAM_ROLE'], | ||
} | ||
end | ||
|
||
let(:variables) { { input: input } } | ||
let(:current_user) { create(:user) } | ||
|
||
context 'when user has permission' do | ||
before do | ||
stub_allowed_ability(TeamPolicy, :assign_role_abilities, user: current_user, subject: team_role.team) | ||
end | ||
|
||
it 'assigns the given abilities to the role' do | ||
mutate! | ||
|
||
abilities = graphql_data_at(:team_roles_assign_abilities, :abilities) | ||
expect(abilities).to be_present | ||
expect(abilities).to be_a(Array) | ||
|
||
expect(abilities).to eq(['CREATE_TEAM_ROLE']) | ||
|
||
is_expected.to create_audit_event( | ||
:team_role_abilities_updated, | ||
author_id: current_user.id, | ||
entity_id: team_role.id, | ||
entity_type: 'TeamRole', | ||
details: { | ||
'new_abilities' => ['create_team_role'], | ||
'old_abilities' => [], | ||
}, | ||
target_id: team_role.team.id, | ||
target_type: 'Team' | ||
) | ||
end | ||
end | ||
|
||
context 'when user does not have permission' do | ||
it 'returns an error' do | ||
mutate! | ||
|
||
expect(graphql_data_at(:team_roles_assign_abilities, :abilities)).to be_nil | ||
expect(graphql_data_at(:team_roles_assign_abilities, :errors)).to include({ 'message' => 'missing_permission' }) | ||
end | ||
end | ||
end |
Oops, something went wrong.