summaryrefslogtreecommitdiff
path: root/app/graphql
diff options
context:
space:
mode:
authorBob Van Landuyt <bob@vanlanduyt.co>2018-06-25 10:59:00 +0200
committerBob Van Landuyt <bob@vanlanduyt.co>2018-06-28 13:50:17 +0200
commit54b56f20b7a70d3e6284c8105eb3d4a568e255b0 (patch)
treede18fca7bd27dcd55817e21c4654cf36c1430c5f /app/graphql
parent627236c9edd7f085ec5070ef7fcfbcbfc9b6de78 (diff)
downloadgitlab-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.rb1
-rw-r--r--app/graphql/types/merge_request_type.rb2
-rw-r--r--app/graphql/types/permission_types/base_permission_type.rb38
-rw-r--r--app/graphql/types/permission_types/merge_request.rb17
-rw-r--r--app/graphql/types/permission_types/project.rb20
-rw-r--r--app/graphql/types/project_type.rb2
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