diff options
author | Rémy Coutable <remy@rymai.me> | 2017-02-17 16:54:46 +0300 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2017-02-17 16:54:46 +0300 |
commit | 10ad2f77358f31fb98d369afaf492564af749b82 (patch) | |
tree | 129411df70b7df85add92d48d5fe3c118bef0013 /lib/api | |
parent | 827a56a47914f128a78deade463d589328d18fc1 (diff) | |
parent | ce54a801feb62c768042587685b5848e06f0a6da (diff) |
Merge branch 'paginate-all-the-things' into 'master'
Paginate all the things
Closes #8099
See merge request !8606
Diffstat (limited to 'lib/api')
-rw-r--r-- | lib/api/api.rb | 9 | ||||
-rw-r--r-- | lib/api/award_emoji.rb | 4 | ||||
-rw-r--r-- | lib/api/boards.rb | 13 | ||||
-rw-r--r-- | lib/api/branches.rb | 10 | ||||
-rw-r--r-- | lib/api/deploy_keys.rb | 14 | ||||
-rw-r--r-- | lib/api/files.rb | 1 | ||||
-rw-r--r-- | lib/api/helpers/pagination.rb | 2 | ||||
-rw-r--r-- | lib/api/labels.rb | 8 | ||||
-rw-r--r-- | lib/api/merge_request_diffs.rb | 6 | ||||
-rw-r--r-- | lib/api/merge_requests.rb | 3 | ||||
-rw-r--r-- | lib/api/pagination_params.rb | 4 | ||||
-rw-r--r-- | lib/api/project_hooks.rb | 4 | ||||
-rw-r--r-- | lib/api/repositories.rb | 14 | ||||
-rw-r--r-- | lib/api/system_hooks.rb | 10 | ||||
-rw-r--r-- | lib/api/tags.rb | 10 | ||||
-rw-r--r-- | lib/api/templates.rb | 12 | ||||
-rw-r--r-- | lib/api/users.rb | 16 | ||||
-rw-r--r-- | lib/api/v3/boards.rb | 51 | ||||
-rw-r--r-- | lib/api/v3/branches.rb | 24 | ||||
-rw-r--r-- | lib/api/v3/labels.rb | 19 | ||||
-rw-r--r-- | lib/api/v3/repositories.rb | 55 | ||||
-rw-r--r-- | lib/api/v3/system_hooks.rb | 19 | ||||
-rw-r--r-- | lib/api/v3/tags.rb | 20 | ||||
-rw-r--r-- | lib/api/v3/users.rb | 64 |
24 files changed, 352 insertions, 40 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 06346ae822a..dbb7271ccbd 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -5,13 +5,22 @@ module API version %w(v3 v4), using: :path version 'v3', using: :path do + mount ::API::V3::Boards + mount ::API::V3::Branches mount ::API::V3::DeployKeys mount ::API::V3::Issues + mount ::API::V3::Labels mount ::API::V3::Members + mount ::API::V3::MergeRequestDiffs mount ::API::V3::MergeRequests + mount ::API::V3::ProjectHooks mount ::API::V3::Projects mount ::API::V3::ProjectSnippets + mount ::API::V3::Repositories + mount ::API::V3::SystemHooks + mount ::API::V3::Tags mount ::API::V3::Templates + mount ::API::V3::Users end before { allow_access_with_scope :api } diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 58a4df54bea..2ef327217ea 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -28,8 +28,8 @@ module API end get endpoint do if can_read_awardable? - awards = paginate(awardable.award_emoji) - present awards, with: Entities::AwardEmoji + awards = awardable.award_emoji + present paginate(awards), with: Entities::AwardEmoji else not_found!("Award Emoji") end diff --git a/lib/api/boards.rb b/lib/api/boards.rb index 13752eb4947..f4226e5a89d 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -1,6 +1,7 @@ module API - # Boards API class Boards < Grape::API + include PaginationParams + before { authenticate! } params do @@ -11,9 +12,12 @@ module API detail 'This feature was introduced in 8.13' success Entities::Board end + params do + use :pagination + end get ':id/boards' do authorize!(:read_board, user_project) - present user_project.boards, with: Entities::Board + present paginate(user_project.boards), with: Entities::Board end params do @@ -40,9 +44,12 @@ module API detail 'Does not include `done` list. This feature was introduced in 8.13' success Entities::List end + params do + use :pagination + end get '/lists' do authorize!(:read_board, user_project) - present board_lists, with: Entities::List + present paginate(board_lists), with: Entities::List end desc 'Get a list of a project board' do diff --git a/lib/api/branches.rb b/lib/api/branches.rb index 9331be1f7de..9d1f5a28ef6 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -1,8 +1,9 @@ require 'mime/types' module API - # Projects API class Branches < Grape::API + include PaginationParams + before { authenticate! } before { authorize! :download_code, user_project } @@ -13,10 +14,13 @@ module API desc 'Get a project repository branches' do success Entities::RepoBranch end + params do + use :pagination + end get ":id/repository/branches" do - branches = user_project.repository.branches.sort_by(&:name) + branches = ::Kaminari.paginate_array(user_project.repository.branches.sort_by(&:name)) - present branches, with: Entities::RepoBranch, project: user_project + present paginate(branches), with: Entities::RepoBranch, project: user_project end desc 'Get a single branch' do diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index 3f5183d46a2..982645c2f64 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -1,12 +1,17 @@ module API class DeployKeys < Grape::API + include PaginationParams + before { authenticate! } + desc 'Return all deploy keys' + params do + use :pagination + end get "deploy_keys" do authenticated_as_admin! - keys = DeployKey.all - present keys, with: Entities::SSHKey + present paginate(DeployKey.all), with: Entities::SSHKey end params do @@ -18,8 +23,11 @@ module API desc "Get a specific project's deploy keys" do success Entities::SSHKey end + params do + use :pagination + end get ":id/deploy_keys" do - present user_project.deploy_keys, with: Entities::SSHKey + present paginate(user_project.deploy_keys), with: Entities::SSHKey end desc 'Get single deploy key' do diff --git a/lib/api/files.rb b/lib/api/files.rb index 2ecdd747c8e..6e16ccd2fd8 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -1,5 +1,4 @@ module API - # Projects API class Files < Grape::API helpers do def commit_params(attrs) diff --git a/lib/api/helpers/pagination.rb b/lib/api/helpers/pagination.rb index 2199eea7e5f..0764b58fb4c 100644 --- a/lib/api/helpers/pagination.rb +++ b/lib/api/helpers/pagination.rb @@ -2,7 +2,7 @@ module API module Helpers module Pagination def paginate(relation) - relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| + relation.page(params[:page]).per(params[:per_page]).tap do |data| add_pagination_headers(data) end end diff --git a/lib/api/labels.rb b/lib/api/labels.rb index 652786d4e3e..d2955af3f95 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -1,6 +1,7 @@ module API - # Labels API class Labels < Grape::API + include PaginationParams + before { authenticate! } params do @@ -10,8 +11,11 @@ module API desc 'Get all labels of the project' do success Entities::Label end + params do + use :pagination + end get ':id/labels' do - present available_labels, with: Entities::Label, current_user: current_user, project: user_project + present paginate(available_labels), with: Entities::Label, current_user: current_user, project: user_project end desc 'Create a new label' do diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index bc3d69f6904..4901a7cfea6 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -1,6 +1,8 @@ module API # MergeRequestDiff API class MergeRequestDiffs < Grape::API + include PaginationParams + before { authenticate! } resource :projects do @@ -12,12 +14,12 @@ module API params do requires :id, type: String, desc: 'The ID of a project' requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' + use :pagination end - 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: Entities::MergeRequestDiff + present paginate(merge_request.merge_request_diffs), with: Entities::MergeRequestDiff end desc 'Get a single merge request diff version' do diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 8e09a6f7354..bdd764abfeb 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -119,8 +119,9 @@ module API end get ':id/merge_requests/:merge_request_id/commits' do merge_request = find_merge_request_with_access(params[:merge_request_id]) + commits = ::Kaminari.paginate_array(merge_request.commits) - present merge_request.commits, with: Entities::RepoCommit + present paginate(commits), with: Entities::RepoCommit end desc 'Show the merge request changes' do diff --git a/lib/api/pagination_params.rb b/lib/api/pagination_params.rb index 8c1e4381a74..f566eb3ed2b 100644 --- a/lib/api/pagination_params.rb +++ b/lib/api/pagination_params.rb @@ -15,8 +15,8 @@ module API included do helpers do params :pagination do - optional :page, type: Integer, desc: 'Current page number' - optional :per_page, type: Integer, desc: 'Number of items per page' + optional :page, type: Integer, default: 1, desc: 'Current page number' + optional :per_page, type: Integer, default: 20, desc: 'Number of items per page' end end end diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index cb679e6658a..f7a28d7ad10 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -32,9 +32,7 @@ module API use :pagination end get ":id/hooks" do - hooks = paginate user_project.hooks - - present hooks, with: Entities::ProjectHook + present paginate(user_project.hooks), with: Entities::ProjectHook end desc 'Get a project hook' do diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 4ca6646a6f1..bfda6f45b0a 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -2,6 +2,8 @@ require 'mime/types' module API class Repositories < Grape::API + include PaginationParams + before { authorize! :download_code, user_project } params do @@ -24,6 +26,7 @@ module API optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used' optional :path, type: String, desc: 'The path of the tree' optional :recursive, type: Boolean, default: false, desc: 'Used to get a recursive tree' + use :pagination end get ':id/repository/tree' do ref = params[:ref_name] || user_project.try(:default_branch) || 'master' @@ -33,8 +36,8 @@ module API not_found!('Tree') unless commit tree = user_project.repository.tree(commit.id, path, recursive: params[:recursive]) - - present tree.sorted_entries, with: Entities::RepoTreeObject + entries = ::Kaminari.paginate_array(tree.sorted_entries) + present paginate(entries), with: Entities::RepoTreeObject end desc 'Get a raw file contents' @@ -100,10 +103,13 @@ module API desc 'Get repository contributors' do success Entities::Contributor end + params do + use :pagination + end get ':id/repository/contributors' do begin - present user_project.repository.contributors, - with: Entities::Contributor + contributors = ::Kaminari.paginate_array(user_project.repository.contributors) + present paginate(contributors), with: Entities::Contributor rescue not_found! end diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb index 708ec8cfe70..d038a3fa828 100644 --- a/lib/api/system_hooks.rb +++ b/lib/api/system_hooks.rb @@ -1,6 +1,7 @@ module API - # Hooks API class SystemHooks < Grape::API + include PaginationParams + before do authenticate! authenticated_as_admin! @@ -10,10 +11,11 @@ module API desc 'Get the list of system hooks' do success Entities::Hook end + params do + use :pagination + end get do - hooks = SystemHook.all - - present hooks, with: Entities::Hook + present paginate(SystemHook.all), with: Entities::Hook end desc 'Create a new system hook' do diff --git a/lib/api/tags.rb b/lib/api/tags.rb index b6fd8f569a9..86759ab882f 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -1,6 +1,7 @@ module API - # Git Tags API class Tags < Grape::API + include PaginationParams + before { authorize! :download_code, user_project } params do @@ -10,9 +11,12 @@ module API desc 'Get a project repository tags' do success Entities::RepoTag end + params do + use :pagination + end get ":id/repository/tags" do - present user_project.repository.tags.sort_by(&:name).reverse, - with: Entities::RepoTag, project: user_project + tags = ::Kaminari.paginate_array(user_project.repository.tags.sort_by(&:name).reverse) + present paginate(tags), with: Entities::RepoTag, project: user_project end desc 'Get a single repository tag' do diff --git a/lib/api/templates.rb b/lib/api/templates.rb index 8a2d66efd89..0fc13b35d5b 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -1,5 +1,7 @@ module API class Templates < Grape::API + include PaginationParams + GLOBAL_TEMPLATE_TYPES = { gitignores: { klass: Gitlab::Template::GitignoreTemplate, @@ -51,12 +53,14 @@ module API end params do optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses' + use :pagination end get "templates/licenses" do options = { featured: declared(params).popular.present? ? true : nil } - present Licensee::License.all(options), with: ::API::Entities::RepoLicense + licences = ::Kaminari.paginate_array(Licensee::License.all(options)) + present paginate(licences), with: Entities::RepoLicense end desc 'Get the text for a specific license' do @@ -82,8 +86,12 @@ module API detail "This feature was introduced in GitLab #{gitlab_version}." success Entities::TemplatesList end + params do + use :pagination + end get "templates/#{template_type}" do - present klass.all, with: Entities::TemplatesList + templates = ::Kaminari.paginate_array(klass.all) + present paginate(templates), with: Entities::TemplatesList end desc 'Get the text for a specific template present in local filesystem' do diff --git a/lib/api/users.rb b/lib/api/users.rb index 82ac3886ac3..05538f5a42f 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -209,6 +209,7 @@ module API end params do requires :id, type: Integer, desc: 'The ID of the user' + use :pagination end get ':id/keys' do authenticated_as_admin! @@ -216,7 +217,7 @@ module API user = User.find_by(id: params[:id]) not_found!('User') unless user - present user.keys, with: Entities::SSHKey + present paginate(user.keys), with: Entities::SSHKey end desc 'Delete an existing SSH key from a specified user. Available only for admins.' do @@ -266,13 +267,14 @@ module API end params do requires :id, type: Integer, desc: 'The ID of the user' + use :pagination end get ':id/emails' do authenticated_as_admin! user = User.find_by(id: params[:id]) not_found!('User') unless user - present user.emails, with: Entities::Email + present paginate(user.emails), with: Entities::Email end desc 'Delete an email address of a specified user. Available only for admins.' do @@ -373,8 +375,11 @@ module API desc "Get the currently authenticated user's SSH keys" do success Entities::SSHKey end + params do + use :pagination + end get "keys" do - present current_user.keys, with: Entities::SSHKey + present paginate(current_user.keys), with: Entities::SSHKey end desc 'Get a single key owned by currently authenticated user' do @@ -423,8 +428,11 @@ module API desc "Get the currently authenticated user's email addresses" do success Entities::Email end + params do + use :pagination + end get "emails" do - present current_user.emails, with: Entities::Email + present paginate(current_user.emails), with: Entities::Email end desc 'Get a single email address owned by the currently authenticated user' do diff --git a/lib/api/v3/boards.rb b/lib/api/v3/boards.rb new file mode 100644 index 00000000000..31d708bc2c8 --- /dev/null +++ b/lib/api/v3/boards.rb @@ -0,0 +1,51 @@ +module API + module V3 + class Boards < Grape::API + before { authenticate! } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + desc 'Get all project boards' do + detail 'This feature was introduced in 8.13' + success ::API::Entities::Board + end + get ':id/boards' do + authorize!(:read_board, user_project) + present user_project.boards, with: ::API::Entities::Board + end + + params do + requires :board_id, type: Integer, desc: 'The ID of a board' + end + segment ':id/boards/:board_id' do + helpers do + def project_board + board = user_project.boards.first + + if params[:board_id] == board.id + board + else + not_found!('Board') + end + end + + def board_lists + project_board.lists.destroyable + end + end + + desc 'Get the lists of a project board' do + detail 'Does not include `done` list. This feature was introduced in 8.13' + success ::API::Entities::List + end + get '/lists' do + authorize!(:read_board, user_project) + present board_lists, with: ::API::Entities::List + end + end + end + end + end +end diff --git a/lib/api/v3/branches.rb b/lib/api/v3/branches.rb new file mode 100644 index 00000000000..733c6b21be5 --- /dev/null +++ b/lib/api/v3/branches.rb @@ -0,0 +1,24 @@ +require 'mime/types' + +module API + module V3 + class Branches < Grape::API + before { authenticate! } + before { authorize! :download_code, user_project } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + desc 'Get a project repository branches' do + success ::API::Entities::RepoBranch + end + get ":id/repository/branches" do + branches = user_project.repository.branches.sort_by(&:name) + + present branches, with: ::API::Entities::RepoBranch, project: user_project + end + end + end + end +end diff --git a/lib/api/v3/labels.rb b/lib/api/v3/labels.rb new file mode 100644 index 00000000000..5c3261311bf --- /dev/null +++ b/lib/api/v3/labels.rb @@ -0,0 +1,19 @@ +module API + module V3 + class Labels < Grape::API + before { authenticate! } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + desc 'Get all labels of the project' do + success ::API::Entities::Label + end + get ':id/labels' do + present available_labels, with: ::API::Entities::Label, current_user: current_user, project: user_project + end + end + end + end +end diff --git a/lib/api/v3/repositories.rb b/lib/api/v3/repositories.rb new file mode 100644 index 00000000000..3549ea225ef --- /dev/null +++ b/lib/api/v3/repositories.rb @@ -0,0 +1,55 @@ +require 'mime/types' + +module API + module V3 + class Repositories < Grape::API + before { authorize! :download_code, user_project } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + helpers do + def handle_project_member_errors(errors) + if errors[:project_access].any? + error!(errors[:project_access], 422) + end + not_found! + end + end + + desc 'Get a project repository tree' do + success ::API::Entities::RepoTreeObject + end + params do + optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used' + optional :path, type: String, desc: 'The path of the tree' + optional :recursive, type: Boolean, default: false, desc: 'Used to get a recursive tree' + end + get ':id/repository/tree' do + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' + path = params[:path] || nil + + commit = user_project.commit(ref) + not_found!('Tree') unless commit + + tree = user_project.repository.tree(commit.id, path, recursive: params[:recursive]) + + present tree.sorted_entries, with: ::API::Entities::RepoTreeObject + end + + desc 'Get repository contributors' do + success ::API::Entities::Contributor + end + get ':id/repository/contributors' do + begin + present user_project.repository.contributors, + with: ::API::Entities::Contributor + rescue + not_found! + end + end + end + end + end +end diff --git a/lib/api/v3/system_hooks.rb b/lib/api/v3/system_hooks.rb new file mode 100644 index 00000000000..391510b9ee0 --- /dev/null +++ b/lib/api/v3/system_hooks.rb @@ -0,0 +1,19 @@ +module API + module V3 + class SystemHooks < Grape::API + before do + authenticate! + authenticated_as_admin! + end + + resource :hooks do + desc 'Get the list of system hooks' do + success ::API::Entities::Hook + end + get do + present SystemHook.all, with: ::API::Entities::Hook + end + end + end + end +end diff --git a/lib/api/v3/tags.rb b/lib/api/v3/tags.rb new file mode 100644 index 00000000000..016e3d86932 --- /dev/null +++ b/lib/api/v3/tags.rb @@ -0,0 +1,20 @@ +module API + module V3 + class Tags < Grape::API + before { authorize! :download_code, user_project } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + desc 'Get a project repository tags' do + success ::API::Entities::RepoTag + end + get ":id/repository/tags" do + tags = user_project.repository.tags.sort_by(&:name).reverse + present tags, with: ::API::Entities::RepoTag, project: user_project + end + end + end + end +end diff --git a/lib/api/v3/users.rb b/lib/api/v3/users.rb new file mode 100644 index 00000000000..ceb139d11b8 --- /dev/null +++ b/lib/api/v3/users.rb @@ -0,0 +1,64 @@ +module API + module V3 + class Users < Grape::API + include PaginationParams + + before do + allow_access_with_scope :read_user if request.get? + authenticate! + end + + resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do + desc 'Get the SSH keys of a specified user. Available only for admins.' do + success ::API::Entities::SSHKey + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + use :pagination + end + get ':id/keys' do + authenticated_as_admin! + + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + present paginate(user.keys), with: ::API::Entities::SSHKey + end + + desc 'Get the emails addresses of a specified user. Available only for admins.' do + success ::API::Entities::Email + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + use :pagination + end + get ':id/emails' do + authenticated_as_admin! + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + present user.emails, with: ::API::Entities::Email + end + end + + resource :user do + desc "Get the currently authenticated user's SSH keys" do + success ::API::Entities::SSHKey + end + params do + use :pagination + end + get "keys" do + present current_user.keys, with: ::API::Entities::SSHKey + end + + desc "Get the currently authenticated user's email addresses" do + success ::API::Entities::Email + end + get "emails" do + present current_user.emails, with: ::API::Entities::Email + end + end + end + end +end |