summaryrefslogtreecommitdiff
path: root/lib/api/projects.rb
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2017-06-28 15:53:12 +0800
committerLin Jen-Shin <godfat@godfat.org>2017-06-28 15:53:12 +0800
commit35674fcd4732681286224c1c5fc92386ff53db7f (patch)
tree31585e8a89ebbf384bf9a9a61e9813331df8cdf7 /lib/api/projects.rb
parent07365e518330289149dd2135424c49fad19f401d (diff)
parent08ad0af49c017d740b43588c0809b3811d25a448 (diff)
downloadgitlab-ce-35674fcd4732681286224c1c5fc92386ff53db7f.tar.gz
Merge remote-tracking branch 'upstream/master' into 15041-Add-Custom-CI-Config-Path15041-Add-Custom-CI-Config-Path
* upstream/master: (12506 commits) Update CHANGELOG.md for 9.3.2 Update architecture.md Fix changelog entry file extension Fix head pipeline stored in merge request for external pipelines updated gitlab-ci.yml to compile locale Ignore JSON files generated from PO files Update mmap2 gem tha disables mmap_obj.gsub! as current implementation uses method that is no longer part of Ruby API Disable rainbow during SimpleExecutor specs to have consistence Slightly refactor pipeline schedules form in preparation for additions Resolve "Submitting reply to existing diff discussion using Cmd/Ctrl+Enter submits twice and refreshes page" Make the SimpleExecutor rescue exceptions in the executing Checks Resolve "Unable to access edit comment from dropdown menu in certain screen sizes" Update changelog item revert removal of requestAnimationFrame and move to a separate MR/discussion rename getEmojiCategoryMap and remove unnecessary parameter Action Buttons on Prio Labels working again by setting pointer events to none on… Remove 'contains' option from Commit.find_all Remove Gitlab::Git::Repository#find_all Use latest chrome and chrome driver in GitLab QA Polish sidebar toggle ...
Diffstat (limited to 'lib/api/projects.rb')
-rw-r--r--lib/api/projects.rb649
1 files changed, 297 insertions, 352 deletions
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 291e7b689bf..20707e97e53 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -1,311 +1,262 @@
module API
# Projects API
class Projects < Grape::API
- before { authenticate! }
+ include PaginationParams
+
+ before { authenticate_non_get! }
+
+ helpers do
+ params :optional_params_ce do
+ optional :description, type: String, desc: 'The description of the project'
+ optional :ci_config_file, type: String, desc: 'The path to CI config file. Default to `.gitlab-ci.yml`'
+ optional :issues_enabled, type: Boolean, desc: 'Flag indication if the issue tracker is enabled'
+ optional :merge_requests_enabled, type: Boolean, desc: 'Flag indication if merge requests are enabled'
+ optional :wiki_enabled, type: Boolean, desc: 'Flag indication if the wiki is enabled'
+ 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 :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.'
+ optional :public_builds, type: Boolean, desc: 'Perform public builds'
+ optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'
+ optional :only_allow_merge_if_pipeline_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed'
+ optional :only_allow_merge_if_all_discussions_are_resolved, type: Boolean, desc: 'Only allow to merge if all discussions are resolved'
+ optional :tag_list, type: Array[String], desc: 'The list of tags for a project'
+ optional :avatar, type: File, desc: 'Avatar image for project'
+ optional :printing_merge_request_link_enabled, type: Boolean, desc: 'Show link to create/view merge request when pushing from the command line'
+ end
+
+ params :optional_params do
+ use :optional_params_ce
+ end
+
+ params :statistics_params do
+ optional :statistics, type: Boolean, default: false, desc: 'Include project statistics'
+ end
+ end
- resource :projects, requirements: { id: /[^\/]+/ } do
+ resource :projects do
helpers do
- def map_public_to_visibility_level(attrs)
- publik = attrs.delete(:public)
- if publik.present? && !attrs[:visibility_level].present?
- publik = to_boolean(publik)
- # Since setting the public attribute to private could mean either
- # private or internal, use the more conservative option, private.
- attrs[:visibility_level] = (publik == true) ? Gitlab::VisibilityLevel::PUBLIC : Gitlab::VisibilityLevel::PRIVATE
- end
- attrs
+ params :collection_params do
+ use :sort_params
+ use :filter_params
+ use :pagination
+
+ optional :simple, type: Boolean, default: false,
+ desc: 'Return only the ID, URL, name, and path of each project'
+ end
+
+ params :sort_params do
+ optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at],
+ default: 'created_at', desc: 'Return projects ordered by field'
+ optional :sort, type: String, values: %w[asc desc], default: 'desc',
+ desc: 'Return projects sorted in ascending and descending order'
+ end
+
+ params :filter_params do
+ optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
+ optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values,
+ desc: 'Limit by visibility'
+ optional :search, type: String, desc: 'Return list of projects matching the search criteria'
+ optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user'
+ optional :starred, type: Boolean, default: false, desc: 'Limit by starred status'
+ optional :membership, type: Boolean, default: false, desc: 'Limit by projects that the current user is a member of'
+ optional :with_issues_enabled, type: Boolean, default: false, desc: 'Limit by enabled issues feature'
+ optional :with_merge_requests_enabled, type: Boolean, default: false, desc: 'Limit by enabled merge requests feature'
+ end
+
+ params :create_params do
+ optional :namespace_id, type: Integer, desc: 'Namespace ID for the new project. Default to the user namespace.'
+ optional :import_url, type: String, desc: 'URL from which the project is imported'
+ end
+
+ def present_projects(options = {})
+ projects = ProjectsFinder.new(current_user: current_user, params: project_finder_params).execute
+ projects = reorder_projects(projects)
+ projects = projects.with_statistics if params[:statistics]
+ projects = projects.with_issues_enabled if params[:with_issues_enabled]
+ projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled]
+
+ options = options.reverse_merge(
+ with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails,
+ statistics: params[:statistics],
+ current_user: current_user
+ )
+ options[:with] = Entities::BasicProjectDetails if params[:simple]
+
+ present paginate(projects), options
end
end
- # Get a projects list for authenticated user
- #
- # Example Request:
- # GET /projects
+ desc 'Get a list of visible projects for authenticated user' do
+ success Entities::BasicProjectDetails
+ end
+ params do
+ use :collection_params
+ use :statistics_params
+ end
get do
- projects = current_user.authorized_projects
- projects = filter_projects(projects)
- projects = paginate projects
- entity = params[:simple] ? Entities::BasicProjectDetails : Entities::ProjectWithAccess
-
- present projects, with: entity, user: current_user
- end
-
- # Get a list of visible projects for authenticated user
- #
- # Example Request:
- # GET /projects/visible
- get '/visible' do
- projects = ProjectsFinder.new.execute(current_user)
- projects = filter_projects(projects)
- projects = paginate projects
- entity = params[:simple] ? Entities::BasicProjectDetails : Entities::ProjectWithAccess
-
- present projects, with: entity, user: current_user
- end
-
- # Get an owned projects list for authenticated user
- #
- # Example Request:
- # GET /projects/owned
- get '/owned' do
- projects = current_user.owned_projects
- projects = filter_projects(projects)
- projects = paginate projects
- present projects, with: Entities::ProjectWithAccess, user: current_user
- end
-
- # Gets starred project for the authenticated user
- #
- # Example Request:
- # GET /projects/starred
- get '/starred' do
- projects = current_user.viewable_starred_projects
- projects = filter_projects(projects)
- projects = paginate projects
- present projects, with: Entities::Project, user: current_user
- end
-
- # Get all projects for admin user
- #
- # Example Request:
- # GET /projects/all
- get '/all' do
- authenticated_as_admin!
- projects = Project.all
- projects = filter_projects(projects)
- projects = paginate projects
- present projects, with: Entities::ProjectWithAccess, user: current_user
- end
-
- # Get a single project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # GET /projects/:id
- get ":id" do
- present user_project, with: Entities::ProjectWithAccess, user: current_user,
- user_can_admin_project: can?(current_user, :admin_project, user_project)
- end
-
- # Get events for a single project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # GET /projects/:id/events
- get ":id/events" do
- events = paginate user_project.events.recent
- present events, with: Entities::Event
- end
-
- # Create new project
- #
- # Parameters:
- # name (required) - name for new project
- # description (optional) - short project description
- # issues_enabled (optional)
- # merge_requests_enabled (optional)
- # builds_enabled (optional)
- # wiki_enabled (optional)
- # snippets_enabled (optional)
- # container_registry_enabled (optional)
- # shared_runners_enabled (optional)
- # namespace_id (optional) - defaults to user namespace
- # public (optional) - if true same as setting visibility_level = 20
- # visibility_level (optional) - 0 by default
- # import_url (optional)
- # public_builds (optional)
- # lfs_enabled (optional)
- # request_access_enabled (optional) - Allow users to request member access
- # ci_config_file (optional)
- # Example Request
- # POST /projects
+ present_projects
+ end
+
+ desc 'Create new project' do
+ success Entities::Project
+ end
+ params do
+ optional :name, type: String, desc: 'The name of the project'
+ optional :path, type: String, desc: 'The path of the repository'
+ at_least_one_of :name, :path
+ use :optional_params
+ use :create_params
+ end
post do
- required_attributes! [:name]
- attrs = attributes_for_keys [:builds_enabled,
- :container_registry_enabled,
- :ci_config_file,
- :description,
- :import_url,
- :issues_enabled,
- :lfs_enabled,
- :merge_requests_enabled,
- :name,
- :namespace_id,
- :only_allow_merge_if_build_succeeds,
- :path,
- :public,
- :public_builds,
- :request_access_enabled,
- :shared_runners_enabled,
- :snippets_enabled,
- :visibility_level,
- :wiki_enabled]
- attrs = map_public_to_visibility_level(attrs)
- @project = ::Projects::CreateService.new(current_user, attrs).execute
- if @project.saved?
- present @project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, @project)
+ attrs = declared_params(include_missing: false)
+ attrs[:builds_enabled] = attrs.delete(:jobs_enabled) if attrs.key?(:jobs_enabled)
+ project = ::Projects::CreateService.new(current_user, attrs).execute
+
+ if project.saved?
+ present project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, project)
else
- if @project.errors[:limit_reached].present?
- error!(@project.errors[:limit_reached], 403)
+ if project.errors[:limit_reached].present?
+ error!(project.errors[:limit_reached], 403)
end
- render_validation_error!(@project)
+ render_validation_error!(project)
end
end
- # Create new project for a specified user. Only available to admin users.
- #
- # Parameters:
- # user_id (required) - The ID of a user
- # name (required) - name for new project
- # description (optional) - short project description
- # default_branch (optional) - 'master' by default
- # issues_enabled (optional)
- # merge_requests_enabled (optional)
- # builds_enabled (optional)
- # wiki_enabled (optional)
- # snippets_enabled (optional)
- # container_registry_enabled (optional)
- # shared_runners_enabled (optional)
- # public (optional) - if true same as setting visibility_level = 20
- # visibility_level (optional)
- # import_url (optional)
- # public_builds (optional)
- # lfs_enabled (optional)
- # request_access_enabled (optional) - Allow users to request member access
- # ci_config_file (optional)
- # Example Request
- # POST /projects/user/:user_id
+ desc 'Create new project for a specified user. Only available to admin users.' do
+ success Entities::Project
+ end
+ params do
+ requires :name, type: String, desc: 'The name of the project'
+ requires :user_id, type: Integer, desc: 'The ID of a user'
+ optional :path, type: String, desc: 'The path of the repository'
+ optional :default_branch, type: String, desc: 'The default branch of the project'
+ use :optional_params
+ use :create_params
+ end
post "user/:user_id" do
authenticated_as_admin!
- user = User.find(params[:user_id])
- attrs = attributes_for_keys [:builds_enabled,
- :ci_config_file,
- :default_branch,
- :description,
- :import_url,
- :issues_enabled,
- :lfs_enabled,
- :merge_requests_enabled,
- :name,
- :only_allow_merge_if_build_succeeds,
- :public,
- :public_builds,
- :request_access_enabled,
- :shared_runners_enabled,
- :snippets_enabled,
- :visibility_level,
- :wiki_enabled]
- attrs = map_public_to_visibility_level(attrs)
- @project = ::Projects::CreateService.new(user, attrs).execute
- if @project.saved?
- present @project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, @project)
+ user = User.find_by(id: params.delete(:user_id))
+ not_found!('User') unless user
+
+ attrs = declared_params(include_missing: false)
+ project = ::Projects::CreateService.new(user, attrs).execute
+
+ if project.saved?
+ present project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, project)
else
- render_validation_error!(@project)
+ render_validation_error!(project)
end
end
+ end
- # Fork new project for the current user or provided namespace.
- #
- # Parameters:
- # id (required) - The ID of a project
- # namespace (optional) - The ID or name of the namespace that the project will be forked into.
- # Example Request
- # POST /projects/fork/:id
- post 'fork/:id' do
- attrs = {}
- namespace_id = params[:namespace]
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects, requirements: { id: %r{[^/]+} } do
+ desc 'Get a single project' do
+ success Entities::ProjectWithAccess
+ end
+ params do
+ use :statistics_params
+ 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]
+ end
+
+ desc 'Fork new project for the current user or provided namespace.' do
+ success Entities::Project
+ end
+ params do
+ optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be forked into'
+ end
+ post ':id/fork' do
+ fork_params = declared_params(include_missing: false)
+ namespace_id = fork_params[:namespace]
if namespace_id.present?
- namespace = Namespace.find_by(id: namespace_id) || Namespace.find_by_path_or_name(namespace_id)
+ fork_params[:namespace] = if namespace_id =~ /^\d+$/
+ Namespace.find_by(id: namespace_id)
+ else
+ Namespace.find_by_path_or_name(namespace_id)
+ end
- unless namespace && can?(current_user, :create_projects, namespace)
+ unless fork_params[:namespace] && can?(current_user, :create_projects, fork_params[:namespace])
not_found!('Target Namespace')
end
-
- attrs[:namespace] = namespace
end
- @forked_project =
- ::Projects::ForkService.new(user_project,
- current_user,
- attrs).execute
+ forked_project = ::Projects::ForkService.new(user_project, current_user, fork_params).execute
- if @forked_project.errors.any?
- conflict!(@forked_project.errors.messages)
+ if forked_project.errors.any?
+ conflict!(forked_project.errors.messages)
else
- present @forked_project, with: Entities::Project,
- user_can_admin_project: can?(current_user, :admin_project, @forked_project)
+ present forked_project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, forked_project)
end
end
- # Update an existing project
- #
- # Parameters:
- # id (required) - the id of a project
- # name (optional) - name of a project
- # path (optional) - path of a project
- # description (optional) - short project description
- # issues_enabled (optional)
- # merge_requests_enabled (optional)
- # builds_enabled (optional)
- # wiki_enabled (optional)
- # snippets_enabled (optional)
- # container_registry_enabled (optional)
- # shared_runners_enabled (optional)
- # public (optional) - if true same as setting visibility_level = 20
- # visibility_level (optional) - visibility level of a project
- # public_builds (optional)
- # lfs_enabled (optional)
- # ci_config_file (optional)
- # Example Request
- # PUT /projects/:id
+ desc 'Update an existing project' do
+ success Entities::Project
+ end
+ params do
+ # CE
+ at_least_one_of_ce =
+ [
+ :jobs_enabled,
+ :container_registry_enabled,
+ :default_branch,
+ :description,
+ :issues_enabled,
+ :lfs_enabled,
+ :merge_requests_enabled,
+ :name,
+ :only_allow_merge_if_all_discussions_are_resolved,
+ :only_allow_merge_if_pipeline_succeeds,
+ :path,
+ :printing_merge_request_link_enabled,
+ :public_builds,
+ :request_access_enabled,
+ :shared_runners_enabled,
+ :snippets_enabled,
+ :tag_list,
+ :visibility,
+ :wiki_enabled
+ ]
+ optional :name, type: String, desc: 'The name of the project'
+ optional :default_branch, type: String, desc: 'The default branch of the project'
+ optional :path, type: String, desc: 'The path of the repository'
+
+ use :optional_params
+ at_least_one_of(*at_least_one_of_ce)
+ end
put ':id' do
- attrs = attributes_for_keys [:builds_enabled,
- :container_registry_enabled,
- :ci_config_file,
- :default_branch,
- :description,
- :issues_enabled,
- :lfs_enabled,
- :merge_requests_enabled,
- :name,
- :only_allow_merge_if_build_succeeds,
- :path,
- :public,
- :public_builds,
- :request_access_enabled,
- :shared_runners_enabled,
- :snippets_enabled,
- :visibility_level,
- :wiki_enabled]
- attrs = map_public_to_visibility_level(attrs)
authorize_admin_project
+ attrs = declared_params(include_missing: false)
authorize! :rename_project, user_project if attrs[:name].present?
- if attrs[:visibility_level].present?
- authorize! :change_visibility_level, user_project
- end
+ authorize! :change_visibility_level, user_project if attrs[:visibility].present?
- ::Projects::UpdateService.new(user_project,
- current_user, attrs).execute
+ attrs[:builds_enabled] = attrs.delete(:jobs_enabled) if attrs.key?(:jobs_enabled)
- if user_project.errors.any?
- render_validation_error!(user_project)
- else
+ result = ::Projects::UpdateService.new(user_project, current_user, attrs).execute
+
+ if result[:status] == :success
present user_project, with: Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, user_project)
+ else
+ render_validation_error!(user_project)
end
end
- # Archive project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # PUT /projects/:id/archive
+ desc 'Archive a project' do
+ success Entities::Project
+ end
post ':id/archive' do
authorize!(:archive_project, user_project)
@@ -314,12 +265,9 @@ module API
present user_project, with: Entities::Project
end
- # Unarchive project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # PUT /projects/:id/unarchive
+ desc 'Unarchive a project' do
+ success Entities::Project
+ end
post ':id/unarchive' do
authorize!(:archive_project, user_project)
@@ -328,12 +276,9 @@ module API
present user_project, with: Entities::Project
end
- # Star project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # POST /projects/:id/star
+ desc 'Star a project' do
+ success Entities::Project
+ end
post ':id/star' do
if current_user.starred?(user_project)
not_modified!
@@ -345,13 +290,10 @@ module API
end
end
- # Unstar project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # DELETE /projects/:id/star
- delete ':id/star' do
+ desc 'Unstar a project' do
+ success Entities::Project
+ end
+ post ':id/unstar' do
if current_user.starred?(user_project)
current_user.toggle_star(user_project)
user_project.reload
@@ -362,71 +304,63 @@ module API
end
end
- # Remove project
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # DELETE /projects/:id
+ desc 'Remove a project'
delete ":id" do
authorize! :remove_project, user_project
::Projects::DestroyService.new(user_project, current_user, {}).async_execute
+
+ accepted!
end
- # Mark this project as forked from another
- #
- # Parameters:
- # id: (required) - The ID of the project being marked as a fork
- # forked_from_id: (required) - The ID of the project it was forked from
- # Example Request:
- # POST /projects/:id/fork/:forked_from_id
+ desc 'Mark this project as forked from another'
+ params do
+ requires :forked_from_id, type: String, desc: 'The ID of the project it was forked from'
+ end
post ":id/fork/:forked_from_id" do
authenticated_as_admin!
- forked_from_project = find_project(params[:forked_from_id])
- unless forked_from_project.nil?
- 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)
- else
- render_api_error!("Project already forked", 409)
- end
+
+ forked_from_project = find_project!(params[:forked_from_id])
+ not_found!("Source Project") unless forked_from_project
+
+ 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)
else
- not_found!("Source Project")
+ render_api_error!("Project already forked", 409)
end
end
- # Remove a forked_from relationship
- #
- # Parameters:
- # id: (required) - The ID of the project being marked as a fork
- # Example Request:
- # DELETE /projects/:id/fork
+ desc 'Remove a forked_from relationship'
delete ":id/fork" do
authorize! :remove_fork_project, user_project
+
if user_project.forked?
user_project.forked_project_link.destroy
+ else
+ not_modified!
end
end
- # Share project with group
- #
- # Parameters:
- # id (required) - The ID of a project
- # group_id (required) - The ID of a group
- # group_access (required) - Level of permissions for sharing
- # expires_at (optional) - Share expiration date
- #
- # Example Request:
- # POST /projects/:id/share
+ desc 'Share the project with a group' do
+ success Entities::ProjectGroupLink
+ end
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of a group'
+ requires :group_access, type: Integer, values: Gitlab::Access.values, desc: 'The group access level'
+ optional :expires_at, type: Date, desc: 'Share expiration date'
+ end
post ":id/share" do
authorize! :admin_project, user_project
- required_attributes! [:group_id, :group_access]
- attrs = attributes_for_keys [:group_id, :group_access, :expires_at]
+ group = Group.find_by_id(params[:group_id])
+
+ unless group && can?(current_user, :read_group, group)
+ not_found!('Group')
+ end
unless user_project.allowed_to_share_with_group?
return render_api_error!("The project sharing with group is disabled", 400)
end
- link = user_project.project_group_links.new(attrs)
+ link = user_project.project_group_links.new(declared_params(include_missing: false))
if link.save
present link, with: Entities::ProjectGroupLink
@@ -435,40 +369,51 @@ module API
end
end
- # Upload a file
- #
- # Parameters:
- # id: (required) - The ID of the project
- # file: (required) - The file to be uploaded
- post ":id/uploads" do
- ::Projects::UploadService.new(user_project, params[:file]).execute
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of the group'
end
+ delete ":id/share/:group_id" do
+ authorize! :admin_project, user_project
+
+ link = user_project.project_group_links.find_by(group_id: params[:group_id])
+ not_found!('Group Link') unless link
- # search for projects current_user has access to
- #
- # Parameters:
- # query (required) - A string contained in the project name
- # per_page (optional) - number of projects to return per page
- # page (optional) - the page to retrieve
- # Example Request:
- # GET /projects/search/:query
- get "/search/:query" do
- search_service = Search::GlobalService.new(current_user, search: params[:query]).execute
- projects = search_service.objects('projects', params[:page])
- projects = projects.reorder(project_order_by => project_sort)
+ link.destroy
+ end
- present paginate(projects), with: Entities::Project
+ desc 'Upload a file'
+ params do
+ requires :file, type: File, desc: 'The file to be uploaded'
+ end
+ post ":id/uploads" do
+ UploadService.new(user_project, params[:file]).execute
end
- # Get a users list
- #
- # Example Request:
- # GET /users
+ desc 'Get the users list of a project' do
+ success Entities::UserBasic
+ end
+ params do
+ optional :search, type: String, desc: 'Return list of users matching the search criteria'
+ use :pagination
+ end
get ':id/users' do
- @users = User.where(id: user_project.team.users.map(&:id))
- @users = @users.search(params[:search]) if params[:search].present?
- @users = paginate @users
- present @users, with: Entities::UserBasic
+ users = user_project.team.users
+ users = users.search(params[:search]) if params[:search].present?
+
+ present paginate(users), with: Entities::UserBasic
+ end
+
+ desc 'Start the housekeeping task for a project' do
+ detail 'This feature was introduced in GitLab 9.0.'
+ end
+ post ':id/housekeeping' do
+ authorize_admin_project
+
+ begin
+ ::Projects::HousekeepingService.new(user_project).execute
+ rescue ::Projects::HousekeepingService::LeaseTaken => error
+ conflict!(error.message)
+ end
end
end
end