diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/api.rb | 9 | ||||
-rw-r--r-- | lib/api/v3/award_emoji.rb | 59 | ||||
-rw-r--r-- | lib/api/v3/boards.rb | 21 | ||||
-rw-r--r-- | lib/api/v3/branches.rb | 20 | ||||
-rw-r--r-- | lib/api/v3/broadcast_messages.rb | 31 | ||||
-rw-r--r-- | lib/api/v3/environments.rb | 29 | ||||
-rw-r--r-- | lib/api/v3/issues.rb | 2 | ||||
-rw-r--r-- | lib/api/v3/labels.rb | 15 | ||||
-rw-r--r-- | lib/api/v3/members.rb | 1 | ||||
-rw-r--r-- | lib/api/v3/merge_requests.rb | 2 | ||||
-rw-r--r-- | lib/api/v3/project_snippets.rb | 2 | ||||
-rw-r--r-- | lib/api/v3/projects.rb | 3 | ||||
-rw-r--r-- | lib/api/v3/runners.rb | 65 | ||||
-rw-r--r-- | lib/api/v3/services.rb | 573 | ||||
-rw-r--r-- | lib/api/v3/system_hooks.rb | 13 | ||||
-rw-r--r-- | lib/api/v3/tags.rb | 20 | ||||
-rw-r--r-- | lib/api/v3/todos.rb | 2 | ||||
-rw-r--r-- | lib/api/v3/triggers.rb | 30 | ||||
-rw-r--r-- | lib/api/v3/users.rb | 32 | ||||
-rw-r--r-- | lib/api/v3/variables.rb | 29 | ||||
-rw-r--r-- | lib/api/variables.rb | 3 |
21 files changed, 958 insertions, 3 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 7aa95a4a3c1..b27ac3f1d15 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -5,10 +5,13 @@ module API version %w(v3 v4), using: :path version 'v3', using: :path do + mount ::API::V3::AwardEmoji mount ::API::V3::Boards mount ::API::V3::Branches + mount ::API::V3::BroadcastMessages mount ::API::V3::Commits mount ::API::V3::DeployKeys + mount ::API::V3::Environments mount ::API::V3::Files mount ::API::V3::Groups mount ::API::V3::Issues @@ -21,12 +24,16 @@ module API mount ::API::V3::Projects mount ::API::V3::ProjectSnippets mount ::API::V3::Repositories + mount ::API::V3::Runners + mount ::API::V3::Services mount ::API::V3::Subscriptions mount ::API::V3::SystemHooks mount ::API::V3::Tags - mount ::API::V3::Todos mount ::API::V3::Templates + mount ::API::V3::Todos + mount ::API::V3::Triggers mount ::API::V3::Users + mount ::API::V3::Variables end before { allow_access_with_scope :api } diff --git a/lib/api/v3/award_emoji.rb b/lib/api/v3/award_emoji.rb new file mode 100644 index 00000000000..1e35283631f --- /dev/null +++ b/lib/api/v3/award_emoji.rb @@ -0,0 +1,59 @@ +module API + module V3 + class AwardEmoji < Grape::API + include PaginationParams + + before { authenticate! } + AWARDABLES = %w[issue merge_request snippet].freeze + + resource :projects do + AWARDABLES.each do |awardable_type| + awardable_string = awardable_type.pluralize + awardable_id_string = "#{awardable_type}_id" + + params do + requires :id, type: String, desc: 'The ID of a project' + requires :"#{awardable_id_string}", type: Integer, desc: "The ID of an Issue, Merge Request or Snippet" + end + + [":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", + ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji"].each do |endpoint| + desc 'Delete a +awardables+ award emoji' do + detail 'This feature was introduced in 8.9' + success ::API::Entities::AwardEmoji + end + params do + requires :award_id, type: Integer, desc: 'The ID of an award emoji' + end + delete "#{endpoint}/:award_id" do + award = awardable.award_emoji.find(params[:award_id]) + + unauthorized! unless award.user == current_user || current_user.admin? + + present award.destroy, with: ::API::Entities::AwardEmoji + end + end + end + end + + helpers do + def awardable + @awardable ||= + begin + if params.include?(:note_id) + note_id = params.delete(:note_id) + + awardable.notes.find(note_id) + elsif params.include?(:issue_id) + user_project.issues.find(params[:issue_id]) + elsif params.include?(:merge_request_id) + user_project.merge_requests.find(params[:merge_request_id]) + else + user_project.snippets.find(params[:snippet_id]) + end + end + end + end + end + end +end diff --git a/lib/api/v3/boards.rb b/lib/api/v3/boards.rb index 31d708bc2c8..b1c2a3c59f2 100644 --- a/lib/api/v3/boards.rb +++ b/lib/api/v3/boards.rb @@ -44,6 +44,27 @@ module API authorize!(:read_board, user_project) present board_lists, with: ::API::Entities::List end + + desc 'Delete a board list' do + detail 'This feature was introduced in 8.13' + success ::API::Entities::List + end + params do + requires :list_id, type: Integer, desc: 'The ID of a board list' + end + delete "/lists/:list_id" do + authorize!(:admin_list, user_project) + + list = board_lists.find(params[:list_id]) + + service = ::Boards::Lists::DestroyService.new(user_project, current_user) + + if service.execute(list) + present list, with: ::API::Entities::List + else + render_api_error!({ error: 'List could not be deleted!' }, 400) + end + end end end end diff --git a/lib/api/v3/branches.rb b/lib/api/v3/branches.rb index 51eb566cf7d..699e41b5537 100644 --- a/lib/api/v3/branches.rb +++ b/lib/api/v3/branches.rb @@ -19,6 +19,26 @@ module API present branches, with: ::API::Entities::RepoBranch, project: user_project end + desc 'Delete a branch' + params do + requires :branch, type: String, desc: 'The name of the branch' + end + delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do + authorize_push_project + + result = DeleteBranchService.new(user_project, current_user). + execute(params[:branch]) + + if result[:status] == :success + status(200) + { + branch_name: params[:branch] + } + else + render_api_error!(result[:message], result[:return_code]) + end + end + desc 'Delete all merged branches' delete ":id/repository/merged_branches" do DeleteMergedBranchesService.new(user_project, current_user).async_execute diff --git a/lib/api/v3/broadcast_messages.rb b/lib/api/v3/broadcast_messages.rb new file mode 100644 index 00000000000..417e4ad0b26 --- /dev/null +++ b/lib/api/v3/broadcast_messages.rb @@ -0,0 +1,31 @@ +module API + module V3 + class BroadcastMessages < Grape::API + include PaginationParams + + before { authenticate! } + before { authenticated_as_admin! } + + resource :broadcast_messages do + helpers do + def find_message + BroadcastMessage.find(params[:id]) + end + end + + desc 'Delete a broadcast message' do + detail 'This feature was introduced in GitLab 8.12.' + success ::API::Entities::BroadcastMessage + end + params do + requires :id, type: Integer, desc: 'Broadcast message ID' + end + delete ':id' do + message = find_message + + present message.destroy, with: ::API::Entities::BroadcastMessage + end + end + end + end +end diff --git a/lib/api/v3/environments.rb b/lib/api/v3/environments.rb new file mode 100644 index 00000000000..3effccfa708 --- /dev/null +++ b/lib/api/v3/environments.rb @@ -0,0 +1,29 @@ +module API + module V3 + class Environments < Grape::API + include PaginationParams + + before { authenticate! } + + params do + requires :id, type: String, desc: 'The project ID' + end + resource :projects do + desc 'Deletes an existing environment' do + detail 'This feature was introduced in GitLab 8.11.' + success ::API::Entities::Environment + end + params do + requires :environment_id, type: Integer, desc: 'The environment ID' + end + delete ':id/environments/:environment_id' do + authorize! :update_environment, user_project + + environment = user_project.environments.find(params[:environment_id]) + + present environment.destroy, with: ::API::Entities::Environment + end + end + end + end +end diff --git a/lib/api/v3/issues.rb b/lib/api/v3/issues.rb index d0af09f0e1e..5d7dfabfcd6 100644 --- a/lib/api/v3/issues.rb +++ b/lib/api/v3/issues.rb @@ -226,6 +226,8 @@ module API not_found!('Issue') unless issue authorize!(:destroy_issue, issue) + + status(200) issue.destroy end end diff --git a/lib/api/v3/labels.rb b/lib/api/v3/labels.rb index 5c3261311bf..41f45d244e3 100644 --- a/lib/api/v3/labels.rb +++ b/lib/api/v3/labels.rb @@ -13,6 +13,21 @@ module API get ':id/labels' do present available_labels, with: ::API::Entities::Label, current_user: current_user, project: user_project end + + desc 'Delete an existing label' do + success ::API::Entities::Label + end + params do + requires :name, type: String, desc: 'The name of the label to be deleted' + end + delete ':id/labels' do + authorize! :admin_label, user_project + + label = user_project.labels.find_by(title: params[:name]) + not_found!('Label') unless label + + present label.destroy, with: ::API::Entities::Label, current_user: current_user, project: user_project + end end end end diff --git a/lib/api/v3/members.rb b/lib/api/v3/members.rb index 19f276d5484..3d4972afd9d 100644 --- a/lib/api/v3/members.rb +++ b/lib/api/v3/members.rb @@ -119,6 +119,7 @@ module API # This is to ensure back-compatibility but 204 behavior should be used # for all DELETE endpoints in 9.0! if member.nil? + status(200 ) { message: "Access revoked", id: params[:user_id].to_i } else ::Members::DestroyService.new(source, current_user, declared_params).execute diff --git a/lib/api/v3/merge_requests.rb b/lib/api/v3/merge_requests.rb index 129f9d850e9..c6574a9104b 100644 --- a/lib/api/v3/merge_requests.rb +++ b/lib/api/v3/merge_requests.rb @@ -103,6 +103,8 @@ module API merge_request = find_project_merge_request(params[:merge_request_id]) authorize!(:destroy_merge_request, merge_request) + + status(200) merge_request.destroy end diff --git a/lib/api/v3/project_snippets.rb b/lib/api/v3/project_snippets.rb index e03e941d30b..809ca4f37ba 100644 --- a/lib/api/v3/project_snippets.rb +++ b/lib/api/v3/project_snippets.rb @@ -121,6 +121,8 @@ module API authorize! :admin_project_snippet, snippet snippet.destroy + + status(200) end desc 'Get a raw project snippet' diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index c3821555452..f3cd0b22e9b 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -359,6 +359,8 @@ module API desc 'Remove a project' delete ":id" do authorize! :remove_project, user_project + + status(200) ::Projects::DestroyService.new(user_project, current_user, {}).async_execute end @@ -384,6 +386,7 @@ module API authorize! :remove_fork_project, user_project if user_project.forked? + status(200) user_project.forked_project_link.destroy else not_modified! diff --git a/lib/api/v3/runners.rb b/lib/api/v3/runners.rb new file mode 100644 index 00000000000..8967141fe3d --- /dev/null +++ b/lib/api/v3/runners.rb @@ -0,0 +1,65 @@ +module API + module V3 + class Runners < Grape::API + include PaginationParams + + before { authenticate! } + + resource :runners do + desc 'Remove a runner' do + success ::API::Entities::Runner + end + params do + requires :id, type: Integer, desc: 'The ID of the runner' + end + delete ':id' do + runner = Ci::Runner.find(params[:id]) + not_found!('Runner') unless runner + + authenticate_delete_runner!(runner) + + status(200) + runner.destroy + end + end + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + before { authorize_admin_project } + + desc "Disable project's runner" do + success ::API::Entities::Runner + end + params do + requires :runner_id, type: Integer, desc: 'The ID of the runner' + end + delete ':id/runners/:runner_id' do + runner_project = user_project.runner_projects.find_by(runner_id: params[:runner_id]) + not_found!('Runner') unless runner_project + + runner = runner_project.runner + forbidden!("Only one project associated with the runner. Please remove the runner instead") if runner.projects.count == 1 + + runner_project.destroy + + present runner, with: ::API::Entities::Runner + end + end + + helpers do + def authenticate_delete_runner!(runner) + return if current_user.is_admin? + forbidden!("Runner is shared") if runner.is_shared? + forbidden!("Runner associated with more than one project") if runner.projects.count > 1 + forbidden!("No access granted") unless user_can_access_runner?(runner) + end + + def user_can_access_runner?(runner) + current_user.ci_authorized_runners.exists?(runner.id) + end + end + end + end +end diff --git a/lib/api/v3/services.rb b/lib/api/v3/services.rb new file mode 100644 index 00000000000..af0a058f69b --- /dev/null +++ b/lib/api/v3/services.rb @@ -0,0 +1,573 @@ +module API + module V3 + class Services < Grape::API + services = { + 'asana' => [ + { + required: true, + name: :api_key, + type: String, + desc: 'User API token' + }, + { + required: false, + name: :restrict_to_branch, + type: String, + desc: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches' + } + ], + 'assembla' => [ + { + required: true, + name: :token, + type: String, + desc: 'The authentication token' + }, + { + required: false, + name: :subdomain, + type: String, + desc: 'Subdomain setting' + } + ], + 'bamboo' => [ + { + required: true, + name: :bamboo_url, + type: String, + desc: 'Bamboo root URL like https://bamboo.example.com' + }, + { + required: true, + name: :build_key, + type: String, + desc: 'Bamboo build plan key like' + }, + { + required: true, + name: :username, + type: String, + desc: 'A user with API access, if applicable' + }, + { + required: true, + name: :password, + type: String, + desc: 'Passord of the user' + } + ], + 'bugzilla' => [ + { + required: true, + name: :new_issue_url, + type: String, + desc: 'New issue URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'Issues URL' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'Project URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'Description' + }, + { + required: false, + name: :title, + type: String, + desc: 'Title' + } + ], + 'buildkite' => [ + { + required: true, + name: :token, + type: String, + desc: 'Buildkite project GitLab token' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'The buildkite project URL' + }, + { + required: false, + name: :enable_ssl_verification, + type: Boolean, + desc: 'Enable SSL verification for communication' + } + ], + 'builds-email' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Comma-separated list of recipient email addresses' + }, + { + required: false, + name: :add_pusher, + type: Boolean, + desc: 'Add pusher to recipients list' + }, + { + required: false, + name: :notify_only_broken_builds, + type: Boolean, + desc: 'Notify only broken builds' + } + ], + 'campfire' => [ + { + required: true, + name: :token, + type: String, + desc: 'Campfire token' + }, + { + required: false, + name: :subdomain, + type: String, + desc: 'Campfire subdomain' + }, + { + required: false, + name: :room, + type: String, + desc: 'Campfire room' + } + ], + 'custom-issue-tracker' => [ + { + required: true, + name: :new_issue_url, + type: String, + desc: 'New issue URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'Issues URL' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'Project URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'Description' + }, + { + required: false, + name: :title, + type: String, + desc: 'Title' + } + ], + 'drone-ci' => [ + { + required: true, + name: :token, + type: String, + desc: 'Drone CI token' + }, + { + required: true, + name: :drone_url, + type: String, + desc: 'Drone CI URL' + }, + { + required: false, + name: :enable_ssl_verification, + type: Boolean, + desc: 'Enable SSL verification for communication' + } + ], + 'emails-on-push' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Comma-separated list of recipient email addresses' + }, + { + required: false, + name: :disable_diffs, + type: Boolean, + desc: 'Disable code diffs' + }, + { + required: false, + name: :send_from_committer_email, + type: Boolean, + desc: 'Send from committer' + } + ], + 'external-wiki' => [ + { + required: true, + name: :external_wiki_url, + type: String, + desc: 'The URL of the external Wiki' + } + ], + 'flowdock' => [ + { + required: true, + name: :token, + type: String, + desc: 'Flowdock token' + } + ], + 'gemnasium' => [ + { + required: true, + name: :api_key, + type: String, + desc: 'Your personal API key on gemnasium.com' + }, + { + required: true, + name: :token, + type: String, + desc: "The project's slug on gemnasium.com" + } + ], + 'hipchat' => [ + { + required: true, + name: :token, + type: String, + desc: 'The room token' + }, + { + required: false, + name: :room, + type: String, + desc: 'The room name or ID' + }, + { + required: false, + name: :color, + type: String, + desc: 'The room color' + }, + { + required: false, + name: :notify, + type: Boolean, + desc: 'Enable notifications' + }, + { + required: false, + name: :api_version, + type: String, + desc: 'Leave blank for default (v2)' + }, + { + required: false, + name: :server, + type: String, + desc: 'Leave blank for default. https://hipchat.example.com' + } + ], + 'irker' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Recipients/channels separated by whitespaces' + }, + { + required: false, + name: :default_irc_uri, + type: String, + desc: 'Default: irc://irc.network.net:6697' + }, + { + required: false, + name: :server_host, + type: String, + desc: 'Server host. Default localhost' + }, + { + required: false, + name: :server_port, + type: Integer, + desc: 'Server port. Default 6659' + }, + { + required: false, + name: :colorize_messages, + type: Boolean, + desc: 'Colorize messages' + } + ], + 'jira' => [ + { + required: true, + name: :url, + type: String, + desc: 'The URL to the JIRA project which is being linked to this GitLab project, e.g., https://jira.example.com' + }, + { + required: true, + name: :project_key, + type: String, + desc: 'The short identifier for your JIRA project, all uppercase, e.g., PROJ' + }, + { + required: false, + name: :username, + type: String, + desc: 'The username of the user created to be used with GitLab/JIRA' + }, + { + required: false, + name: :password, + type: String, + desc: 'The password of the user created to be used with GitLab/JIRA' + }, + { + required: false, + name: :jira_issue_transition_id, + type: Integer, + desc: 'The ID of a transition that moves issues to a closed state. You can find this number under the JIRA workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`' + } + ], + + 'kubernetes' => [ + { + required: true, + name: :namespace, + type: String, + desc: 'The Kubernetes namespace to use' + }, + { + required: true, + name: :api_url, + type: String, + desc: 'The URL to the Kubernetes cluster API, e.g., https://kubernetes.example.com' + }, + { + required: true, + name: :token, + type: String, + desc: 'The service token to authenticate against the Kubernetes cluster with' + }, + { + required: false, + name: :ca_pem, + type: String, + desc: 'A custom certificate authority bundle to verify the Kubernetes cluster with (PEM format)' + }, + ], + 'mattermost-slash-commands' => [ + { + required: true, + name: :token, + type: String, + desc: 'The Mattermost token' + } + ], + 'slack-slash-commands' => [ + { + required: true, + name: :token, + type: String, + desc: 'The Slack token' + } + ], + 'pipelines-email' => [ + { + required: true, + name: :recipients, + type: String, + desc: 'Comma-separated list of recipient email addresses' + }, + { + required: false, + name: :notify_only_broken_builds, + type: Boolean, + desc: 'Notify only broken builds' + } + ], + 'pivotaltracker' => [ + { + required: true, + name: :token, + type: String, + desc: 'The Pivotaltracker token' + }, + { + required: false, + name: :restrict_to_branch, + type: String, + desc: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.' + } + ], + 'pushover' => [ + { + required: true, + name: :api_key, + type: String, + desc: 'The application key' + }, + { + required: true, + name: :user_key, + type: String, + desc: 'The user key' + }, + { + required: true, + name: :priority, + type: String, + desc: 'The priority' + }, + { + required: true, + name: :device, + type: String, + desc: 'Leave blank for all active devices' + }, + { + required: true, + name: :sound, + type: String, + desc: 'The sound of the notification' + } + ], + 'redmine' => [ + { + required: true, + name: :new_issue_url, + type: String, + desc: 'The new issue URL' + }, + { + required: true, + name: :project_url, + type: String, + desc: 'The project URL' + }, + { + required: true, + name: :issues_url, + type: String, + desc: 'The issues URL' + }, + { + required: false, + name: :description, + type: String, + desc: 'The description of the tracker' + } + ], + 'slack' => [ + { + required: true, + name: :webhook, + type: String, + desc: 'The Slack webhook. e.g. https://hooks.slack.com/services/...' + }, + { + required: false, + name: :new_issue_url, + type: String, + desc: 'The user name' + }, + { + required: false, + name: :channel, + type: String, + desc: 'The channel name' + } + ], + 'mattermost' => [ + { + required: true, + name: :webhook, + type: String, + desc: 'The Mattermost webhook. e.g. http://mattermost_host/hooks/...' + } + ], + 'teamcity' => [ + { + required: true, + name: :teamcity_url, + type: String, + desc: 'TeamCity root URL like https://teamcity.example.com' + }, + { + required: true, + name: :build_type, + type: String, + desc: 'Build configuration ID' + }, + { + required: true, + name: :username, + type: String, + desc: 'A user with permissions to trigger a manual build' + }, + { + required: true, + name: :password, + type: String, + desc: 'The password of the user' + } + ] + } + + resource :projects do + before { authenticate! } + before { authorize_admin_project } + + helpers do + def service_attributes(service) + service.fields.inject([]) do |arr, hash| + arr << hash[:name].to_sym + end + end + end + + desc "Delete a service for project" + params do + requires :service_slug, type: String, values: services.keys, desc: 'The name of the service' + end + delete ":id/services/:service_slug" do + service = user_project.find_or_initialize_service(params[:service_slug].underscore) + + attrs = service_attributes(service).inject({}) do |hash, key| + hash.merge!(key => nil) + end + + if service.update_attributes(attrs.merge(active: false)) + status(200) + true + else + render_api_error!('400 Bad Request', 400) + end + end + end + end + end +end diff --git a/lib/api/v3/system_hooks.rb b/lib/api/v3/system_hooks.rb index 391510b9ee0..5787c06fc12 100644 --- a/lib/api/v3/system_hooks.rb +++ b/lib/api/v3/system_hooks.rb @@ -13,6 +13,19 @@ module API get do present SystemHook.all, with: ::API::Entities::Hook end + + desc 'Delete a hook' do + success ::API::Entities::Hook + end + params do + requires :id, type: Integer, desc: 'The ID of the system hook' + end + delete ":id" do + hook = SystemHook.find_by(id: params[:id]) + not_found!('System hook') unless hook + + present hook.destroy, with: ::API::Entities::Hook + end end end end diff --git a/lib/api/v3/tags.rb b/lib/api/v3/tags.rb index 016e3d86932..6913720d9c5 100644 --- a/lib/api/v3/tags.rb +++ b/lib/api/v3/tags.rb @@ -14,6 +14,26 @@ module API tags = user_project.repository.tags.sort_by(&:name).reverse present tags, with: ::API::Entities::RepoTag, project: user_project end + + desc 'Delete a repository tag' + params do + requires :tag_name, type: String, desc: 'The name of the tag' + end + delete ":id/repository/tags/:tag_name", requirements: { tag_name: /.+/ } do + authorize_push_project + + result = ::Tags::DestroyService.new(user_project, current_user). + execute(params[:tag_name]) + + if result[:status] == :success + status(200) + { + tag_name: params[:tag_name] + } + else + render_api_error!(result[:message], result[:return_code]) + end + end end end end diff --git a/lib/api/v3/todos.rb b/lib/api/v3/todos.rb index 4f9b5fe72a6..e60cb25e57b 100644 --- a/lib/api/v3/todos.rb +++ b/lib/api/v3/todos.rb @@ -19,6 +19,8 @@ module API desc 'Mark all todos as done' delete do + status(200) + todos = TodosFinder.new(current_user, params).execute TodoService.new.mark_todos_as_done(todos, current_user) end diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb new file mode 100644 index 00000000000..4051d4bca8d --- /dev/null +++ b/lib/api/v3/triggers.rb @@ -0,0 +1,30 @@ +module API + module V3 + class Triggers < Grape::API + include PaginationParams + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + desc 'Delete a trigger' do + success ::API::Entities::Trigger + end + params do + requires :token, type: String, desc: 'The unique token of trigger' + end + delete ':id/triggers/:token' do + authenticate! + authorize! :admin_build, user_project + + trigger = user_project.triggers.find_by(token: params[:token].to_s) + return not_found!('Trigger') unless trigger + + trigger.destroy + + present trigger, with: ::API::Entities::Trigger + end + end + end + end +end diff --git a/lib/api/v3/users.rb b/lib/api/v3/users.rb index 7838cdc46a7..14f54731730 100644 --- a/lib/api/v3/users.rb +++ b/lib/api/v3/users.rb @@ -92,6 +92,25 @@ module API present paginate(events), with: ::API::V3::Entities::Event end + + desc 'Delete an existing SSH key from a specified user. Available only for admins.' do + success ::API::Entities::SSHKey + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key_id, type: Integer, desc: 'The ID of the SSH key' + end + delete ':id/keys/:key_id' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + key = user.keys.find_by(id: params[:key_id]) + not_found!('Key') unless key + + present key.destroy, with: ::API::Entities::SSHKey + end end resource :user do @@ -111,6 +130,19 @@ module API get "emails" do present current_user.emails, with: ::API::Entities::Email end + + desc 'Delete an SSH key from the currently authenticated user' do + success ::API::Entities::SSHKey + end + params do + requires :key_id, type: Integer, desc: 'The ID of the SSH key' + end + delete "keys/:key_id" do + key = current_user.keys.find_by(id: params[:key_id]) + not_found!('Key') unless key + + present key.destroy, with: ::API::Entities::SSHKey + end end end end diff --git a/lib/api/v3/variables.rb b/lib/api/v3/variables.rb new file mode 100644 index 00000000000..0f55a14fb28 --- /dev/null +++ b/lib/api/v3/variables.rb @@ -0,0 +1,29 @@ +module API + module V3 + class Variables < Grape::API + include PaginationParams + + before { authenticate! } + before { authorize! :admin_build, user_project } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + + resource :projects do + desc 'Delete an existing variable from a project' do + success ::API::Entities::Variable + end + params do + requires :key, type: String, desc: 'The key of the variable' + end + delete ':id/variables/:key' do + variable = user_project.variables.find_by(key: params[:key]) + not_found!('Variable') unless variable + + present variable.destroy, with: ::API::Entities::Variable + end + end + end + end +end diff --git a/lib/api/variables.rb b/lib/api/variables.rb index 259bc051d52..77e5d54c225 100644 --- a/lib/api/variables.rb +++ b/lib/api/variables.rb @@ -1,5 +1,4 @@ module API - # Projects variables API class Variables < Grape::API include PaginationParams @@ -81,7 +80,7 @@ module API end delete ':id/variables/:key' do variable = user_project.variables.find_by(key: params[:key]) - return not_found!('Variable') unless variable + not_found!('Variable') unless variable variable.destroy end |