diff options
author | Jose Ivan Vargas <jvargas@gitlab.com> | 2017-09-13 12:21:33 -0500 |
---|---|---|
committer | Jose Ivan Vargas <jvargas@gitlab.com> | 2017-09-13 12:21:33 -0500 |
commit | 4c0beb6c024b25ff24c7c2ea966bacab0ee860d5 (patch) | |
tree | f3e61556a1cc9132f439d222dca9d6366eb8a6ca /lib/api | |
parent | 2d58626a33bc0d4e78eaf0c25965d18a6239fa3b (diff) | |
parent | 33010da28b0f2e00e96cc4bf6c439363905a81d5 (diff) | |
download | gitlab-ce-4c0beb6c024b25ff24c7c2ea966bacab0ee860d5.tar.gz |
Merge branch 'master' into sh-headless-chrome-support
Diffstat (limited to 'lib/api')
-rw-r--r-- | lib/api/api.rb | 12 | ||||
-rw-r--r-- | lib/api/broadcast_messages.rb | 2 | ||||
-rw-r--r-- | lib/api/commits.rb | 2 | ||||
-rw-r--r-- | lib/api/entities.rb | 18 | ||||
-rw-r--r-- | lib/api/groups.rb | 7 | ||||
-rw-r--r-- | lib/api/helpers.rb | 26 | ||||
-rw-r--r-- | lib/api/helpers/internal_helpers.rb | 9 | ||||
-rw-r--r-- | lib/api/internal.rb | 11 | ||||
-rw-r--r-- | lib/api/job_artifacts.rb | 80 | ||||
-rw-r--r-- | lib/api/jobs.rb | 78 | ||||
-rw-r--r-- | lib/api/lint.rb | 2 | ||||
-rw-r--r-- | lib/api/merge_request_diffs.rb | 2 | ||||
-rw-r--r-- | lib/api/milestone_responses.rb | 2 | ||||
-rw-r--r-- | lib/api/projects.rb | 2 | ||||
-rw-r--r-- | lib/api/v3/entities.rb | 3 | ||||
-rw-r--r-- | lib/api/v3/merge_request_diffs.rb | 2 | ||||
-rw-r--r-- | lib/api/v3/milestones.rb | 1 | ||||
-rw-r--r-- | lib/api/v3/projects.rb | 9 | ||||
-rw-r--r-- | lib/api/wikis.rb | 89 |
19 files changed, 267 insertions, 90 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 94df543853b..79e55a2f4f7 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -2,6 +2,16 @@ module API class API < Grape::API include APIGuard + LOG_FILENAME = Rails.root.join("log", "api_json.log") + + use GrapeLogging::Middleware::RequestLogger, + logger: Logger.new(LOG_FILENAME), + formatter: Gitlab::GrapeLogging::Formatters::LogrageWithTimestamp.new, + include: [ + GrapeLogging::Loggers::FilterParameters.new, + GrapeLogging::Loggers::ClientEnv.new + ] + allow_access_with_scope :api prefix :api @@ -108,6 +118,7 @@ module API mount ::API::Internal mount ::API::Issues mount ::API::Jobs + mount ::API::JobArtifacts mount ::API::Keys mount ::API::Labels mount ::API::Lint @@ -143,6 +154,7 @@ module API mount ::API::Variables mount ::API::GroupVariables mount ::API::Version + mount ::API::Wikis route :any, '*path' do error!('404 Not Found', 404) diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb index 0b45621ce7b..d7138b2f2fe 100644 --- a/lib/api/broadcast_messages.rb +++ b/lib/api/broadcast_messages.rb @@ -20,7 +20,7 @@ module API use :pagination end get do - messages = BroadcastMessage.all + messages = BroadcastMessage.all.order_id_desc present paginate(messages), with: Entities::BroadcastMessage end diff --git a/lib/api/commits.rb b/lib/api/commits.rb index ea78737288a..4b8d248f5f7 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -104,7 +104,7 @@ module API not_found! 'Commit' unless commit - commit.raw_diffs.to_a + present commit.raw_diffs.to_a, with: Entities::RepoDiff end desc "Get a commit's comments" do diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 031dd02c6eb..52c49e5caa9 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1,5 +1,15 @@ module API module Entities + class WikiPageBasic < Grape::Entity + expose :format + expose :slug + expose :title + end + + class WikiPage < WikiPageBasic + expose :content + end + class UserSafe < Grape::Entity expose :id, :name, :username end @@ -35,7 +45,7 @@ module API expose :confirmed_at expose :last_activity_on expose :email - expose :color_scheme_id, :projects_limit, :current_sign_in_at + expose :theme_id, :color_scheme_id, :projects_limit, :current_sign_in_at expose :identities, using: Entities::Identity expose :can_create_group?, as: :can_create_group expose :can_create_project?, as: :can_create_project @@ -119,6 +129,7 @@ module API expose :archived?, as: :archived expose :visibility expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } + expose :resolve_outdated_diff_discussions expose :container_registry_enabled # Expose old field names with the new permissions methods to keep API compatible @@ -290,10 +301,11 @@ module API end class RepoDiff < Grape::Entity - expose :old_path, :new_path, :a_mode, :b_mode, :diff + expose :old_path, :new_path, :a_mode, :b_mode expose :new_file?, as: :new_file expose :renamed_file?, as: :renamed_file expose :deleted_file?, as: :deleted_file + expose :json_safe_diff, as: :diff end class ProtectedRefAccess < Grape::Entity @@ -545,7 +557,7 @@ module API end class Event < Grape::Entity - expose :title, :project_id, :action_name + expose :project_id, :action_name expose :target_id, :target_iid, :target_type, :author_id expose :target_title expose :created_at diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 31a918eda60..e817dcbbc4b 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -74,7 +74,12 @@ module API use :optional_params end post do - authorize! :create_group + parent_group = find_group!(params[:parent_id]) if params[:parent_id].present? + if parent_group + authorize! :create_subgroup, parent_group + else + authorize! :create_group + end group = ::Groups::CreateService.new(current_user, declared_params(include_missing: false)).execute diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3d377fdb9eb..00dbc2aee7a 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -56,6 +56,12 @@ module API @project ||= find_project!(params[:id]) end + def wiki_page + page = user_project.wiki.find_page(params[:slug]) + + page || not_found!('Wiki Page') + end + def available_labels @available_labels ||= LabelsFinder.new(current_user, project_id: user_project.id).execute end @@ -87,7 +93,7 @@ module API end def find_group(id) - if id =~ /^\d+$/ + if id.to_s =~ /^\d+$/ Group.find_by(id: id) else Group.find_by_full_path(id) @@ -128,6 +134,10 @@ module API merge_request end + def find_build!(id) + user_project.builds.find(id.to_i) + end + def authenticate! unauthorized! unless current_user && can?(initial_current_user, :access_api) end @@ -160,6 +170,14 @@ module API authorize! :admin_project, user_project end + def authorize_read_builds! + authorize! :read_build, user_project + end + + def authorize_update_builds! + authorize! :update_build, user_project + end + def require_gitlab_workhorse! unless env['HTTP_GITLAB_WORKHORSE'].present? forbidden!('Request should be executed via GitLab Workhorse') @@ -210,7 +228,7 @@ module API def bad_request!(attribute) message = ["400 (Bad request)"] - message << "\"" + attribute.to_s + "\" not given" + message << "\"" + attribute.to_s + "\" not given" if attribute render_api_error!(message.join(' '), 400) end @@ -432,6 +450,10 @@ module API header(*Gitlab::Workhorse.send_git_archive(repository, ref: ref, format: format)) end + def send_artifacts_entry(build, entry) + header(*Gitlab::Workhorse.send_artifacts_entry(build, entry)) + end + # The Grape Error Middleware only has access to env but no params. We workaround this by # defining a method that returns the right value. def define_params_for_grape_middleware diff --git a/lib/api/helpers/internal_helpers.rb b/lib/api/helpers/internal_helpers.rb index f57ff0f2632..4c0db4d42b1 100644 --- a/lib/api/helpers/internal_helpers.rb +++ b/lib/api/helpers/internal_helpers.rb @@ -46,6 +46,15 @@ module API ::MergeRequests::GetUrlsService.new(project).execute(params[:changes]) end + def redis_ping + result = Gitlab::Redis::SharedState.with { |redis| redis.ping } + + result == 'PONG' + rescue => e + Rails.logger.warn("GitLab: An unexpected error occurred in pinging to Redis: #{e}") + false + end + private def set_project diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 622bd9650e4..c0fef56378f 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -88,7 +88,8 @@ module API { api_version: API.version, gitlab_version: Gitlab::VERSION, - gitlab_rev: Gitlab::REVISION + gitlab_rev: Gitlab::REVISION, + redis: redis_ping } end @@ -142,6 +143,14 @@ module API { success: true, recovery_codes: codes } end + post '/pre_receive' do + status 200 + + reference_counter_increased = Gitlab::ReferenceCounter.new(params[:gl_repository]).increase + + { reference_counter_increased: reference_counter_increased } + end + post "/notify_post_receive" do status 200 diff --git a/lib/api/job_artifacts.rb b/lib/api/job_artifacts.rb new file mode 100644 index 00000000000..2a8fa7659bf --- /dev/null +++ b/lib/api/job_artifacts.rb @@ -0,0 +1,80 @@ +module API + class JobArtifacts < Grape::API + before { authenticate_non_get! } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + desc 'Download the artifacts file from a job' do + detail 'This feature was introduced in GitLab 8.10' + end + params do + requires :ref_name, type: String, desc: 'The ref from repository' + requires :job, type: String, desc: 'The name for the job' + end + get ':id/jobs/artifacts/:ref_name/download', + requirements: { ref_name: /.+/ } do + authorize_read_builds! + + builds = user_project.latest_successful_builds_for(params[:ref_name]) + latest_build = builds.find_by!(name: params[:job]) + + present_artifacts!(latest_build.artifacts_file) + end + + desc 'Download the artifacts file from a job' do + detail 'This feature was introduced in GitLab 8.5' + end + params do + requires :job_id, type: Integer, desc: 'The ID of a job' + end + get ':id/jobs/:job_id/artifacts' do + authorize_read_builds! + + build = find_build!(params[:job_id]) + + present_artifacts!(build.artifacts_file) + end + + desc 'Download a specific file from artifacts archive' do + detail 'This feature was introduced in GitLab 10.0' + end + params do + requires :job_id, type: Integer, desc: 'The ID of a job' + requires :artifact_path, type: String, desc: 'Artifact path' + end + get ':id/jobs/:job_id/artifacts/*artifact_path', format: false do + authorize_read_builds! + + build = find_build!(params[:job_id]) + not_found! unless build.artifacts? + + path = Gitlab::Ci::Build::Artifacts::Path + .new(params[:artifact_path]) + bad_request! unless path.valid? + + send_artifacts_entry(build, path) + end + + desc 'Keep the artifacts to prevent them from being deleted' do + success Entities::Job + end + params do + requires :job_id, type: Integer, desc: 'The ID of a job' + end + post ':id/jobs/:job_id/artifacts/keep' do + authorize_update_builds! + + build = find_build!(params[:job_id]) + authorize!(:update_build, build) + return not_found!(build) unless build.artifacts? + + build.keep_artifacts! + + status 200 + present build, with: Entities::Job + end + end + end +end diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 5bab96398fd..3c1c412ba42 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -66,42 +66,11 @@ module API get ':id/jobs/:job_id' do authorize_read_builds! - build = get_build!(params[:job_id]) + build = find_build!(params[:job_id]) present build, with: Entities::Job end - desc 'Download the artifacts file from a job' do - detail 'This feature was introduced in GitLab 8.5' - end - params do - requires :job_id, type: Integer, desc: 'The ID of a job' - end - get ':id/jobs/:job_id/artifacts' do - authorize_read_builds! - - build = get_build!(params[:job_id]) - - present_artifacts!(build.artifacts_file) - end - - desc 'Download the artifacts file from a job' do - detail 'This feature was introduced in GitLab 8.10' - end - params do - requires :ref_name, type: String, desc: 'The ref from repository' - requires :job, type: String, desc: 'The name for the job' - end - get ':id/jobs/artifacts/:ref_name/download', - requirements: { ref_name: /.+/ } do - authorize_read_builds! - - builds = user_project.latest_successful_builds_for(params[:ref_name]) - latest_build = builds.find_by!(name: params[:job]) - - present_artifacts!(latest_build.artifacts_file) - end - # TODO: We should use `present_file!` and leave this implementation for backward compatibility (when build trace # is saved in the DB instead of file). But before that, we need to consider how to replace the value of # `runners_token` with some mask (like `xxxxxx`) when sending trace file directly by workhorse. @@ -112,7 +81,7 @@ module API get ':id/jobs/:job_id/trace' do authorize_read_builds! - build = get_build!(params[:job_id]) + build = find_build!(params[:job_id]) header 'Content-Disposition', "infile; filename=\"#{build.id}.log\"" content_type 'text/plain' @@ -131,7 +100,7 @@ module API post ':id/jobs/:job_id/cancel' do authorize_update_builds! - build = get_build!(params[:job_id]) + build = find_build!(params[:job_id]) authorize!(:update_build, build) build.cancel @@ -148,7 +117,7 @@ module API post ':id/jobs/:job_id/retry' do authorize_update_builds! - build = get_build!(params[:job_id]) + build = find_build!(params[:job_id]) authorize!(:update_build, build) return forbidden!('Job is not retryable') unless build.retryable? @@ -166,7 +135,7 @@ module API post ':id/jobs/:job_id/erase' do authorize_update_builds! - build = get_build!(params[:job_id]) + build = find_build!(params[:job_id]) authorize!(:update_build, build) return forbidden!('Job is not erasable!') unless build.erasable? @@ -174,25 +143,6 @@ module API present build, with: Entities::Job end - desc 'Keep the artifacts to prevent them from being deleted' do - success Entities::Job - end - params do - requires :job_id, type: Integer, desc: 'The ID of a job' - end - post ':id/jobs/:job_id/artifacts/keep' do - authorize_update_builds! - - build = get_build!(params[:job_id]) - authorize!(:update_build, build) - return not_found!(build) unless build.artifacts? - - build.keep_artifacts! - - status 200 - present build, with: Entities::Job - end - desc 'Trigger a manual job' do success Entities::Job detail 'This feature was added in GitLab 8.11' @@ -203,7 +153,7 @@ module API post ":id/jobs/:job_id/play" do authorize_read_builds! - build = get_build!(params[:job_id]) + build = find_build!(params[:job_id]) authorize!(:update_build, build) bad_request!("Unplayable Job") unless build.playable? @@ -216,14 +166,6 @@ module API end helpers do - def find_build(id) - user_project.builds.find_by(id: id.to_i) - end - - def get_build!(id) - find_build(id) || not_found! - end - def filter_builds(builds, scope) return builds if scope.nil? || scope.empty? @@ -234,14 +176,6 @@ module API builds.where(status: available_statuses && scope) end - - def authorize_read_builds! - authorize! :read_build, user_project - end - - def authorize_update_builds! - authorize! :update_build, user_project - end end end end diff --git a/lib/api/lint.rb b/lib/api/lint.rb index ae43a4a3237..d202eaa4c49 100644 --- a/lib/api/lint.rb +++ b/lib/api/lint.rb @@ -6,7 +6,7 @@ module API requires :content, type: String, desc: 'Content of .gitlab-ci.yml' end post '/lint' do - error = Ci::GitlabCiYamlProcessor.validation_message(params[:content]) + error = Gitlab::Ci::YamlProcessor.validation_message(params[:content]) status 200 diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index c3affcc6c6b..95ef8f42954 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -21,7 +21,7 @@ module API get ":id/merge_requests/:merge_request_iid/versions" do merge_request = find_merge_request_with_access(params[:merge_request_iid]) - present paginate(merge_request.merge_request_diffs), with: Entities::MergeRequestDiff + present paginate(merge_request.merge_request_diffs.order_id_desc), with: Entities::MergeRequestDiff end desc 'Get a single merge request diff version' do diff --git a/lib/api/milestone_responses.rb b/lib/api/milestone_responses.rb index ef09d9505d2..c570eace862 100644 --- a/lib/api/milestone_responses.rb +++ b/lib/api/milestone_responses.rb @@ -28,7 +28,7 @@ module API end def list_milestones_for(parent) - milestones = parent.milestones + milestones = parent.milestones.order_id_desc milestones = Milestone.filter_by_state(milestones, params[:state]) milestones = filter_by_iid(milestones, params[:iids]) if params[:iids].present? milestones = filter_by_search(milestones, params[:search]) if params[:search] diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 4845242a173..7dc19788462 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -16,6 +16,7 @@ module API optional :jobs_enabled, type: Boolean, desc: 'Flag indication if jobs are enabled' optional :snippets_enabled, type: Boolean, desc: 'Flag indication if snippets are enabled' optional :shared_runners_enabled, type: Boolean, desc: 'Flag indication if shared runners are enabled for that project' + optional :resolve_outdated_diff_discussions, type: Boolean, desc: 'Automatically resolve merge request diffs discussions on lines changed with a push' optional :container_registry_enabled, type: Boolean, desc: 'Flag indication if the container registry is enabled for that project' optional :lfs_enabled, type: Boolean, desc: 'Flag indication if Git LFS is enabled for that project' optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the project.' @@ -236,6 +237,7 @@ module API at_least_one_of_ce = [ :jobs_enabled, + :resolve_outdated_diff_discussions, :container_registry_enabled, :default_branch, :description, diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb index a9a35f2a4bd..c928ce5265b 100644 --- a/lib/api/v3/entities.rb +++ b/lib/api/v3/entities.rb @@ -31,7 +31,7 @@ module API end class Event < Grape::Entity - expose :title, :project_id, :action_name + expose :project_id, :action_name expose :target_id, :target_type, :author_id expose :target_title expose :created_at @@ -64,6 +64,7 @@ module API expose :owner, using: ::API::Entities::UserBasic, unless: ->(project, options) { project.group } expose :name, :name_with_namespace expose :path, :path_with_namespace + expose :resolve_outdated_diff_discussions expose :container_registry_enabled # Expose old field names with the new permissions methods to keep API compatible diff --git a/lib/api/v3/merge_request_diffs.rb b/lib/api/v3/merge_request_diffs.rb index 35f462e907b..22866fc2845 100644 --- a/lib/api/v3/merge_request_diffs.rb +++ b/lib/api/v3/merge_request_diffs.rb @@ -20,7 +20,7 @@ module API get ":id/merge_requests/:merge_request_id/versions" do merge_request = find_merge_request_with_access(params[:merge_request_id]) - present merge_request.merge_request_diffs, with: ::API::Entities::MergeRequestDiff + present merge_request.merge_request_diffs.order_id_desc, with: ::API::Entities::MergeRequestDiff end desc 'Get a single merge request diff version' do diff --git a/lib/api/v3/milestones.rb b/lib/api/v3/milestones.rb index 4c7061d4939..9be4cf9d22a 100644 --- a/lib/api/v3/milestones.rb +++ b/lib/api/v3/milestones.rb @@ -34,6 +34,7 @@ module API milestones = user_project.milestones milestones = filter_milestones_state(milestones, params[:state]) milestones = filter_by_iid(milestones, params[:iid]) if params[:iid].present? + milestones = milestones.order_id_desc present paginate(milestones), with: ::API::Entities::Milestone end diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index 449876c10d9..7c260b8d910 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -18,6 +18,7 @@ module API optional :builds_enabled, type: Boolean, desc: 'Flag indication if builds are enabled' optional :snippets_enabled, type: Boolean, desc: 'Flag indication if snippets are enabled' optional :shared_runners_enabled, type: Boolean, desc: 'Flag indication if shared runners are enabled for that project' + optional :resolve_outdated_diff_discussions, type: Boolean, desc: 'Automatically resolve merge request diffs discussions on lines changed with a push' optional :container_registry_enabled, type: Boolean, desc: 'Flag indication if the container registry is enabled for that project' optional :lfs_enabled, type: Boolean, desc: 'Flag indication if Git LFS is enabled for that project' optional :public, type: Boolean, desc: 'Create a public project. The same as visibility_level = 20.' @@ -119,7 +120,7 @@ module API get do authenticate! - present_projects current_user.authorized_projects, + present_projects current_user.authorized_projects.order_id_desc, with: ::API::V3::Entities::ProjectWithAccess end @@ -296,9 +297,9 @@ module API use :optional_params at_least_one_of :name, :description, :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, - :shared_runners_enabled, :container_registry_enabled, - :lfs_enabled, :public, :visibility_level, :public_builds, - :request_access_enabled, :only_allow_merge_if_build_succeeds, + :shared_runners_enabled, :resolve_outdated_diff_discussions, + :container_registry_enabled, :lfs_enabled, :public, :visibility_level, + :public_builds, :request_access_enabled, :only_allow_merge_if_build_succeeds, :only_allow_merge_if_all_discussions_are_resolved, :path, :default_branch end diff --git a/lib/api/wikis.rb b/lib/api/wikis.rb new file mode 100644 index 00000000000..b3fc4e876ad --- /dev/null +++ b/lib/api/wikis.rb @@ -0,0 +1,89 @@ +module API + class Wikis < Grape::API + helpers do + params :wiki_page_params do + requires :content, type: String, desc: 'Content of a wiki page' + requires :title, type: String, desc: 'Title of a wiki page' + optional :format, + type: String, + values: ProjectWiki::MARKUPS.values.map(&:to_s), + default: 'markdown', + desc: 'Format of a wiki page. Available formats are markdown, rdoc, and asciidoc' + end + end + + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + desc 'Get a list of wiki pages' do + success Entities::WikiPageBasic + end + params do + optional :with_content, type: Boolean, default: false, desc: "Include pages' content" + end + get ':id/wikis' do + authorize! :read_wiki, user_project + + entity = params[:with_content] ? Entities::WikiPage : Entities::WikiPageBasic + present user_project.wiki.pages, with: entity + end + + desc 'Get a wiki page' do + success Entities::WikiPage + end + params do + requires :slug, type: String, desc: 'The slug of a wiki page' + end + get ':id/wikis/:slug' do + authorize! :read_wiki, user_project + + present wiki_page, with: Entities::WikiPage + end + + desc 'Create a wiki page' do + success Entities::WikiPage + end + params do + use :wiki_page_params + end + post ':id/wikis' do + authorize! :create_wiki, user_project + + page = WikiPages::CreateService.new(user_project, current_user, params).execute + + if page.valid? + present page, with: Entities::WikiPage + else + render_validation_error!(page) + end + end + + desc 'Update a wiki page' do + success Entities::WikiPage + end + params do + use :wiki_page_params + end + put ':id/wikis/:slug' do + authorize! :create_wiki, user_project + + page = WikiPages::UpdateService.new(user_project, current_user, params).execute(wiki_page) + + if page.valid? + present page, with: Entities::WikiPage + else + render_validation_error!(page) + end + end + + desc 'Delete a wiki page' + params do + requires :slug, type: String, desc: 'The slug of a wiki page' + end + delete ':id/wikis/:slug' do + authorize! :admin_wiki, user_project + + status 204 + WikiPages::DestroyService.new(user_project, current_user).execute(wiki_page) + end + end + end +end |