diff options
Diffstat (limited to 'app/graphql/mutations')
-rw-r--r-- | app/graphql/mutations/issues/base.rb | 34 | ||||
-rw-r--r-- | app/graphql/mutations/issues/set_confidential.rb | 27 | ||||
-rw-r--r-- | app/graphql/mutations/issues/set_due_date.rb | 27 | ||||
-rw-r--r-- | app/graphql/mutations/snippets/base.rb | 30 | ||||
-rw-r--r-- | app/graphql/mutations/snippets/create.rb | 77 | ||||
-rw-r--r-- | app/graphql/mutations/snippets/destroy.rb | 33 | ||||
-rw-r--r-- | app/graphql/mutations/snippets/mark_as_spam.rb | 39 | ||||
-rw-r--r-- | app/graphql/mutations/snippets/update.rb | 54 | ||||
-rw-r--r-- | app/graphql/mutations/todos/base.rb | 6 | ||||
-rw-r--r-- | app/graphql/mutations/todos/mark_all_done.rb | 35 | ||||
-rw-r--r-- | app/graphql/mutations/todos/mark_done.rb | 7 | ||||
-rw-r--r-- | app/graphql/mutations/todos/restore.rb | 36 |
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 |