Commit 6d0f9bbc authored by Rémy Coutable's avatar Rémy Coutable Committed by Robert Speicher

Merge branch 'ci-lfs-fetch' into 'master'

Allow to fetch LFS from CI

## What does this MR do?

This adds support for fetching LFS object from CI jobs (mostly it's made for supporting GitLab CI).

## What is left?

- [x] Write tests covering a new authorization mechanism

cc @grzesiek @marin

See merge request !4465
parent 95621c01
...@@ -76,6 +76,7 @@ v 8.9.0 (unreleased) ...@@ -76,6 +76,7 @@ v 8.9.0 (unreleased)
- Pipelines can be canceled only when there are running builds - Pipelines can be canceled only when there are running builds
- Allow authentication using personal access tokens - Allow authentication using personal access tokens
- Use downcased path to container repository as this is expected path by Docker - Use downcased path to container repository as this is expected path by Docker
- Allow to use CI token to fetch LFS objects
- Custom notification settings - Custom notification settings
- Projects pending deletion will render a 404 page - Projects pending deletion will render a 404 page
- Measure queue duration between gitlab-workhorse and Rails - Measure queue duration between gitlab-workhorse and Rails
......
...@@ -31,7 +31,7 @@ module Grack ...@@ -31,7 +31,7 @@ module Grack
auth! auth!
lfs_response = Gitlab::Lfs::Router.new(project, @user, @request).try_call lfs_response = Gitlab::Lfs::Router.new(project, @user, @ci, @request).try_call
return lfs_response unless lfs_response.nil? return lfs_response unless lfs_response.nil?
if @user.nil? && !@ci if @user.nil? && !@ci
......
...@@ -2,10 +2,11 @@ module Gitlab ...@@ -2,10 +2,11 @@ module Gitlab
module Lfs module Lfs
class Response class Response
def initialize(project, user, request) def initialize(project, user, ci, request)
@origin_project = project @origin_project = project
@project = storage_project(project) @project = storage_project(project)
@user = user @user = user
@ci = ci
@env = request.env @env = request.env
@request = request @request = request
end end
...@@ -189,7 +190,7 @@ module Gitlab ...@@ -189,7 +190,7 @@ module Gitlab
return render_not_enabled unless Gitlab.config.lfs.enabled return render_not_enabled unless Gitlab.config.lfs.enabled
unless @project.public? unless @project.public?
return render_unauthorized unless @user return render_unauthorized unless @user || @ci
return render_forbidden unless user_can_fetch? return render_forbidden unless user_can_fetch?
end end
...@@ -210,7 +211,7 @@ module Gitlab ...@@ -210,7 +211,7 @@ module Gitlab
def user_can_fetch? def user_can_fetch?
# Check user access against the project they used to initiate the pull # Check user access against the project they used to initiate the pull
@user.can?(:download_code, @origin_project) @ci || @user.can?(:download_code, @origin_project)
end end
def user_can_push? def user_can_push?
......
module Gitlab module Gitlab
module Lfs module Lfs
class Router class Router
def initialize(project, user, request) attr_reader :project, :user, :ci, :request
def initialize(project, user, ci, request)
@project = project @project = project
@user = user @user = user
@ci = ci
@env = request.env @env = request.env
@request = request @request = request
end end
...@@ -80,7 +83,7 @@ module Gitlab ...@@ -80,7 +83,7 @@ module Gitlab
def lfs def lfs
return unless @project return unless @project
Gitlab::Lfs::Response.new(@project, @user, @request) Gitlab::Lfs::Response.new(@project, @user, @ci, @request)
end end
def sanitize_tmp_filename(name) def sanitize_tmp_filename(name)
......
...@@ -17,12 +17,15 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -17,12 +17,15 @@ describe Gitlab::Lfs::Router, lib: true do
} }
end end
let(:lfs_router_auth) { new_lfs_router(project, user) } let(:lfs_router_auth) { new_lfs_router(project, user: user) }
let(:lfs_router_noauth) { new_lfs_router(project, nil) } let(:lfs_router_ci_auth) { new_lfs_router(project, ci: true) }
let(:lfs_router_public_auth) { new_lfs_router(public_project, user) } let(:lfs_router_noauth) { new_lfs_router(project) }
let(:lfs_router_public_noauth) { new_lfs_router(public_project, nil) } let(:lfs_router_public_auth) { new_lfs_router(public_project, user: user) }
let(:lfs_router_forked_noauth) { new_lfs_router(forked_project, nil) } let(:lfs_router_public_ci_auth) { new_lfs_router(public_project, ci: true) }
let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user_two) } let(:lfs_router_public_noauth) { new_lfs_router(public_project) }
let(:lfs_router_forked_noauth) { new_lfs_router(forked_project) }
let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user: user_two) }
let(:lfs_router_forked_ci_auth) { new_lfs_router(forked_project, ci: true) }
let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" } let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" }
let(:sample_size) { 499013 } let(:sample_size) { 499013 }
...@@ -80,6 +83,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -80,6 +83,7 @@ describe Gitlab::Lfs::Router, lib: true do
context 'with required headers' do context 'with required headers' do
before do before do
project.lfs_objects << lfs_object
env['HTTP_X_SENDFILE_TYPE'] = "X-Sendfile" env['HTTP_X_SENDFILE_TYPE'] = "X-Sendfile"
end end
...@@ -91,7 +95,6 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -91,7 +95,6 @@ describe Gitlab::Lfs::Router, lib: true do
context 'when user has project access' do context 'when user has project access' do
before do before do
project.lfs_objects << lfs_object
project.team << [user, :master] project.team << [user, :master]
end end
...@@ -104,6 +107,17 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -104,6 +107,17 @@ describe Gitlab::Lfs::Router, lib: true do
expect(lfs_router_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path) expect(lfs_router_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path)
end end
end end
context 'when CI is authorized' do
it "responds with status 200" do
expect(lfs_router_ci_auth.try_call.first).to eq(200)
end
it "responds with the file location" do
expect(lfs_router_ci_auth.try_call[1]['Content-Type']).to eq("application/octet-stream")
expect(lfs_router_ci_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path)
end
end
end end
context 'without required headers' do context 'without required headers' do
...@@ -134,143 +148,145 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -134,143 +148,145 @@ describe Gitlab::Lfs::Router, lib: true do
end end
describe 'download' do describe 'download' do
describe 'when user is authenticated' do before do
before do body = { 'operation' => 'download',
body = { 'operation' => 'download', 'objects' => [
'objects' => [ { 'oid' => sample_oid,
{ 'oid' => sample_oid, 'size' => sample_size
'size' => sample_size }]
}] }.to_json
}.to_json env['rack.input'] = StringIO.new(body)
env['rack.input'] = StringIO.new(body) end
end
describe 'when user has download access' do shared_examples 'an authorized requests' do
context 'when downloading an lfs object that is assigned to our project' do
before do before do
@auth = authorize(user) project.lfs_objects << lfs_object
env["HTTP_AUTHORIZATION"] = @auth
project.team << [user, :reporter]
end end
context 'when downloading an lfs object that is assigned to our project' do it 'responds with status 200 and href to download' do
before do response = router.try_call
project.lfs_objects << lfs_object expect(response.first).to eq(200)
end response_body = ActiveSupport::JSON.decode(response.last.first)
it 'responds with status 200 and href to download' do
response = lfs_router_auth.try_call
expect(response.first).to eq(200)
response_body = ActiveSupport::JSON.decode(response.last.first)
expect(response_body).to eq('objects' => [ expect(response_body).to eq('objects' => [
{ 'oid' => sample_oid, { 'oid' => sample_oid,
'size' => sample_size, 'size' => sample_size,
'actions' => { 'actions' => {
'download' => { 'download' => {
'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
'header' => { 'Authorization' => @auth } 'header' => { 'Authorization' => auth }
}
} }
}]) }
end }])
end end
end
context 'when downloading an lfs object that is assigned to other project' do context 'when downloading an lfs object that is assigned to other project' do
before do before do
public_project.lfs_objects << lfs_object public_project.lfs_objects << lfs_object
end end
it 'responds with status 200 and error message' do it 'responds with status 200 and error message' do
response = lfs_router_auth.try_call response = router.try_call
expect(response.first).to eq(200) expect(response.first).to eq(200)
response_body = ActiveSupport::JSON.decode(response.last.first) response_body = ActiveSupport::JSON.decode(response.last.first)
expect(response_body).to eq('objects' => [ expect(response_body).to eq('objects' => [
{ 'oid' => sample_oid, { 'oid' => sample_oid,
'size' => sample_size, 'size' => sample_size,
'error' => { 'error' => {
'code' => 404, 'code' => 404,
'message' => "Object does not exist on the server or you don't have permissions to access it", 'message' => "Object does not exist on the server or you don't have permissions to access it",
} }
}]) }])
end
end end
end
context 'when downloading a lfs object that does not exist' do context 'when downloading a lfs object that does not exist' do
before do before do
body = { 'operation' => 'download', body = { 'operation' => 'download',
'objects' => [ 'objects' => [
{ 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
'size' => 1575078 'size' => 1575078
}] }]
}.to_json }.to_json
env['rack.input'] = StringIO.new(body) env['rack.input'] = StringIO.new(body)
end end
it "responds with status 200 and error message" do it "responds with status 200 and error message" do
response = lfs_router_auth.try_call response = router.try_call
expect(response.first).to eq(200) expect(response.first).to eq(200)
response_body = ActiveSupport::JSON.decode(response.last.first) response_body = ActiveSupport::JSON.decode(response.last.first)
expect(response_body).to eq('objects' => [ expect(response_body).to eq('objects' => [
{ 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
'size' => 1575078, 'size' => 1575078,
'error' => { 'error' => {
'code' => 404, 'code' => 404,
'message' => "Object does not exist on the server or you don't have permissions to access it", 'message' => "Object does not exist on the server or you don't have permissions to access it",
} }
}]) }])
end
end end
end
context 'when downloading one new and one existing lfs object' do context 'when downloading one new and one existing lfs object' do
before do before do
body = { 'operation' => 'download', body = { 'operation' => 'download',
'objects' => [ 'objects' => [
{ 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
'size' => 1575078 'size' => 1575078
}, },
{ 'oid' => sample_oid, { 'oid' => sample_oid,
'size' => sample_size 'size' => sample_size
} }
] ]
}.to_json }.to_json
env['rack.input'] = StringIO.new(body) env['rack.input'] = StringIO.new(body)
project.lfs_objects << lfs_object project.lfs_objects << lfs_object
end end
it "responds with status 200 with upload hypermedia link for the new object" do it "responds with status 200 with upload hypermedia link for the new object" do
response = lfs_router_auth.try_call response = router.try_call
expect(response.first).to eq(200) expect(response.first).to eq(200)
response_body = ActiveSupport::JSON.decode(response.last.first) response_body = ActiveSupport::JSON.decode(response.last.first)
expect(response_body).to eq('objects' => [ expect(response_body).to eq('objects' => [
{ 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
'size' => 1575078, 'size' => 1575078,
'error' => { 'error' => {
'code' => 404, 'code' => 404,
'message' => "Object does not exist on the server or you don't have permissions to access it", 'message' => "Object does not exist on the server or you don't have permissions to access it",
} }
}, },
{ 'oid' => sample_oid, { 'oid' => sample_oid,
'size' => sample_size, 'size' => sample_size,
'actions' => { 'actions' => {
'download' => { 'download' => {
'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
'header' => { 'Authorization' => @auth } 'header' => { 'Authorization' => auth }
}
} }
}]) }
end }])
end end
end end
end
context 'when user is authenticated' do
let(:auth) { authorize(user) }
before do
env["HTTP_AUTHORIZATION"] = auth
project.team << [user, role]
end
it_behaves_like 'an authorized requests' do
let(:role) { :reporter }
let(:router) { lfs_router_auth }
end
context 'when user does is not member of the project' do context 'when user does is not member of the project' do
before do let(:role) { :guest }
@auth = authorize(user)
env["HTTP_AUTHORIZATION"] = @auth
project.team << [user, :guest]
end
it 'responds with 403' do it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403) expect(lfs_router_auth.try_call.first).to eq(403)
...@@ -278,11 +294,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -278,11 +294,7 @@ describe Gitlab::Lfs::Router, lib: true do
end end
context 'when user does not have download access' do context 'when user does not have download access' do
before do let(:role) { :guest }
@auth = authorize(user)
env["HTTP_AUTHORIZATION"] = @auth
project.team << [user, :guest]
end
it 'responds with 403' do it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403) expect(lfs_router_auth.try_call.first).to eq(403)
...@@ -290,18 +302,19 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -290,18 +302,19 @@ describe Gitlab::Lfs::Router, lib: true do
end end
end end
context 'when user is not authenticated' do context 'when CI is authorized' do
let(:auth) { 'gitlab-ci-token:password' }
before do before do
body = { 'operation' => 'download', env["HTTP_AUTHORIZATION"] = auth
'objects' => [ end
{ 'oid' => sample_oid,
'size' => sample_size
}],
}.to_json it_behaves_like 'an authorized requests' do
env['rack.input'] = StringIO.new(body) let(:router) { lfs_router_ci_auth }
end end
end
context 'when user is not authenticated' do
describe 'is accessing public project' do describe 'is accessing public project' do
before do before do
public_project.lfs_objects << lfs_object public_project.lfs_objects << lfs_object
...@@ -338,17 +351,17 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -338,17 +351,17 @@ describe Gitlab::Lfs::Router, lib: true do
end end
describe 'upload' do describe 'upload' do
describe 'when user is authenticated' do before do
before do body = { 'operation' => 'upload',
body = { 'operation' => 'upload', 'objects' => [
'objects' => [ { 'oid' => sample_oid,
{ 'oid' => sample_oid, 'size' => sample_size
'size' => sample_size }]
}] }.to_json
}.to_json env['rack.input'] = StringIO.new(body)
env['rack.input'] = StringIO.new(body) end
end
describe 'when request is authenticated' do
describe 'when user has project push access' do describe 'when user has project push access' do
before do before do
@auth = authorize(user) @auth = authorize(user)
...@@ -440,15 +453,15 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -440,15 +453,15 @@ describe Gitlab::Lfs::Router, lib: true do
expect(lfs_router_auth.try_call.first).to eq(403) expect(lfs_router_auth.try_call.first).to eq(403)
end end
end end
end
context 'when user is not authenticated' do context 'when CI is authorized' do
before do it 'responds with 401' do
env['rack.input'] = StringIO.new( expect(lfs_router_ci_auth.try_call.first).to eq(401)
{ 'objects' => [], 'operation' => 'upload' }.to_json end
)
end end
end
context 'when user is not authenticated' do
context 'when user has push access' do context 'when user has push access' do
before do before do
project.team << [user, :master] project.team << [user, :master]
...@@ -465,6 +478,18 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -465,6 +478,18 @@ describe Gitlab::Lfs::Router, lib: true do
end end
end end
end end
context 'when CI is authorized' do
let(:auth) { 'gitlab-ci-token:password' }
before do
env["HTTP_AUTHORIZATION"] = auth
end
it "responds with status 403" do
expect(lfs_router_public_ci_auth.try_call.first).to eq(401)
end
end
end end
describe 'unsupported' do describe 'unsupported' do
...@@ -490,13 +515,68 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -490,13 +515,68 @@ describe Gitlab::Lfs::Router, lib: true do
env['REQUEST_METHOD'] = 'PUT' env['REQUEST_METHOD'] = 'PUT'
end end
describe 'to one project' do shared_examples 'unauthorized' do
describe 'when user has push access to the project' do context 'and request is sent by gitlab-workhorse to authorize the request' do
before do before do
project.team << [user, :master] header_for_upload_authorize(router.project)
end
it 'responds with status 401' do
expect(router.try_call.first).to eq(401)
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do
headers_for_upload_finalize(router.project)
end
it 'responds with status 401' do
expect(router.try_call.first).to eq(401)
end
end
context 'and request is sent with a malformed headers' do
before do
env["PATH_INFO"] = "#{router.project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}"
env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd"
end
it 'does not recognize it as a valid lfs command' do
expect(router.try_call).to eq(nil)
end
end
end
shared_examples 'forbidden' do
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(router.project)
end
it 'responds with 403' do
expect(router.try_call.first).to eq(403)
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do
headers_for_upload_finalize(router.project)
end
it 'responds with 403' do
expect(router.try_call.first).to eq(403)
end end
end
end
describe 'to one project' do
describe 'when user is authenticated' do
describe 'when user has push access to the project' do
before do
project.team << [user, :developer]
end
describe 'when user is authenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do context 'and request is sent by gitlab-workhorse to authorize the request' do
before do before do
header_for_upload_authorize(project) header_for_upload_authorize(project)
...@@ -524,100 +604,35 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -524,100 +604,35 @@ describe Gitlab::Lfs::Router, lib: true do
end end
end end
describe 'when user is unauthenticated' do describe 'and user does not have push access' do
let(:lfs_router_noauth) { new_lfs_router(project, nil) } let(:router) { lfs_router_auth }
context 'and request is sent by gitlab-workhorse to authorize the request' do it_behaves_like 'forbidden'
before do
header_for_upload_authorize(project)
end
it 'responds with status 401' do
expect(lfs_router_noauth.try_call.first).to eq(401)
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do
headers_for_upload_finalize(project)
end
it 'responds with status 401' do
expect(lfs_router_noauth.try_call.first).to eq(401)
end
end
context 'and request is sent with a malformed headers' do
before do
env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}"
env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd"
end
it 'does not recognize it as a valid lfs command' do
expect(lfs_router_noauth.try_call).to eq(nil)
end
end
end end
end end
describe 'and user does not have push access' do context 'when CI is authenticated' do
describe 'when user is authenticated' do let(:router) { lfs_router_ci_auth }
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(project)
end
it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403)
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do
headers_for_upload_finalize(project)
end
it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403)
end
end
end
describe 'when user is unauthenticated' do it_behaves_like 'unauthorized'
let(:lfs_router_noauth) { new_lfs_router(project, nil) } end
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(project)
end
it 'responds with 401' do context 'for unauthenticated' do
expect(lfs_router_noauth.try_call.first).to eq(401) let(:router) { new_lfs_router(project) }
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do it_behaves_like 'unauthorized'
before do
headers_for_upload_finalize(project)
end
it 'responds with 401' do
expect(lfs_router_noauth.try_call.first).to eq(401)
end
end
end
end end
end end
describe "to a forked project" do describe 'to a forked project' do
let(:forked_project) { fork_project(public_project, user) } let(:forked_project) { fork_project(public_project, user) }
describe 'when user has push access to the project' do describe 'when user is authenticated' do
before do describe 'when user has push access to the project' do
forked_project.team << [user_two, :master] before do
end forked_project.team << [user_two, :developer]
end
describe 'when user is authenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do context 'and request is sent by gitlab-workhorse to authorize the request' do
before do before do
header_for_upload_authorize(forked_project) header_for_upload_authorize(forked_project)
...@@ -645,78 +660,28 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -645,78 +660,28 @@ describe Gitlab::Lfs::Router, lib: true do
end end
end end
describe 'when user is unauthenticated' do describe 'and user does not have push access' do
context 'and request is sent by gitlab-workhorse to authorize the request' do let(:router) { lfs_router_forked_auth }
before do
header_for_upload_authorize(forked_project)
end
it 'responds with status 401' do
expect(lfs_router_forked_noauth.try_call.first).to eq(401)
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do
headers_for_upload_finalize(forked_project)
end
it 'responds with status 401' do it_behaves_like 'forbidden'
expect(lfs_router_forked_noauth.try_call.first).to eq(401)
end
end
end end
end end
describe 'and user does not have push access' do context 'when CI is authenticated' do
describe 'when user is authenticated' do let(:router) { lfs_router_forked_ci_auth }
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(forked_project)
end
it 'responds with 403' do it_behaves_like 'unauthorized'
expect(lfs_router_forked_auth.try_call.first).to eq(403) end
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do
headers_for_upload_finalize(forked_project)
end
it 'responds with 403' do
expect(lfs_router_forked_auth.try_call.first).to eq(403)
end
end
end
describe 'when user is unauthenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(forked_project)
end
it 'responds with 401' do
expect(lfs_router_forked_noauth.try_call.first).to eq(401)
end
end
context 'and request is sent by gitlab-workhorse to finalize the upload' do context 'for unauthenticated' do
before do let(:router) { lfs_router_forked_noauth }
headers_for_upload_finalize(forked_project)
end
it 'responds with 401' do it_behaves_like 'unauthorized'
expect(lfs_router_forked_noauth.try_call.first).to eq(401)
end
end
end
end end
describe 'and second project not related to fork or a source project' do describe 'and second project not related to fork or a source project' do
let(:second_project) { create(:project) } let(:second_project) { create(:project) }
let(:lfs_router_second_project) { new_lfs_router(second_project, user) } let(:lfs_router_second_project) { new_lfs_router(second_project, user: user) }
before do before do
public_project.lfs_objects << lfs_object public_project.lfs_objects << lfs_object
...@@ -745,8 +710,8 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -745,8 +710,8 @@ describe Gitlab::Lfs::Router, lib: true do
ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password) ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password)
end end
def new_lfs_router(project, user) def new_lfs_router(project, user: nil, ci: false)
Gitlab::Lfs::Router.new(project, user, request) Gitlab::Lfs::Router.new(project, user, ci, request)
end end
def header_for_upload_authorize(project) def header_for_upload_authorize(project)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment