From b1c40590e7738a782d1295d743a6a3957723c4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20=C4=8Cupi=C4=87?= Date: Mon, 29 Jan 2018 00:23:36 +0100 Subject: Extend Runner API helpers with cache info storage --- lib/api/helpers/runner.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index 2cae53dba53..ad8c1c4407c 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -27,6 +27,8 @@ module API end def update_runner_info + update_runner_info_cache + return unless update_runner? current_runner.contacted_at = Time.now @@ -35,13 +37,17 @@ module API end def update_runner? - # Use a random threshold to prevent beating DB updates. - # It generates a distribution between [40m, 80m]. - # - contacted_at_max_age = UPDATE_RUNNER_EVERY + Random.rand(UPDATE_RUNNER_EVERY) + # Use a 1h threshold to prevent beating DB updates. current_runner.contacted_at.nil? || - (Time.now - current_runner.contacted_at) >= contacted_at_max_age + (Time.now - current_runner.contacted_at) >= UPDATE_RUNNER_EVERY + end + + def update_runner_info_cache + Gitlab::Redis::SharedState.with do |redis| + redis_key = "#{current_runner.runner_info_key}:contacted_at" + redis.set(redis_key, Time.now) + end end def validate_job!(job) -- cgit v1.2.1 From 397442a06140a8cf38bebe3f4519311b1448f23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20=C4=8Cupi=C4=87?= Date: Mon, 29 Jan 2018 17:21:30 +0100 Subject: Update runner info on all authenticated requests --- lib/api/helpers/runner.rb | 2 ++ lib/api/runner.rb | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index ad8c1c4407c..5ac9181f878 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -20,6 +20,8 @@ module API def authenticate_runner! forbidden! unless current_runner + + update_runner_info end def current_runner diff --git a/lib/api/runner.rb b/lib/api/runner.rb index 80feb629d54..50cb1df92ad 100644 --- a/lib/api/runner.rb +++ b/lib/api/runner.rb @@ -78,7 +78,6 @@ module API post '/request' do authenticate_runner! no_content! unless current_runner.active? - update_runner_info if current_runner.runner_queue_value_latest?(params[:last_update]) header 'X-GitLab-Last-Update', params[:last_update] -- cgit v1.2.1 From bdd3e39b0bd4e8fcec5d6e2d97297840211dd921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20=C4=8Cupi=C4=87?= Date: Mon, 29 Jan 2018 20:56:28 +0100 Subject: Move info update implementation to Ci::Runner model --- lib/api/helpers/runner.rb | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index 5ac9181f878..8f45cae0e60 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -5,7 +5,6 @@ module API JOB_TOKEN_HEADER = 'HTTP_JOB_TOKEN'.freeze JOB_TOKEN_PARAM = :token - UPDATE_RUNNER_EVERY = 10 * 60 def runner_registration_token_valid? ActiveSupport::SecurityUtils.variable_size_secure_compare(params[:token], @@ -21,37 +20,13 @@ module API def authenticate_runner! forbidden! unless current_runner - update_runner_info + current_runner.update_runner_info(get_runner_version_from_params) end def current_runner @runner ||= ::Ci::Runner.find_by_token(params[:token].to_s) end - def update_runner_info - update_runner_info_cache - - return unless update_runner? - - current_runner.contacted_at = Time.now - current_runner.assign_attributes(get_runner_version_from_params) - current_runner.save if current_runner.changed? - end - - def update_runner? - # Use a 1h threshold to prevent beating DB updates. - - current_runner.contacted_at.nil? || - (Time.now - current_runner.contacted_at) >= UPDATE_RUNNER_EVERY - end - - def update_runner_info_cache - Gitlab::Redis::SharedState.with do |redis| - redis_key = "#{current_runner.runner_info_key}:contacted_at" - redis.set(redis_key, Time.now) - end - end - def validate_job!(job) not_found! unless job -- cgit v1.2.1 From 38c242126d10d0887ca0d3dd8565ef2669dfec46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20=C4=8Cupi=C4=87?= Date: Sun, 4 Feb 2018 18:34:21 +0100 Subject: Refactor runner attribute caching implementation --- lib/api/helpers/runner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index 8f45cae0e60..87ba40e26e1 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -20,7 +20,7 @@ module API def authenticate_runner! forbidden! unless current_runner - current_runner.update_runner_info(get_runner_version_from_params) + current_runner.update_cached_info(get_runner_version_from_params) end def current_runner -- cgit v1.2.1 From 7381944565701f2a8db5d58d5bc3c7e52e7f60bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarka=20Kadlecova=CC=81?= Date: Wed, 31 Jan 2018 15:59:59 +0100 Subject: Support search in API --- lib/api/api.rb | 1 + lib/api/entities.rb | 25 ++++++----- lib/api/search.rb | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/api/v3/projects.rb | 2 +- 4 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 lib/api/search.rb (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index f3f64244589..e953f3d2eca 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -146,6 +146,7 @@ module API mount ::API::Repositories mount ::API::Runner mount ::API::Runners + mount ::API::Search mount ::API::Services mount ::API::Settings mount ::API::SidekiqMetrics diff --git a/lib/api/entities.rb b/lib/api/entities.rb index e13463ec66b..7838de13c56 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -314,24 +314,20 @@ module API end end - class ProjectSnippet < Grape::Entity + class Snippet < Grape::Entity expose :id, :title, :file_name, :description expose :author, using: Entities::UserBasic expose :updated_at, :created_at - - expose :web_url do |snippet, options| + expose :project_id + expose :web_url do |snippet| Gitlab::UrlBuilder.build(snippet) end end - class PersonalSnippet < Grape::Entity - expose :id, :title, :file_name, :description - expose :author, using: Entities::UserBasic - expose :updated_at, :created_at + class ProjectSnippet < Snippet + end - expose :web_url do |snippet| - Gitlab::UrlBuilder.build(snippet) - end + class PersonalSnippet < Snippet expose :raw_url do |snippet| Gitlab::UrlBuilder.build(snippet) + "/raw" end @@ -1168,5 +1164,14 @@ module API class ApplicationWithSecret < Application expose :secret end + + class Blob < Grape::Entity + expose :basename + expose :data + expose :filename + expose :id + expose :ref + expose :startline + end end end diff --git a/lib/api/search.rb b/lib/api/search.rb new file mode 100644 index 00000000000..31121b3ee2d --- /dev/null +++ b/lib/api/search.rb @@ -0,0 +1,110 @@ +module API + class Search < Grape::API + include PaginationParams + + before { authenticate! } + + helpers do + SCOPE_ENTITY = { + merge_requests: Entities::MergeRequestBasic, + issues: Entities::IssueBasic, + projects: Entities::BasicProjectDetails, + milestones: Entities::Milestone, + notes: Entities::Note, + commits: Entities::Commit, + blobs: Entities::Blob, + wiki_blobs: Entities::Blob, + snippet_titles: Entities::Snippet, + snippet_blobs: Entities::Snippet + }.freeze + + def search(additional_params = {}) + search_params = { + scope: params[:scope], + search: params[:search], + snippets: snippets?, + page: params[:page], + per_page: params[:per_page], + without_counts: false + }.merge(additional_params) + + results = SearchService.new(current_user, search_params).search_objects + + process_results(results) + end + + def process_results(results) + case params[:scope] + when 'wiki_blobs' + paginate(results).map { |blob| Gitlab::ProjectSearchResults.parse_search_result(blob) } + when 'blobs' + paginate(results).map { |blob| blob[1] } + else + paginate(results) + end + end + + def snippets? + %w(snippet_blobs snippet_titles).include?(params[:scope]).to_s + end + + def entity + SCOPE_ENTITY[params[:scope].to_sym] + end + end + + resource :search do + desc 'Search on GitLab' do + detail 'This feature was introduced in GitLab 10.5.' + end + params do + requires :search, type: String, desc: 'The expression it should be searched for' + requires :scope, type: String, desc: 'The scope of search, available scopes: + projects, issues, merge_requests, milestones, snippet_titles, snippet_blobs', + values: %w(projects issues merge_requests milestones snippet_titles snippet_blobs) + use :pagination + end + get do + present search, with: entity + end + end + + resource :groups, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + desc 'Search on GitLab' do + detail 'This feature was introduced in GitLab 10.5.' + end + params do + requires :id, type: String, desc: 'The ID of a group' + requires :search, type: String, desc: 'The expression it should be searched for' + requires :scope, type: String, desc: 'The scope of search, available scopes: + projects, issues, merge_requests, milestones', + values: %w(projects issues merge_requests milestones) + use :pagination + end + get ':id/-/search' do + find_group!(params[:id]) + + present search(group_id: params[:id]), with: entity + end + end + + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do + desc 'Search on GitLab' do + detail 'This feature was introduced in GitLab 10.5.' + end + params do + requires :id, type: String, desc: 'The ID of a project' + requires :search, type: String, desc: 'The expression it should be searched for' + requires :scope, type: String, desc: 'The scope of search, available scopes: + issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs', + values: %w(issues merge_requests milestones notes wiki_blobs commits blobs) + use :pagination + end + get ':id/-/search' do + find_project!(params[:id]) + + present search(project_id: params[:id]), with: entity + end + end + end +end diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index c856ba99f09..7d8b1f369fe 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -174,7 +174,7 @@ module API use :pagination end get "/search/:query", requirements: { query: %r{[^/]+} } do - search_service = Search::GlobalService.new(current_user, search: params[:query]).execute + search_service = ::Search::GlobalService.new(current_user, search: params[:query]).execute projects = search_service.objects('projects', params[:page], false) projects = projects.reorder(params[:order_by] => params[:sort]) -- cgit v1.2.1 From 1b2400b529628da08e406e2391ef37c0b05f889e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarka=20Kadlecov=C3=A1?= Date: Tue, 6 Feb 2018 17:53:42 +0100 Subject: Return only limited pagination headers for search API endpoints --- lib/api/helpers/pagination.rb | 17 +++++++++++++---- lib/api/search.rb | 3 +-- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/helpers/pagination.rb b/lib/api/helpers/pagination.rb index bb70370ba77..09805049169 100644 --- a/lib/api/helpers/pagination.rb +++ b/lib/api/helpers/pagination.rb @@ -12,13 +12,16 @@ module API private def add_pagination_headers(paginated_data) - header 'X-Total', paginated_data.total_count.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 header 'X-Prev-Page', paginated_data.prev_page.to_s header 'Link', pagination_links(paginated_data) + + return if data_without_counts?(paginated_data) + + header 'X-Total', paginated_data.total_count.to_s + header 'X-Total-Pages', total_pages(paginated_data).to_s end def pagination_links(paginated_data) @@ -37,8 +40,10 @@ module API request_params[:page] = 1 links << %(<#{request_url}?#{request_params.to_query}>; rel="first") - request_params[:page] = total_pages(paginated_data) - links << %(<#{request_url}?#{request_params.to_query}>; rel="last") + unless data_without_counts?(paginated_data) + request_params[:page] = total_pages(paginated_data) + links << %(<#{request_url}?#{request_params.to_query}>; rel="last") + end links.join(', ') end @@ -55,6 +60,10 @@ module API relation end + + def data_without_counts?(paginated_data) + paginated_data.is_a?(Kaminari::PaginatableWithoutCount) + end end end end diff --git a/lib/api/search.rb b/lib/api/search.rb index 31121b3ee2d..3912c66657e 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -24,8 +24,7 @@ module API search: params[:search], snippets: snippets?, page: params[:page], - per_page: params[:per_page], - without_counts: false + per_page: params[:per_page] }.merge(additional_params) results = SearchService.new(current_user, search_params).search_objects -- cgit v1.2.1 From 86e98c832a4eeaac616daef4ef9ddebeb7191fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarka=20Kadlecov=C3=A1?= Date: Wed, 7 Feb 2018 14:20:18 +0100 Subject: Small code/doc changes --- lib/api/search.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/search.rb b/lib/api/search.rb index 3912c66657e..9f08fd96a3b 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -58,8 +58,10 @@ module API end params do requires :search, type: String, desc: 'The expression it should be searched for' - requires :scope, type: String, desc: 'The scope of search, available scopes: - projects, issues, merge_requests, milestones, snippet_titles, snippet_blobs', + requires :scope, + type: String, + desc: 'The scope of search, available scopes: + projects, issues, merge_requests, milestones, snippet_titles, snippet_blobs', values: %w(projects issues merge_requests milestones snippet_titles snippet_blobs) use :pagination end @@ -75,8 +77,10 @@ module API params do requires :id, type: String, desc: 'The ID of a group' requires :search, type: String, desc: 'The expression it should be searched for' - requires :scope, type: String, desc: 'The scope of search, available scopes: - projects, issues, merge_requests, milestones', + requires :scope, + type: String, + desc: 'The scope of search, available scopes: + projects, issues, merge_requests, milestones', values: %w(projects issues merge_requests milestones) use :pagination end @@ -94,8 +98,10 @@ module API params do requires :id, type: String, desc: 'The ID of a project' requires :search, type: String, desc: 'The expression it should be searched for' - requires :scope, type: String, desc: 'The scope of search, available scopes: - issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs', + requires :scope, + type: String, + desc: 'The scope of search, available scopes: + issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs', values: %w(issues merge_requests milestones notes wiki_blobs commits blobs) use :pagination end -- cgit v1.2.1 From 6b0c6e69e1b249f14624550fcbca7f5ee6f51410 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Fri, 1 Dec 2017 13:58:49 +0000 Subject: Use hashed storage in the specs --- lib/api/internal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 9285fb90cdc..b3660e4a1d0 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -13,7 +13,7 @@ module API # key_id - ssh key id for Git over SSH # user_id - user id for Git over HTTP # protocol - Git access protocol being used, e.g. HTTP or SSH - # project - project path with namespace + # project - project full_path (not path on disk) # action - git action (git-upload-pack or git-receive-pack) # changes - changes as "oldrev newrev ref", see Gitlab::ChangesList post "/allowed" do -- cgit v1.2.1 From b7cd99c376c2f953f30a4bf982b69780e3d6985b Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Fri, 22 Dec 2017 16:54:55 +0100 Subject: Allow including custom attributes in API responses --- lib/api/entities.rb | 5 +++++ lib/api/groups.rb | 29 ++++++++++++++++++++++++++--- lib/api/helpers/custom_attributes.rb | 28 ++++++++++++++++++++++++++++ lib/api/projects.rb | 19 ++++++++++++++++--- lib/api/users.rb | 9 ++++++++- 5 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 lib/api/helpers/custom_attributes.rb (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 7838de13c56..dc8e2b26316 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -22,6 +22,7 @@ module API end expose :avatar_path, if: ->(user, options) { options.fetch(:only_path, false) && user.avatar_path } + expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes expose :web_url do |user, options| Gitlab::Routing.url_helpers.user_url(user) @@ -109,6 +110,8 @@ module API expose :star_count, :forks_count expose :last_activity_at + expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes + def self.preload_relation(projects_relation, options = {}) projects_relation.preload(:project_feature, :route) .preload(namespace: [:route, :owner], @@ -230,6 +233,8 @@ module API expose :parent_id end + expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes + expose :statistics, if: :statistics do with_options format_with: -> (value) { value.to_i } do expose :storage_size diff --git a/lib/api/groups.rb b/lib/api/groups.rb index b81f07a1770..4a4df1b8b9e 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -1,6 +1,7 @@ module API class Groups < Grape::API include PaginationParams + include Helpers::CustomAttributes before { authenticate_non_get! } @@ -67,6 +68,8 @@ module API } groups = groups.with_statistics if options[:statistics] + groups, options = with_custom_attributes(groups, options) + present paginate(groups), options end end @@ -79,6 +82,7 @@ module API end params do use :group_list_params + use :with_custom_attributes end get do groups = find_groups(params) @@ -142,9 +146,20 @@ module API desc 'Get a single group, with containing projects.' do success Entities::GroupDetail end + params do + use :with_custom_attributes + end get ":id" do group = find_group!(params[:id]) - present group, with: Entities::GroupDetail, current_user: current_user + + options = { + with: Entities::GroupDetail, + current_user: current_user + } + + group, options = with_custom_attributes(group, options) + + present group, options end desc 'Remove a group.' @@ -175,12 +190,19 @@ module API optional :starred, type: Boolean, default: false, desc: 'Limit by starred status' use :pagination + use :with_custom_attributes end get ":id/projects" do projects = find_group_projects(params) - entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project - present entity.prepare_relation(projects), with: entity, current_user: current_user + options = { + with: params[:simple] ? Entities::BasicProjectDetails : Entities::Project, + current_user: current_user + } + + projects, options = with_custom_attributes(projects, options) + + present options[:with].prepare_relation(projects), options end desc 'Get a list of subgroups in this group.' do @@ -188,6 +210,7 @@ module API end params do use :group_list_params + use :with_custom_attributes end get ":id/subgroups" do groups = find_groups(params) diff --git a/lib/api/helpers/custom_attributes.rb b/lib/api/helpers/custom_attributes.rb new file mode 100644 index 00000000000..70e4eda95f8 --- /dev/null +++ b/lib/api/helpers/custom_attributes.rb @@ -0,0 +1,28 @@ +module API + module Helpers + module CustomAttributes + extend ActiveSupport::Concern + + included do + helpers do + params :with_custom_attributes do + optional :with_custom_attributes, type: Boolean, default: false, desc: 'Include custom attributes in the response' + end + + def with_custom_attributes(collection_or_resource, options = {}) + options = options.merge( + with_custom_attributes: params[:with_custom_attributes] && + can?(current_user, :read_custom_attribute) + ) + + if options[:with_custom_attributes] && collection_or_resource.is_a?(ActiveRecord::Relation) + collection_or_resource = collection_or_resource.includes(:custom_attributes) + end + + [collection_or_resource, options] + end + end + end + end + end +end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 5b481121a10..e90892a90f7 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -3,6 +3,7 @@ require_dependency 'declarative_policy' module API class Projects < Grape::API include PaginationParams + include Helpers::CustomAttributes before { authenticate_non_get! } @@ -80,6 +81,7 @@ module API projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] projects = projects.with_statistics if params[:statistics] projects = paginate(projects) + projects, options = with_custom_attributes(projects, options) if current_user project_members = current_user.project_members.preload(:source, user: [notification_settings: :source]) @@ -107,6 +109,7 @@ module API requires :user_id, type: String, desc: 'The ID or username of the user' use :collection_params use :statistics_params + use :with_custom_attributes end get ":user_id/projects" do user = find_user(params[:user_id]) @@ -127,6 +130,7 @@ module API params do use :collection_params use :statistics_params + use :with_custom_attributes end get do present_projects load_projects @@ -196,11 +200,19 @@ module API end params do use :statistics_params + use :with_custom_attributes end get ":id" do - entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails - present user_project, with: entity, current_user: current_user, - user_can_admin_project: can?(current_user, :admin_project, user_project), statistics: params[:statistics] + options = { + with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, + current_user: current_user, + user_can_admin_project: can?(current_user, :admin_project, user_project), + statistics: params[:statistics] + } + + project, options = with_custom_attributes(user_project, options) + + present project, options end desc 'Fork new project for the current user or provided namespace.' do @@ -242,6 +254,7 @@ module API end params do use :collection_params + use :with_custom_attributes end get ':id/forks' do forks = ForkProjectsFinder.new(user_project, params: project_finder_params, current_user: current_user).execute diff --git a/lib/api/users.rb b/lib/api/users.rb index 3cc12724b8a..3920171205f 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -2,6 +2,7 @@ module API class Users < Grape::API include PaginationParams include APIGuard + include Helpers::CustomAttributes allow_access_with_scope :read_user, if: -> (request) { request.get? } @@ -70,6 +71,7 @@ module API use :sort_params use :pagination + use :with_custom_attributes end get do authenticated_as_admin! if params[:external].present? || (params[:extern_uid].present? && params[:provider].present?) @@ -94,8 +96,9 @@ module API entity = current_user&.admin? ? Entities::UserWithAdmin : Entities::UserBasic users = users.preload(:identities, :u2f_registrations) if entity == Entities::UserWithAdmin + users, options = with_custom_attributes(users, with: entity) - present paginate(users), with: entity + present paginate(users), options end desc 'Get a single user' do @@ -103,12 +106,16 @@ module API end params do requires :id, type: Integer, desc: 'The ID of the user' + + use :with_custom_attributes end get ":id" do user = User.find_by(id: params[:id]) not_found!('User') unless user && can?(current_user, :read_user, user) opts = current_user&.admin? ? { with: Entities::UserWithAdmin } : { with: Entities::User } + user, opts = with_custom_attributes(user, opts) + present user, opts end -- cgit v1.2.1 From cea2a8f741d623ca2085e8149112de3a20a4779f Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 24 Oct 2017 13:28:06 +0300 Subject: Basic ref fetching for commits --- lib/api/commits.rb | 25 +++++++++++++++++++++++++ lib/api/entities.rb | 16 +++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commits.rb b/lib/api/commits.rb index d8fd6a6eb06..3cf88551fa7 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -156,6 +156,31 @@ module API end end + desc 'Get all reference a commit is pushed to' do + detail 'This feature was introduced in GitLab 10.6' + success Entities::SimpleRef + end + params do + requires :sha, type: String, desc: 'A commit sha' + optional :type, type: String, values: %w(branches tags all), default: 'all', desc: 'Scope' + end + get ':id/repository/commits/:sha/refs', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do + commit = user_project.commit(params[:sha]) + not_found!('Commit') unless commit + + case params[:type] + when 'branches' + refs = user_project.repository.branch_names_contains(commit.id) + when 'tags' + refs = user_project.repository.tag_names_contains(commit.id) + else + refs = user_project.repository.branch_names_contains(commit.id) + refs.push(*user_project.repository.tag_names_contains(commit.id)) + end + + present refs, with: Entities::SimpleRef + end + desc 'Post comment to commit' do success Entities::CommitNote end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 7838de13c56..e8c9ba6fce5 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -276,7 +276,17 @@ module API expose :last_pipeline, using: 'API::Entities::PipelineBasic' end - class Branch < Grape::Entity + class BasicRef < Grape::Entity + expose :name + end + + class SimpleRef < Grape::Entity + expose :name do |ref, options| + ref + end + end + + class Branch < BasicRef expose :name expose :commit, using: Entities::Commit do |repo_branch, options| @@ -845,8 +855,8 @@ module API expose :description end - class Tag < Grape::Entity - expose :name, :message + class Tag < BasicRef + expose :message expose :commit, using: Entities::Commit do |repo_tag, options| options[:project].repository.commit(repo_tag.dereferenced_target) -- cgit v1.2.1 From 4cefb568d96c4868404caa14534a4329e2dd887f Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 9 Feb 2018 14:30:27 +0100 Subject: Incorporate feedback --- lib/api/commits.rb | 29 +++++++++++++++-------------- lib/api/entities.rb | 10 +++------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 3cf88551fa7..6d845253c3a 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -156,29 +156,30 @@ module API end end - desc 'Get all reference a commit is pushed to' do + desc 'Get all references a commit is pushed to' do detail 'This feature was introduced in GitLab 10.6' - success Entities::SimpleRef + success Entities::BasicRef end params do requires :sha, type: String, desc: 'A commit sha' - optional :type, type: String, values: %w(branches tags all), default: 'all', desc: 'Scope' + optional :type, type: String, values: %w[branches tags all], default: 'all', desc: 'Scope' end get ':id/repository/commits/:sha/refs', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do commit = user_project.commit(params[:sha]) not_found!('Commit') unless commit - case params[:type] - when 'branches' - refs = user_project.repository.branch_names_contains(commit.id) - when 'tags' - refs = user_project.repository.tag_names_contains(commit.id) - else - refs = user_project.repository.branch_names_contains(commit.id) - refs.push(*user_project.repository.tag_names_contains(commit.id)) - end + refs = + case params[:type] + when 'branches' + user_project.repository.branch_names_contains(commit.id) + when 'tags' + user_project.repository.tag_names_contains(commit.id) + else + refs = user_project.repository.branch_names_contains(commit.id) + refs.concat(user_project.repository.tag_names_contains(commit.id)) + end - present refs, with: Entities::SimpleRef + present refs, with: Entities::BasicRef end desc 'Post comment to commit' do @@ -190,7 +191,7 @@ module API optional :path, type: String, desc: 'The file path' given :path do requires :line, type: Integer, desc: 'The line number' - requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line' + requires :line_type, type: String, values: %w[new old], default: 'new', desc: 'The type of the line' end end post ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do diff --git a/lib/api/entities.rb b/lib/api/entities.rb index e8c9ba6fce5..054c04bbd98 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -277,16 +277,12 @@ module API end class BasicRef < Grape::Entity - expose :name - end - - class SimpleRef < Grape::Entity expose :name do |ref, options| ref end end - class Branch < BasicRef + class Branch < Grape::Entity expose :name expose :commit, using: Entities::Commit do |repo_branch, options| @@ -855,8 +851,8 @@ module API expose :description end - class Tag < BasicRef - expose :message + class Tag < Grape::Entity + expose :name, :message expose :commit, using: Entities::Commit do |repo_tag, options| options[:project].repository.commit(repo_tag.dereferenced_target) -- cgit v1.2.1 From 922d156a5e0412a12662df94e03479f7ed015f7b Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 9 Feb 2018 17:46:41 +0100 Subject: Separate branch and tag names --- lib/api/commits.rb | 8 ++++---- lib/api/entities.rb | 8 ++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 6d845253c3a..afaf68114e8 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -171,12 +171,12 @@ module API refs = case params[:type] when 'branches' - user_project.repository.branch_names_contains(commit.id) + user_project.repository.branch_names_contains(commit.id).map {|branch_name| [branch_name, true]} when 'tags' - user_project.repository.tag_names_contains(commit.id) + user_project.repository.tag_names_contains(commit.id).map {|tag_name| [tag_name, false]} else - refs = user_project.repository.branch_names_contains(commit.id) - refs.concat(user_project.repository.tag_names_contains(commit.id)) + refs = user_project.repository.branch_names_contains(commit.id).map {|branch_name| [branch_name, true]} + refs.concat(user_project.repository.tag_names_contains(commit.id).map {|tag_name| [tag_name, false]}) end present refs, with: Entities::BasicRef diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 054c04bbd98..c7a817877f0 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -277,8 +277,12 @@ module API end class BasicRef < Grape::Entity - expose :name do |ref, options| - ref + expose :branch_name, if: lambda { |ref, options| ref[1] } do |ref, options| + ref[0] + end + + expose :tag_name, if: lambda { |ref, options| !ref[1] } do |ref, options| + ref[0] end end -- cgit v1.2.1 From 68ff219c4ec9088005ab872e141912f35ecc59f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarka=20Kadlecov=C3=A1?= Date: Fri, 9 Feb 2018 15:38:52 +0100 Subject: API - fix searching in group/project specified by path --- lib/api/search.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/api') diff --git a/lib/api/search.rb b/lib/api/search.rb index 9f08fd96a3b..b9982e03bb3 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -85,9 +85,9 @@ module API use :pagination end get ':id/-/search' do - find_group!(params[:id]) + group = find_group!(params[:id]) - present search(group_id: params[:id]), with: entity + present search(group_id: group.id), with: entity end end @@ -106,9 +106,9 @@ module API use :pagination end get ':id/-/search' do - find_project!(params[:id]) + project = find_project!(params[:id]) - present search(project_id: params[:id]), with: entity + present search(project_id: project.id), with: entity end end end -- cgit v1.2.1 From fec9fb05a5775b864ef6768df166d39fcb2be4bc Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 18 Jan 2018 23:10:19 +0000 Subject: Merge branch 'security-10-4-todo-api-reveals-sensitive-information' into 'security-10-4' Restrict Todo API mark_as_done endpoint to the user's todos only --- lib/api/todos.rb | 2 +- lib/api/v3/todos.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/todos.rb b/lib/api/todos.rb index ffccfebe752..c6dbcf84e3a 100644 --- a/lib/api/todos.rb +++ b/lib/api/todos.rb @@ -60,7 +60,7 @@ module API end post ':id/mark_as_done' do TodoService.new.mark_todos_as_done_by_ids(params[:id], current_user) - todo = Todo.find(params[:id]) + todo = current_user.todos.find(params[:id]) present todo, with: Entities::Todo, current_user: current_user end diff --git a/lib/api/v3/todos.rb b/lib/api/v3/todos.rb index 2f2cf259987..3e2c61f6dbd 100644 --- a/lib/api/v3/todos.rb +++ b/lib/api/v3/todos.rb @@ -12,7 +12,7 @@ module API end delete ':id' do TodoService.new.mark_todos_as_done_by_ids(params[:id], current_user) - todo = Todo.find(params[:id]) + todo = current_user.todos.find(params[:id]) present todo, with: ::API::Entities::Todo, current_user: current_user end -- cgit v1.2.1 From 848f49801d2c45227c525fb5ecdf8b71e7711ded Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 12 Feb 2018 12:40:55 +0100 Subject: add entity and update spec --- lib/api/api.rb | 1 + lib/api/entities.rb | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'lib/api') diff --git a/lib/api/api.rb b/lib/api/api.rb index e953f3d2eca..754549f72f0 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -138,6 +138,7 @@ module API mount ::API::PagesDomains mount ::API::Pipelines mount ::API::PipelineSchedules + mount ::API::ProjectImport mount ::API::ProjectHooks mount ::API::Projects mount ::API::ProjectMilestones diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 7838de13c56..8fbad2b6959 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -90,6 +90,11 @@ module API expose :created_at end + class ProjectImportStatus < ProjectIdentity + expose :import_status + expose :import_error, if: :import_error + end + class BasicProjectDetails < ProjectIdentity include ::API::ProjectsRelationBuilder -- cgit v1.2.1 From 82ff66ef31d6ff8ba2332f51b38f79b3bd7d64a5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 12 Feb 2018 12:42:33 +0100 Subject: add post import API endpoint --- lib/api/project_import.rb | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 lib/api/project_import.rb (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb new file mode 100644 index 00000000000..4bbb78a62f9 --- /dev/null +++ b/lib/api/project_import.rb @@ -0,0 +1,48 @@ +module API + class ProjectImport < Grape::API + include PaginationParams + + helpers do + def import_params + declared_params(include_missing: false) + end + + def file_is_valid? + import_params[:file] && import_params[:file].respond_to?(:read) + end + end + + before do + not_found! unless Gitlab::CurrentSettings.import_sources.include?('gitlab_project') + end + + params do + optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' + requires :file, type: File, desc: 'The project export file to be imported' + end + resource :projects do + desc 'Get export status' do + success Entities::ProjectImportStatus + end + post 'import' do + render_api_error!('The branch refname is invalid', 400) unless file_is_valid? + + namespace = import_params[:namespace] + + namespace = if namespace && namespace =~ /^\d+$/ + Namespace.find_by(id: namespace) + elsif namespace.blank? + current_user.namespace + else + Namespace.find_by_path_or_name(namespace) + end + + project = ::Projects::GitlabProjectsImportService.new(current_user, import_params).execute + + render_api_error!(link.project.full_messages.first, 400) unless project.saved? + + present project, with: Entities::ProjectImportStatus + end + end + end +end -- cgit v1.2.1 From d3b3f5d1b4def5e87f90a2347acc0b0ee8edc80a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 12 Feb 2018 14:46:47 +0100 Subject: update import API and spec --- lib/api/project_import.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index 4bbb78a62f9..396c316af22 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -17,6 +17,7 @@ module API end params do + requires :name, type: String, desc: 'The new project name' optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' requires :file, type: File, desc: 'The project export file to be imported' end @@ -37,9 +38,11 @@ module API Namespace.find_by_path_or_name(namespace) end - project = ::Projects::GitlabProjectsImportService.new(current_user, import_params).execute + project_params = import_params.merge(namespace: namespace.id) - render_api_error!(link.project.full_messages.first, 400) unless project.saved? + project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute + + render_api_error!(project.full_messages.first, 400) unless project.saved? present project, with: Entities::ProjectImportStatus end -- cgit v1.2.1 From 516d33f5ac8f65d8d69d1e5e88efbf0faabbe0eb Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 12 Feb 2018 15:26:59 +0100 Subject: update import API and spec --- lib/api/project_import.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index 396c316af22..1b63f4d4d9f 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -17,7 +17,7 @@ module API end params do - requires :name, type: String, desc: 'The new project name' + requires :path, type: String, desc: 'The new project path and name' optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' requires :file, type: File, desc: 'The project export file to be imported' end @@ -38,7 +38,7 @@ module API Namespace.find_by_path_or_name(namespace) end - project_params = import_params.merge(namespace: namespace.id) + project_params = import_params.merge(namespace_id: namespace.id) project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute -- cgit v1.2.1 From 7ec1a022b79c68dd3232c0abf07d119f0dad808f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 12 Feb 2018 16:02:15 +0100 Subject: fix file upload --- lib/api/project_import.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index 1b63f4d4d9f..5a4e4189a58 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -8,7 +8,7 @@ module API end def file_is_valid? - import_params[:file] && import_params[:file].respond_to?(:read) + import_params[:file] && import_params[:file]['tempfile'].respond_to?(:read) end end @@ -26,7 +26,7 @@ module API success Entities::ProjectImportStatus end post 'import' do - render_api_error!('The branch refname is invalid', 400) unless file_is_valid? + render_api_error!('The file is invalid', 400) unless file_is_valid? namespace = import_params[:namespace] @@ -38,7 +38,8 @@ module API Namespace.find_by_path_or_name(namespace) end - project_params = import_params.merge(namespace_id: namespace.id) + project_params = import_params.merge(namespace_id: namespace.id, + file: import_params[:file]['tempfile']) project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute -- cgit v1.2.1 From 583ed0eb94ff938b4986491e27af5f3c97ea6baf Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 13 Feb 2018 09:24:10 +0100 Subject: add import status endpoint --- lib/api/project_import.rb | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index 5a4e4189a58..d554d6d12bd 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -16,12 +16,13 @@ module API not_found! unless Gitlab::CurrentSettings.import_sources.include?('gitlab_project') end - params do - requires :path, type: String, desc: 'The new project path and name' - optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' - requires :file, type: File, desc: 'The project export file to be imported' - end - resource :projects do + resource :projects, requirements: { id: %r{[^/]+} } do + + params do + requires :path, type: String, desc: 'The new project path and name' + optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' + requires :file, type: File, desc: 'The project export file to be imported' + end desc 'Get export status' do success Entities::ProjectImportStatus end @@ -40,13 +41,22 @@ module API project_params = import_params.merge(namespace_id: namespace.id, file: import_params[:file]['tempfile']) - project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute - render_api_error!(project.full_messages.first, 400) unless project.saved? + render_api_error!(project&.full_messages&.first, 400) unless project&.saved? present project, with: Entities::ProjectImportStatus end + + params do + requires :id, type: String, desc: 'The ID of a project' + end + desc 'Get export status' do + success Entities::ProjectImportStatus + end + get ':id/import' do + present user_project, with: Entities::ProjectImportStatus + end end end end -- cgit v1.2.1 From 4a0d56daacc3f1825c5f9644a0ea63842fa9da7d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 13 Feb 2018 09:47:47 +0100 Subject: fix entity --- lib/api/entities.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8fbad2b6959..ffdb06b8094 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -92,7 +92,9 @@ module API class ProjectImportStatus < ProjectIdentity expose :import_status - expose :import_error, if: :import_error + + # TODO: Use `expose_nil` once we upgrade the grape-entity gem + expose :import_error, if: lambda { |status, _ops| status.import_error } end class BasicProjectDetails < ProjectIdentity -- cgit v1.2.1 From 79879145e5cfb3837b3a2f77fb7c35bd1234068c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 13 Feb 2018 10:54:04 +0100 Subject: add more specs --- lib/api/project_import.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index d554d6d12bd..1e51c92cbf1 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -17,7 +17,6 @@ module API end resource :projects, requirements: { id: %r{[^/]+} } do - params do requires :path, type: String, desc: 'The new project path and name' optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' @@ -30,11 +29,10 @@ module API render_api_error!('The file is invalid', 400) unless file_is_valid? namespace = import_params[:namespace] - - namespace = if namespace && namespace =~ /^\d+$/ - Namespace.find_by(id: namespace) - elsif namespace.blank? + namespace = if namespace.blank? current_user.namespace + elsif namespace =~ /^\d+$/ + Namespace.find_by(id: namespace) else Namespace.find_by_path_or_name(namespace) end @@ -43,7 +41,7 @@ module API file: import_params[:file]['tempfile']) project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute - render_api_error!(project&.full_messages&.first, 400) unless project&.saved? + render_api_error!(project.errors.full_messages&.first, 400) unless project.saved? present project, with: Entities::ProjectImportStatus end -- cgit v1.2.1 From 17e5ef4b269f4c13d22bd5c10086c6226dc43543 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 13 Feb 2018 15:04:19 +0100 Subject: add docs and changelog --- lib/api/project_import.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index 1e51c92cbf1..e93c14ddcf5 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -19,8 +19,8 @@ module API resource :projects, requirements: { id: %r{[^/]+} } do params do requires :path, type: String, desc: 'The new project path and name' - optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' requires :file, type: File, desc: 'The project export file to be imported' + optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' end desc 'Get export status' do success Entities::ProjectImportStatus -- cgit v1.2.1 From e8813520029f0f07b0cf2d8463337ae09f15b7fe Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 13 Feb 2018 15:18:52 +0100 Subject: refactor api class --- lib/api/project_import.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index e93c14ddcf5..b0511342b63 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -13,7 +13,7 @@ module API end before do - not_found! unless Gitlab::CurrentSettings.import_sources.include?('gitlab_project') + forbidden! unless Gitlab::CurrentSettings.import_sources.include?('gitlab_project') end resource :projects, requirements: { id: %r{[^/]+} } do @@ -22,12 +22,14 @@ module API requires :file, type: File, desc: 'The project export file to be imported' optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' end - desc 'Get export status' do + desc 'Create a new project import' do success Entities::ProjectImportStatus end post 'import' do render_api_error!('The file is invalid', 400) unless file_is_valid? + Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42437') + namespace = import_params[:namespace] namespace = if namespace.blank? current_user.namespace @@ -49,7 +51,7 @@ module API params do requires :id, type: String, desc: 'The ID of a project' end - desc 'Get export status' do + desc 'Get a project export status' do success Entities::ProjectImportStatus end get ':id/import' do -- cgit v1.2.1 From b0b4ae1875529cd7ca786bd5eccd49be9a40a038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarka=20Kadlecov=C3=A1?= Date: Tue, 13 Feb 2018 13:41:35 +0100 Subject: API - Include project in commits&blobs search results --- lib/api/entities.rb | 2 ++ lib/api/search.rb | 12 ++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'lib/api') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 7838de13c56..1608af97d38 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -274,6 +274,7 @@ module API expose :stats, using: Entities::CommitStats, if: :stats expose :status expose :last_pipeline, using: 'API::Entities::PipelineBasic' + expose :project_id end class Branch < Grape::Entity @@ -1172,6 +1173,7 @@ module API expose :id expose :ref expose :startline + expose :project_id end end end diff --git a/lib/api/search.rb b/lib/api/search.rb index b9982e03bb3..3556ad98c52 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -11,7 +11,7 @@ module API projects: Entities::BasicProjectDetails, milestones: Entities::Milestone, notes: Entities::Note, - commits: Entities::Commit, + commits: Entities::CommitDetail, blobs: Entities::Blob, wiki_blobs: Entities::Blob, snippet_titles: Entities::Snippet, @@ -35,7 +35,7 @@ module API def process_results(results) case params[:scope] when 'wiki_blobs' - paginate(results).map { |blob| Gitlab::ProjectSearchResults.parse_search_result(blob) } + paginate(results).map { |blob| Gitlab::ProjectSearchResults.parse_search_result(blob, user_project) } when 'blobs' paginate(results).map { |blob| blob[1] } else @@ -85,9 +85,7 @@ module API use :pagination end get ':id/-/search' do - group = find_group!(params[:id]) - - present search(group_id: group.id), with: entity + present search(group_id: user_group.id), with: entity end end @@ -106,9 +104,7 @@ module API use :pagination end get ':id/-/search' do - project = find_project!(params[:id]) - - present search(project_id: project.id), with: entity + present search(project_id: user_project.id), with: entity end end end -- cgit v1.2.1 From a724f7e35f9f8ed9692b0f3f4d6c8a62632cdec4 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 13 Feb 2018 20:22:37 +0100 Subject: Refactor commits/refs API to use hash and add pagination headers --- lib/api/commits.rb | 19 +++++++------------ lib/api/entities.rb | 8 +------- 2 files changed, 8 insertions(+), 19 deletions(-) (limited to 'lib/api') diff --git a/lib/api/commits.rb b/lib/api/commits.rb index afaf68114e8..d83c43ee49b 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -162,24 +162,19 @@ module API end params do requires :sha, type: String, desc: 'A commit sha' - optional :type, type: String, values: %w[branches tags all], default: 'all', desc: 'Scope' + optional :type, type: String, values: %w[branch tag all], default: 'all', desc: 'Scope' + use :pagination end get ':id/repository/commits/:sha/refs', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do commit = user_project.commit(params[:sha]) not_found!('Commit') unless commit - refs = - case params[:type] - when 'branches' - user_project.repository.branch_names_contains(commit.id).map {|branch_name| [branch_name, true]} - when 'tags' - user_project.repository.tag_names_contains(commit.id).map {|tag_name| [tag_name, false]} - else - refs = user_project.repository.branch_names_contains(commit.id).map {|branch_name| [branch_name, true]} - refs.concat(user_project.repository.tag_names_contains(commit.id).map {|tag_name| [tag_name, false]}) - end + refs = [] + refs.concat(user_project.repository.branch_names_contains(commit.id).map {|name| { type: 'branch', name: name }}) unless params[:type] == 'tag' + refs.concat(user_project.repository.tag_names_contains(commit.id).map {|name| { type: 'tag', name: name }}) unless params[:type] == 'branch' + refs = Kaminari.paginate_array(refs) - present refs, with: Entities::BasicRef + present paginate(refs), with: Entities::BasicRef end desc 'Post comment to commit' do diff --git a/lib/api/entities.rb b/lib/api/entities.rb index c7a817877f0..c8cda85b170 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -277,13 +277,7 @@ module API end class BasicRef < Grape::Entity - expose :branch_name, if: lambda { |ref, options| ref[1] } do |ref, options| - ref[0] - end - - expose :tag_name, if: lambda { |ref, options| !ref[1] } do |ref, options| - ref[0] - end + expose :type, :name end class Branch < Grape::Entity -- cgit v1.2.1 From e613d777b258a4f7070d2b7aaee093901e4b7ed7 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 14 Feb 2018 14:46:40 +0100 Subject: refactor code based on feedback --- lib/api/project_import.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index b0511342b63..88fe1d2b5f5 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -10,19 +10,24 @@ module API def file_is_valid? import_params[:file] && import_params[:file]['tempfile'].respond_to?(:read) end + + def validate_file! + render_api_error!('The file is invalid', 400) unless file_is_valid? + end end before do forbidden! unless Gitlab::CurrentSettings.import_sources.include?('gitlab_project') end - resource :projects, requirements: { id: %r{[^/]+} } do + resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do params do requires :path, type: String, desc: 'The new project path and name' requires :file, type: File, desc: 'The project export file to be imported' optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' end desc 'Create a new project import' do + detail 'This feature was introduced in GitLab 10.6.' success Entities::ProjectImportStatus end post 'import' do @@ -30,13 +35,10 @@ module API Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42437') - namespace = import_params[:namespace] - namespace = if namespace.blank? - current_user.namespace - elsif namespace =~ /^\d+$/ - Namespace.find_by(id: namespace) + namespace = if import_params[:namespace] + find_namespace!(import_params[:namespace]) else - Namespace.find_by_path_or_name(namespace) + current_user.namespace end project_params = import_params.merge(namespace_id: namespace.id, @@ -52,6 +54,7 @@ module API requires :id, type: String, desc: 'The ID of a project' end desc 'Get a project export status' do + detail 'This feature was introduced in GitLab 10.6.' success Entities::ProjectImportStatus end get ':id/import' do -- cgit v1.2.1 From 0abd85f919053efa8a03add9ae43ce9ea2d02ae5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 14 Feb 2018 14:59:11 +0100 Subject: refactor code based on feedback --- lib/api/project_import.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index 88fe1d2b5f5..a6da9b90fe3 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -31,7 +31,7 @@ module API success Entities::ProjectImportStatus end post 'import' do - render_api_error!('The file is invalid', 400) unless file_is_valid? + validate_file! Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42437') -- cgit v1.2.1 From 890d7b540b1ffbadcde490a2e1b741bbb1af3cf4 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 16 Feb 2018 14:37:26 +0100 Subject: update docs --- lib/api/project_import.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index a6da9b90fe3..c32e2f26ae3 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -24,7 +24,7 @@ module API params do requires :path, type: String, desc: 'The new project path and name' requires :file, type: File, desc: 'The project export file to be imported' - optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be imported into. Defaults to the user namespace.' + optional :namespace, type: String, desc: "The ID or name of the namespace that the project will be imported into. Defaults to the current user's namespace." end desc 'Create a new project import' do detail 'This feature was introduced in GitLab 10.6.' -- cgit v1.2.1 From d8dfec0ffa4fdbb383bf4f0d1ef71969adb50dd3 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 16 Feb 2018 18:03:34 +0100 Subject: Fix project import API after import service refactor --- lib/api/project_import.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/api') diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb index c32e2f26ae3..a509c1f32c1 100644 --- a/lib/api/project_import.rb +++ b/lib/api/project_import.rb @@ -41,8 +41,12 @@ module API current_user.namespace end - project_params = import_params.merge(namespace_id: namespace.id, - file: import_params[:file]['tempfile']) + project_params = { + path: import_params[:path], + namespace_id: namespace.id, + file: import_params[:file]['tempfile'] + } + project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute render_api_error!(project.errors.full_messages&.first, 400) unless project.saved? -- cgit v1.2.1