From 76c3d2d434d3c550c3de912abc0a5b1dc1455368 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 9 Jun 2017 16:24:54 -0500 Subject: Add full JSON endpoints for issue notes and discussions --- lib/api/entities.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 09a88869063..89ab2118dd5 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1,11 +1,11 @@ module API module Entities class UserSafe < Grape::Entity - expose :name, :username + expose :id, :name, :username end class UserBasic < UserSafe - expose :id, :state + expose :state expose :avatar_url do |user, options| user.avatar_url(only_path: false) end -- cgit v1.2.1 From 9770c57fab0315865a33c8b6df269eded0d57b5c Mon Sep 17 00:00:00 2001 From: Brian Neel Date: Thu, 3 Aug 2017 22:20:34 -0400 Subject: Re-enable SqlInjection and CommandInjection --- lib/api/helpers/members_helpers.rb | 4 +++- lib/api/notes.rb | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb index d9cae1501f8..a50ea0b52aa 100644 --- a/lib/api/helpers/members_helpers.rb +++ b/lib/api/helpers/members_helpers.rb @@ -1,8 +1,10 @@ +# rubocop:disable GitlabSecurity/PublicSend + module API module Helpers module MembersHelpers def find_source(source_type, id) - public_send("find_#{source_type}!", id) + public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend end def authorize_admin_source!(source_type, source) diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 65ff89edf65..4e4e473994b 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -139,7 +139,7 @@ module API helpers do def find_project_noteable(noteables_str, noteable_id) - public_send("find_project_#{noteables_str.singularize}", noteable_id) + public_send("find_project_#{noteables_str.singularize}", noteable_id) # rubocop:disable GitlabSecurity/PublicSend end def noteable_read_ability_name(noteable) -- cgit v1.2.1 From c946ee1282655d332da4ba99c448d6f68cf87cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 9 Aug 2017 11:52:22 +0200 Subject: Enable the Layout/SpaceBeforeBlockBraces cop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- lib/api/entities.rb | 2 +- lib/api/v3/entities.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 6ba4005dd0b..3bb1910a441 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -132,7 +132,7 @@ module API expose :lfs_enabled?, as: :lfs_enabled expose :creator_id expose :namespace, using: 'API::Entities::Namespace' - expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? } + expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? } expose :import_status expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } expose :avatar_url do |user, options| diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb index 773f667abe0..4a2e9c9cbb0 100644 --- a/lib/api/v3/entities.rb +++ b/lib/api/v3/entities.rb @@ -68,7 +68,7 @@ module API expose :lfs_enabled?, as: :lfs_enabled expose :creator_id expose :namespace, using: 'API::Entities::Namespace' - expose :forked_from_project, using: ::API::Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? } + expose :forked_from_project, using: ::API::Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? } expose :avatar_url do |user, options| user.avatar_url(only_path: false) end -- cgit v1.2.1 From 0395c47193b3bbf6b4f060f28c9f632580313a35 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Mon, 10 Jul 2017 17:43:57 +0200 Subject: Migrate events into a new format This commit migrates events data in such a way that push events are stored much more efficiently. This is done by creating a shadow table called "events_for_migration", and a table called "push_event_payloads" which is used for storing push data of push events. The background migration in this commit will copy events from the "events" table into the "events_for_migration" table, push events in will also have a row created in "push_event_payloads". This approach allows us to reclaim space in the next release by simply swapping the "events" and "events_for_migration" tables, then dropping the old events (now "events_for_migration") table. The new table structure is also optimised for storage space, and does not include the unused "title" column nor the "data" column (since this data is moved to "push_event_payloads"). == Newly Created Events Newly created events are inserted into both "events" and "events_for_migration", both using the exact same primary key value. The table "push_event_payloads" in turn has a foreign key to the _shadow_ table. This removes the need for recreating and validating the foreign key after swapping the tables. Since the shadow table also has a foreign key to "projects.id" we also don't have to worry about orphaned rows. This approach however does require some additional storage as we're duplicating a portion of the events data for at least 1 release. The exact amount is hard to estimate, but for GitLab.com this is expected to be between 10 and 20 GB at most. The background migration in this commit deliberately does _not_ update the "events" table as doing so would put a lot of pressure on PostgreSQL's auto vacuuming system. == Supporting Both Old And New Events Application code has also been adjusted to support push events using both the old and new data formats. This is done by creating a PushEvent class which extends the regular Event class. Using Rails' Single Table Inheritance system we can ensure the right class is used for the right data, which in this case is based on the value of `events.action`. To support displaying old and new data at the same time the PushEvent class re-defines a few methods of the Event class, falling back to their original implementations for push events in the old format. Once all existing events have been migrated the various push event related methods can be removed from the Event model, and the calls to `super` can be removed from the methods in the PushEvent model. The UI and event atom feed have also been slightly changed to better handle this new setup, fortunately only a few changes were necessary to make this work. == API Changes The API only displays push data of events in the new format. Supporting both formats in the API is a bit more difficult compared to the UI. Since the old push data was not really well documented (apart from one example that used an incorrect "action" nmae) I decided that supporting both was not worth the effort, especially since events will be migrated in a few days _and_ new events are created in the correct format. --- lib/api/entities.rb | 12 +++++++++++- lib/api/v3/entities.rb | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 3bb1910a441..18cd604a216 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -497,14 +497,24 @@ module API expose :author, using: Entities::UserBasic end + class PushEventPayload < Grape::Entity + expose :commit_count, :action, :ref_type, :commit_from, :commit_to + expose :ref, :commit_title + end + class Event < Grape::Entity expose :title, :project_id, :action_name expose :target_id, :target_iid, :target_type, :author_id - expose :data, :target_title + expose :target_title expose :created_at expose :note, using: Entities::Note, if: ->(event, options) { event.note? } expose :author, using: Entities::UserBasic, if: ->(event, options) { event.author } + expose :push_event_payload, + as: :push_data, + using: PushEventPayload, + if: -> (event, _) { event.push? } + expose :author_username do |event, options| event.author&.username end diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb index 4a2e9c9cbb0..a9a35f2a4bd 100644 --- a/lib/api/v3/entities.rb +++ b/lib/api/v3/entities.rb @@ -25,14 +25,24 @@ module API expose(:downvote?) { |note| false } end + class PushEventPayload < Grape::Entity + expose :commit_count, :action, :ref_type, :commit_from, :commit_to + expose :ref, :commit_title + end + class Event < Grape::Entity expose :title, :project_id, :action_name expose :target_id, :target_type, :author_id - expose :data, :target_title + expose :target_title expose :created_at expose :note, using: Entities::Note, if: ->(event, options) { event.note? } expose :author, using: ::API::Entities::UserBasic, if: ->(event, options) { event.author } + expose :push_event_payload, + as: :push_data, + using: PushEventPayload, + if: -> (event, _) { event.push? } + expose :author_username do |event, options| event.author&.username end -- cgit v1.2.1 From 4f0fa13eb85994b747c1eb253e346b76b98b5c5b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 11 Aug 2017 20:50:35 +0800 Subject: Show error message for API 500 error in tests, and document have_gitlab_http_status --- lib/api/helpers.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 99b8b62691f..3582ed81b0f 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -257,7 +257,15 @@ module API message << " " << trace.join("\n ") API.logger.add Logger::FATAL, message - rack_response({ 'message' => '500 Internal Server Error' }.to_json, 500) + + response_message = + if Rails.env.test? + message + else + '500 Internal Server Error' + end + + rack_response({ 'message' => response_message }.to_json, 500) end # project helpers -- cgit v1.2.1 From 09a348eb139178be534d181273a360a3125df9f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 11 Aug 2017 14:08:20 +0200 Subject: Include the `is_admin` field in the `GET /users/:id` API when current user is an admin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- lib/api/users.rb | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'lib/api') diff --git a/lib/api/users.rb b/lib/api/users.rb index a590f2692a2..e2019d6d512 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -79,22 +79,17 @@ module API end desc 'Get a single user' do - success Entities::UserBasic + success Entities::User end params do requires :id, type: Integer, desc: 'The ID of the user' end get ":id" do user = User.find_by(id: params[:id]) - not_found!('User') unless user + not_found!('User') unless user && can?(current_user, :read_user, user) - if current_user && current_user.admin? - present user, with: Entities::UserPublic - elsif can?(current_user, :read_user, user) - present user, with: Entities::User - else - render_api_error!("User not found.", 404) - end + opts = current_user&.admin? ? { with: Entities::UserWithAdmin } : {} + present user, opts end desc 'Create a user. Available only for admins.' do -- cgit v1.2.1 From 649d042dbc9e2bfda96bb98b0eabd4b00ea2daff Mon Sep 17 00:00:00 2001 From: Robin Bobbitt Date: Mon, 31 Jul 2017 17:34:47 -0400 Subject: Add option to disable project export on instance --- lib/api/settings.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/api') diff --git a/lib/api/settings.rb b/lib/api/settings.rb index d55a61fa638..667ba468ce6 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -29,6 +29,7 @@ module API desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com' optional :disabled_oauth_sign_in_sources, type: Array[String], desc: 'Disable certain OAuth sign-in sources' optional :enabled_git_access_protocol, type: String, values: %w[ssh http nil], desc: 'Allow only the selected protocols to be used for Git access.' + optional :project_export_enabled, type: Boolean, desc: 'Enable project export' optional :gravatar_enabled, type: Boolean, desc: 'Flag indicating if the Gravatar service is enabled' optional :default_projects_limit, type: Integer, desc: 'The maximum number of personal projects' optional :max_attachment_size, type: Integer, desc: 'Maximum attachment size in MB' -- cgit v1.2.1 From aef9f1eb9405e9bab92b15f5c99bf06eaf28a5d6 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Mon, 14 Aug 2017 15:22:09 +0200 Subject: Cache the number of forks of a project The number of forks of a project doesn't change very frequently and running a COUNT(*) every time this information is requested can be quite expensive. We also end up running such a COUNT(*) query at least twice on the homepage of a project. By caching this data and refreshing it when necessary we can reduce project homepage loading times by around 60 milliseconds (based on the timings of https://gitlab.com/gitlab-org/gitlab-ce). --- lib/api/projects.rb | 2 ++ lib/api/v3/projects.rb | 2 ++ 2 files changed, 4 insertions(+) (limited to 'lib/api') diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 89dda88d3f5..15c3832b032 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -351,6 +351,8 @@ module API if user_project.forked_from_project.nil? user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id) + + ::Projects::ForksCountService.new(forked_from_project).refresh_cache else render_api_error!("Project already forked", 409) end diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index eb090453b48..449876c10d9 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -388,6 +388,8 @@ module API if user_project.forked_from_project.nil? user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id) + + ::Projects::ForksCountService.new(forked_from_project).refresh_cache else render_api_error!("Project already forked", 409) end -- cgit v1.2.1 From 260c8da060a6039cbd47cfe31c8ec6d6f9b43de0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 10 Aug 2017 12:39:26 -0400 Subject: Whitelist or fix additional `Gitlab/PublicSend` cop violations An upcoming update to rubocop-gitlab-security added additional violations. --- lib/api/api_guard.rb | 2 +- lib/api/entities.rb | 5 +++-- lib/api/runners.rb | 2 +- lib/api/v3/notes.rb | 6 +++--- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/api') diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index 0d2d71e336a..c4c0fdda665 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -122,7 +122,7 @@ module API error_classes = [MissingTokenError, TokenNotFoundError, ExpiredError, RevokedError, InsufficientScopeError] - base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler + base.__send__(:rescue_from, *error_classes, oauth2_bearer_token_error_handler) # rubocop:disable GitlabSecurity/PublicSend end def oauth2_bearer_token_error_handler diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 18cd604a216..716e3f11744 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -541,8 +541,9 @@ module API target_url = "namespace_project_#{target_type}_url" target_anchor = "note_#{todo.note_id}" if todo.note_id? - Gitlab::Routing.url_helpers.public_send(target_url, - todo.project.namespace, todo.project, todo.target, anchor: target_anchor) + Gitlab::Routing + .url_helpers + .public_send(target_url, todo.project.namespace, todo.project, todo.target, anchor: target_anchor) # rubocop:disable GitlabSecurity/PublicSend end expose :body diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 5bf5a18e42f..31f940fe96b 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -153,7 +153,7 @@ module API render_api_error!('Scope contains invalid value', 400) end - runners.send(scope) + runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend end def get_runner(id) diff --git a/lib/api/v3/notes.rb b/lib/api/v3/notes.rb index 23fe95e42e4..d49772b92f2 100644 --- a/lib/api/v3/notes.rb +++ b/lib/api/v3/notes.rb @@ -22,7 +22,7 @@ module API use :pagination end get ":id/#{noteables_str}/:noteable_id/notes" do - noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id]) + noteable = user_project.public_send(noteables_str.to_sym).find(params[:noteable_id]) # rubocop:disable GitlabSecurity/PublicSend if can?(current_user, noteable_read_ability_name(noteable), noteable) # We exclude notes that are cross-references and that cannot be viewed @@ -50,7 +50,7 @@ module API requires :noteable_id, type: Integer, desc: 'The ID of the noteable' end get ":id/#{noteables_str}/:noteable_id/notes/:note_id" do - noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id]) + noteable = user_project.public_send(noteables_str.to_sym).find(params[:noteable_id]) # rubocop:disable GitlabSecurity/PublicSend note = noteable.notes.find(params[:note_id]) can_read_note = can?(current_user, noteable_read_ability_name(noteable), noteable) && !note.cross_reference_not_visible_for?(current_user) @@ -76,7 +76,7 @@ module API noteable_id: params[:noteable_id] } - noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id]) + noteable = user_project.public_send(noteables_str.to_sym).find(params[:noteable_id]) # rubocop:disable GitlabSecurity/PublicSend if can?(current_user, noteable_read_ability_name(noteable), noteable) if params[:created_at] && (current_user.admin? || user_project.owner == current_user) -- cgit v1.2.1 From b7e98620046501144302ff8f9fbf22ff03ef4db7 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Thu, 10 Aug 2017 16:16:54 -0300 Subject: Fix API responses when dealing with txt files --- lib/api/files.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/api') diff --git a/lib/api/files.rb b/lib/api/files.rb index 450334fee84..e2ac7142bc4 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -1,5 +1,8 @@ module API class Files < Grape::API + # Prevents returning plain/text responses for files with .txt extension + after_validation { content_type "application/json" } + helpers do def commit_params(attrs) { -- cgit v1.2.1 From 4edfad96784e8f77ec8ead26f01b4012977ba58a Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 15 Aug 2017 13:44:37 -0400 Subject: Enable Layout/TrailingWhitespace cop and auto-correct offenses --- lib/api/entities.rb | 2 +- lib/api/protected_branches.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 18cd604a216..4219808fdc3 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -83,7 +83,7 @@ module API expose :created_at, :last_activity_at end - class Project < BasicProjectDetails + class Project < BasicProjectDetails include ::API::Helpers::RelatedResourcesHelpers expose :_links do diff --git a/lib/api/protected_branches.rb b/lib/api/protected_branches.rb index d742f2e18d0..dccf4fa27a7 100644 --- a/lib/api/protected_branches.rb +++ b/lib/api/protected_branches.rb @@ -61,7 +61,7 @@ module API service_args = [user_project, current_user, protected_branch_params] protected_branch = ::ProtectedBranches::CreateService.new(*service_args).execute - + if protected_branch.persisted? present protected_branch, with: Entities::ProtectedBranch, project: user_project else -- cgit v1.2.1 From dc8e1676cda528cfca9ec9679da10ff90ec76282 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 16 Aug 2017 18:06:59 +0200 Subject: Upgrade grape to 1.0 Main feature was the deprication of the Hashie stuff, so the access by calling keys as method is gone now. --- lib/api/helpers.rb | 2 +- lib/api/jobs.rb | 4 ++-- lib/api/templates.rb | 6 +++--- lib/api/v3/builds.rb | 2 +- lib/api/v3/templates.rb | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3582ed81b0f..b56fd2388b3 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -290,7 +290,7 @@ module API def uploaded_file(field, uploads_path) if params[field] - bad_request!("#{field} is not a file") unless params[field].respond_to?(:filename) + bad_request!("#{field} is not a file") unless params[field][:filename] return params[field] end diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 8a67de10bca..a40018b214e 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -16,9 +16,9 @@ module API case scope when String [scope] - when Hashie::Mash + when ::Hash scope.values - when Hashie::Array + when ::Array scope else ['unknown'] diff --git a/lib/api/templates.rb b/lib/api/templates.rb index 0fc13b35d5b..f70bc0622b7 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -57,7 +57,7 @@ module API end get "templates/licenses" do options = { - featured: declared(params).popular.present? ? true : nil + featured: declared(params)[:popular].present? ? true : nil } licences = ::Kaminari.paginate_array(Licensee::License.all(options)) present paginate(licences), with: Entities::RepoLicense @@ -71,7 +71,7 @@ module API requires :name, type: String, desc: 'The name of the template' end get "templates/licenses/:name", requirements: { name: /[\w\.-]+/ } do - not_found!('License') unless Licensee::License.find(declared(params).name) + not_found!('License') unless Licensee::License.find(declared(params)[:name]) template = parsed_license_template @@ -102,7 +102,7 @@ module API requires :name, type: String, desc: 'The name of the template' end get "templates/#{template_type}/:name" do - new_template = klass.find(declared(params).name) + new_template = klass.find(declared(params)[:name]) render_response(template_type, new_template) end diff --git a/lib/api/v3/builds.rb b/lib/api/v3/builds.rb index 93ad9eb26b8..c189d486f50 100644 --- a/lib/api/v3/builds.rb +++ b/lib/api/v3/builds.rb @@ -16,7 +16,7 @@ module API coerce_with: ->(scope) { if scope.is_a?(String) [scope] - elsif scope.is_a?(Hashie::Mash) + elsif scope.is_a?(::Hash) scope.values else ['unknown'] diff --git a/lib/api/v3/templates.rb b/lib/api/v3/templates.rb index 4c577a8d2b7..2a2fb59045c 100644 --- a/lib/api/v3/templates.rb +++ b/lib/api/v3/templates.rb @@ -59,7 +59,7 @@ module API end get route do options = { - featured: declared(params).popular.present? ? true : nil + featured: declared(params)[:popular].present? ? true : nil } present Licensee::License.all(options), with: ::API::Entities::RepoLicense end @@ -76,7 +76,7 @@ module API requires :name, type: String, desc: 'The name of the template' end get route, requirements: { name: /[\w\.-]+/ } do - not_found!('License') unless Licensee::License.find(declared(params).name) + not_found!('License') unless Licensee::License.find(declared(params)[:name]) template = parsed_license_template @@ -111,7 +111,7 @@ module API requires :name, type: String, desc: 'The name of the template' end get route do - new_template = klass.find(declared(params).name) + new_template = klass.find(declared(params)[:name]) render_response(template_type, new_template) end -- cgit v1.2.1 From fdf4f0fc0884c0346b16ec107a1ea1084dd4a32f Mon Sep 17 00:00:00 2001 From: Jordan Patterson Date: Thu, 17 Aug 2017 09:18:07 -0300 Subject: don't add next page link if current page is out of range --- lib/api/helpers/pagination.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/helpers/pagination.rb b/lib/api/helpers/pagination.rb index 0764b58fb4c..e86e221e092 100644 --- a/lib/api/helpers/pagination.rb +++ b/lib/api/helpers/pagination.rb @@ -30,7 +30,7 @@ module API links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") unless paginated_data.first_page? request_params[:page] = paginated_data.current_page + 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? + links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? || paginated_data.out_of_range? request_params[:page] = 1 links << %(<#{request_url}?#{request_params.to_query}>; rel="first") -- cgit v1.2.1 From e17d9529faa4d292d7f869a0f9ebbbcde4cc6f9e Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Thu, 17 Aug 2017 17:56:01 +0200 Subject: Total Pages should be at least one And the link to the last page cannot be `page=0`. --- lib/api/helpers/pagination.rb | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers/pagination.rb b/lib/api/helpers/pagination.rb index e86e221e092..95108292aac 100644 --- a/lib/api/helpers/pagination.rb +++ b/lib/api/helpers/pagination.rb @@ -11,7 +11,7 @@ module API def add_pagination_headers(paginated_data) header 'X-Total', paginated_data.total_count.to_s - header 'X-Total-Pages', paginated_data.total_pages.to_s + header 'X-Total-Pages', total_pages(paginated_data).to_s header 'X-Per-Page', paginated_data.limit_value.to_s header 'X-Page', paginated_data.current_page.to_s header 'X-Next-Page', paginated_data.next_page.to_s @@ -26,20 +26,25 @@ module API links = [] - request_params[:page] = paginated_data.current_page - 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") unless paginated_data.first_page? + request_params[:page] = paginated_data.prev_page + links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") if request_params[:page] - request_params[:page] = paginated_data.current_page + 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? || paginated_data.out_of_range? + request_params[:page] = paginated_data.next_page + links << %(<#{request_url}?#{request_params.to_query}>; rel="next") if request_params[:page] request_params[:page] = 1 links << %(<#{request_url}?#{request_params.to_query}>; rel="first") - request_params[:page] = paginated_data.total_pages + request_params[:page] = total_pages(paginated_data) links << %(<#{request_url}?#{request_params.to_query}>; rel="last") links.join(', ') end + + def total_pages(paginated_data) + # Ensure there is in total at least 1 page + [paginated_data.total_pages, 1].max + end end end end -- cgit v1.2.1 From 502d6464b07154d74eecbeddbf2cd6dba841380f Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 23 Aug 2017 13:01:11 +0100 Subject: Allow v4 API GET requests for groups to be unauthenticated --- lib/api/groups.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/api') diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 49c3b2278c7..892fd239df4 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -2,7 +2,7 @@ module API class Groups < Grape::API include PaginationParams - before { authenticate! } + before { authenticate_non_get! } helpers do params :optional_params_ce do @@ -48,10 +48,10 @@ module API end get do groups = if params[:owned] - current_user.owned_groups - elsif current_user.admin + current_user ? current_user.owned_groups : Group.none + elsif current_user&.admin? Group.all - elsif params[:all_available] + elsif params[:all_available] || current_user.nil? GroupsFinder.new(current_user).execute else current_user.groups -- cgit v1.2.1 From 2adff699cea2cf1e60180d7eae73dfe5e8a09235 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 24 Aug 2017 11:33:06 +0100 Subject: Refactor complicated API group finding rules into GroupsFinder --- lib/api/groups.rb | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'lib/api') diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 892fd239df4..e56427304a6 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -47,16 +47,8 @@ module API use :pagination end get do - groups = if params[:owned] - current_user ? current_user.owned_groups : Group.none - elsif current_user&.admin? - Group.all - elsif params[:all_available] || current_user.nil? - GroupsFinder.new(current_user).execute - else - current_user.groups - end - + find_params = { all_available: params[:all_available], owned: params[:owned] } + groups = GroupsFinder.new(current_user, find_params).execute groups = groups.search(params[:search]) if params[:search].present? groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present? groups = groups.reorder(params[:order_by] => params[:sort]) -- cgit v1.2.1 From 998afa5f74558be215a924d95aa131a69831ca43 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 1 Mar 2017 14:35:48 +0100 Subject: API: Respect the 'If-Unmodified-Since' for delete endpoints --- lib/api/access_requests.rb | 3 +++ lib/api/award_emoji.rb | 1 + lib/api/boards.rb | 1 + lib/api/broadcast_messages.rb | 1 + lib/api/deploy_keys.rb | 2 ++ lib/api/environments.rb | 1 + lib/api/groups.rb | 2 ++ lib/api/helpers.rb | 8 ++++++++ lib/api/issues.rb | 2 ++ lib/api/labels.rb | 2 ++ lib/api/members.rb | 3 ++- lib/api/merge_requests.rb | 2 ++ lib/api/notes.rb | 2 ++ lib/api/project_hooks.rb | 2 ++ lib/api/project_snippets.rb | 2 ++ lib/api/projects.rb | 2 ++ lib/api/runners.rb | 2 ++ lib/api/services.rb | 2 ++ lib/api/snippets.rb | 1 + lib/api/system_hooks.rb | 2 ++ lib/api/triggers.rb | 2 ++ lib/api/users.rb | 28 ++++++++++++++++++++++++++++ 22 files changed, 72 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index cdacf9839e5..0c5b8862d79 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -67,6 +67,9 @@ module API end delete ":id/access_requests/:user_id" do source = find_source(source_type, params[:id]) + member = source.public_send(:requesters).find_by!(user_id: params[:user_id]) + + check_unmodified_since(member.updated_at) status 204 ::Members::DestroyService.new(source, current_user, params) diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 5a028fc9d0b..51a8587d26e 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -85,6 +85,7 @@ module API end delete "#{endpoint}/:award_id" do award = awardable.award_emoji.find(params[:award_id]) + check_unmodified_since(award.updated_at) unauthorized! unless award.user == current_user || current_user.admin? diff --git a/lib/api/boards.rb b/lib/api/boards.rb index 5a2d7a681e3..d36df77dc6c 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -124,6 +124,7 @@ module API authorize!(:admin_list, user_project) list = board_lists.find(params[:list_id]) + check_unmodified_since(list.updated_at) service = ::Boards::Lists::DestroyService.new(user_project, current_user) diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb index 9980aec4752..352972b584a 100644 --- a/lib/api/broadcast_messages.rb +++ b/lib/api/broadcast_messages.rb @@ -90,6 +90,7 @@ module API end delete ':id' do message = find_message + check_unmodified_since(message.updated_at) status 204 message.destroy diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index 42e7c1486b0..971cc816454 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -125,6 +125,8 @@ module API key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id]) not_found!('Deploy Key') unless key + check_unmodified_since(key.updated_at) + status 204 key.destroy end diff --git a/lib/api/environments.rb b/lib/api/environments.rb index c774a5c6685..3fc423ae79a 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -78,6 +78,7 @@ module API authorize! :update_environment, user_project environment = user_project.environments.find(params[:environment_id]) + check_unmodified_since(environment.updated_at) status 204 environment.destroy diff --git a/lib/api/groups.rb b/lib/api/groups.rb index e56427304a6..c9b32a85487 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -117,6 +117,8 @@ module API delete ":id" do group = find_group!(params[:id]) authorize! :admin_group, group + + check_unmodified_since(group.updated_at) status 204 ::Groups::DestroyService.new(group, current_user).execute diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index b56fd2388b3..1c74a14d91c 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -11,6 +11,14 @@ module API declared(params, options).to_h.symbolize_keys end + def check_unmodified_since(last_modified) + if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) if headers.key?('If-Unmodified-Since') rescue nil + + if if_unmodified_since && if_unmodified_since < last_modified + render_api_error!('412 Precondition Failed', 412) + end + end + def current_user return @current_user if defined?(@current_user) diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 4cec1145f3a..cee9898d3a6 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -230,6 +230,8 @@ module API not_found!('Issue') unless issue authorize!(:destroy_issue, issue) + check_unmodified_since(issue.updated_at) + status 204 issue.destroy end diff --git a/lib/api/labels.rb b/lib/api/labels.rb index 4520c98d951..45fa57fdf55 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -56,6 +56,8 @@ module API label = user_project.labels.find_by(title: params[:name]) not_found!('Label') unless label + check_unmodified_since(label.updated_at) + status 204 label.destroy end diff --git a/lib/api/members.rb b/lib/api/members.rb index bb970b7cd54..5634f123eca 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -94,7 +94,8 @@ module API delete ":id/members/:user_id" do source = find_source(source_type, params[:id]) # Ensure that memeber exists - source.members.find_by!(user_id: params[:user_id]) + member = source.members.find_by!(user_id: params[:user_id]) + check_unmodified_since(member.updated_at) status 204 ::Members::DestroyService.new(source, current_user, declared_params).execute diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 8810d4e441d..c6fecc1aa6c 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -164,6 +164,8 @@ module API merge_request = find_project_merge_request(params[:merge_request_iid]) authorize!(:destroy_merge_request, merge_request) + check_unmodified_since(merge_request.updated_at) + status 204 merge_request.destroy end diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 4e4e473994b..58d71787aca 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -129,7 +129,9 @@ module API end delete ":id/#{noteables_str}/:noteable_id/notes/:note_id" do note = user_project.notes.find(params[:note_id]) + authorize! :admin_note, note + check_unmodified_since(note.updated_at) status 204 ::Notes::DestroyService.new(user_project, current_user).execute(note) diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 649dd891f56..74d736fda59 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -96,6 +96,8 @@ module API delete ":id/hooks/:hook_id" do hook = user_project.hooks.find(params.delete(:hook_id)) + check_unmodified_since(hook.updated_at) + status 204 hook.destroy end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index f3d905b0068..645162d564d 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -116,6 +116,8 @@ module API not_found!('Snippet') unless snippet authorize! :admin_project_snippet, snippet + check_unmodified_since(snippet.updated_at) + status 204 snippet.destroy end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 15c3832b032..eab0ca0b3c9 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -334,6 +334,8 @@ module API desc 'Remove a project' delete ":id" do authorize! :remove_project, user_project + check_unmodified_since(user_project.updated_at) + ::Projects::DestroyService.new(user_project, current_user, {}).async_execute accepted! diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 31f940fe96b..e3b2eb904b7 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -77,7 +77,9 @@ module API end delete ':id' do runner = get_runner(params[:id]) + authenticate_delete_runner!(runner) + check_unmodified_since(runner.updated_at) status 204 runner.destroy! diff --git a/lib/api/services.rb b/lib/api/services.rb index 843c05ae32e..4fef3383e5e 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -655,6 +655,8 @@ module API end delete ":id/services/:service_slug" do service = user_project.find_or_initialize_service(params[:service_slug].underscore) + # Todo, not sure + check_unmodified_since(service.updated_at) attrs = service_attributes(service).inject({}) do |hash, key| hash.merge!(key => nil) diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb index 35ece56c65c..7107b3d669c 100644 --- a/lib/api/snippets.rb +++ b/lib/api/snippets.rb @@ -122,6 +122,7 @@ module API return not_found!('Snippet') unless snippet authorize! :destroy_personal_snippet, snippet + check_unmodified_since(snippet.updated_at) status 204 snippet.destroy diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb index c0179037440..64066a75b15 100644 --- a/lib/api/system_hooks.rb +++ b/lib/api/system_hooks.rb @@ -66,6 +66,8 @@ module API hook = SystemHook.find_by(id: params[:id]) not_found!('System hook') unless hook + check_unmodified_since(hook.updated_at) + status 204 hook.destroy end diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index edfdb63d183..4ae70c65759 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -140,6 +140,8 @@ module API trigger = user_project.triggers.find(params.delete(:trigger_id)) return not_found!('Trigger') unless trigger + check_unmodified_since(trigger.updated_at) + status 204 trigger.destroy end diff --git a/lib/api/users.rb b/lib/api/users.rb index e2019d6d512..942bb72cf97 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -230,7 +230,12 @@ module API key = user.keys.find_by(id: params[:key_id]) not_found!('Key') unless key +<<<<<<< HEAD status 204 +======= + check_unmodified_since(key.updated_at) + +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints key.destroy end @@ -287,7 +292,14 @@ module API email = user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email +<<<<<<< HEAD Emails::DestroyService.new(user, email: email.email).execute +======= + check_unmodified_since(email.updated_at) + + email.destroy + user.update_secondary_emails! +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end desc 'Delete a user. Available only for admins.' do @@ -299,11 +311,18 @@ module API end delete ":id" do authenticated_as_admin! + user = User.find_by(id: params[:id]) not_found!('User') unless user +<<<<<<< HEAD status 204 user.delete_async(deleted_by: current_user, params: params) +======= + check_unmodified_since(user.updated_at) + + ::Users::DestroyService.new(current_user).execute(user) +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end desc 'Block a user. Available only for admins.' @@ -481,6 +500,8 @@ module API key = current_user.keys.find_by(id: params[:key_id]) not_found!('Key') unless key + check_unmodified_since(key.updated_at) + status 204 key.destroy end @@ -533,6 +554,7 @@ module API email = current_user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email +<<<<<<< HEAD status 204 Emails::DestroyService.new(current_user, email: email.email).execute end @@ -550,6 +572,12 @@ module API .reorder(last_activity_on: :asc) present paginate(activities), with: Entities::UserActivity +======= + check_unmodified_since(email.updated_at) + + email.destroy + current_user.update_secondary_emails! +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end end end -- cgit v1.2.1 From e80313f9ee5b3495a8713e6ddae111bc8106155b Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 2 Mar 2017 13:14:13 +0100 Subject: Conditionally destroy a ressource --- lib/api/access_requests.rb | 11 +++++----- lib/api/award_emoji.rb | 4 +--- lib/api/boards.rb | 11 +++++----- lib/api/broadcast_messages.rb | 4 +--- lib/api/deploy_keys.rb | 5 +---- lib/api/environments.rb | 4 +--- lib/api/groups.rb | 7 +++---- lib/api/helpers.rb | 17 +++++++++++++--- lib/api/issues.rb | 4 +--- lib/api/labels.rb | 5 +---- lib/api/members.rb | 7 +++---- lib/api/merge_requests.rb | 4 +--- lib/api/notes.rb | 6 +++--- lib/api/project_hooks.rb | 5 +---- lib/api/project_snippets.rb | 4 +--- lib/api/projects.rb | 5 +++-- lib/api/runner.rb | 6 ++++-- lib/api/runners.rb | 7 ++----- lib/api/services.rb | 4 ++-- lib/api/snippets.rb | 4 +--- lib/api/system_hooks.rb | 5 +---- lib/api/triggers.rb | 5 +---- lib/api/users.rb | 47 ++++++++++++------------------------------- 23 files changed, 69 insertions(+), 112 deletions(-) (limited to 'lib/api') diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index 0c5b8862d79..4fa9b2b2494 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -67,13 +67,12 @@ module API end delete ":id/access_requests/:user_id" do source = find_source(source_type, params[:id]) - member = source.public_send(:requesters).find_by!(user_id: params[:user_id]) + member = source.requesters.find_by!(user_id: params[:user_id]) - check_unmodified_since(member.updated_at) - - status 204 - ::Members::DestroyService.new(source, current_user, params) - .execute(:requesters) + destroy_conditionally!(member) do + ::Members::DestroyService.new(source, current_user, params) + .execute(:requesters) + end end end end diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 51a8587d26e..8e3851640da 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -85,12 +85,10 @@ module API end delete "#{endpoint}/:award_id" do award = awardable.award_emoji.find(params[:award_id]) - check_unmodified_since(award.updated_at) unauthorized! unless award.user == current_user || current_user.admin? - status 204 - award.destroy + destroy_conditionally!(award) end end end diff --git a/lib/api/boards.rb b/lib/api/boards.rb index d36df77dc6c..0d11c5fc971 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -122,14 +122,13 @@ module API end delete "/lists/:list_id" do authorize!(:admin_list, user_project) - list = board_lists.find(params[:list_id]) - check_unmodified_since(list.updated_at) - - service = ::Boards::Lists::DestroyService.new(user_project, current_user) - unless service.execute(list) - render_api_error!({ error: 'List could not be deleted!' }, 400) + destroy_conditionally!(list) do |list| + service = ::Boards::Lists::DestroyService.new(user_project, current_user) + unless service.execute(list) + render_api_error!({ error: 'List could not be deleted!' }, 400) + end end end end diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb index 352972b584a..0b45621ce7b 100644 --- a/lib/api/broadcast_messages.rb +++ b/lib/api/broadcast_messages.rb @@ -90,10 +90,8 @@ module API end delete ':id' do message = find_message - check_unmodified_since(message.updated_at) - status 204 - message.destroy + destroy_conditionally!(message) end end end diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index 971cc816454..f405c341398 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -125,10 +125,7 @@ module API key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id]) not_found!('Deploy Key') unless key - check_unmodified_since(key.updated_at) - - status 204 - key.destroy + destroy_conditionally!(key) end end end diff --git a/lib/api/environments.rb b/lib/api/environments.rb index 3fc423ae79a..e33269f9483 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -78,10 +78,8 @@ module API authorize! :update_environment, user_project environment = user_project.environments.find(params[:environment_id]) - check_unmodified_since(environment.updated_at) - status 204 - environment.destroy + destroy_conditionally!(environment) end desc 'Stops an existing environment' do diff --git a/lib/api/groups.rb b/lib/api/groups.rb index c9b32a85487..ee2ad27837b 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -117,11 +117,10 @@ module API delete ":id" do group = find_group!(params[:id]) authorize! :admin_group, group - - check_unmodified_since(group.updated_at) - status 204 - ::Groups::DestroyService.new(group, current_user).execute + destroy_conditionally!(group) do |group| + ::Groups::DestroyService.new(group, current_user).execute + end end desc 'Get a list of projects in this group.' do diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 1c74a14d91c..8d4f8c01903 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -11,14 +11,25 @@ module API declared(params, options).to_h.symbolize_keys end - def check_unmodified_since(last_modified) - if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) if headers.key?('If-Unmodified-Since') rescue nil + def check_unmodified_since!(last_modified) + if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) rescue nil - if if_unmodified_since && if_unmodified_since < last_modified + if if_unmodified_since && last_modified > if_unmodified_since render_api_error!('412 Precondition Failed', 412) end end + def destroy_conditionally!(resource, last_update_field: :updated_at) + check_unmodified_since!(resource.public_send(last_update_field)) + + status 204 + if block_given? + yield resource + else + resource.destroy + end + end + def current_user return @current_user if defined?(@current_user) diff --git a/lib/api/issues.rb b/lib/api/issues.rb index cee9898d3a6..6503629e2a2 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -230,10 +230,8 @@ module API not_found!('Issue') unless issue authorize!(:destroy_issue, issue) - check_unmodified_since(issue.updated_at) - status 204 - issue.destroy + destroy_conditionally!(issue) end desc 'List merge requests closing issue' do diff --git a/lib/api/labels.rb b/lib/api/labels.rb index 45fa57fdf55..c0cf618ee8d 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -56,10 +56,7 @@ module API label = user_project.labels.find_by(title: params[:name]) not_found!('Label') unless label - check_unmodified_since(label.updated_at) - - status 204 - label.destroy + destroy_conditionally!(label) end desc 'Update an existing label. At least one optional parameter is required.' do diff --git a/lib/api/members.rb b/lib/api/members.rb index 5634f123eca..a5d3d7f25a0 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -93,12 +93,11 @@ module API end delete ":id/members/:user_id" do source = find_source(source_type, params[:id]) - # Ensure that memeber exists member = source.members.find_by!(user_id: params[:user_id]) - check_unmodified_since(member.updated_at) - status 204 - ::Members::DestroyService.new(source, current_user, declared_params).execute + destroy_conditionally!(member) do + ::Members::DestroyService.new(source, current_user, declared_params).execute + end end end end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index c6fecc1aa6c..969c6064662 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -164,10 +164,8 @@ module API merge_request = find_project_merge_request(params[:merge_request_iid]) authorize!(:destroy_merge_request, merge_request) - check_unmodified_since(merge_request.updated_at) - status 204 - merge_request.destroy + destroy_conditionally!(merge_request) end params do diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 58d71787aca..e116448c15b 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -131,10 +131,10 @@ module API note = user_project.notes.find(params[:note_id]) authorize! :admin_note, note - check_unmodified_since(note.updated_at) - status 204 - ::Notes::DestroyService.new(user_project, current_user).execute(note) + destroy_conditionally!(note) do |note| + ::Notes::DestroyService.new(user_project, current_user).execute(note) + end end end end diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 74d736fda59..5b457bbe639 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -96,10 +96,7 @@ module API delete ":id/hooks/:hook_id" do hook = user_project.hooks.find(params.delete(:hook_id)) - check_unmodified_since(hook.updated_at) - - status 204 - hook.destroy + destroy_conditionally!(hook) end end end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index 645162d564d..704e8c6718d 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -116,10 +116,8 @@ module API not_found!('Snippet') unless snippet authorize! :admin_project_snippet, snippet - check_unmodified_since(snippet.updated_at) - status 204 - snippet.destroy + destroy_conditionally!(snippet) end desc 'Get a raw project snippet' diff --git a/lib/api/projects.rb b/lib/api/projects.rb index eab0ca0b3c9..36fe3f243b9 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -334,9 +334,10 @@ module API desc 'Remove a project' delete ":id" do authorize! :remove_project, user_project - check_unmodified_since(user_project.updated_at) - ::Projects::DestroyService.new(user_project, current_user, {}).async_execute + destroy_conditionally!(user_project) do + ::Projects::DestroyService.new(user_project, current_user, {}).async_execute + end accepted! end diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 88fc62d33df..daa8ddbe251 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -45,8 +45,10 @@ module API end delete '/' do authenticate_runner! - status 204 - Ci::Runner.find_by_token(params[:token]).destroy + + runner = Ci::Runner.find_by_token(params[:token]) + + destroy_conditionally!(runner) end desc 'Validates authentication credentials' do diff --git a/lib/api/runners.rb b/lib/api/runners.rb index e3b2eb904b7..68c2120cc15 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -79,10 +79,8 @@ module API runner = get_runner(params[:id]) authenticate_delete_runner!(runner) - check_unmodified_since(runner.updated_at) - status 204 - runner.destroy! + destroy_conditionally!(runner) end end @@ -137,8 +135,7 @@ module API runner = runner_project.runner forbidden!("Only one project associated with the runner. Please remove the runner instead") if runner.projects.count == 1 - status 204 - runner_project.destroy + destroy_conditionally!(runner_project) end end diff --git a/lib/api/services.rb b/lib/api/services.rb index 4fef3383e5e..2b5ef75b6bf 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -655,8 +655,8 @@ module API end delete ":id/services/:service_slug" do service = user_project.find_or_initialize_service(params[:service_slug].underscore) - # Todo, not sure - check_unmodified_since(service.updated_at) + # Todo: Check if this done the right way + check_unmodified_since!(service.updated_at) attrs = service_attributes(service).inject({}) do |hash, key| hash.merge!(key => nil) diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb index 7107b3d669c..00eb7c60f16 100644 --- a/lib/api/snippets.rb +++ b/lib/api/snippets.rb @@ -122,10 +122,8 @@ module API return not_found!('Snippet') unless snippet authorize! :destroy_personal_snippet, snippet - check_unmodified_since(snippet.updated_at) - status 204 - snippet.destroy + destroy_conditionally!(snippet) end desc 'Get a raw snippet' do diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb index 64066a75b15..6b6a03e3300 100644 --- a/lib/api/system_hooks.rb +++ b/lib/api/system_hooks.rb @@ -66,10 +66,7 @@ module API hook = SystemHook.find_by(id: params[:id]) not_found!('System hook') unless hook - check_unmodified_since(hook.updated_at) - - status 204 - hook.destroy + destroy_conditionally!(hook) end end end diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index 4ae70c65759..c9fee7e5193 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -140,10 +140,7 @@ module API trigger = user_project.triggers.find(params.delete(:trigger_id)) return not_found!('Trigger') unless trigger - check_unmodified_since(trigger.updated_at) - - status 204 - trigger.destroy + destroy_conditionally!(trigger) end end end diff --git a/lib/api/users.rb b/lib/api/users.rb index 942bb72cf97..d7c7b9ae9c1 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -230,13 +230,7 @@ module API key = user.keys.find_by(id: params[:key_id]) not_found!('Key') unless key -<<<<<<< HEAD - status 204 -======= - check_unmodified_since(key.updated_at) - ->>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints - key.destroy + destroy_conditionally!(key) end desc 'Add an email address to a specified user. Available only for admins.' do @@ -292,14 +286,11 @@ module API email = user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email -<<<<<<< HEAD - Emails::DestroyService.new(user, email: email.email).execute -======= - check_unmodified_since(email.updated_at) + destroy_conditionally!(email) do |email| + Emails::DestroyService.new(current_user, email: email.email).execute + end - email.destroy user.update_secondary_emails! ->>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end desc 'Delete a user. Available only for admins.' do @@ -315,14 +306,9 @@ module API user = User.find_by(id: params[:id]) not_found!('User') unless user -<<<<<<< HEAD - status 204 - user.delete_async(deleted_by: current_user, params: params) -======= - check_unmodified_since(user.updated_at) - - ::Users::DestroyService.new(current_user).execute(user) ->>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints + destroy_conditionally!(user) do + user.delete_async(deleted_by: current_user, params: params) + end end desc 'Block a user. Available only for admins.' @@ -500,10 +486,7 @@ module API key = current_user.keys.find_by(id: params[:key_id]) not_found!('Key') unless key - check_unmodified_since(key.updated_at) - - status 204 - key.destroy + destroy_conditionally!(key) end desc "Get the currently authenticated user's email addresses" do @@ -554,9 +537,11 @@ module API email = current_user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email -<<<<<<< HEAD - status 204 - Emails::DestroyService.new(current_user, email: email.email).execute + destroy_conditionally!(email) do |email| + Emails::DestroyService.new(current_user, email: email.email).execute + end + + current_user.update_secondary_emails! end desc 'Get a list of user activities' @@ -572,12 +557,6 @@ module API .reorder(last_activity_on: :asc) present paginate(activities), with: Entities::UserActivity -======= - check_unmodified_since(email.updated_at) - - email.destroy - current_user.update_secondary_emails! ->>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end end end -- cgit v1.2.1 From f0f3f38576c0691e6d0e751c962382beea998afb Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 2 Mar 2017 14:21:36 +0100 Subject: Use commit date for branches and tags --- lib/api/branches.rb | 15 +++++++++++---- lib/api/tags.rb | 15 +++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'lib/api') diff --git a/lib/api/branches.rb b/lib/api/branches.rb index d3dbf941298..b87f7cdbad1 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -125,11 +125,18 @@ module API delete ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do authorize_push_project - result = DeleteBranchService.new(user_project, current_user) - .execute(params[:branch]) + branch = user_project.repository.find_branch(params[:branch]) + not_found!('Branch') unless branch + + commit = user_project.repository.commit(branch.dereferenced_target) + + destroy_conditionally!(commit, last_update_field: :authored_date) do + result = DeleteBranchService.new(user_project, current_user) + .execute(params[:branch]) - if result[:status] != :success - render_api_error!(result[:message], result[:return_code]) + if result[:status] != :success + render_api_error!(result[:message], result[:return_code]) + end end end diff --git a/lib/api/tags.rb b/lib/api/tags.rb index 1333747cced..81b17935b81 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -65,11 +65,18 @@ module API delete ':id/repository/tags/:tag_name', requirements: TAG_ENDPOINT_REQUIREMENTS do authorize_push_project - result = ::Tags::DestroyService.new(user_project, current_user) - .execute(params[:tag_name]) + tag = user_project.repository.find_tag(params[:tag_name]) + not_found!('Tag') unless tag + + commit = user_project.repository.commit(tag.dereferenced_target) + + destroy_conditionally!(commit, last_update_field: :authored_date) do + result = ::Tags::DestroyService.new(user_project, current_user) + .execute(params[:tag_name]) - if result[:status] != :success - render_api_error!(result[:message], result[:return_code]) + if result[:status] != :success + render_api_error!(result[:message], result[:return_code]) + end end end -- cgit v1.2.1 From dcd4ea473cab20eee05995ecaca043da98ca5a8d Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 24 Aug 2017 10:41:54 +0200 Subject: Update remaining endpoints --- lib/api/group_variables.rb | 3 +-- lib/api/helpers.rb | 2 +- lib/api/pipeline_schedules.rb | 3 +-- lib/api/projects.rb | 1 - lib/api/protected_branches.rb | 4 +--- lib/api/services.rb | 14 +++++++------- lib/api/users.rb | 7 +++++-- lib/api/variables.rb | 1 + 8 files changed, 17 insertions(+), 18 deletions(-) (limited to 'lib/api') diff --git a/lib/api/group_variables.rb b/lib/api/group_variables.rb index f64da4ab77b..25152f30998 100644 --- a/lib/api/group_variables.rb +++ b/lib/api/group_variables.rb @@ -88,8 +88,7 @@ module API variable = user_group.variables.find_by(key: params[:key]) not_found!('GroupVariable') unless variable - status 204 - variable.destroy + destroy_conditionally!(variable) end end end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 8d4f8c01903..84980864151 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -14,7 +14,7 @@ module API def check_unmodified_since!(last_modified) if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) rescue nil - if if_unmodified_since && last_modified > if_unmodified_since + if if_unmodified_since && last_modified && last_modified > if_unmodified_since render_api_error!('412 Precondition Failed', 412) end end diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index dbeaf9e17ef..e3123ef4e2d 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -117,8 +117,7 @@ module API not_found!('PipelineSchedule') unless pipeline_schedule authorize! :admin_pipeline_schedule, pipeline_schedule - status :accepted - present pipeline_schedule.destroy, with: Entities::PipelineScheduleDetails + destroy_conditionally!(pipeline_schedule) end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 36fe3f243b9..78e25b6da03 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -1,7 +1,6 @@ require_dependency 'declarative_policy' module API - # Projects API class Projects < Grape::API include PaginationParams diff --git a/lib/api/protected_branches.rb b/lib/api/protected_branches.rb index dccf4fa27a7..15fcb9e8e27 100644 --- a/lib/api/protected_branches.rb +++ b/lib/api/protected_branches.rb @@ -76,9 +76,7 @@ module API delete ':id/protected_branches/:name', requirements: BRANCH_ENDPOINT_REQUIREMENTS do protected_branch = user_project.protected_branches.find_by!(name: params[:name]) - protected_branch.destroy - - status 204 + destroy_conditionally!(protected_branch) end end end diff --git a/lib/api/services.rb b/lib/api/services.rb index 2b5ef75b6bf..ff9ddd44439 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -655,15 +655,15 @@ module API end delete ":id/services/:service_slug" do service = user_project.find_or_initialize_service(params[:service_slug].underscore) - # Todo: Check if this done the right way - check_unmodified_since!(service.updated_at) - attrs = service_attributes(service).inject({}) do |hash, key| - hash.merge!(key => nil) - end + destroy_conditionally!(service) do + attrs = service_attributes(service).inject({}) do |hash, key| + hash.merge!(key => nil) + end - unless service.update_attributes(attrs.merge(active: false)) - render_api_error!('400 Bad Request', 400) + unless service.update_attributes(attrs.merge(active: false)) + render_api_error!('400 Bad Request', 400) + end end end diff --git a/lib/api/users.rb b/lib/api/users.rb index d7c7b9ae9c1..96f47bb618a 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -408,8 +408,11 @@ module API requires :impersonation_token_id, type: Integer, desc: 'The ID of the impersonation token' end delete ':impersonation_token_id' do - status 204 - find_impersonation_token.revoke! + token = find_impersonation_token + + destroy_conditionally!(token) do + token.revoke! + end end end end diff --git a/lib/api/variables.rb b/lib/api/variables.rb index 7c0fdd3d1be..da71787abab 100644 --- a/lib/api/variables.rb +++ b/lib/api/variables.rb @@ -88,6 +88,7 @@ module API variable = user_project.variables.find_by(key: params[:key]) not_found!('Variable') unless variable + # Variables don't have any timestamp. Therfore, destroy unconditionally. status 204 variable.destroy end -- cgit v1.2.1 From ee4820a5268d02fb7ed142511d1a194f06629a1e Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Mon, 28 Aug 2017 17:13:22 +0200 Subject: Add a spec when ressource is not modified --- lib/api/projects.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/api') diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 78e25b6da03..78d900984ac 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -365,8 +365,7 @@ module API authorize! :remove_fork_project, user_project if user_project.forked? - status 204 - user_project.forked_project_link.destroy + destroy_conditionally!(user_project.forked_project_link) else not_modified! end @@ -410,8 +409,7 @@ module API link = user_project.project_group_links.find_by(group_id: params[:group_id]) not_found!('Group Link') unless link - status 204 - link.destroy + destroy_conditionally!(link) end desc 'Upload a file' -- cgit v1.2.1 From 9226804bf32bcecd826818eb626714b52285c5e8 Mon Sep 17 00:00:00 2001 From: Maxim Rydkin Date: Thu, 24 Aug 2017 19:44:36 +0300 Subject: replace `is_runner_queue_value_latest?` with `runner_queue_value_latest?` --- lib/api/runner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 88fc62d33df..1a7ded31c91 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -78,7 +78,7 @@ module API no_content! unless current_runner.active? update_runner_info - if current_runner.is_runner_queue_value_latest?(params[:last_update]) + if current_runner.runner_queue_value_latest?(params[:last_update]) header 'X-GitLab-Last-Update', params[:last_update] Gitlab::Metrics.add_event(:build_not_found_cached) return no_content! -- cgit v1.2.1 From ce1ce82045f168143ccc143f5200ea9da820d990 Mon Sep 17 00:00:00 2001 From: Travis Miller Date: Mon, 21 Aug 2017 17:42:03 -0500 Subject: Resolve new N+1 by adding preloads and metadata to issues end points --- lib/api/entities.rb | 22 ++++++++++++++++++++-- lib/api/issues.rb | 22 +++++++++++++++++++--- 2 files changed, 39 insertions(+), 5 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index e8dd61e493f..e18c69b7a3d 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -320,7 +320,10 @@ module API end class IssueBasic < ProjectEntity - expose :label_names, as: :labels + expose :labels do |issue, options| + # Avoids an N+1 query since labels are preloaded + issue.labels.map(&:title).sort + end expose :milestone, using: Entities::Milestone expose :assignees, :author, using: Entities::UserBasic @@ -329,7 +332,22 @@ module API end expose :user_notes_count - expose :upvotes, :downvotes + expose :upvotes do |issue, options| + if options[:issuable_metadata] + # Avoids an N+1 query when metadata is included + options[:issuable_metadata][issue.id].upvotes + else + issue.upvotes + end + end + expose :downvotes do |issue, options| + if options[:issuable_metadata] + # Avoids an N+1 query when metadata is included + options[:issuable_metadata][issue.id].downvotes + else + issue.downvotes + end + end expose :due_date expose :confidential diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 4cec1145f3a..64a425eb96e 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -4,6 +4,8 @@ module API before { authenticate! } + helpers ::Gitlab::IssuableMetadata + helpers do def find_issues(args = {}) args = params.merge(args) @@ -13,6 +15,7 @@ module API args[:label_name] = args.delete(:labels) issues = IssuesFinder.new(current_user, args).execute + .preload(:assignees, :labels, :notes) issues.reorder(args[:order_by] => args[:sort]) end @@ -65,7 +68,11 @@ module API get do issues = find_issues - present paginate(issues), with: Entities::IssueBasic, current_user: current_user + options = { with: Entities::IssueBasic, + current_user: current_user } + options[:issuable_metadata] = issuable_meta_data(issues, 'Issue') + + present paginate(issues), options end end @@ -86,7 +93,11 @@ module API issues = find_issues(group_id: group.id) - present paginate(issues), with: Entities::IssueBasic, current_user: current_user + options = { with: Entities::IssueBasic, + current_user: current_user } + options[:issuable_metadata] = issuable_meta_data(issues, 'Issue') + + present paginate(issues), options end end @@ -109,7 +120,12 @@ module API issues = find_issues(project_id: project.id) - present paginate(issues), with: Entities::IssueBasic, current_user: current_user, project: user_project + options = { with: Entities::IssueBasic, + current_user: current_user, + project: user_project } + options[:issuable_metadata] = issuable_meta_data(issues, 'Issue') + + present paginate(issues), options end desc 'Get a single project issue' do -- cgit v1.2.1 From 749c389345cf382b740277db62f7d4b849902d60 Mon Sep 17 00:00:00 2001 From: Travis Miller Date: Mon, 28 Aug 2017 19:02:26 -0500 Subject: Add time stats to issue and merge request API end points --- lib/api/entities.rb | 22 +++++++++++++++++++++- lib/api/issues.rb | 28 +++++++++++++++++----------- lib/api/merge_requests.rb | 2 +- 3 files changed, 39 insertions(+), 13 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index e18c69b7a3d..803b48dd88a 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -354,6 +354,10 @@ module API expose :web_url do |issue, options| Gitlab::UrlBuilder.build(issue) end + + expose :time_stats, using: 'API::Entities::IssuableTimeStats' do |issue| + issue + end end class Issue < IssueBasic @@ -383,10 +387,22 @@ module API end class IssuableTimeStats < Grape::Entity + format_with(:time_tracking_formatter) do |time_spent| + Gitlab::TimeTrackingFormatter.output(time_spent) + end + expose :time_estimate expose :total_time_spent expose :human_time_estimate - expose :human_total_time_spent + + with_options(format_with: :time_tracking_formatter) do + expose :total_time_spent, as: :human_total_time_spent + end + + def total_time_spent + # Avoids an N+1 query since timelogs are preloaded + object.timelogs.map(&:time_spent).sum + end end class ExternalIssue < Grape::Entity @@ -436,6 +452,10 @@ module API expose :web_url do |merge_request, options| Gitlab::UrlBuilder.build(merge_request) end + + expose :time_stats, using: 'API::Entities::IssuableTimeStats' do |merge_request| + merge_request + end end class MergeRequest < MergeRequestBasic diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 64a425eb96e..c30e430ae85 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -15,7 +15,7 @@ module API args[:label_name] = args.delete(:labels) issues = IssuesFinder.new(current_user, args).execute - .preload(:assignees, :labels, :notes) + .preload(:assignees, :labels, :notes, :timelogs) issues.reorder(args[:order_by] => args[:sort]) end @@ -68,9 +68,11 @@ module API get do issues = find_issues - options = { with: Entities::IssueBasic, - current_user: current_user } - options[:issuable_metadata] = issuable_meta_data(issues, 'Issue') + options = { + with: Entities::IssueBasic, + current_user: current_user, + issuable_metadata: issuable_meta_data(issues, 'Issue') + } present paginate(issues), options end @@ -93,9 +95,11 @@ module API issues = find_issues(group_id: group.id) - options = { with: Entities::IssueBasic, - current_user: current_user } - options[:issuable_metadata] = issuable_meta_data(issues, 'Issue') + options = { + with: Entities::IssueBasic, + current_user: current_user, + issuable_metadata: issuable_meta_data(issues, 'Issue') + } present paginate(issues), options end @@ -120,10 +124,12 @@ module API issues = find_issues(project_id: project.id) - options = { with: Entities::IssueBasic, - current_user: current_user, - project: user_project } - options[:issuable_metadata] = issuable_meta_data(issues, 'Issue') + options = { + with: Entities::IssueBasic, + current_user: current_user, + project: user_project, + issuable_metadata: issuable_meta_data(issues, 'Issue') + } present paginate(issues), options end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 8810d4e441d..a3284afb745 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -21,7 +21,7 @@ module API return merge_requests if args[:view] == 'simple' merge_requests - .preload(:notes, :author, :assignee, :milestone, :merge_request_diff, :labels) + .preload(:notes, :author, :assignee, :milestone, :merge_request_diff, :labels, :timelogs) end params :merge_requests_params do -- cgit v1.2.1 From 67c042e4a5603a39494c3c7e407161348d7e85f3 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 29 Aug 2017 16:49:43 +0200 Subject: Respect the default visibility level when creating a group --- lib/api/groups.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/groups.rb b/lib/api/groups.rb index e56427304a6..15266e9d4e5 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -7,7 +7,9 @@ module API helpers do params :optional_params_ce do optional :description, type: String, desc: 'The description of the group' - optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the group' + optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, + default: Gitlab::VisibilityLevel.string_level(Gitlab::CurrentSettings.current_application_settings.default_group_visibility), + desc: 'The visibility of the group' optional :lfs_enabled, type: Boolean, desc: 'Enable/disable LFS for the projects in this group' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :share_with_group_lock, type: Boolean, desc: 'Prevent sharing a project with another group within this group' -- cgit v1.2.1 From 9edaff0d3547ba9854e69655a4ae4d5095b8a25f Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 30 Aug 2017 10:11:24 +0200 Subject: Make rubocop happy --- lib/api/groups.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 15266e9d4e5..cf3cee0073c 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -7,9 +7,11 @@ module API helpers do params :optional_params_ce do optional :description, type: String, desc: 'The description of the group' - optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, - default: Gitlab::VisibilityLevel.string_level(Gitlab::CurrentSettings.current_application_settings.default_group_visibility), - desc: 'The visibility of the group' + optional :visibility, type: String, + values: Gitlab::VisibilityLevel.string_values, + default: Gitlab::VisibilityLevel.string_level( + Gitlab::CurrentSettings.current_application_settings.default_group_visibility), + desc: 'The visibility of the group' optional :lfs_enabled, type: Boolean, desc: 'Enable/disable LFS for the projects in this group' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :share_with_group_lock, type: Boolean, desc: 'Prevent sharing a project with another group within this group' -- cgit v1.2.1 From b9d8946395ebe2b0d05e464e6a2af1181c7f1b90 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Wed, 30 Aug 2017 13:33:39 +0100 Subject: Don't use public_send in destroy_conditionally! helper As we only override in two places, we could just ask for the value rather than the method name. --- lib/api/branches.rb | 2 +- lib/api/helpers.rb | 6 ++++-- lib/api/tags.rb | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/api') diff --git a/lib/api/branches.rb b/lib/api/branches.rb index b87f7cdbad1..a989394ad91 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -130,7 +130,7 @@ module API commit = user_project.repository.commit(branch.dereferenced_target) - destroy_conditionally!(commit, last_update_field: :authored_date) do + destroy_conditionally!(commit, last_updated: commit.authored_date) do result = DeleteBranchService.new(user_project, current_user) .execute(params[:branch]) diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 84980864151..3d377fdb9eb 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -19,8 +19,10 @@ module API end end - def destroy_conditionally!(resource, last_update_field: :updated_at) - check_unmodified_since!(resource.public_send(last_update_field)) + def destroy_conditionally!(resource, last_updated: nil) + last_updated ||= resource.updated_at + + check_unmodified_since!(last_updated) status 204 if block_given? diff --git a/lib/api/tags.rb b/lib/api/tags.rb index 81b17935b81..912415e3a7f 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -70,7 +70,7 @@ module API commit = user_project.repository.commit(tag.dereferenced_target) - destroy_conditionally!(commit, last_update_field: :authored_date) do + destroy_conditionally!(commit, last_updated: commit.authored_date) do result = ::Tags::DestroyService.new(user_project, current_user) .execute(params[:tag_name]) -- cgit v1.2.1 From f3b6c552f6763e20bbccaa80e306d939d6cf602c Mon Sep 17 00:00:00 2001 From: Marc Siegfriedt Date: Mon, 21 Aug 2017 21:09:45 +0000 Subject: fix :file_path - add requirements: --- lib/api/files.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/files.rb b/lib/api/files.rb index e2ac7142bc4..1598d3c00b8 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -1,5 +1,7 @@ module API class Files < Grape::API + FILE_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(file_path: API::NO_SLASH_URL_PART_REGEX) + # Prevents returning plain/text responses for files with .txt extension after_validation { content_type "application/json" } @@ -58,13 +60,13 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: FILE_ENDPOINT_REQUIREMENTS do desc 'Get raw file contents from the repository' params do requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb' requires :ref, type: String, desc: 'The name of branch, tag commit' end - get ":id/repository/files/:file_path/raw" do + get ":id/repository/files/:file_path/raw", requirements: FILE_ENDPOINT_REQUIREMENTS do assign_file_vars! send_git_blob @repo, @blob @@ -75,7 +77,7 @@ module API requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb' requires :ref, type: String, desc: 'The name of branch, tag or commit' end - get ":id/repository/files/:file_path", requirements: { file_path: /.+/ } do + get ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do assign_file_vars! { @@ -95,7 +97,7 @@ module API params do use :extended_file_params end - post ":id/repository/files/:file_path", requirements: { file_path: /.+/ } do + post ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do authorize! :push_code, user_project file_params = declared_params(include_missing: false) @@ -113,7 +115,7 @@ module API params do use :extended_file_params end - put ":id/repository/files/:file_path", requirements: { file_path: /.+/ } do + put ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do authorize! :push_code, user_project file_params = declared_params(include_missing: false) @@ -137,7 +139,7 @@ module API params do use :simple_file_params end - delete ":id/repository/files/:file_path", requirements: { file_path: /.+/ } do + delete ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do authorize! :push_code, user_project file_params = declared_params(include_missing: false) -- cgit v1.2.1 From b0f982fbdf69c292ab4530c0aaaf1ab42f4e7a01 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 21 Aug 2017 11:30:03 +0100 Subject: Add settings for minimum key strength and allowed key type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an amalgamation of: * Cory Hinshaw: Initial implementation !5552 * Rémy Coutable: Updates !9350 * Nick Thomas: Resolve conflicts and add ED25519 support !13712 --- lib/api/entities.rb | 1 + lib/api/settings.rb | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 803b48dd88a..8f766ba4f8d 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -744,6 +744,7 @@ module API expose(:default_snippet_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_snippet_visibility) } expose(:default_group_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_group_visibility) } expose :password_authentication_enabled, as: :signin_enabled + expose :allowed_key_types end class Release < Grape::Entity diff --git a/lib/api/settings.rb b/lib/api/settings.rb index 667ba468ce6..6ace0e1e390 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -122,6 +122,12 @@ module API optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.' optional :polling_interval_multiplier, type: BigDecimal, desc: 'Interval multiplier used by endpoints that perform polling. Set to 0 to disable polling.' + optional :minimum_rsa_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('rsa'), desc: 'The minimum allowed bit length of an uploaded RSA key.' + optional :minimum_dsa_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('dsa'), desc: 'The minimum allowed bit length of an uploaded DSA key.' + optional :minimum_ecdsa_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('ecdsa'), desc: 'The minimum allowed curve size (in bits) of an uploaded ECDSA key.' + optional :minimum_ed25519_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('ed25519'), desc: 'The minimum allowed curve size (in bits) of an uploaded ED25519 key.' + optional :allowed_key_types, type: Array[String], values: Gitlab::SSHPublicKey.technology_names, desc: 'The SSH key types accepted by the application (`rsa`, `dsa`, `ecdsa` or `ed25519`).' + optional(*::ApplicationSettingsHelper.visible_attributes) at_least_one_of(*::ApplicationSettingsHelper.visible_attributes) end -- cgit v1.2.1 From 6847060266792471c9c14518a5106e0f622cd6c5 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Fri, 25 Aug 2017 14:08:48 +0100 Subject: Rework the permissions model for SSH key restrictions `allowed_key_types` is removed and the `minimum__bits` fields are renamed to `_key_restriction`. A special sentinel value (`-1`) signifies that the key type is disabled. This also feeds through to the UI - checkboxes per key type are out, inline selection of "forbidden" and "allowed" (i.e., no restrictions) are in. As with the previous model, unknown key types are disallowed, even if the underlying ssh daemon happens to support them. The defaults have also been changed from the lowest known bit size to "no restriction". So if someone does happen to have a 768-bit RSA key, it will continue to work on upgrade, at least until the administrator restricts them. --- lib/api/entities.rb | 1 - lib/api/settings.rb | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8f766ba4f8d..803b48dd88a 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -744,7 +744,6 @@ module API expose(:default_snippet_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_snippet_visibility) } expose(:default_group_visibility) { |setting, _options| Gitlab::VisibilityLevel.string_level(setting.default_group_visibility) } expose :password_authentication_enabled, as: :signin_enabled - expose :allowed_key_types end class Release < Grape::Entity diff --git a/lib/api/settings.rb b/lib/api/settings.rb index 6ace0e1e390..01123e45ee0 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -122,11 +122,12 @@ module API optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.' optional :polling_interval_multiplier, type: BigDecimal, desc: 'Interval multiplier used by endpoints that perform polling. Set to 0 to disable polling.' - optional :minimum_rsa_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('rsa'), desc: 'The minimum allowed bit length of an uploaded RSA key.' - optional :minimum_dsa_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('dsa'), desc: 'The minimum allowed bit length of an uploaded DSA key.' - optional :minimum_ecdsa_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('ecdsa'), desc: 'The minimum allowed curve size (in bits) of an uploaded ECDSA key.' - optional :minimum_ed25519_bits, type: Integer, values: Gitlab::SSHPublicKey.allowed_sizes('ed25519'), desc: 'The minimum allowed curve size (in bits) of an uploaded ED25519 key.' - optional :allowed_key_types, type: Array[String], values: Gitlab::SSHPublicKey.technology_names, desc: 'The SSH key types accepted by the application (`rsa`, `dsa`, `ecdsa` or `ed25519`).' + ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type| + optional :"#{type}_key_restriction", + type: Integer, + values: ApplicationSetting.supported_key_restrictions(type), + desc: "Restrictions on the complexity of uploaded #{type.upcase} keys. A value of #{ApplicationSetting::FORBIDDEN_KEY_VALUE} disables all #{type.upcase} keys." + end optional(*::ApplicationSettingsHelper.visible_attributes) at_least_one_of(*::ApplicationSettingsHelper.visible_attributes) -- cgit v1.2.1 From eb05bdc6f589f6f0713df12582eb9f18fc4022b3 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 28 Aug 2017 21:58:36 +0100 Subject: Move the key restriction validation to its own class --- lib/api/settings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/settings.rb b/lib/api/settings.rb index 01123e45ee0..851b226e9e5 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -125,7 +125,7 @@ module API ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type| optional :"#{type}_key_restriction", type: Integer, - values: ApplicationSetting.supported_key_restrictions(type), + values: KeyRestrictionValidator.supported_key_restrictions(type), desc: "Restrictions on the complexity of uploaded #{type.upcase} keys. A value of #{ApplicationSetting::FORBIDDEN_KEY_VALUE} disables all #{type.upcase} keys." end -- cgit v1.2.1 From 5883ce95efcc4cc04f949f9b4e66d73fbede94e2 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Thu, 31 Aug 2017 10:47:03 +0100 Subject: `current_application_settings` belongs on `Gitlab::CurrentSettings` The initializers including this were doing so at the top level, so every object loaded after them had a `current_application_settings` method. However, if someone had rack-attack enabled (which was loaded before these initializers), it would try to load the API, and fail, because `Gitlab::CurrentSettings` didn't have that method. To fix this: 1. Don't include `Gitlab::CurrentSettings` at the top level. We do not need `Object.new.current_application_settings` to work. 2. Make `Gitlab::CurrentSettings` explicitly `extend self`, as we already use it like that in several places. 3. Change the initializers to use that new form. --- lib/api/helpers/runner.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/api') diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index f8645e364ce..282af32ca94 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -1,6 +1,8 @@ module API module Helpers module Runner + include Gitlab::CurrentSettings + JOB_TOKEN_HEADER = 'HTTP_JOB_TOKEN'.freeze JOB_TOKEN_PARAM = :token UPDATE_RUNNER_EVERY = 10 * 60 -- cgit v1.2.1 From 6a2ee0968e811d31fb4cc23b30a6b42e42adf47b Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 31 Aug 2017 13:44:49 +0200 Subject: API: Use defined project requirements --- lib/api/access_requests.rb | 2 +- lib/api/award_emoji.rb | 2 +- lib/api/boards.rb | 2 +- lib/api/commit_statuses.rb | 2 +- lib/api/deploy_keys.rb | 2 +- lib/api/deployments.rb | 2 +- lib/api/environments.rb | 2 +- lib/api/events.rb | 2 +- lib/api/group_milestones.rb | 2 +- lib/api/group_variables.rb | 2 +- lib/api/groups.rb | 2 +- lib/api/issues.rb | 4 ++-- lib/api/jobs.rb | 2 +- lib/api/labels.rb | 2 +- lib/api/members.rb | 2 +- lib/api/merge_request_diffs.rb | 2 +- lib/api/merge_requests.rb | 2 +- lib/api/notes.rb | 2 +- lib/api/notification_settings.rb | 2 +- lib/api/pipeline_schedules.rb | 2 +- lib/api/pipelines.rb | 2 +- lib/api/project_hooks.rb | 2 +- lib/api/project_milestones.rb | 2 +- lib/api/project_snippets.rb | 2 +- lib/api/projects.rb | 4 ++-- lib/api/repositories.rb | 2 +- lib/api/runners.rb | 2 +- lib/api/services.rb | 4 ++-- lib/api/subscriptions.rb | 2 +- lib/api/todos.rb | 2 +- lib/api/triggers.rb | 2 +- lib/api/variables.rb | 2 +- 32 files changed, 35 insertions(+), 35 deletions(-) (limited to 'lib/api') diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index 4fa9b2b2494..374b611f55e 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: "The #{source_type} ID" end - resource source_type.pluralize, requirements: { id: %r{[^/]+} } do + resource source_type.pluralize, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc "Gets a list of access requests for a #{source_type}." do detail 'This feature was introduced in GitLab 8.11.' success Entities::AccessRequester diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 8e3851640da..c3d93996816 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -12,7 +12,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do AWARDABLES.each do |awardable_params| awardable_string = awardable_params[:type].pluralize awardable_id_string = "#{awardable_params[:type]}_#{awardable_params[:find_by]}" diff --git a/lib/api/boards.rb b/lib/api/boards.rb index 0d11c5fc971..366b0dc9a6f 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get all project boards' do detail 'This feature was introduced in 8.13' success Entities::Board diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 485b680cd5f..78e889a4c35 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -5,7 +5,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do include PaginationParams before { authenticate! } diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index f405c341398..281269b1190 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -17,7 +17,7 @@ module API params do requires :id, type: String, desc: 'The ID of the project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do before { authorize_admin_project } desc "Get a specific project's deploy keys" do diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb index 46b936897f6..1efee9a1324 100644 --- a/lib/api/deployments.rb +++ b/lib/api/deployments.rb @@ -8,7 +8,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get all deployments of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::Deployment diff --git a/lib/api/environments.rb b/lib/api/environments.rb index e33269f9483..5c63ec028d9 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get all environments of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::Environment diff --git a/lib/api/events.rb b/lib/api/events.rb index dabdf579119..b0713ff1d54 100644 --- a/lib/api/events.rb +++ b/lib/api/events.rb @@ -67,7 +67,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc "List a Project's visible events" do success Entities::Event end diff --git a/lib/api/group_milestones.rb b/lib/api/group_milestones.rb index b85eb59dc0a..93fa0b95857 100644 --- a/lib/api/group_milestones.rb +++ b/lib/api/group_milestones.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups, requirements: { id: %r{[^/]+} } do + resource :groups, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get a list of group milestones' do success Entities::Milestone end diff --git a/lib/api/group_variables.rb b/lib/api/group_variables.rb index 25152f30998..92800ce6450 100644 --- a/lib/api/group_variables.rb +++ b/lib/api/group_variables.rb @@ -9,7 +9,7 @@ module API requires :id, type: String, desc: 'The ID of a group' end - resource :groups, requirements: { id: %r{[^/]+} } do + resource :groups, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get group-level variables' do success Entities::Variable end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 8c494a54329..31a918eda60 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -89,7 +89,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups, requirements: { id: %r{[^/]+} } do + resource :groups, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Update a group. Available only for users who can administrate groups.' do success Entities::Group end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 0297023226f..e4c2c390853 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -81,7 +81,7 @@ module API params do requires :id, type: String, desc: 'The ID of a group' end - resource :groups, requirements: { id: %r{[^/]+} } do + resource :groups, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get a list of group issues' do success Entities::IssueBasic end @@ -108,7 +108,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do include TimeTrackingEndpoints desc 'Get a list of project issues' do diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index a40018b214e..5bab96398fd 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do helpers do params :optional_scope do optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show', diff --git a/lib/api/labels.rb b/lib/api/labels.rb index c0cf618ee8d..e41a1720ac1 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get all labels of the project' do success Entities::Label end diff --git a/lib/api/members.rb b/lib/api/members.rb index a5d3d7f25a0..22e4bdead41 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: "The #{source_type} ID" end - resource source_type.pluralize, requirements: { id: %r{[^/]+} } do + resource source_type.pluralize, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Gets a list of group or project members viewable by the authenticated user.' do success Entities::Member end diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index 4b79eac2b8b..c3affcc6c6b 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -8,7 +8,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get a list of merge request diff versions' do detail 'This feature was introduced in GitLab 8.12.' success Entities::MergeRequestDiff diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index eec8d9357aa..7bcbf9f20ff 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -72,7 +72,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do include TimeTrackingEndpoints helpers do diff --git a/lib/api/notes.rb b/lib/api/notes.rb index e116448c15b..d6e7203adaf 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do NOTEABLE_TYPES.each do |noteable_type| noteables_str = noteable_type.to_s.underscore.pluralize diff --git a/lib/api/notification_settings.rb b/lib/api/notification_settings.rb index 5d113c94b22..bcc0833aa5c 100644 --- a/lib/api/notification_settings.rb +++ b/lib/api/notification_settings.rb @@ -54,7 +54,7 @@ module API params do requires :id, type: String, desc: "The #{source_type} ID" end - resource source_type.pluralize, requirements: { id: %r{[^/]+} } do + resource source_type.pluralize, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc "Get #{source_type} level notification level settings, defaults to Global" do detail 'This feature was introduced in GitLab 8.12' success Entities::NotificationSetting diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index e3123ef4e2d..ef01cbc7875 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get all pipeline schedules' do success Entities::PipelineSchedule end diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index e505cae3992..74b3376a1f3 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The project ID' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get all Pipelines of the project' do detail 'This feature was introduced in GitLab 8.11.' success Entities::PipelineBasic diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 5b457bbe639..86066e2b58f 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -24,7 +24,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get project hooks' do success Entities::ProjectHook end diff --git a/lib/api/project_milestones.rb b/lib/api/project_milestones.rb index 451998c726a..0cb209a02d0 100644 --- a/lib/api/project_milestones.rb +++ b/lib/api/project_milestones.rb @@ -10,7 +10,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get a list of project milestones' do success Entities::Milestone end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index 704e8c6718d..2ccda1c1aa1 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -7,7 +7,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do helpers do def handle_project_member_errors(errors) if errors[:project_access].any? diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 78d900984ac..4845242a173 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -95,7 +95,7 @@ module API end end - resource :users, requirements: { user_id: %r{[^/]+} } do + resource :users, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get a user projects' do success Entities::BasicProjectDetails end @@ -183,7 +183,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get a single project' do success Entities::ProjectWithAccess end diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 14d2bff9cb5..2255fb1b70d 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -9,7 +9,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do helpers do def handle_project_member_errors(errors) if errors[:project_access].any? diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 68c2120cc15..1ea9a7918d7 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -87,7 +87,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do before { authorize_admin_project } desc 'Get runners available for project' do diff --git a/lib/api/services.rb b/lib/api/services.rb index ff9ddd44439..2cbd0517dc3 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -601,7 +601,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do before { authenticate! } before { authorize_admin_project } @@ -691,7 +691,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc "Trigger a slash command for #{service_slug}" do detail 'Added in GitLab 8.13' end diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb index 91567909998..b3e1e23031a 100644 --- a/lib/api/subscriptions.rb +++ b/lib/api/subscriptions.rb @@ -12,7 +12,7 @@ module API requires :id, type: String, desc: 'The ID of a project' requires :subscribable_id, type: String, desc: 'The ID of a resource' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do subscribable_types.each do |type, finder| type_singularized = type.singularize entity_class = Entities.const_get(type_singularized.camelcase) diff --git a/lib/api/todos.rb b/lib/api/todos.rb index 55191169dd4..ffccfebe752 100644 --- a/lib/api/todos.rb +++ b/lib/api/todos.rb @@ -12,7 +12,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do ISSUABLE_TYPES.each do |type, finder| type_id_str = "#{type.singularize}_iid".to_sym diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index c9fee7e5193..dd6801664b1 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -5,7 +5,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Trigger a GitLab project pipeline' do success Entities::Pipeline end diff --git a/lib/api/variables.rb b/lib/api/variables.rb index da71787abab..d08876ae1b9 100644 --- a/lib/api/variables.rb +++ b/lib/api/variables.rb @@ -9,7 +9,7 @@ module API requires :id, type: String, desc: 'The ID of a project' end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do desc 'Get project variables' do success Entities::Variable end -- cgit v1.2.1 From eaf60bb5441190e2ffcf219b3169bda2237d57cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Tue, 29 Aug 2017 23:10:41 -0300 Subject: Implement /internal/post_receive unified endpoint for PostReceive tasks --- lib/api/helpers/internal_helpers.rb | 4 ++++ lib/api/internal.rb | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/helpers/internal_helpers.rb b/lib/api/helpers/internal_helpers.rb index ecb79317093..f57ff0f2632 100644 --- a/lib/api/helpers/internal_helpers.rb +++ b/lib/api/helpers/internal_helpers.rb @@ -42,6 +42,10 @@ module API ::Users::ActivityService.new(actor, 'Git SSH').execute if commands.include?(params[:action]) end + def merge_request_urls + ::MergeRequests::GetUrlsService.new(project).execute(params[:changes]) + end + private def set_project diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 8b007869dc3..622bd9650e4 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -68,7 +68,7 @@ module API end get "/merge_request_urls" do - ::MergeRequests::GetUrlsService.new(project).execute(params[:changes]) + merge_request_urls end # @@ -155,6 +155,21 @@ module API # render_api_error!(e, 500) # end end + + post '/post_receive' do + status 200 + + PostReceive.perform_async(params[:gl_repository], params[:identifier], + params[:changes]) + broadcast_message = BroadcastMessage.current&.last&.message + reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease + + { + merge_request_urls: merge_request_urls, + broadcast_message: broadcast_message, + reference_counter_decreased: reference_counter_decreased + } + end end end end -- cgit v1.2.1 From 6f19fc1147a60f279db35428993ac532841195ad Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 24 Aug 2017 01:28:57 +0900 Subject: Add API support --- lib/api/entities.rb | 1 + lib/api/runners.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 9df9a515990..f13f2d723bb 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -775,6 +775,7 @@ module API expose :tag_list expose :run_untagged expose :locked + expose :access_level expose :version, :revision, :platform, :architecture expose :contacted_at expose :token, if: lambda { |runner, options| options[:current_user].admin? || !runner.is_shared? } diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 1ea9a7918d7..d8fc44e5790 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -55,7 +55,8 @@ module API optional :tag_list, type: Array[String], desc: 'The list of tags for a runner' optional :run_untagged, type: Boolean, desc: 'Flag indicating the runner can execute untagged jobs' optional :locked, type: Boolean, desc: 'Flag indicating the runner is locked' - at_least_one_of :description, :active, :tag_list, :run_untagged, :locked + optional :access_level, type: Integer, desc: 'The access_level of the runner' + at_least_one_of :description, :active, :tag_list, :run_untagged, :locked, :access_level end put ':id' do runner = get_runner(params.delete(:id)) -- cgit v1.2.1 From 13b9b5f11a556b2841aabbf46516d1acab79aa0d Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 29 Aug 2017 16:09:30 +0900 Subject: Improve API arguments as String --- lib/api/runners.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/runners.rb b/lib/api/runners.rb index d8fc44e5790..d3559ef71be 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -55,7 +55,8 @@ module API optional :tag_list, type: Array[String], desc: 'The list of tags for a runner' optional :run_untagged, type: Boolean, desc: 'Flag indicating the runner can execute untagged jobs' optional :locked, type: Boolean, desc: 'Flag indicating the runner is locked' - optional :access_level, type: Integer, desc: 'The access_level of the runner' + optional :access_level, type: String, values: Ci::Runner.access_levels.keys, + desc: 'The access_level of the runner' at_least_one_of :description, :active, :tag_list, :run_untagged, :locked, :access_level end put ':id' do -- cgit v1.2.1 From d8478d166b96b7b40b27b162d6afd170a5c8d763 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Fri, 1 Sep 2017 17:54:07 +0900 Subject: Fix spec --- lib/api/commit_statuses.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 78e889a4c35..6314ea63197 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -74,7 +74,8 @@ module API source: :external, sha: commit.sha, ref: ref, - user: current_user) + user: current_user, + protected: @project.protected_for?(ref)) end status = GenericCommitStatus.running_or_pending.find_or_initialize_by( @@ -82,7 +83,8 @@ module API pipeline: pipeline, name: name, ref: ref, - user: current_user + user: current_user, + protected: @project.protected_for?(ref) ) optional_attributes = -- cgit v1.2.1 From f3f1ad3992c039563188a84787b1e916e367d702 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 4 Sep 2017 14:09:03 +0200 Subject: Add API endpoint for downloading single job artifact --- lib/api/jobs.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib/api') diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 5bab96398fd..41b3b28037c 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -85,6 +85,25 @@ module API 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 = get_build!(params[:job_id]) + not_found! unless build.artifacts? + + entry = build.artifacts_metadata_entry(params[:artifact_path]) + not_found! unless entry.exists? + + Gitlab::Workhorse.send_artifacts_entry(build, entry) + end + desc 'Download the artifacts file from a job' do detail 'This feature was introduced in GitLab 8.10' end -- cgit v1.2.1 From 8ca5c333fd5170a900c7fa28b6bfcbe1a8bc6477 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Fri, 18 Aug 2017 17:25:35 +0900 Subject: Extend API: Pipeline Schedule Variable --- lib/api/entities.rb | 3 +- lib/api/pipeline_schedules.rb | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index f13f2d723bb..09d7d9ad349 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -819,7 +819,7 @@ module API class Variable < Grape::Entity expose :key, :value - expose :protected?, as: :protected + expose :protected?, as: :protected, if: -> (entity, options) { entity.respond_to?(protected?) } end class Pipeline < PipelineBasic @@ -840,6 +840,7 @@ module API class PipelineScheduleDetails < PipelineSchedule expose :last_pipeline, using: Entities::PipelineBasic + expose :variables, using: Entities::Variable end class EnvironmentBasic < Grape::Entity diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index ef01cbc7875..e82b974c8cd 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -119,6 +119,76 @@ module API destroy_conditionally!(pipeline_schedule) end + + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + end + resource :variables, requirements: { pipeline_schedule_id: %r{[^/]+} } do + desc 'Create a new pipeline schedule variable' do + success Entities::PipelineScheduleDetails + end + params do + requires :key, type: String, desc: 'The key of the variable' + requires :value, type: String, desc: 'The value of the variable' + end + post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do + authorize! :read_pipeline_schedule, user_project + + not_found!('PipelineSchedule') unless pipeline_schedule + authorize! :update_pipeline_schedule, pipeline_schedule + + variable_params = declared_params(include_missing: false) + variable = pipeline_schedule.variables.create(variable_params) + + if variable.persisted? + present variable, with: Entities::Variable + else + render_validation_error!(variable) + end + end + + desc 'Edit a pipeline schedule variable' do + success Entities::PipelineScheduleDetails + end + params do + optional :key, type: String, desc: 'The key of the variable' + optional :value, type: String, desc: 'The value of the variable' + end + put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do + authorize! :read_pipeline_schedule, user_project + + not_found!('PipelineSchedule') unless pipeline_schedule + authorize! :update_pipeline_schedule, pipeline_schedule + + variable = pipeline_schedule.variables.find_by(key: params[:key]) + not_found!('Variable') unless variable + + if variable.update(declared_params(include_missing: false)) + present variable, with: Entities::Variable + else + render_validation_error!(variable) + end + end + + desc 'Delete a pipeline schedule variable' do + success Entities::PipelineScheduleDetails + end + params do + requires :key, type: String, desc: 'The key of the variable' + end + delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do + authorize! :read_pipeline_schedule, user_project + + not_found!('PipelineSchedule') unless pipeline_schedule + authorize! :admin_pipeline_schedule, pipeline_schedule + + variable = pipeline_schedule.variables.find_by(key: params[:key]) + not_found!('Variable') unless variable + + status :accepted + present variable, with: Entities::Variable + end + end end helpers do -- cgit v1.2.1 From 03f72f0f419b7e05fe9207c90b92b02ef7291cd1 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 22 Aug 2017 02:21:37 +0900 Subject: Add spec (Halfway) --- lib/api/entities.rb | 2 +- lib/api/pipeline_schedules.rb | 103 ++++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 54 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 09d7d9ad349..81cf7039260 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -819,7 +819,7 @@ module API class Variable < Grape::Entity expose :key, :value - expose :protected?, as: :protected, if: -> (entity, options) { entity.respond_to?(protected?) } + expose :protected?, as: :protected, if: -> (entity, options) { entity.respond_to?(:protected?) } end class Pipeline < PipelineBasic diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index e82b974c8cd..ffb9a09834d 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -120,74 +120,71 @@ module API destroy_conditionally!(pipeline_schedule) end + desc 'Create a new pipeline schedule variable' do + success Entities::Variable + end params do requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + requires :key, type: String, desc: 'The key of the variable' + requires :value, type: String, desc: 'The value of the variable' end - resource :variables, requirements: { pipeline_schedule_id: %r{[^/]+} } do - desc 'Create a new pipeline schedule variable' do - success Entities::PipelineScheduleDetails - end - params do - requires :key, type: String, desc: 'The key of the variable' - requires :value, type: String, desc: 'The value of the variable' - end - post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do - authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule - authorize! :update_pipeline_schedule, pipeline_schedule + post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do + authorize! :read_pipeline_schedule, user_project - variable_params = declared_params(include_missing: false) - variable = pipeline_schedule.variables.create(variable_params) + not_found!('PipelineSchedule') unless pipeline_schedule + authorize! :update_pipeline_schedule, pipeline_schedule - if variable.persisted? - present variable, with: Entities::Variable - else - render_validation_error!(variable) - end + variable_params = declared_params(include_missing: false) + variable = pipeline_schedule.variables.create(variable_params) + if variable.persisted? + present variable, with: Entities::Variable + else + render_validation_error!(variable) end + end - desc 'Edit a pipeline schedule variable' do - success Entities::PipelineScheduleDetails - end - params do - optional :key, type: String, desc: 'The key of the variable' - optional :value, type: String, desc: 'The value of the variable' - end - put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do - authorize! :read_pipeline_schedule, user_project + desc 'Edit a pipeline schedule variable' do + success Entities::Variable + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + requires :key, type: String, desc: 'The key of the variable' + optional :value, type: String, desc: 'The value of the variable' + end + put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do + authorize! :read_pipeline_schedule, user_project - not_found!('PipelineSchedule') unless pipeline_schedule - authorize! :update_pipeline_schedule, pipeline_schedule + not_found!('PipelineSchedule') unless pipeline_schedule + authorize! :update_pipeline_schedule, pipeline_schedule - variable = pipeline_schedule.variables.find_by(key: params[:key]) - not_found!('Variable') unless variable + variable = pipeline_schedule.variables.find_by(key: params[:key]) + not_found!('Variable') unless variable - if variable.update(declared_params(include_missing: false)) - present variable, with: Entities::Variable - else - render_validation_error!(variable) - end + if variable.update(declared_params(include_missing: false)) + present variable, with: Entities::Variable + else + render_validation_error!(variable) end + end - desc 'Delete a pipeline schedule variable' do - success Entities::PipelineScheduleDetails - end - params do - requires :key, type: String, desc: 'The key of the variable' - end - delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do - authorize! :read_pipeline_schedule, user_project + desc 'Delete a pipeline schedule variable' do + success Entities::Variable + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + requires :key, type: String, desc: 'The key of the variable' + end + delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do + authorize! :read_pipeline_schedule, user_project - not_found!('PipelineSchedule') unless pipeline_schedule - authorize! :admin_pipeline_schedule, pipeline_schedule + not_found!('PipelineSchedule') unless pipeline_schedule + authorize! :admin_pipeline_schedule, pipeline_schedule - variable = pipeline_schedule.variables.find_by(key: params[:key]) - not_found!('Variable') unless variable + variable = pipeline_schedule.variables.find_by(key: params[:key]) + not_found!('Variable') unless variable - status :accepted - present variable, with: Entities::Variable - end + status :accepted + present variable, with: Entities::Variable end end -- cgit v1.2.1 From fb8f32a92cdfe4cca24cb80a91e8fe48d6b0df25 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 22 Aug 2017 21:42:17 +0900 Subject: Finish spec --- lib/api/pipeline_schedules.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index ffb9a09834d..7a3f74006c6 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -184,7 +184,7 @@ module API not_found!('Variable') unless variable status :accepted - present variable, with: Entities::Variable + present variable.destroy, with: Entities::Variable end end -- cgit v1.2.1 From 362f2226a5febb7a3a82e86f4a83e87a870d67b3 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 24 Aug 2017 21:51:46 +0900 Subject: Improve by zj nice catches --- lib/api/entities.rb | 2 +- lib/api/pipeline_schedules.rb | 37 +++++++++++++------------------------ 2 files changed, 14 insertions(+), 25 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 81cf7039260..0092cc14e74 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -819,7 +819,7 @@ module API class Variable < Grape::Entity expose :key, :value - expose :protected?, as: :protected, if: -> (entity, options) { entity.respond_to?(:protected?) } + expose :protected?, as: :protected, if: -> (entity, _) { entity.respond_to?(:protected?) } end class Pipeline < PipelineBasic diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index 7a3f74006c6..a6414bfe3f4 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -33,8 +33,6 @@ module API get ':id/pipeline_schedules/:pipeline_schedule_id' do authorize! :read_pipeline_schedule, user_project - not_found!('PipelineSchedule') unless pipeline_schedule - present pipeline_schedule, with: Entities::PipelineScheduleDetails end @@ -75,8 +73,6 @@ module API end put ':id/pipeline_schedules/:pipeline_schedule_id' do authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule authorize! :update_pipeline_schedule, pipeline_schedule if pipeline_schedule.update(declared_params(include_missing: false)) @@ -94,8 +90,6 @@ module API end post ':id/pipeline_schedules/:pipeline_schedule_id/take_ownership' do authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule authorize! :update_pipeline_schedule, pipeline_schedule if pipeline_schedule.own!(current_user) @@ -113,8 +107,6 @@ module API end delete ':id/pipeline_schedules/:pipeline_schedule_id' do authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule authorize! :admin_pipeline_schedule, pipeline_schedule destroy_conditionally!(pipeline_schedule) @@ -130,8 +122,6 @@ module API end post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule authorize! :update_pipeline_schedule, pipeline_schedule variable_params = declared_params(include_missing: false) @@ -153,17 +143,12 @@ module API end put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule authorize! :update_pipeline_schedule, pipeline_schedule - variable = pipeline_schedule.variables.find_by(key: params[:key]) - not_found!('Variable') unless variable - - if variable.update(declared_params(include_missing: false)) - present variable, with: Entities::Variable + if pipeline_schedule_variable.update(declared_params(include_missing: false)) + present pipeline_schedule_variable, with: Entities::Variable else - render_validation_error!(variable) + render_validation_error!(pipeline_schedule_variable) end end @@ -176,15 +161,10 @@ module API end delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do authorize! :read_pipeline_schedule, user_project - - not_found!('PipelineSchedule') unless pipeline_schedule authorize! :admin_pipeline_schedule, pipeline_schedule - variable = pipeline_schedule.variables.find_by(key: params[:key]) - not_found!('Variable') unless variable - status :accepted - present variable.destroy, with: Entities::Variable + present pipeline_schedule_variable.destroy, with: Entities::Variable end end @@ -194,6 +174,15 @@ module API user_project.pipeline_schedules .preload(:owner, :last_pipeline) .find_by(id: params.delete(:pipeline_schedule_id)) + + @pipeline_schedule || not_found!('Pipeline Schedule') + end + + def pipeline_schedule_variable + @pipeline_schedule_variable ||= + pipeline_schedule.variables.find_by(key: params[:key]) + + @pipeline_schedule_variable || not_found!('Pipeline Schedule Variable') end end end -- cgit v1.2.1 From bb22989c388bb7322e95af72c48d8422494d96e7 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Wed, 30 Aug 2017 20:40:19 +0900 Subject: Improve def pipeline_schedule with authrozation code --- lib/api/pipeline_schedules.rb | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'lib/api') diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index a6414bfe3f4..51baf12e287 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -31,8 +31,6 @@ module API requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' end get ':id/pipeline_schedules/:pipeline_schedule_id' do - authorize! :read_pipeline_schedule, user_project - present pipeline_schedule, with: Entities::PipelineScheduleDetails end @@ -72,7 +70,6 @@ module API optional :active, type: Boolean, desc: 'The activation of pipeline schedule' end put ':id/pipeline_schedules/:pipeline_schedule_id' do - authorize! :read_pipeline_schedule, user_project authorize! :update_pipeline_schedule, pipeline_schedule if pipeline_schedule.update(declared_params(include_missing: false)) @@ -89,7 +86,6 @@ module API requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' end post ':id/pipeline_schedules/:pipeline_schedule_id/take_ownership' do - authorize! :read_pipeline_schedule, user_project authorize! :update_pipeline_schedule, pipeline_schedule if pipeline_schedule.own!(current_user) @@ -106,7 +102,6 @@ module API requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' end delete ':id/pipeline_schedules/:pipeline_schedule_id' do - authorize! :read_pipeline_schedule, user_project authorize! :admin_pipeline_schedule, pipeline_schedule destroy_conditionally!(pipeline_schedule) @@ -121,7 +116,6 @@ module API requires :value, type: String, desc: 'The value of the variable' end post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do - authorize! :read_pipeline_schedule, user_project authorize! :update_pipeline_schedule, pipeline_schedule variable_params = declared_params(include_missing: false) @@ -142,7 +136,6 @@ module API optional :value, type: String, desc: 'The value of the variable' end put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do - authorize! :read_pipeline_schedule, user_project authorize! :update_pipeline_schedule, pipeline_schedule if pipeline_schedule_variable.update(declared_params(include_missing: false)) @@ -160,7 +153,6 @@ module API requires :key, type: String, desc: 'The key of the variable' end delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do - authorize! :read_pipeline_schedule, user_project authorize! :admin_pipeline_schedule, pipeline_schedule status :accepted @@ -171,18 +163,23 @@ module API helpers do def pipeline_schedule @pipeline_schedule ||= - user_project.pipeline_schedules - .preload(:owner, :last_pipeline) - .find_by(id: params.delete(:pipeline_schedule_id)) - - @pipeline_schedule || not_found!('Pipeline Schedule') + user_project + .pipeline_schedules + .preload(:owner, :last_pipeline) + .find_by(id: params.delete(:pipeline_schedule_id)).tap do |pipeline_schedule| + unless pipeline_schedule || can?(current_user, :read_pipeline_schedule, pipeline_schedule) + not_found!('Pipeline Schedule') + end + end end def pipeline_schedule_variable @pipeline_schedule_variable ||= - pipeline_schedule.variables.find_by(key: params[:key]) - - @pipeline_schedule_variable || not_found!('Pipeline Schedule Variable') + pipeline_schedule.variables.find_by(key: params[:key]).tap do |pipeline_schedule_variable| + unless pipeline_schedule_variable + not_found!('Pipeline Schedule Variable') + end + end end end end -- cgit v1.2.1 From 2f906430fa9efa61b7808e5849611fef6ecb59a5 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 4 Sep 2017 21:53:19 +0900 Subject: Fix security breaching --- lib/api/pipeline_schedules.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb index 51baf12e287..37f32411296 100644 --- a/lib/api/pipeline_schedules.rb +++ b/lib/api/pipeline_schedules.rb @@ -167,7 +167,7 @@ module API .pipeline_schedules .preload(:owner, :last_pipeline) .find_by(id: params.delete(:pipeline_schedule_id)).tap do |pipeline_schedule| - unless pipeline_schedule || can?(current_user, :read_pipeline_schedule, pipeline_schedule) + unless can?(current_user, :read_pipeline_schedule, pipeline_schedule) not_found!('Pipeline Schedule') end end -- cgit v1.2.1 From 75130a41ba19b80ac7b2300721915787ac4681bf Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 24 Aug 2017 17:08:32 +0900 Subject: Remove CreateTriggerRequestService and forbit to save variables on Ci::TriggerRequest --- lib/api/triggers.rb | 8 ++++---- lib/api/v3/triggers.rb | 31 +++++++++++++++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'lib/api') diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index dd6801664b1..276d3b5fb79 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -15,16 +15,16 @@ module API optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do + authenticate! + authorize! :admin_build, user_project + # validate variables params[:variables] = params[:variables].to_h unless params[:variables].all? { |key, value| key.is_a?(String) && value.is_a?(String) } render_api_error!('variables needs to be a map of key-valued strings', 400) end - project = find_project(params[:id]) - not_found! unless project - - result = Ci::PipelineTriggerService.new(project, nil, params).execute + result = Ci::PipelineTriggerService.new(user_project, nil, params).execute not_found! unless result if result[:http_status] diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb index e9d4c35307b..ffc1a38acbc 100644 --- a/lib/api/v3/triggers.rb +++ b/lib/api/v3/triggers.rb @@ -16,25 +16,32 @@ module API optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end post ":id/(ref/:ref/)trigger/builds", requirements: { ref: /.+/ } do - project = find_project(params[:id]) - trigger = Ci::Trigger.find_by_token(params[:token].to_s) - not_found! unless project && trigger - unauthorized! unless trigger.project == project + authenticate! + authorize! :admin_build, user_project # validate variables - variables = params[:variables].to_h - unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) } + params[:variables] = params[:variables].to_h + unless params[:variables].all? { |key, value| key.is_a?(String) && value.is_a?(String) } render_api_error!('variables needs to be a map of key-valued strings', 400) end - # create request and trigger builds - result = Ci::CreateTriggerRequestService.execute(project, trigger, params[:ref].to_s, variables) - pipeline = result.pipeline + result = Ci::PipelineTriggerService.new(user_project, nil, params).execute + not_found! unless result - if pipeline.persisted? - present result.trigger_request, with: ::API::V3::Entities::TriggerRequest + if result[:http_status] + render_api_error!(result[:message], result[:http_status]) else - render_validation_error!(pipeline) + pipeline = result[:pipeline] + trigger_request = pipeline.trigger_request + + # Ws swtiched to Ci::PipelineVariable from Ci::TriggerRequest.variables. + # Ci::TriggerRequest doesn't save variables anymore. + # Although, to prevent braking compatibility, copying variables and present it as Ci::TriggerRequest. + pipeline.variables.each do |variable| + trigger_request.variables << { key: variable.key, value: variable.value } + end + + present trigger_request, with: ::API::V3::Entities::TriggerRequest end end -- cgit v1.2.1 From acc7497855167d4f6ba481422112645a1a04a885 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Sat, 26 Aug 2017 04:04:57 +0900 Subject: Revert autheticate! in Trigger API --- lib/api/triggers.rb | 8 ++++---- lib/api/v3/triggers.rb | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'lib/api') diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index 276d3b5fb79..dd6801664b1 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -15,16 +15,16 @@ module API optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do - authenticate! - authorize! :admin_build, user_project - # validate variables params[:variables] = params[:variables].to_h unless params[:variables].all? { |key, value| key.is_a?(String) && value.is_a?(String) } render_api_error!('variables needs to be a map of key-valued strings', 400) end - result = Ci::PipelineTriggerService.new(user_project, nil, params).execute + project = find_project(params[:id]) + not_found! unless project + + result = Ci::PipelineTriggerService.new(project, nil, params).execute not_found! unless result if result[:http_status] diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb index ffc1a38acbc..e1da96104a5 100644 --- a/lib/api/v3/triggers.rb +++ b/lib/api/v3/triggers.rb @@ -16,16 +16,16 @@ module API optional :variables, type: Hash, desc: 'The list of variables to be injected into build' end post ":id/(ref/:ref/)trigger/builds", requirements: { ref: /.+/ } do - authenticate! - authorize! :admin_build, user_project - # validate variables params[:variables] = params[:variables].to_h unless params[:variables].all? { |key, value| key.is_a?(String) && value.is_a?(String) } render_api_error!('variables needs to be a map of key-valued strings', 400) end - result = Ci::PipelineTriggerService.new(user_project, nil, params).execute + project = find_project(params[:id]) + not_found! unless project + + result = Ci::PipelineTriggerService.new(project, nil, params).execute not_found! unless result if result[:http_status] -- cgit v1.2.1 From cff104ec4b0dd2c53ed907ab7ca423b7c587dee8 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 28 Aug 2017 23:29:28 +0900 Subject: Fix spec --- lib/api/v3/triggers.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb index e1da96104a5..497ccbe20c6 100644 --- a/lib/api/v3/triggers.rb +++ b/lib/api/v3/triggers.rb @@ -34,9 +34,10 @@ module API pipeline = result[:pipeline] trigger_request = pipeline.trigger_request - # Ws swtiched to Ci::PipelineVariable from Ci::TriggerRequest.variables. + # We switched to Ci::PipelineVariable from Ci::TriggerRequest.variables. # Ci::TriggerRequest doesn't save variables anymore. - # Although, to prevent braking compatibility, copying variables and present it as Ci::TriggerRequest. + # Here is copying Ci::PipelineVariable to Ci::TriggerRequest.variables for presenting the variables. + # The same endpoint in v4 API pressents Pipeline instead of TriggerRequest, so it doesn't need such a process. pipeline.variables.each do |variable| trigger_request.variables << { key: variable.key, value: variable.value } end -- cgit v1.2.1 From d614c431055286eaab3b82e810186ac19a2c4fd7 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Fri, 1 Sep 2017 00:17:56 +0900 Subject: Fix trigger_request.variables --- lib/api/v3/triggers.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/api') diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb index 497ccbe20c6..13cfb9fe38b 100644 --- a/lib/api/v3/triggers.rb +++ b/lib/api/v3/triggers.rb @@ -32,15 +32,13 @@ module API render_api_error!(result[:message], result[:http_status]) else pipeline = result[:pipeline] - trigger_request = pipeline.trigger_request + trigger_request = Ci::TriggerRequest.find_by(commit_id: pipeline.id) # We switched to Ci::PipelineVariable from Ci::TriggerRequest.variables. # Ci::TriggerRequest doesn't save variables anymore. # Here is copying Ci::PipelineVariable to Ci::TriggerRequest.variables for presenting the variables. # The same endpoint in v4 API pressents Pipeline instead of TriggerRequest, so it doesn't need such a process. - pipeline.variables.each do |variable| - trigger_request.variables << { key: variable.key, value: variable.value } - end + trigger_request.variables = params[:variables] present trigger_request, with: ::API::V3::Entities::TriggerRequest end -- cgit v1.2.1 From 48f017d1e84498eec38d276d94918021a985bfee Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 5 Sep 2017 01:22:57 +0900 Subject: Use pipeline.trigger_requests.last --- lib/api/v3/triggers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/v3/triggers.rb b/lib/api/v3/triggers.rb index 13cfb9fe38b..534911fde5c 100644 --- a/lib/api/v3/triggers.rb +++ b/lib/api/v3/triggers.rb @@ -32,12 +32,12 @@ module API render_api_error!(result[:message], result[:http_status]) else pipeline = result[:pipeline] - trigger_request = Ci::TriggerRequest.find_by(commit_id: pipeline.id) # We switched to Ci::PipelineVariable from Ci::TriggerRequest.variables. # Ci::TriggerRequest doesn't save variables anymore. # Here is copying Ci::PipelineVariable to Ci::TriggerRequest.variables for presenting the variables. # The same endpoint in v4 API pressents Pipeline instead of TriggerRequest, so it doesn't need such a process. + trigger_request = pipeline.trigger_requests.last trigger_request.variables = params[:variables] present trigger_request, with: ::API::V3::Entities::TriggerRequest -- cgit v1.2.1 From cf9c54bd312dcb7b4b7f0602e83013d8d32a9413 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Sun, 3 Sep 2017 16:34:50 +0900 Subject: Add my_reaction_emoji param to /issues API --- lib/api/issues.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/api') diff --git a/lib/api/issues.rb b/lib/api/issues.rb index e4c2c390853..1729df2aad0 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -36,6 +36,7 @@ module API optional :assignee_id, type: Integer, desc: 'Return issues which are assigned to the user with the given ID' optional :scope, type: String, values: %w[created-by-me assigned-to-me all], desc: 'Return issues for the given scope: `created-by-me`, `assigned-to-me` or `all`' + optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji' use :pagination end -- cgit v1.2.1 From 7e42711659d514be77119698d2611830fb83090d Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Mon, 4 Sep 2017 10:43:14 +0900 Subject: Add my_reaction_emoji param to /merge_requests API --- lib/api/merge_requests.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/api') diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 7bcbf9f20ff..56d72d511da 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -40,6 +40,7 @@ module API optional :assignee_id, type: Integer, desc: 'Return merge requests which are assigned to the user with the given ID' optional :scope, type: String, values: %w[created-by-me assigned-to-me all], desc: 'Return merge requests for the given scope: `created-by-me`, `assigned-to-me` or `all`' + optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji' use :pagination end end -- cgit v1.2.1 From dcf09d11447c264f4b4028ea80eea2be913c2f5b Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 31 Aug 2017 03:20:54 +0900 Subject: Implement `failure_reason` on `ci_builds` --- lib/api/commit_statuses.rb | 2 +- lib/api/runner.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 6314ea63197..c129cc9171d 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -103,7 +103,7 @@ module API when 'success' status.success! when 'failed' - status.drop! + status.drop!(:api) when 'canceled' status.cancel! else diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 11999354594..604bfd53296 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -127,7 +127,7 @@ module API when 'success' job.success when 'failed' - job.drop + job.drop(:failed_job_state) end end -- cgit v1.2.1 From b1af1f268b97c8518bf2806bca48f49174a8aead Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 31 Aug 2017 03:36:15 +0900 Subject: Fix enum wording --- lib/api/commit_statuses.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index c129cc9171d..9ab64452d2b 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -103,7 +103,7 @@ module API when 'success' status.success! when 'failed' - status.drop!(:api) + status.drop!(:failed_by_api) when 'canceled' status.cancel! else -- cgit v1.2.1 From 1d7c0390722c96aa66af5b26f5a826b97293dcd6 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 31 Aug 2017 22:03:41 +0900 Subject: Fix enum lists --- lib/api/commit_statuses.rb | 2 +- lib/api/runner.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 9ab64452d2b..829eef18795 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -103,7 +103,7 @@ module API when 'success' status.success! when 'failed' - status.drop!(:failed_by_api) + status.drop!(:api_failure) when 'canceled' status.cancel! else diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 604bfd53296..701c1bff1e0 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -127,7 +127,7 @@ module API when 'success' job.success when 'failed' - job.drop(:failed_job_state) + job.drop(:job_failure) end end -- cgit v1.2.1 From 68f6c61cf621db82ac98d561782590b1866fcf6f Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Fri, 1 Sep 2017 16:52:11 +0900 Subject: - Allow runner API to pass failure_reason - Fix spec --- lib/api/runner.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 701c1bff1e0..44ca42fef68 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -114,6 +114,8 @@ module API requires :id, type: Integer, desc: %q(Job's ID) optional :trace, type: String, desc: %q(Job's full trace) optional :state, type: String, desc: %q(Job's status: success, failed) + optional :failure_reason, type: String, values: CommitStatus.failure_reasons.keys, + desc: %q(Job's failure_reason) end put '/:id' do job = authenticate_job! @@ -127,7 +129,11 @@ module API when 'success' job.success when 'failed' - job.drop(:job_failure) + if params[:failure_reason] + job.drop(params[:failure_reason].to_sym) + else + job.drop(:job_failure) + end end end -- cgit v1.2.1 From 5d50cbfaab1d67ffaea6064aeac848f1fc1127a6 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 4 Sep 2017 22:46:37 +0900 Subject: Use unknown_failure for runner --- lib/api/runner.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/api') diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 44ca42fef68..76354fd8c98 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -129,11 +129,8 @@ module API when 'success' job.success when 'failed' - if params[:failure_reason] - job.drop(params[:failure_reason].to_sym) - else - job.drop(:job_failure) - end + failure_reason = params[:failure_reason] ? params[:failure_reason].to_sym : :unknown_failure + job.drop(failure_reason) end end -- cgit v1.2.1 From 38d9b4d77d85e26f827ff9640243494adc8597ed Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 5 Sep 2017 15:10:34 +0900 Subject: Use script_failure. Add runner_system_failure. Improve spec. --- lib/api/runner.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 76354fd8c98..a3987c560dd 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -129,8 +129,7 @@ module API when 'success' job.success when 'failed' - failure_reason = params[:failure_reason] ? params[:failure_reason].to_sym : :unknown_failure - job.drop(failure_reason) + job.drop(params[:failure_reason] || :unknown_failure) end end -- cgit v1.2.1 From dfb8fcbb651812d209d2f42baf6c2bb0e851c861 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 5 Sep 2017 11:16:49 +0200 Subject: Use API helper to send artifact file through Workhorse --- lib/api/helpers.rb | 4 ++++ lib/api/jobs.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3d377fdb9eb..f9ce1165544 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -432,6 +432,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/jobs.rb b/lib/api/jobs.rb index 41b3b28037c..41c70a2dcb7 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -101,7 +101,7 @@ module API entry = build.artifacts_metadata_entry(params[:artifact_path]) not_found! unless entry.exists? - Gitlab::Workhorse.send_artifacts_entry(build, entry) + send_artifacts_entry(build, entry) end desc 'Download the artifacts file from a job' do -- cgit v1.2.1 From 02aa269e34b7c05a52e5226fc02d91ffbbb6010f Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Tue, 5 Sep 2017 10:55:12 +1100 Subject: Add branch existence check to the APIv4 branches via HEAD request --- lib/api/branches.rb | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'lib/api') diff --git a/lib/api/branches.rb b/lib/api/branches.rb index a989394ad91..642c1140fcc 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -24,17 +24,22 @@ module API present paginate(branches), with: Entities::RepoBranch, project: user_project end - desc 'Get a single branch' do - success Entities::RepoBranch - end - params do - requires :branch, type: String, desc: 'The name of the branch' - end - get ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do - branch = user_project.repository.find_branch(params[:branch]) - not_found!("Branch") unless branch + resource ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do + desc 'Get a single branch' do + success Entities::RepoBranch + end + params do + requires :branch, type: String, desc: 'The name of the branch' + end + head do + user_project.repository.branch_exists?(params[:branch]) ? status(204) : status(404) + end + get do + branch = user_project.repository.find_branch(params[:branch]) + not_found!('Branch') unless branch - present branch, with: Entities::RepoBranch, project: user_project + present branch, with: Entities::RepoBranch, project: user_project + end end # Note: This API will be deprecated in favor of the protected branches API. -- cgit v1.2.1 From 3b874414c06156767117b7aa7ae705c7342d887c Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 5 Sep 2017 12:27:40 +0200 Subject: Do not use artifacts metadata to access single artifact --- lib/api/jobs.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 41c70a2dcb7..3d71d6bb062 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -98,10 +98,11 @@ module API build = get_build!(params[:job_id]) not_found! unless build.artifacts? - entry = build.artifacts_metadata_entry(params[:artifact_path]) - not_found! unless entry.exists? + path = Gitlab::Ci::Build::Artifacts::Path + .new(params[:artifact_path]) + not_found! unless path.valid? - send_artifacts_entry(build, entry) + send_artifacts_entry(build, path) end desc 'Download the artifacts file from a job' do -- cgit v1.2.1 From d4154ef30f52b30054e8e5d9bbf172d8700e8049 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 5 Sep 2017 13:22:15 +0200 Subject: Do not require API authentication if artifacts are public --- lib/api/jobs.rb | 79 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 36 deletions(-) (limited to 'lib/api') diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 3d71d6bb062..9e2af071e0a 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -2,12 +2,12 @@ module API class Jobs < Grape::API include PaginationParams - before { authenticate! } - params do requires :id, type: String, desc: 'The ID of a project' end resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + before { authenticate! } + helpers do params :optional_scope do optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show', @@ -71,40 +71,6 @@ module API 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 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 = get_build!(params[:job_id]) - not_found! unless build.artifacts? - - path = Gitlab::Ci::Build::Artifacts::Path - .new(params[:artifact_path]) - not_found! unless path.valid? - - send_artifacts_entry(build, path) - end - desc 'Download the artifacts file from a job' do detail 'This feature was introduced in GitLab 8.10' end @@ -235,6 +201,47 @@ module API end end + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + before { authenticate_non_get! } + + 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 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 = get_build!(params[:job_id]) + not_found! unless build.artifacts? + + path = Gitlab::Ci::Build::Artifacts::Path + .new(params[:artifact_path]) + not_found! unless path.valid? + + send_artifacts_entry(build, path) + end + end + helpers do def find_build(id) user_project.builds.find_by(id: id.to_i) -- cgit v1.2.1 From b69579742b5379760ccc868d359a9b6d1d225861 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 25 Aug 2017 12:01:34 +0200 Subject: API: Add GPG key management --- lib/api/entities.rb | 4 +++ lib/api/users.rb | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0092cc14e74..031dd02c6eb 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -491,6 +491,10 @@ module API expose :user, using: Entities::UserPublic end + class GPGKey < Grape::Entity + expose :id, :key, :created_at + end + class Note < Grape::Entity # Only Issue and MergeRequest have iid NOTEABLE_TYPES_WITH_IID = %w(Issue MergeRequest).freeze diff --git a/lib/api/users.rb b/lib/api/users.rb index 96f47bb618a..82991dc9d16 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -492,6 +492,76 @@ module API destroy_conditionally!(key) end + desc "Get the currently authenticated user's GPG keys" do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + use :pagination + end + get 'gpg_keys' do + present paginate(current_user.gpg_keys), with: Entities::GPGKey + end + + desc 'Get a single GPG key owned by currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + get 'gpg_keys/:key_id' do + key = current_user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + present key, with: Entities::GPGKey + end + + desc 'Add a new GPG key to the currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :key, type: String, desc: 'The new GPG key' + end + post 'gpg_keys' do + key = current_user.gpg_keys.new(declared_params) + + if key.save + present key, with: Entities::GPGKey + else + render_validation_error!(key) + end + end + + desc 'Revoke a GPG key owned by currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + post 'gpg_keys/:key_id/revoke' do + key = current_user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + key.revoke + status :accepted + end + + desc 'Delete a GPG key from the currently authenticated user' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :key_id, type: Integer, desc: 'The ID of the SSH key' + end + delete 'gpg_keys/:key_id' do + key = current_user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + status 204 + key.destroy + end + desc "Get the currently authenticated user's email addresses" do success Entities::Email end -- cgit v1.2.1 From 97371848c5fccb7ba066cc0c50c0d3ed15ec5971 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 25 Aug 2017 12:24:41 +0200 Subject: API: Add GPG key management for admins --- lib/api/users.rb | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'lib/api') diff --git a/lib/api/users.rb b/lib/api/users.rb index 82991dc9d16..1825c90a23b 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -233,6 +233,86 @@ module API destroy_conditionally!(key) end + desc 'Add a GPG key to a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key, type: String, desc: 'The new GPG key' + end + post ':id/gpg_keys' do + authenticated_as_admin! + + user = User.find_by(id: params.delete(:id)) + not_found!('User') unless user + + key = user.gpg_keys.new(declared_params(include_missing: false)) + + if key.save + present key, with: Entities::GPGKey + else + render_validation_error!(key) + end + end + + desc 'Get the GPG keys of a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + success Entities::GPGKey + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + use :pagination + end + get ':id/gpg_keys' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + present paginate(user.gpg_keys), with: Entities::GPGKey + end + + desc 'Delete an existing GPG key from a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + delete ':id/gpg_keys/:key_id' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + key = user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + status 204 + key.destroy + end + + desc 'Revokes an existing GPG key from a specified user. Available only for admins.' do + detail 'This feature was added in GitLab 10.0' + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + requires :key_id, type: Integer, desc: 'The ID of the GPG key' + end + post ':id/gpg_keys/:key_id/revoke' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + key = user.gpg_keys.find_by(id: params[:key_id]) + not_found!('GPG Key') unless key + + key.revoke + status :accepted + end + desc 'Add an email address to a specified user. Available only for admins.' do success Entities::Email end -- cgit v1.2.1 From 8323e55b6c0d59627c584b49e70d4f6ccfd3c8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 31 Aug 2017 18:00:40 -0300 Subject: Return a value to check if redis is available on /internal/check --- lib/api/helpers/internal_helpers.rb | 9 +++++++++ lib/api/internal.rb | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/api') 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..85b66593175 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 -- cgit v1.2.1 From ff3eeffa083e6f2299db9c622611762028578bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 31 Aug 2017 18:01:07 -0300 Subject: Implement /internal/pre-receive for shell operations --- lib/api/internal.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/api') diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 85b66593175..c0fef56378f 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -143,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 -- cgit v1.2.1 From ef4b3a39bc705dfa47762868ea064d2dbadc16e6 Mon Sep 17 00:00:00 2001 From: Ashley Dumaine Date: Mon, 28 Aug 2017 17:38:06 -0400 Subject: Add functionality to collapse outdated diff comments regardless of discussion resolution --- lib/api/entities.rb | 1 + lib/api/projects.rb | 2 ++ lib/api/v3/entities.rb | 1 + lib/api/v3/projects.rb | 7 ++++--- 4 files changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 031dd02c6eb..2799fec9cb6 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -119,6 +119,7 @@ module API expose :archived?, as: :archived expose :visibility expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } + expose :collapse_outdated_diff_comments expose :container_registry_enabled # Expose old field names with the new permissions methods to keep API compatible diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 4845242a173..558eace80f3 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 :collapse_outdated_diff_comments, type: Boolean, desc: 'Collapse outdated diffs regardless of discussion resolution' 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, + :collapse_outdated_diff_comments, :container_registry_enabled, :default_branch, :description, diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb index a9a35f2a4bd..c00df7d00de 100644 --- a/lib/api/v3/entities.rb +++ b/lib/api/v3/entities.rb @@ -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 :collapse_outdated_diff_comments expose :container_registry_enabled # Expose old field names with the new permissions methods to keep API compatible diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index 449876c10d9..2a8906587ce 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 :collapse_outdated_diff_comments, type: Boolean, desc: 'Collapse outdated diffs regardless of discussion resolution' 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.' @@ -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, :collapse_outdated_diff_comments, + :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 -- cgit v1.2.1 From a3f76b76a4b8db85c6fa557a5e801dcea7195735 Mon Sep 17 00:00:00 2001 From: Ashley Dumaine Date: Fri, 1 Sep 2017 18:39:22 -0400 Subject: change collapse to resolve and comments to discussions --- lib/api/entities.rb | 2 +- lib/api/projects.rb | 4 ++-- lib/api/v3/entities.rb | 2 +- lib/api/v3/projects.rb | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 2799fec9cb6..9114b69606b 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -119,7 +119,7 @@ module API expose :archived?, as: :archived expose :visibility expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } - expose :collapse_outdated_diff_comments + 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/projects.rb b/lib/api/projects.rb index 558eace80f3..7dc19788462 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -16,7 +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 :collapse_outdated_diff_comments, type: Boolean, desc: 'Collapse outdated diffs regardless of discussion resolution' + 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.' @@ -237,7 +237,7 @@ module API at_least_one_of_ce = [ :jobs_enabled, - :collapse_outdated_diff_comments, + :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 c00df7d00de..ac47a713966 100644 --- a/lib/api/v3/entities.rb +++ b/lib/api/v3/entities.rb @@ -64,7 +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 :collapse_outdated_diff_comments + 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/projects.rb b/lib/api/v3/projects.rb index 2a8906587ce..74df246bdfe 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -18,7 +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 :collapse_outdated_diff_comments, type: Boolean, desc: 'Collapse outdated diffs regardless of discussion resolution' + 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.' @@ -297,7 +297,7 @@ 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, :collapse_outdated_diff_comments, + :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, -- cgit v1.2.1 From 80b3dcc777c72ee1853b4228baf6310ccd5e44d8 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 6 Sep 2017 11:20:12 +0200 Subject: Extract job artifacts API code to a separate file --- lib/api/api.rb | 1 + lib/api/helpers.rb | 12 ++++++ lib/api/job_artifacts.rb | 80 ++++++++++++++++++++++++++++++++++++ lib/api/jobs.rb | 105 +++-------------------------------------------- 4 files changed, 99 insertions(+), 99 deletions(-) create mode 100644 lib/api/job_artifacts.rb (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index 94df543853b..1405a5d0f0e 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -108,6 +108,7 @@ module API mount ::API::Internal mount ::API::Issues mount ::API::Jobs + mount ::API::JobArtifacts mount ::API::Keys mount ::API::Labels mount ::API::Lint diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index f9ce1165544..6fa1527461f 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -128,6 +128,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 +164,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') diff --git a/lib/api/job_artifacts.rb b/lib/api/job_artifacts.rb new file mode 100644 index 00000000000..e0c5449e65e --- /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]) + not_found! 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 9e2af071e0a..19161aabd37 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -66,28 +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.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. @@ -98,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' @@ -117,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 @@ -134,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? @@ -152,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? @@ -160,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' @@ -189,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? @@ -201,56 +165,7 @@ module API end end - params do - requires :id, type: String, desc: 'The ID of a project' - end - resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do - before { authenticate_non_get! } - - 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 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 = get_build!(params[:job_id]) - not_found! unless build.artifacts? - - path = Gitlab::Ci::Build::Artifacts::Path - .new(params[:artifact_path]) - not_found! unless path.valid? - - send_artifacts_entry(build, path) - end - 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? @@ -261,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 -- cgit v1.2.1 From c922fb4b68e3d57bf5328b6825040f1871a48b66 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 6 Sep 2017 11:31:08 +0200 Subject: Respond with a bad request if artifact path is invalid --- lib/api/helpers.rb | 2 +- lib/api/job_artifacts.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 6fa1527461f..e646c63467a 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -222,7 +222,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 diff --git a/lib/api/job_artifacts.rb b/lib/api/job_artifacts.rb index e0c5449e65e..2a8fa7659bf 100644 --- a/lib/api/job_artifacts.rb +++ b/lib/api/job_artifacts.rb @@ -52,7 +52,7 @@ module API path = Gitlab::Ci::Build::Artifacts::Path .new(params[:artifact_path]) - not_found! unless path.valid? + bad_request! unless path.valid? send_artifacts_entry(build, path) end -- cgit v1.2.1 From ec7a12da818898b278a3e47a9b96ccebafbe5b4c Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 6 Sep 2017 14:45:28 +0200 Subject: Revert moving authorization hook in jobs API --- lib/api/jobs.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index 19161aabd37..3c1c412ba42 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -2,12 +2,12 @@ module API class Jobs < Grape::API include PaginationParams + before { authenticate! } + params do requires :id, type: String, desc: 'The ID of a project' end resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do - before { authenticate! } - helpers do params :optional_scope do optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show', -- cgit v1.2.1 From bca72f5906ed38dc231ef066231238758c1cb42d Mon Sep 17 00:00:00 2001 From: "micael.bergeron" Date: Sun, 3 Sep 2017 07:45:44 -0400 Subject: wip: fake its a binary diff --- lib/api/commits.rb | 2 +- lib/api/entities.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/api') 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 9114b69606b..0c63dc345c2 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -291,10 +291,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 :diff end class ProtectedRefAccess < Grape::Entity -- cgit v1.2.1 From c9aa7932152bd10f6fc7b87b3263922aa4b911b7 Mon Sep 17 00:00:00 2001 From: "micael.bergeron" Date: Mon, 4 Sep 2017 13:34:15 -0400 Subject: revert to using a simple representation --- lib/api/entities.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0c63dc345c2..1d224d7bc21 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -295,7 +295,7 @@ module API expose :new_file?, as: :new_file expose :renamed_file?, as: :renamed_file expose :deleted_file?, as: :deleted_file - expose :diff + expose :json_safe_diff, as: :diff end class ProtectedRefAccess < Grape::Entity -- cgit v1.2.1 From 235b105c917c16ab14a79ba13280aff4fd9f1cf9 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Wed, 30 Aug 2017 15:38:16 +0200 Subject: Finish migration to the new events setup This finishes the procedure for migrating events from the old format into the new format. Code no longer uses the old setup and the database tables used during the migration process are swapped, with the old table being dropped. While the database migration can be reversed this will 1) take a lot of time as data has to be coped around 2) won't restore data in the "events.data" column as we have no way of restoring this. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/37241 --- lib/api/entities.rb | 2 +- lib/api/v3/entities.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 031dd02c6eb..403c91cacc7 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -545,7 +545,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/v3/entities.rb b/lib/api/v3/entities.rb index a9a35f2a4bd..576652ab6d9 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 -- cgit v1.2.1 From 6c49a628000605d1beb120431003abb329b9fd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D=C3=A1vila?= Date: Thu, 17 Aug 2017 10:37:36 -0500 Subject: Restore some changes from !9199 --- lib/api/entities.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 1d224d7bc21..d5f2c422c58 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -35,7 +35,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 -- cgit v1.2.1 From 2915bb27078a3eae0bac36bd2c3a2e1c4998130c Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Thu, 7 Sep 2017 09:21:52 +1100 Subject: Add API support for wiki pages --- lib/api/api.rb | 1 + lib/api/entities.rb | 10 ++++++ lib/api/helpers.rb | 6 ++++ lib/api/wikis.rb | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 lib/api/wikis.rb (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index 94df543853b..9f67cb598f6 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -143,6 +143,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/entities.rb b/lib/api/entities.rb index e8dd61e493f..3c0fc4c2564 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 :name, :username end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index b56fd2388b3..0932f8eb76f 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -35,6 +35,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 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 -- cgit v1.2.1 From f7c8032e0993a6dc6bb808b0f2234324d3fe9707 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 6 Sep 2017 22:41:15 -0700 Subject: Add JSON logger in `log/api_json.log` for Grape API endpoints Closes #36189 --- lib/api/api.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index 1405a5d0f0e..63df22c508b 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -2,6 +2,15 @@ module API class API < Grape::API include APIGuard + LOG_FILENAME = Rails.root.join("log", "api_json.log") + + use GrapeLogging::Middleware::RequestLogger, + logger: ::Gitlab::ApiLogger.new(LOG_FILENAME), + formatter: GrapeLogging::Formatters::Json.new, + include: [ GrapeLogging::Loggers::Response.new, + GrapeLogging::Loggers::FilterParameters.new, + GrapeLogging::Loggers::ClientEnv.new ] + allow_access_with_scope :api prefix :api -- cgit v1.2.1 From cfd475a45ee2655fa0148b0b561f95b44fe8641b Mon Sep 17 00:00:00 2001 From: Tiago Botelho Date: Tue, 15 Aug 2017 11:27:37 +0100 Subject: Removes default scope from sortable --- lib/api/broadcast_messages.rb | 2 +- lib/api/merge_request_diffs.rb | 2 +- lib/api/milestone_responses.rb | 2 +- lib/api/v3/merge_request_diffs.rb | 2 +- lib/api/v3/milestones.rb | 1 + lib/api/v3/projects.rb | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) (limited to 'lib/api') 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/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/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..6b338ce2d6a 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -119,7 +119,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 -- cgit v1.2.1 From c304dfd4d6ca0f52537044742bb6dd6c219bdbbf Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 7 Sep 2017 07:02:46 -0700 Subject: Fix Rubocop failures in API logger --- lib/api/api.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index 63df22c508b..0ab0c8c490a 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -7,9 +7,11 @@ module API use GrapeLogging::Middleware::RequestLogger, logger: ::Gitlab::ApiLogger.new(LOG_FILENAME), formatter: GrapeLogging::Formatters::Json.new, - include: [ GrapeLogging::Loggers::Response.new, - GrapeLogging::Loggers::FilterParameters.new, - GrapeLogging::Loggers::ClientEnv.new ] + include: [ + GrapeLogging::Loggers::Response.new, + GrapeLogging::Loggers::FilterParameters.new, + GrapeLogging::Loggers::ClientEnv.new + ] allow_access_with_scope :api prefix :api -- cgit v1.2.1 From 35dec2c3e87f2f44c3ab0269e7f737afdc28801a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 7 Sep 2017 07:48:13 -0700 Subject: Use a custom GrapeLogging formatter to get the timestamp --- lib/api/api.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index 0ab0c8c490a..af0b38963f5 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -5,8 +5,8 @@ module API LOG_FILENAME = Rails.root.join("log", "api_json.log") use GrapeLogging::Middleware::RequestLogger, - logger: ::Gitlab::ApiLogger.new(LOG_FILENAME), - formatter: GrapeLogging::Formatters::Json.new, + logger: Logger.new(LOG_FILENAME), + formatter: Gitlab::GrapeLogging::Formatters::LogrageWithTimestamp.new, include: [ GrapeLogging::Loggers::Response.new, GrapeLogging::Loggers::FilterParameters.new, -- cgit v1.2.1 From 62bb6235c229a869052180f9709c4801116f02cc Mon Sep 17 00:00:00 2001 From: Ruben Davila Date: Thu, 7 Sep 2017 13:35:45 -0500 Subject: Make Members with Owner and Master roles always able to create subgroups --- lib/api/groups.rb | 7 ++++++- lib/api/helpers.rb | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/api') 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 8b03df65ae4..00dbc2aee7a 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -93,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) -- cgit v1.2.1