summaryrefslogtreecommitdiff
path: root/lib/api
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api')
-rw-r--r--lib/api/api.rb8
-rw-r--r--lib/api/badges.rb1
-rw-r--r--lib/api/entities.rb8
-rw-r--r--lib/api/features.rb7
-rw-r--r--lib/api/helpers.rb39
-rw-r--r--lib/api/helpers/projects_helpers.rb38
-rw-r--r--lib/api/issues.rb2
-rw-r--r--lib/api/project_export.rb19
-rw-r--r--lib/api/project_hooks.rb1
-rw-r--r--lib/api/project_import.rb16
-rw-r--r--lib/api/projects.rb34
-rw-r--r--lib/api/repositories.rb2
-rw-r--r--lib/api/runner.rb35
-rw-r--r--lib/api/v3/repositories.rb2
14 files changed, 134 insertions, 78 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 62ffebeacb0..073471b4c4d 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -78,6 +78,14 @@ module API
rack_response({ 'message' => '404 Not found' }.to_json, 404)
end
+ rescue_from UploadedFile::InvalidPathError do |e|
+ rack_response({ 'message' => e.message }.to_json, 400)
+ end
+
+ rescue_from ObjectStorage::RemoteStoreError do |e|
+ rack_response({ 'message' => e.message }.to_json, 500)
+ end
+
# Retain 405 error rather than a 500 error for Grape 0.15.0+.
# https://github.com/ruby-grape/grape/blob/a3a28f5b5dfbb2797442e006dbffd750b27f2a76/UPGRADING.md#changes-to-method-not-allowed-routes
rescue_from Grape::Exceptions::MethodNotAllowed do |e|
diff --git a/lib/api/badges.rb b/lib/api/badges.rb
index 334948b2995..8ceffe9c5ef 100644
--- a/lib/api/badges.rb
+++ b/lib/api/badges.rb
@@ -127,6 +127,7 @@ module API
end
destroy_conditionally!(badge)
+ body false
end
end
end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 38161d1f127..8aad320e376 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -72,7 +72,7 @@ module API
class ProjectHook < Hook
expose :project_id, :issues_events, :confidential_issues_events
- expose :note_events, :pipeline_events, :wiki_page_events
+ expose :note_events, :confidential_note_events, :pipeline_events, :wiki_page_events
expose :job_events
end
@@ -206,6 +206,7 @@ module API
expose :request_access_enabled
expose :only_allow_merge_if_all_discussions_are_resolved
expose :printing_merge_request_link_enabled
+ expose :merge_method
expose :statistics, using: 'API::Entities::ProjectStatistics', if: :statistics
@@ -405,6 +406,7 @@ module API
class IssueBasic < ProjectEntity
expose :closed_at
+ expose :closed_by, using: Entities::UserBasic
expose :labels do |issue, options|
# Avoids an N+1 query since labels are preloaded
issue.labels.map(&:title).sort
@@ -792,7 +794,7 @@ module API
expose :id, :title, :created_at, :updated_at, :active
expose :push_events, :issues_events, :confidential_issues_events
expose :merge_requests_events, :tag_push_events, :note_events
- expose :pipeline_events, :wiki_page_events
+ expose :confidential_note_events, :pipeline_events, :wiki_page_events
expose :job_events
# Expose serialized properties
expose :properties do |service, options|
@@ -926,7 +928,7 @@ module API
end
class Tag < Grape::Entity
- expose :name, :message
+ expose :name, :message, :target
expose :commit, using: Entities::Commit do |repo_tag, options|
options[:project].repository.commit(repo_tag.dereferenced_target)
diff --git a/lib/api/features.rb b/lib/api/features.rb
index 9385c6ca174..11d848584d9 100644
--- a/lib/api/features.rb
+++ b/lib/api/features.rb
@@ -65,6 +65,13 @@ module API
present feature, with: Entities::Feature, current_user: current_user
end
+
+ desc 'Remove the gate value for the given feature'
+ delete ':name' do
+ Feature.get(params[:name]).remove
+
+ status 204
+ end
end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index e59e8a45908..61dab1dd5cb 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -83,12 +83,13 @@ module API
end
def available_labels_for(label_parent)
- search_params =
- if label_parent.is_a?(Project)
- { project_id: label_parent.id }
- else
- { group_id: label_parent.id, only_group_labels: true }
- end
+ search_params = { include_ancestor_groups: true }
+
+ if label_parent.is_a?(Project)
+ search_params[:project_id] = label_parent.id
+ else
+ search_params.merge!(group_id: label_parent.id, only_group_labels: true)
+ end
LabelsFinder.new(current_user, search_params).execute
end
@@ -388,28 +389,6 @@ module API
# file helpers
- def uploaded_file(field, uploads_path)
- if params[field]
- bad_request!("#{field} is not a file") unless params[field][:filename]
- return params[field]
- end
-
- return nil unless params["#{field}.path"] && params["#{field}.name"]
-
- # sanitize file paths
- # this requires all paths to exist
- required_attributes! %W(#{field}.path)
- uploads_path = File.realpath(uploads_path)
- file_path = File.realpath(params["#{field}.path"])
- bad_request!('Bad file path') unless file_path.start_with?(uploads_path)
-
- UploadedFile.new(
- file_path,
- params["#{field}.name"],
- params["#{field}.type"] || 'application/octet-stream'
- )
- end
-
def present_disk_file!(path, filename, content_type = 'application/octet-stream')
filename ||= File.basename(path)
header['Content-Disposition'] = "attachment; filename=#{filename}"
@@ -489,8 +468,8 @@ module API
header(*Gitlab::Workhorse.send_git_blob(repository, blob))
end
- def send_git_archive(repository, ref:, format:)
- header(*Gitlab::Workhorse.send_git_archive(repository, ref: ref, format: format))
+ def send_git_archive(repository, **kwargs)
+ header(*Gitlab::Workhorse.send_git_archive(repository, **kwargs))
end
def send_artifacts_entry(build, entry)
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
new file mode 100644
index 00000000000..381d5e8968c
--- /dev/null
+++ b/lib/api/helpers/projects_helpers.rb
@@ -0,0 +1,38 @@
+module API
+ module Helpers
+ module ProjectsHelpers
+ extend ActiveSupport::Concern
+
+ included do
+ helpers do
+ params :optional_project_params_ce do
+ optional :description, type: String, desc: 'The description of the project'
+ optional :ci_config_path, type: String, desc: 'The path to CI config file. Defaults 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 :resolve_outdated_diff_discussions, type: Boolean, desc: 'Automatically resolve merge request diffs discussions on lines changed with a push'
+ optional :container_registry_enabled, type: Boolean, desc: 'Flag indication if the container registry is enabled for that project'
+ optional :lfs_enabled, type: Boolean, desc: 'Flag indication if Git LFS is enabled for that project'
+ optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the project.'
+ 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'
+ optional :merge_method, type: String, values: %w(ff rebase_merge merge), desc: 'The merge method used when merging merge requests'
+ end
+
+ params :optional_project_params do
+ use :optional_project_params_ce
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index f74b3b26802..88e7f46c92c 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -97,7 +97,7 @@ module API
get ":id/issues" do
group = find_group!(params[:id])
- issues = paginate(find_issues(group_id: group.id))
+ issues = paginate(find_issues(group_id: group.id, include_subgroups: true))
options = {
with: Entities::IssueBasic,
diff --git a/lib/api/project_export.rb b/lib/api/project_export.rb
index efc4a33ae1b..5ef4e9d530c 100644
--- a/lib/api/project_export.rb
+++ b/lib/api/project_export.rb
@@ -33,11 +33,28 @@ module API
end
params do
optional :description, type: String, desc: 'Override the project description'
+ optional :upload, type: Hash do
+ optional :url, type: String, desc: 'The URL to upload the project'
+ optional :http_method, type: String, default: 'PUT', desc: 'HTTP method to upload the exported project'
+ end
end
post ':id/export' do
project_export_params = declared_params(include_missing: false)
+ after_export_params = project_export_params.delete(:upload) || {}
- user_project.add_export_job(current_user: current_user, params: project_export_params)
+ export_strategy = if after_export_params[:url].present?
+ params = after_export_params.slice(:url, :http_method).symbolize_keys
+
+ Gitlab::ImportExport::AfterExportStrategies::WebUploadStrategy.new(params)
+ end
+
+ if export_strategy&.invalid?
+ render_validation_error!(export_strategy)
+ else
+ user_project.add_export_job(current_user: current_user,
+ after_export_strategy: export_strategy,
+ params: project_export_params)
+ end
accepted!
end
diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb
index f82241058e5..68921ae439b 100644
--- a/lib/api/project_hooks.rb
+++ b/lib/api/project_hooks.rb
@@ -14,6 +14,7 @@ module API
optional :merge_requests_events, type: Boolean, desc: "Trigger hook on merge request events"
optional :tag_push_events, type: Boolean, desc: "Trigger hook on tag push events"
optional :note_events, type: Boolean, desc: "Trigger hook on note(comment) events"
+ optional :confidential_note_events, type: Boolean, desc: "Trigger hook on confidential note(comment) events"
optional :job_events, type: Boolean, desc: "Trigger hook on job events"
optional :pipeline_events, type: Boolean, desc: "Trigger hook on pipeline events"
optional :wiki_page_events, type: Boolean, desc: "Trigger hook on wiki events"
diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb
index a509c1f32c1..bc5152e539f 100644
--- a/lib/api/project_import.rb
+++ b/lib/api/project_import.rb
@@ -1,6 +1,7 @@
module API
class ProjectImport < Grape::API
include PaginationParams
+ include Helpers::ProjectsHelpers
helpers do
def import_params
@@ -25,6 +26,12 @@ module API
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 current user's namespace."
+ optional :overwrite, type: Boolean, default: false, desc: 'If there is a project in the same namespace and with the same name overwrite it'
+ optional :override_params,
+ type: Hash,
+ desc: 'New project params to override values in the export' do
+ use :optional_project_params
+ end
end
desc 'Create a new project import' do
detail 'This feature was introduced in GitLab 10.6.'
@@ -44,10 +51,15 @@ module API
project_params = {
path: import_params[:path],
namespace_id: namespace.id,
- file: import_params[:file]['tempfile']
+ file: import_params[:file]['tempfile'],
+ overwrite: import_params[:overwrite]
}
- project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute
+ override_params = import_params.delete(:override_params)
+
+ project = ::Projects::GitlabProjectsImportService.new(
+ current_user, project_params, override_params
+ ).execute
render_api_error!(project.errors.full_messages&.first, 400) unless project.saved?
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 467bc78dad8..d0a4a23e074 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -4,36 +4,11 @@ module API
class Projects < Grape::API
include PaginationParams
include Helpers::CustomAttributes
+ include Helpers::ProjectsHelpers
before { authenticate_non_get! }
helpers do
- params :optional_params_ce do
- optional :description, type: String, desc: 'The description of the project'
- optional :ci_config_path, type: String, desc: 'The path to CI config file. Defaults 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 :resolve_outdated_diff_discussions, type: Boolean, desc: 'Automatically resolve merge request diffs discussions on lines changed with a push'
- optional :container_registry_enabled, type: Boolean, desc: 'Flag indication if the container registry is enabled for that project'
- optional :lfs_enabled, type: Boolean, desc: 'Flag indication if Git LFS is enabled for that project'
- optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the project.'
- 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
@@ -143,7 +118,7 @@ module API
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 :optional_project_params
use :create_params
end
post do
@@ -171,7 +146,7 @@ module API
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 :optional_project_params
use :create_params
end
post "user/:user_id" do
@@ -274,6 +249,7 @@ module API
:issues_enabled,
:lfs_enabled,
:merge_requests_enabled,
+ :merge_method,
:name,
:only_allow_merge_if_all_discussions_are_resolved,
:only_allow_merge_if_pipeline_succeeds,
@@ -291,7 +267,7 @@ module API
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
+ use :optional_project_params
at_least_one_of(*at_least_one_of_ce)
end
put ':id' do
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 9638c53a1df..2396dc73f0e 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -88,7 +88,7 @@ module API
end
get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do
begin
- send_git_archive user_project.repository, ref: params[:sha], format: params[:format]
+ send_git_archive user_project.repository, ref: params[:sha], format: params[:format], append_sha: true
rescue
not_found!('File')
end
diff --git a/lib/api/runner.rb b/lib/api/runner.rb
index 57c0a729535..60aeb69e10a 100644
--- a/lib/api/runner.rb
+++ b/lib/api/runner.rb
@@ -186,7 +186,7 @@ module API
status 200
content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
- Gitlab::Workhorse.artifact_upload_ok
+ JobArtifactUploader.workhorse_authorize
end
desc 'Upload artifacts for job' do
@@ -201,13 +201,15 @@ module API
requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token)
optional :expire_in, type: String, desc: %q(Specify when artifacts should expire)
- optional :file, type: File, desc: %q(Artifact's file)
optional 'file.path', type: String, desc: %q(path to locally stored body (generated by Workhorse))
optional 'file.name', type: String, desc: %q(real filename as send in Content-Disposition (generated by Workhorse))
optional 'file.type', type: String, desc: %q(real content type as send in Content-Type (generated by Workhorse))
- optional 'file.sha256', type: String, desc: %q(sha256 checksum of the file)
+ optional 'file.size', type: Integer, desc: %q(real size of file (generated by Workhorse))
+ optional 'file.sha256', type: String, desc: %q(sha256 checksum of the file (generated by Workhorse))
optional 'metadata.path', type: String, desc: %q(path to locally stored body (generated by Workhorse))
optional 'metadata.name', type: String, desc: %q(filename (generated by Workhorse))
+ optional 'metadata.size', type: Integer, desc: %q(real size of metadata (generated by Workhorse))
+ optional 'metadata.sha256', type: String, desc: %q(sha256 checksum of metadata (generated by Workhorse))
end
post '/:id/artifacts' do
not_allowed! unless Gitlab.config.artifacts.enabled
@@ -216,21 +218,34 @@ module API
job = authenticate_job!
forbidden!('Job is not running!') unless job.running?
- workhorse_upload_path = JobArtifactUploader.workhorse_upload_path
- artifacts = uploaded_file(:file, workhorse_upload_path)
- metadata = uploaded_file(:metadata, workhorse_upload_path)
+ artifacts = UploadedFile.from_params(params, :file, JobArtifactUploader.workhorse_local_upload_path)
+ metadata = UploadedFile.from_params(params, :metadata, JobArtifactUploader.workhorse_local_upload_path)
bad_request!('Missing artifacts file!') unless artifacts
file_to_large! unless artifacts.size < max_artifacts_size
+ bad_request!("Already uploaded") if job.job_artifacts_archive
+
expire_in = params['expire_in'] ||
Gitlab::CurrentSettings.current_application_settings.default_artifacts_expire_in
- job.build_job_artifacts_archive(project: job.project, file_type: :archive, file: artifacts, file_sha256: params['file.sha256'], expire_in: expire_in)
- job.build_job_artifacts_metadata(project: job.project, file_type: :metadata, file: metadata, expire_in: expire_in) if metadata
- job.artifacts_expire_in = expire_in
+ job.build_job_artifacts_archive(
+ project: job.project,
+ file: artifacts,
+ file_type: :archive,
+ file_sha256: artifacts.sha256,
+ expire_in: expire_in)
+
+ if metadata
+ job.build_job_artifacts_metadata(
+ project: job.project,
+ file: metadata,
+ file_type: :metadata,
+ file_sha256: metadata.sha256,
+ expire_in: expire_in)
+ end
- if job.save
+ if job.update(artifacts_expire_in: expire_in)
present job, with: Entities::JobRequest::Response
else
render_validation_error!(job)
diff --git a/lib/api/v3/repositories.rb b/lib/api/v3/repositories.rb
index 5b54734bb45..f701d64e886 100644
--- a/lib/api/v3/repositories.rb
+++ b/lib/api/v3/repositories.rb
@@ -75,7 +75,7 @@ module API
end
get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do
begin
- send_git_archive user_project.repository, ref: params[:sha], format: params[:format]
+ send_git_archive user_project.repository, ref: params[:sha], format: params[:format], append_sha: true
rescue
not_found!('File')
end