diff options
Diffstat (limited to 'lib/api')
-rw-r--r-- | lib/api/api.rb | 13 | ||||
-rw-r--r-- | lib/api/entities.rb | 28 | ||||
-rw-r--r-- | lib/api/helpers.rb | 32 | ||||
-rw-r--r-- | lib/api/internal.rb | 25 | ||||
-rw-r--r-- | lib/api/merge_request_diffs.rb | 45 | ||||
-rw-r--r-- | lib/api/project_hooks.rb | 2 | ||||
-rw-r--r-- | lib/api/projects.rb | 9 |
7 files changed, 140 insertions, 14 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 6b8bfbbdae6..4602e627fdb 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -18,22 +18,14 @@ module API end rescue_from :all do |exception| - # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60 - # why is this not wrapped in something reusable? - trace = exception.backtrace - - message = "\n#{exception.class} (#{exception.message}):\n" - message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) - message << " " << trace.join("\n ") - - API.logger.add Logger::FATAL, message - rack_response({ 'message' => '500 Internal Server Error' }.to_json, 500) + handle_api_exception(exception) end format :json content_type :txt, "text/plain" # Ensure the namespace is right, otherwise we might load Grape::API::Helpers + helpers ::SentryHelper helpers ::API::Helpers mount ::API::AccessRequests @@ -75,5 +67,6 @@ module API mount ::API::Triggers mount ::API::Users mount ::API::Variables + mount ::API::MergeRequestDiffs end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 66b85ab1793..cbb324dd06d 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -49,7 +49,7 @@ module API class ProjectHook < Hook expose :project_id, :push_events expose :issues_events, :merge_requests_events, :tag_push_events - expose :note_events, :build_events, :pipeline_events + expose :note_events, :build_events, :pipeline_events, :wiki_page_events expose :enable_ssl_verification end @@ -90,6 +90,7 @@ module API expose :shared_with_groups do |project, options| SharedGroup.represent(project.project_group_links.all, options) end + expose :only_allow_merge_if_build_succeeds end class Member < UserBasic @@ -177,6 +178,10 @@ module API # TODO (rspeicher): Deprecated; remove in 9.0 expose(:expires_at) { |snippet| nil } + + expose :web_url do |snippet, options| + Gitlab::UrlBuilder.build(snippet) + end end class ProjectEntity < Grape::Entity @@ -206,6 +211,10 @@ module API expose :user_notes_count expose :upvotes, :downvotes expose :due_date + + expose :web_url do |issue, options| + Gitlab::UrlBuilder.build(issue) + end end class ExternalIssue < Grape::Entity @@ -229,6 +238,10 @@ module API expose :user_notes_count expose :should_remove_source_branch?, as: :should_remove_source_branch expose :force_remove_source_branch?, as: :force_remove_source_branch + + expose :web_url do |merge_request, options| + Gitlab::UrlBuilder.build(merge_request) + end end class MergeRequestChanges < MergeRequest @@ -237,6 +250,19 @@ module API end end + class MergeRequestDiff < Grape::Entity + expose :id, :head_commit_sha, :base_commit_sha, :start_commit_sha, + :created_at, :merge_request_id, :state, :real_size + end + + class MergeRequestDiffFull < MergeRequestDiff + expose :commits, using: Entities::RepoCommit + + expose :diffs, using: Entities::RepoDiff do |compare, _| + compare.raw_diffs(all_diffs: true).to_a + end + end + class SSHKey < Grape::Entity expose :id, :title, :key, :created_at end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index d0469d6602d..da4b1bf9902 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -279,6 +279,24 @@ module API error!({ 'message' => message }, status) end + def handle_api_exception(exception) + if sentry_enabled? && report_exception?(exception) + define_params_for_grape_middleware + sentry_context + Raven.capture_exception(exception) + end + + # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60 + trace = exception.backtrace + + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << trace.join("\n ") + + API.logger.add Logger::FATAL, message + rack_response({ 'message' => '500 Internal Server Error' }.to_json, 500) + end + # Projects helpers def filter_projects(projects) @@ -419,5 +437,19 @@ module API Entities::Issue end 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 + self.define_singleton_method(:params) { Rack::Request.new(env).params.symbolize_keys } + end + + # We could get a Grape or a standard Ruby exception. We should only report anything that + # is clearly an error. + def report_exception?(exception) + return true unless exception.respond_to?(:status) + + exception.status == 500 + end end end diff --git a/lib/api/internal.rb b/lib/api/internal.rb index d8e9ac406c4..5b54c11ef62 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -101,6 +101,31 @@ module API {} end end + + post '/two_factor_recovery_codes' do + status 200 + + key = Key.find(params[:key_id]) + user = key.user + + # Make sure this isn't a deploy key + unless key.type.nil? + return { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' } + end + + unless user.present? + return { success: false, message: 'Could not find a user for the given key' } + end + + unless user.two_factor_enabled? + return { success: false, message: 'Two-factor authentication is not enabled for this user' } + end + + codes = user.generate_otp_backup_codes! + user.save! + + { success: true, recovery_codes: codes } + end end end end diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb new file mode 100644 index 00000000000..07435d78468 --- /dev/null +++ b/lib/api/merge_request_diffs.rb @@ -0,0 +1,45 @@ +module API + # MergeRequestDiff API + class MergeRequestDiffs < Grape::API + before { authenticate! } + + resource :projects do + desc 'Get a list of merge request diff versions' do + detail 'This feature was introduced in GitLab 8.12.' + success Entities::MergeRequestDiff + end + + params do + requires :id, type: String, desc: 'The ID of a project' + requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' + end + + get ":id/merge_requests/:merge_request_id/versions" do + merge_request = user_project.merge_requests. + find(params[:merge_request_id]) + + authorize! :read_merge_request, merge_request + present merge_request.merge_request_diffs, with: Entities::MergeRequestDiff + end + + desc 'Get a single merge request diff version' do + detail 'This feature was introduced in GitLab 8.12.' + success Entities::MergeRequestDiffFull + end + + params do + requires :id, type: String, desc: 'The ID of a project' + requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' + requires :version_id, type: Integer, desc: 'The ID of a merge request diff version' + end + + get ":id/merge_requests/:merge_request_id/versions/:version_id" do + merge_request = user_project.merge_requests. + find(params[:merge_request_id]) + + authorize! :read_merge_request, merge_request + present merge_request.merge_request_diffs.find(params[:version_id]), with: Entities::MergeRequestDiffFull + end + end + end +end diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 3f63cd678e8..14f5be3b5f6 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -46,6 +46,7 @@ module API :note_events, :build_events, :pipeline_events, + :wiki_page_events, :enable_ssl_verification ] @hook = user_project.hooks.new(attrs) @@ -80,6 +81,7 @@ module API :note_events, :build_events, :pipeline_events, + :wiki_page_events, :enable_ssl_verification ] diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 60cfc103afd..71efd4f33ca 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -123,7 +123,8 @@ module API :public, :visibility_level, :import_url, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(current_user, attrs).execute if @project.saved? @@ -172,7 +173,8 @@ module API :public, :visibility_level, :import_url, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(user, attrs).execute if @project.saved? @@ -234,7 +236,8 @@ module API :shared_runners_enabled, :public, :visibility_level, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) authorize_admin_project authorize! :rename_project, user_project if attrs[:name].present? |