Commit 6bc22d95 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Add test coverage to LFS fetching

parent 2f545a15
module Gitlab module Gitlab
module Lfs module Lfs
class Router class Router
attr_reader :project, :user, :ci, :request
def initialize(project, user, ci, request) def initialize(project, user, ci, request)
@project = project @project = project
@user = user @user = user
......
...@@ -83,6 +83,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -83,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
...@@ -94,7 +95,6 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -94,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
...@@ -148,7 +148,6 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -148,7 +148,6 @@ 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' => [
...@@ -159,20 +158,14 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -159,20 +158,14 @@ describe Gitlab::Lfs::Router, lib: true do
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
before do
@auth = authorize(user)
env["HTTP_AUTHORIZATION"] = @auth
project.team << [user, :reporter]
end
context 'when downloading an lfs object that is assigned to our project' do context 'when downloading an lfs object that is assigned to our project' do
before do before do
project.lfs_objects << lfs_object project.lfs_objects << lfs_object
end end
it 'responds with status 200 and href to download' do it 'responds with status 200 and href to download' 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)
...@@ -182,7 +175,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -182,7 +175,7 @@ describe Gitlab::Lfs::Router, lib: true do
'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 }
} }
} }
}]) }])
...@@ -195,7 +188,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -195,7 +188,7 @@ describe Gitlab::Lfs::Router, lib: true do
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)
...@@ -222,7 +215,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -222,7 +215,7 @@ describe Gitlab::Lfs::Router, lib: true do
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)
...@@ -254,7 +247,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -254,7 +247,7 @@ describe Gitlab::Lfs::Router, lib: true do
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)
...@@ -271,7 +264,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -271,7 +264,7 @@ describe Gitlab::Lfs::Router, lib: true do
'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 }
} }
} }
}]) }])
...@@ -279,24 +272,29 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -279,24 +272,29 @@ describe Gitlab::Lfs::Router, lib: true do
end end
end end
context 'when user does is not member of the project' do context 'when user is authenticated' do
let(:auth) { authorize(user) }
before do before do
@auth = authorize(user) env["HTTP_AUTHORIZATION"] = auth
env["HTTP_AUTHORIZATION"] = @auth project.team << [user, role]
project.team << [user, :guest] end
it_behaves_like 'an authorized requests' do
let(:role) { :reporter }
let(:router) { lfs_router_auth }
end end
context 'when user does is not member of the project' do
let(:role) { :guest }
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)
end end
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)
...@@ -304,18 +302,19 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -304,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
...@@ -352,7 +351,6 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -352,7 +351,6 @@ 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' => [
...@@ -363,6 +361,7 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -363,6 +361,7 @@ describe Gitlab::Lfs::Router, lib: true do
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)
...@@ -454,15 +453,15 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -454,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]
...@@ -479,6 +478,18 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -479,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
...@@ -504,109 +515,80 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -504,109 +515,80 @@ 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
before do
project.team << [user, :master]
end
describe 'when user is authenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do
before do
header_for_upload_authorize(project)
end
it 'responds with status 200, location of lfs store and object details' do
json_response = ActiveSupport::JSON.decode(lfs_router_auth.try_call.last.first)
expect(lfs_router_auth.try_call.first).to eq(200)
expect(json_response['StoreLFSPath']).to eq("#{Gitlab.config.shared.path}/lfs-objects/tmp/upload")
expect(json_response['LfsOid']).to eq(sample_oid)
expect(json_response['LfsSize']).to eq(sample_size)
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 200 and lfs object is linked to the project' do
expect(lfs_router_auth.try_call.first).to eq(200)
expect(lfs_object.projects.pluck(:id)).to include(project.id)
end
end
end
describe 'when user is unauthenticated' do
let(:lfs_router_noauth) { new_lfs_router(project) }
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(router.project)
end end
it 'responds with status 401' do it 'responds with status 401' do
expect(lfs_router_noauth.try_call.first).to eq(401) expect(router.try_call.first).to eq(401)
end end
end end
context 'and request is sent by gitlab-workhorse to finalize the upload' do context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do before do
headers_for_upload_finalize(project) headers_for_upload_finalize(router.project)
end end
it 'responds with status 401' do it 'responds with status 401' do
expect(lfs_router_noauth.try_call.first).to eq(401) expect(router.try_call.first).to eq(401)
end end
end end
context 'and request is sent with a malformed headers' do context 'and request is sent with a malformed headers' do
before do before do
env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}" 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" env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd"
end end
it 'does not recognize it as a valid lfs command' do it 'does not recognize it as a valid lfs command' do
expect(lfs_router_noauth.try_call).to eq(nil) expect(router.try_call).to eq(nil)
end
end end
end end
end end
describe 'and user does not have push access' do shared_examples 'forbidden' do
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(router.project)
end end
it 'responds with 403' do it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403) expect(router.try_call.first).to eq(403)
end end
end end
context 'and request is sent by gitlab-workhorse to finalize the upload' do context 'and request is sent by gitlab-workhorse to finalize the upload' do
before do before do
headers_for_upload_finalize(project) headers_for_upload_finalize(router.project)
end end
it 'responds with 403' do it 'responds with 403' do
expect(lfs_router_auth.try_call.first).to eq(403) expect(router.try_call.first).to eq(403)
end end
end end
end end
describe 'when user is unauthenticated' do describe 'to one project' do
let(:lfs_router_noauth) { new_lfs_router(project) } describe 'when user is authenticated' do
describe 'when user has push access to the project' do
before do
project.team << [user, :developer]
end
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)
end end
it 'responds with 401' do it 'responds with status 200, location of lfs store and object details' do
expect(lfs_router_noauth.try_call.first).to eq(401) json_response = ActiveSupport::JSON.decode(lfs_router_auth.try_call.last.first)
expect(lfs_router_auth.try_call.first).to eq(200)
expect(json_response['StoreLFSPath']).to eq("#{Gitlab.config.shared.path}/lfs-objects/tmp/upload")
expect(json_response['LfsOid']).to eq(sample_oid)
expect(json_response['LfsSize']).to eq(sample_size)
end end
end end
...@@ -615,23 +597,42 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -615,23 +597,42 @@ describe Gitlab::Lfs::Router, lib: true do
headers_for_upload_finalize(project) headers_for_upload_finalize(project)
end end
it 'responds with 401' do it 'responds with status 200 and lfs object is linked to the project' do
expect(lfs_router_noauth.try_call.first).to eq(401) expect(lfs_router_auth.try_call.first).to eq(200)
expect(lfs_object.projects.pluck(:id)).to include(project.id)
end end
end end
end end
describe 'and user does not have push access' do
let(:router) { lfs_router_auth }
it_behaves_like 'forbidden'
end end
end end
describe "to a forked project" do context 'when CI is authenticated' do
let(:router) { lfs_router_ci_auth }
it_behaves_like 'unauthorized'
end
context 'for unauthenticated' do
let(:router) { new_lfs_router(project) }
it_behaves_like 'unauthorized'
end
end
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 is authenticated' do
describe 'when user has push access to the project' do describe 'when user has push access to the project' do
before do before do
forked_project.team << [user_two, :master] forked_project.team << [user_two, :developer]
end 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)
...@@ -659,73 +660,23 @@ describe Gitlab::Lfs::Router, lib: true do ...@@ -659,73 +660,23 @@ describe Gitlab::Lfs::Router, lib: true do
end 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 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
expect(lfs_router_forked_noauth.try_call.first).to eq(401)
end
end
end
end
describe 'and user does not have push access' do describe 'and user does not have push access' do
describe 'when user is authenticated' do let(:router) { lfs_router_forked_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
expect(lfs_router_forked_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(forked_project)
end
it 'responds with 403' do it_behaves_like 'forbidden'
expect(lfs_router_forked_auth.try_call.first).to eq(403)
end
end end
end end
describe 'when user is unauthenticated' do context 'when CI is authenticated' do
context 'and request is sent by gitlab-workhorse to authorize the request' do let(:router) { lfs_router_forked_ci_auth }
before do
header_for_upload_authorize(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
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
......
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