diff options
author | Bob Van Landuyt <bob@vanlanduyt.co> | 2018-06-25 10:59:00 +0200 |
---|---|---|
committer | Bob Van Landuyt <bob@vanlanduyt.co> | 2018-06-28 13:50:17 +0200 |
commit | 54b56f20b7a70d3e6284c8105eb3d4a568e255b0 (patch) | |
tree | de18fca7bd27dcd55817e21c4654cf36c1430c5f /app/graphql | |
parent | 627236c9edd7f085ec5070ef7fcfbcbfc9b6de78 (diff) | |
download | gitlab-ce-54b56f20b7a70d3e6284c8105eb3d4a568e255b0.tar.gz |
Expose permissions on types in GraphQL
This adds a reusable way to expose permissions for a user to types in
GraphQL.
Diffstat (limited to 'app/graphql')
-rw-r--r-- | app/graphql/types/base_object.rb | 1 | ||||
-rw-r--r-- | app/graphql/types/merge_request_type.rb | 2 | ||||
-rw-r--r-- | app/graphql/types/permission_types/base_permission_type.rb | 38 | ||||
-rw-r--r-- | app/graphql/types/permission_types/merge_request.rb | 17 | ||||
-rw-r--r-- | app/graphql/types/permission_types/project.rb | 20 | ||||
-rw-r--r-- | app/graphql/types/project_type.rb | 2 |
6 files changed, 80 insertions, 0 deletions
diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index e033ef96ce9..754adf4c04d 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -1,6 +1,7 @@ module Types class BaseObject < GraphQL::Schema::Object prepend Gitlab::Graphql::Present + prepend Gitlab::Graphql::ExposePermissions field_class Types::BaseField end diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index d5d24952984..a1f3c0dd8c0 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -1,5 +1,7 @@ module Types class MergeRequestType < BaseObject + expose_permissions Types::PermissionTypes::MergeRequest + present_using MergeRequestPresenter graphql_name 'MergeRequest' diff --git a/app/graphql/types/permission_types/base_permission_type.rb b/app/graphql/types/permission_types/base_permission_type.rb new file mode 100644 index 00000000000..934ed572e56 --- /dev/null +++ b/app/graphql/types/permission_types/base_permission_type.rb @@ -0,0 +1,38 @@ +module Types + module PermissionTypes + class BasePermissionType < BaseObject + extend Gitlab::Allowable + + RESOLVING_KEYWORDS = [:resolver, :method, :hash_key, :function].to_set.freeze + + def self.abilities(*abilities) + abilities.each { |ability| ability_field(ability) } + end + + def self.ability_field(ability, **kword_args) + unless resolving_keywords?(kword_args) + kword_args[:resolve] ||= -> (object, args, context) do + can?(context[:current_user], ability, object, args.to_h) + end + end + + permission_field(ability, **kword_args) + end + + def self.permission_field(name, **kword_args) + kword_args = kword_args.reverse_merge( + name: name, + type: GraphQL::BOOLEAN_TYPE, + description: "Whether or not a user can perform `#{name}` on this resource", + null: false) + + field(**kword_args) + end + + def self.resolving_keywords?(arguments) + RESOLVING_KEYWORDS.intersect?(arguments.keys.to_set) + end + private_class_method :resolving_keywords? + end + end +end diff --git a/app/graphql/types/permission_types/merge_request.rb b/app/graphql/types/permission_types/merge_request.rb new file mode 100644 index 00000000000..5c21f6ee9c6 --- /dev/null +++ b/app/graphql/types/permission_types/merge_request.rb @@ -0,0 +1,17 @@ +module Types + module PermissionTypes + class MergeRequest < BasePermissionType + present_using MergeRequestPresenter + description 'Check permissions for the current user on a merge request' + graphql_name 'MergeRequestPermissions' + + abilities :read_merge_request, :admin_merge_request, + :update_merge_request, :create_note + + permission_field :push_to_source_branch, method: :can_push_to_source_branch? + permission_field :remove_source_branch, method: :can_remove_source_branch? + permission_field :cherry_pick_on_current_merge_request, method: :can_cherry_pick_on_current_merge_request? + permission_field :revert_on_current_merge_request, method: :can_revert_on_current_merge_request? + end + end +end diff --git a/app/graphql/types/permission_types/project.rb b/app/graphql/types/permission_types/project.rb new file mode 100644 index 00000000000..755699a4415 --- /dev/null +++ b/app/graphql/types/permission_types/project.rb @@ -0,0 +1,20 @@ +module Types + module PermissionTypes + class Project < BasePermissionType + graphql_name 'ProjectPermissions' + + abilities :change_namespace, :change_visibility_level, :rename_project, + :remove_project, :archive_project, :remove_fork_project, + :remove_pages, :read_project, :create_merge_request_in, + :read_wiki, :read_project_member, :create_issue, :upload_file, + :read_cycle_analytics, :download_code, :download_wiki_code, + :fork_project, :create_project_snippet, :read_commit_status, + :request_access, :create_pipeline, :create_pipeline_schedule, + :create_merge_request_from, :create_wiki, :push_code, + :create_deployment, :push_to_delete_protected_branch, + :admin_wiki, :admin_project, :update_pages, + :admin_remote_mirror, :create_label, :update_wiki, :destroy_wiki, + :create_pages, :destroy_pages + end + end +end diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index d9058ae7431..a832e8b4bde 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -1,5 +1,7 @@ module Types class ProjectType < BaseObject + expose_permissions Types::PermissionTypes::Project + graphql_name 'Project' field :id, GraphQL::ID_TYPE, null: false |