summaryrefslogtreecommitdiff
path: root/app/graphql/mutations
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/mutations')
-rw-r--r--app/graphql/mutations/issues/base.rb34
-rw-r--r--app/graphql/mutations/issues/set_confidential.rb27
-rw-r--r--app/graphql/mutations/issues/set_due_date.rb27
-rw-r--r--app/graphql/mutations/snippets/base.rb30
-rw-r--r--app/graphql/mutations/snippets/create.rb77
-rw-r--r--app/graphql/mutations/snippets/destroy.rb33
-rw-r--r--app/graphql/mutations/snippets/mark_as_spam.rb39
-rw-r--r--app/graphql/mutations/snippets/update.rb54
-rw-r--r--app/graphql/mutations/todos/base.rb6
-rw-r--r--app/graphql/mutations/todos/mark_all_done.rb35
-rw-r--r--app/graphql/mutations/todos/mark_done.rb7
-rw-r--r--app/graphql/mutations/todos/restore.rb36
12 files changed, 401 insertions, 4 deletions
diff --git a/app/graphql/mutations/issues/base.rb b/app/graphql/mutations/issues/base.rb
new file mode 100644
index 00000000000..b7fa234a50b
--- /dev/null
+++ b/app/graphql/mutations/issues/base.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Issues
+ class Base < BaseMutation
+ include Mutations::ResolvesProject
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: "The project the issue to mutate is in"
+
+ argument :iid, GraphQL::STRING_TYPE,
+ required: true,
+ description: "The iid of the issue to mutate"
+
+ field :issue,
+ Types::IssueType,
+ null: true,
+ description: "The issue after mutation"
+
+ authorize :update_issue
+
+ private
+
+ def find_object(project_path:, iid:)
+ project = resolve_project(full_path: project_path)
+ resolver = Resolvers::IssuesResolver
+ .single.new(object: project, context: context)
+
+ resolver.resolve(iid: iid)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/issues/set_confidential.rb b/app/graphql/mutations/issues/set_confidential.rb
new file mode 100644
index 00000000000..0fff5518665
--- /dev/null
+++ b/app/graphql/mutations/issues/set_confidential.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Issues
+ class SetConfidential < Base
+ graphql_name 'IssueSetConfidential'
+
+ argument :confidential,
+ GraphQL::BOOLEAN_TYPE,
+ required: true,
+ description: 'Whether or not to set the issue as a confidential.'
+
+ def resolve(project_path:, iid:, confidential:)
+ issue = authorized_find!(project_path: project_path, iid: iid)
+ project = issue.project
+
+ ::Issues::UpdateService.new(project, current_user, confidential: confidential)
+ .execute(issue)
+
+ {
+ issue: issue,
+ errors: issue.errors.full_messages
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/issues/set_due_date.rb b/app/graphql/mutations/issues/set_due_date.rb
new file mode 100644
index 00000000000..1855c6f053b
--- /dev/null
+++ b/app/graphql/mutations/issues/set_due_date.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Issues
+ class SetDueDate < Base
+ graphql_name 'IssueSetDueDate'
+
+ argument :due_date,
+ Types::TimeType,
+ required: true,
+ description: 'The desired due date for the issue'
+
+ def resolve(project_path:, iid:, due_date:)
+ issue = authorized_find!(project_path: project_path, iid: iid)
+ project = issue.project
+
+ ::Issues::UpdateService.new(project, current_user, due_date: due_date)
+ .execute(issue)
+
+ {
+ issue: issue,
+ errors: issue.errors.full_messages
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/base.rb b/app/graphql/mutations/snippets/base.rb
new file mode 100644
index 00000000000..9dc6d49774e
--- /dev/null
+++ b/app/graphql/mutations/snippets/base.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Snippets
+ class Base < BaseMutation
+ field :snippet,
+ Types::SnippetType,
+ null: true,
+ description: 'The snippet after mutation'
+
+ private
+
+ def find_object(id:)
+ GitlabSchema.object_from_id(id)
+ end
+
+ def authorized_resource?(snippet)
+ Ability.allowed?(context[:current_user], ability_for(snippet), snippet)
+ end
+
+ def ability_for(snippet)
+ "#{ability_name}_#{snippet.to_ability_name}".to_sym
+ end
+
+ def ability_name
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
new file mode 100644
index 00000000000..fe1f543ea1a
--- /dev/null
+++ b/app/graphql/mutations/snippets/create.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Snippets
+ class Create < BaseMutation
+ include Mutations::ResolvesProject
+
+ graphql_name 'CreateSnippet'
+
+ field :snippet,
+ Types::SnippetType,
+ null: true,
+ description: 'The snippet after mutation'
+
+ argument :title, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Title of the snippet'
+
+ argument :file_name, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'File name of the snippet'
+
+ argument :content, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Content of the snippet'
+
+ argument :description, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Description of the snippet'
+
+ argument :visibility_level, Types::VisibilityLevelsEnum,
+ description: 'The visibility level of the snippet',
+ required: true
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: false,
+ description: 'The project full path the snippet is associated with'
+
+ def resolve(args)
+ project_path = args.delete(:project_path)
+
+ if project_path.present?
+ project = find_project!(project_path: project_path)
+ elsif !can_create_personal_snippet?
+ raise_resource_not_avaiable_error!
+ end
+
+ snippet = CreateSnippetService.new(project,
+ context[:current_user],
+ args).execute
+
+ {
+ snippet: snippet.valid? ? snippet : nil,
+ errors: errors_on_object(snippet)
+ }
+ end
+
+ private
+
+ def find_project!(project_path:)
+ authorized_find!(full_path: project_path)
+ end
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+
+ def authorized_resource?(project)
+ Ability.allowed?(context[:current_user], :create_project_snippet, project)
+ end
+
+ def can_create_personal_snippet?
+ Ability.allowed?(context[:current_user], :create_personal_snippet)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/destroy.rb b/app/graphql/mutations/snippets/destroy.rb
new file mode 100644
index 00000000000..115fcfd6488
--- /dev/null
+++ b/app/graphql/mutations/snippets/destroy.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Snippets
+ class Destroy < Base
+ graphql_name 'DestroySnippet'
+
+ ERROR_MSG = 'Error deleting the snippet'
+
+ argument :id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the snippet to destroy'
+
+ def resolve(id:)
+ snippet = authorized_find!(id: id)
+
+ result = snippet.destroy
+ errors = result ? [] : [ERROR_MSG]
+
+ {
+ errors: errors
+ }
+ end
+
+ private
+
+ def ability_name
+ "admin"
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/mark_as_spam.rb b/app/graphql/mutations/snippets/mark_as_spam.rb
new file mode 100644
index 00000000000..260a9753f76
--- /dev/null
+++ b/app/graphql/mutations/snippets/mark_as_spam.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Snippets
+ class MarkAsSpam < Base
+ graphql_name 'MarkAsSpamSnippet'
+
+ argument :id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the snippet to update'
+
+ def resolve(id:)
+ snippet = authorized_find!(id: id)
+
+ result = mark_as_spam(snippet)
+ errors = result ? [] : ['Error with Akismet. Please check the logs for more info.']
+
+ {
+ errors: errors
+ }
+ end
+
+ private
+
+ def mark_as_spam(snippet)
+ SpamService.new(snippet).mark_as_spam!
+ end
+
+ def authorized_resource?(snippet)
+ super && snippet.submittable_as_spam_by?(context[:current_user])
+ end
+
+ def ability_name
+ "admin"
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb
new file mode 100644
index 00000000000..27c232bc7f8
--- /dev/null
+++ b/app/graphql/mutations/snippets/update.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Snippets
+ class Update < Base
+ graphql_name 'UpdateSnippet'
+
+ argument :id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the snippet to update'
+
+ argument :title, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Title of the snippet'
+
+ argument :file_name, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'File name of the snippet'
+
+ argument :content, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Content of the snippet'
+
+ argument :description, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Description of the snippet'
+
+ argument :visibility_level, Types::VisibilityLevelsEnum,
+ description: 'The visibility level of the snippet',
+ required: false
+
+ def resolve(args)
+ snippet = authorized_find!(id: args.delete(:id))
+
+ result = UpdateSnippetService.new(snippet.project,
+ context[:current_user],
+ snippet,
+ args).execute
+
+ {
+ snippet: result ? snippet : snippet.reset,
+ errors: errors_on_object(snippet)
+ }
+ end
+
+ private
+
+ def ability_name
+ "update"
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/todos/base.rb b/app/graphql/mutations/todos/base.rb
index b6c7b320be1..2a72019fbac 100644
--- a/app/graphql/mutations/todos/base.rb
+++ b/app/graphql/mutations/todos/base.rb
@@ -9,6 +9,12 @@ module Mutations
GitlabSchema.object_from_id(id)
end
+ def map_to_global_ids(ids)
+ return [] if ids.blank?
+
+ ids.map { |id| to_global_id(id) }
+ end
+
def to_global_id(id)
::URI::GID.build(app: GlobalID.app, model_name: Todo.name, model_id: id, params: nil).to_s
end
diff --git a/app/graphql/mutations/todos/mark_all_done.rb b/app/graphql/mutations/todos/mark_all_done.rb
new file mode 100644
index 00000000000..5694985717c
--- /dev/null
+++ b/app/graphql/mutations/todos/mark_all_done.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Todos
+ class MarkAllDone < ::Mutations::Todos::Base
+ graphql_name 'TodosMarkAllDone'
+
+ authorize :update_user
+
+ field :updated_ids,
+ [GraphQL::ID_TYPE],
+ null: false,
+ description: 'Ids of the updated todos'
+
+ def resolve
+ authorize!(current_user)
+
+ updated_ids = mark_all_todos_done
+
+ {
+ updated_ids: map_to_global_ids(updated_ids),
+ errors: []
+ }
+ end
+
+ private
+
+ def mark_all_todos_done
+ return [] unless current_user
+
+ TodoService.new.mark_all_todos_as_done_by_user(current_user)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/todos/mark_done.rb b/app/graphql/mutations/todos/mark_done.rb
index 5483708b5c6..d738e387c43 100644
--- a/app/graphql/mutations/todos/mark_done.rb
+++ b/app/graphql/mutations/todos/mark_done.rb
@@ -16,22 +16,21 @@ module Mutations
null: false,
description: 'The requested todo'
- # rubocop: disable CodeReuse/ActiveRecord
def resolve(id:)
todo = authorized_find!(id: id)
- mark_done(Todo.where(id: todo.id)) unless todo.done?
+
+ mark_done(todo)
{
todo: todo.reset,
errors: errors_on_object(todo)
}
end
- # rubocop: enable CodeReuse/ActiveRecord
private
def mark_done(todo)
- TodoService.new.mark_todos_as_done(todo, current_user)
+ TodoService.new.mark_todo_as_done(todo, current_user)
end
end
end
diff --git a/app/graphql/mutations/todos/restore.rb b/app/graphql/mutations/todos/restore.rb
new file mode 100644
index 00000000000..c4597bd84a2
--- /dev/null
+++ b/app/graphql/mutations/todos/restore.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Todos
+ class Restore < ::Mutations::Todos::Base
+ graphql_name 'TodoRestore'
+
+ authorize :update_todo
+
+ argument :id,
+ GraphQL::ID_TYPE,
+ required: true,
+ description: 'The global id of the todo to restore'
+
+ field :todo, Types::TodoType,
+ null: false,
+ description: 'The requested todo'
+
+ def resolve(id:)
+ todo = authorized_find!(id: id)
+ restore(todo.id) if todo.done?
+
+ {
+ todo: todo.reset,
+ errors: errors_on_object(todo)
+ }
+ end
+
+ private
+
+ def restore(id)
+ TodoService.new.mark_todos_as_pending_by_ids([id], current_user)
+ end
+ end
+ end
+end