Add artifacts uploading authorize API
This commit is contained in:
parent
7e46db0f5a
commit
2a7f555caf
|
@ -68,6 +68,10 @@ module API
|
|||
token = (params[JOB_TOKEN_PARAM] || env[JOB_TOKEN_HEADER]).to_s
|
||||
token && job.valid_token?(token)
|
||||
end
|
||||
|
||||
def max_artifacts_size
|
||||
current_application_settings.max_artifacts_size.megabytes.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -144,6 +144,36 @@ module API
|
|||
header 'Job-Status', job.status
|
||||
header 'Range', "0-#{job.trace_length}"
|
||||
end
|
||||
|
||||
desc 'Authorize artifacts uploading for job' do
|
||||
http_codes [[200, 'Upload allowed'],
|
||||
[403, 'Forbidden'],
|
||||
[405, 'Artifacts support not enabled'],
|
||||
[413, 'File too large']]
|
||||
end
|
||||
params do
|
||||
requires :id, type: Fixnum, desc: %q(Job's ID)
|
||||
optional :token, type: String, desc: %q(Job's authentication token)
|
||||
optional :filesize, type: Fixnum, desc: %q(ARtifacts filesize)
|
||||
end
|
||||
post '/:id/artifacts/authorize' do
|
||||
not_allowed! unless Gitlab.config.artifacts.enabled
|
||||
require_gitlab_workhorse!
|
||||
Gitlab::Workhorse.verify_api_request!(headers)
|
||||
|
||||
job = Ci::Build.find_by_id(params[:id])
|
||||
authenticate_job!(job)
|
||||
forbidden!('Job is not running') unless job.running?
|
||||
|
||||
if params[:filesize]
|
||||
file_size = params[:filesize].to_i
|
||||
file_to_large! unless file_size < max_artifacts_size
|
||||
end
|
||||
|
||||
status 200
|
||||
content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
|
||||
Gitlab::Workhorse.artifact_upload_ok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -614,5 +614,82 @@ describe API::Runner do
|
|||
2.times { patch_the_trace('') }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'artifacts' do
|
||||
let(:jwt_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
|
||||
let(:headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => jwt_token } }
|
||||
let(:headers_with_token) { headers.merge(API::Helpers::Runner::JOB_TOKEN_HEADER => job.token) }
|
||||
|
||||
before { job.run! }
|
||||
|
||||
describe 'POST /api/v4/jobs/:id/artifacts/authorize' do
|
||||
context 'when using token as parameter' do
|
||||
it 'authorizes posting artifacts to running job' do
|
||||
authorize_artifacts_with_token_in_params
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
|
||||
expect(json_response['TempPath']).not_to be_nil
|
||||
end
|
||||
|
||||
it 'fails to post too large artifact' do
|
||||
stub_application_setting(max_artifacts_size: 0)
|
||||
authorize_artifacts_with_token_in_params(filesize: 100)
|
||||
|
||||
expect(response).to have_http_status(413)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using token as header' do
|
||||
it 'authorizes posting artifacts to running job' do
|
||||
authorize_artifacts_with_token_in_headers
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
|
||||
expect(json_response['TempPath']).not_to be_nil
|
||||
end
|
||||
|
||||
it 'fails to post too large artifact' do
|
||||
stub_application_setting(max_artifacts_size: 0)
|
||||
authorize_artifacts_with_token_in_headers(filesize: 100)
|
||||
|
||||
expect(response).to have_http_status(413)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using runners token' do
|
||||
it 'fails to authorize artifacts posting' do
|
||||
authorize_artifacts(token: job.project.runners_token)
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
it 'reject requests that did not go through gitlab-workhorse' do
|
||||
headers.delete(Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER)
|
||||
authorize_artifacts
|
||||
expect(response).to have_http_status(500)
|
||||
end
|
||||
|
||||
context 'authorization token is invalid' do
|
||||
it 'responds with forbidden' do
|
||||
authorize_artifacts(token: 'invalid', filesize: 100 )
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
def authorize_artifacts(params = {}, request_headers = headers)
|
||||
post api("/jobs/#{job.id}/artifacts/authorize"), params, request_headers
|
||||
end
|
||||
|
||||
def authorize_artifacts_with_token_in_params(params = {}, request_headers = headers)
|
||||
params = params.merge(token: job.token)
|
||||
authorize_artifacts(params, request_headers)
|
||||
end
|
||||
|
||||
def authorize_artifacts_with_token_in_headers(params = {}, request_headers = headers_with_token)
|
||||
authorize_artifacts(params, request_headers)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue