2015-10-12 10:42:14 -04:00
require 'spec_helper'
2015-12-09 05:55:36 -05:00
describe Gitlab :: Lfs :: Router , lib : true do
2015-10-12 10:42:14 -04:00
let ( :project ) { create ( :project ) }
let ( :public_project ) { create ( :project , :public ) }
let ( :forked_project ) { fork_project ( public_project , user ) }
let ( :user ) { create ( :user ) }
let ( :user_two ) { create ( :user ) }
let! ( :lfs_object ) { create ( :lfs_object , :with_file ) }
let ( :request ) { Rack :: Request . new ( env ) }
let ( :env ) do
{
'rack.input' = > '' ,
'REQUEST_METHOD' = > 'GET' ,
}
end
2016-06-03 07:57:40 -04:00
let ( :lfs_router_auth ) { new_lfs_router ( project , user : user ) }
let ( :lfs_router_ci_auth ) { new_lfs_router ( project , ci : true ) }
let ( :lfs_router_noauth ) { new_lfs_router ( project ) }
let ( :lfs_router_public_auth ) { new_lfs_router ( public_project , user : user ) }
let ( :lfs_router_public_ci_auth ) { new_lfs_router ( public_project , ci : true ) }
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 ) }
2015-10-12 10:42:14 -04:00
let ( :sample_oid ) { " b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80 " }
let ( :sample_size ) { 499013 }
2016-05-10 22:58:06 -04:00
let ( :respond_with_deprecated ) { [ 501 , { " Content-Type " = > " application/json; charset=utf-8 " } , [ " { \" message \" : \" Server supports batch API only, please update your Git LFS client to version 1.0.1 and up. \" , \" documentation_url \" : \" #{ Gitlab . config . gitlab . url } /help \" } " ] ] }
let ( :respond_with_disabled ) { [ 501 , { " Content-Type " = > " application/json; charset=utf-8 " } , [ " { \" message \" : \" Git LFS is not enabled on this GitLab server, contact your admin. \" , \" documentation_url \" : \" #{ Gitlab . config . gitlab . url } /help \" } " ] ] }
2015-10-12 10:42:14 -04:00
describe 'when lfs is disabled' do
before do
allow ( Gitlab . config . lfs ) . to receive ( :enabled ) . and_return ( false )
2015-11-20 06:45:30 -05:00
env [ 'REQUEST_METHOD' ] = 'POST'
body = {
'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078
} ,
{ 'oid' = > sample_oid ,
'size' = > sample_size
}
] ,
'operation' = > 'upload'
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
env [ " PATH_INFO " ] = " #{ project . repository . path_with_namespace } .git/info/lfs/objects/batch "
2015-10-12 10:42:14 -04:00
end
it 'responds with 501' do
expect ( lfs_router_auth . try_call ) . to match_array ( respond_with_disabled )
end
end
2015-11-20 06:45:30 -05:00
describe 'when fetching lfs object using deprecated API' do
2015-10-12 10:42:14 -04:00
before do
enable_lfs
env [ " PATH_INFO " ] = " #{ project . repository . path_with_namespace } .git/info/lfs/objects/ #{ sample_oid } "
end
2015-11-20 06:45:30 -05:00
it 'responds with 501' do
expect ( lfs_router_auth . try_call ) . to match_array ( respond_with_deprecated )
2015-10-12 10:42:14 -04:00
end
2015-11-20 06:45:30 -05:00
end
2015-10-12 10:42:14 -04:00
2015-11-20 06:45:30 -05:00
describe 'when fetching lfs object' do
before do
enable_lfs
env [ 'HTTP_ACCEPT' ] = " application/vnd.git-lfs+json; charset=utf-8 "
env [ " PATH_INFO " ] = " #{ project . repository . path_with_namespace } .git/gitlab-lfs/objects/ #{ sample_oid } "
2015-10-12 10:42:14 -04:00
end
describe 'and request comes from gitlab-workhorse' do
context 'without user being authorized' do
it " responds with status 401 " do
expect ( lfs_router_noauth . try_call . first ) . to eq ( 401 )
end
end
context 'with required headers' do
before do
2016-06-21 05:26:44 -04:00
project . lfs_objects << lfs_object
2015-10-12 10:42:14 -04:00
env [ 'HTTP_X_SENDFILE_TYPE' ] = " X-Sendfile "
end
context 'when user does not have project access' do
it " responds with status 403 " do
expect ( lfs_router_auth . try_call . first ) . to eq ( 403 )
end
end
context 'when user has project access' do
before do
project . team << [ user , :master ]
end
it " responds with status 200 " do
expect ( lfs_router_auth . try_call . first ) . to eq ( 200 )
end
it " responds with the file location " do
expect ( lfs_router_auth . try_call [ 1 ] [ 'Content-Type' ] ) . to eq ( " application/octet-stream " )
expect ( lfs_router_auth . try_call [ 1 ] [ 'X-Sendfile' ] ) . to eq ( lfs_object . file . path )
end
end
2016-06-03 07:57:40 -04:00
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
2015-10-12 10:42:14 -04:00
end
context 'without required headers' do
it " responds with status 403 " do
expect ( lfs_router_auth . try_call . first ) . to eq ( 403 )
end
end
end
2015-11-20 06:45:30 -05:00
end
2015-10-12 10:42:14 -04:00
2015-11-20 06:45:30 -05:00
describe 'when handling lfs request using deprecated API' do
before do
enable_lfs
env [ 'REQUEST_METHOD' ] = 'POST'
env [ " PATH_INFO " ] = " #{ project . repository . path_with_namespace } .git/info/lfs/objects "
end
2015-10-12 10:42:14 -04:00
2015-11-20 06:45:30 -05:00
it 'responds with 501' do
expect ( lfs_router_auth . try_call ) . to match_array ( respond_with_deprecated )
2015-10-12 10:42:14 -04:00
end
end
2015-11-20 05:59:32 -05:00
describe 'when handling lfs batch request' do
2015-10-12 10:42:14 -04:00
before do
enable_lfs
env [ 'REQUEST_METHOD' ] = 'POST'
2015-11-20 05:59:32 -05:00
env [ 'PATH_INFO' ] = " #{ project . repository . path_with_namespace } .git/info/lfs/objects/batch "
2015-10-12 10:42:14 -04:00
end
2015-11-20 05:59:32 -05:00
describe 'download' do
2016-06-21 05:26:44 -04:00
before do
body = { 'operation' = > 'download' ,
'objects' = > [
{ 'oid' = > sample_oid ,
'size' = > sample_size
} ]
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
end
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
shared_examples 'an authorized requests' do
context 'when downloading an lfs object that is assigned to our project' do
2015-10-12 10:42:14 -04:00
before do
2016-06-21 05:26:44 -04:00
project . lfs_objects << lfs_object
2015-10-12 10:42:14 -04:00
end
2016-06-21 05:26:44 -04:00
it 'responds with status 200 and href to download' do
response = router . try_call
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
expect ( response_body ) . to eq ( 'objects' = > [
{ 'oid' = > sample_oid ,
'size' = > sample_size ,
'actions' = > {
'download' = > {
'href' = > " #{ project . http_url_to_repo } /gitlab-lfs/objects/ #{ sample_oid } " ,
'header' = > { 'Authorization' = > auth }
2015-11-20 05:59:32 -05:00
}
2016-06-21 05:26:44 -04:00
}
} ] )
2015-11-20 05:59:32 -05:00
end
2016-06-21 05:26:44 -04:00
end
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
context 'when downloading an lfs object that is assigned to other project' do
before do
public_project . lfs_objects << lfs_object
end
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
it 'responds with status 200 and error message' do
response = router . try_call
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
expect ( response_body ) . to eq ( 'objects' = > [
{ 'oid' = > sample_oid ,
'size' = > sample_size ,
'error' = > {
'code' = > 404 ,
'message' = > " Object does not exist on the server or you don't have permissions to access it " ,
}
} ] )
2015-11-20 05:59:32 -05:00
end
2016-06-21 05:26:44 -04:00
end
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
context 'when downloading a lfs object that does not exist' do
before do
body = { 'operation' = > 'download' ,
'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078
} ]
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
end
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
it " responds with status 200 and error message " do
response = router . try_call
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
expect ( response_body ) . to eq ( 'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078 ,
'error' = > {
'code' = > 404 ,
'message' = > " Object does not exist on the server or you don't have permissions to access it " ,
}
} ] )
2015-11-20 05:59:32 -05:00
end
2016-06-21 05:26:44 -04:00
end
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
context 'when downloading one new and one existing lfs object' do
before do
body = { 'operation' = > 'download' ,
'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078
} ,
{ 'oid' = > sample_oid ,
'size' = > sample_size
}
]
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
project . lfs_objects << lfs_object
end
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
it " responds with status 200 with upload hypermedia link for the new object " do
response = router . try_call
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
expect ( response_body ) . to eq ( 'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078 ,
'error' = > {
'code' = > 404 ,
'message' = > " Object does not exist on the server or you don't have permissions to access it " ,
}
} ,
{ 'oid' = > sample_oid ,
'size' = > sample_size ,
'actions' = > {
'download' = > {
'href' = > " #{ project . http_url_to_repo } /gitlab-lfs/objects/ #{ sample_oid } " ,
'header' = > { 'Authorization' = > auth }
2015-11-20 06:21:41 -05:00
}
2016-06-21 05:26:44 -04:00
}
} ] )
2015-10-12 10:42:14 -04:00
end
end
2016-06-21 05:26:44 -04:00
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
2015-10-12 10:42:14 -04:00
2015-11-20 05:59:32 -05:00
context 'when user does is not member of the project' do
2016-06-21 05:26:44 -04:00
let ( :role ) { :guest }
2015-10-12 10:42:14 -04:00
2015-11-20 05:59:32 -05:00
it 'responds with 403' do
expect ( lfs_router_auth . try_call . first ) . to eq ( 403 )
2015-10-12 10:42:14 -04:00
end
end
2015-11-20 05:59:32 -05:00
context 'when user does not have download access' do
2016-06-21 05:26:44 -04:00
let ( :role ) { :guest }
2015-11-20 05:59:32 -05:00
it 'responds with 403' do
expect ( lfs_router_auth . try_call . first ) . to eq ( 403 )
end
end
end
2016-06-21 05:26:44 -04:00
context 'when CI is authorized' do
let ( :auth ) { 'gitlab-ci-token:password' }
2015-11-20 05:59:32 -05:00
before do
2016-06-21 05:26:44 -04:00
env [ " HTTP_AUTHORIZATION " ] = auth
end
2015-11-20 06:21:41 -05:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'an authorized requests' do
let ( :router ) { lfs_router_ci_auth }
2015-11-20 05:59:32 -05:00
end
2016-06-21 05:26:44 -04:00
end
2015-11-20 05:59:32 -05:00
2016-06-21 05:26:44 -04:00
context 'when user is not authenticated' do
2015-11-20 05:59:32 -05:00
describe 'is accessing public project' do
2015-10-12 10:42:14 -04:00
before do
public_project . lfs_objects << lfs_object
end
2015-11-20 05:59:32 -05:00
it 'responds with status 200 and href to download' do
response = lfs_router_public_noauth . try_call
2015-10-12 10:42:14 -04:00
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
2015-11-20 06:21:41 -05:00
expect ( response_body ) . to eq ( 'objects' = > [
{ 'oid' = > sample_oid ,
'size' = > sample_size ,
'actions' = > {
'download' = > {
'href' = > " #{ public_project . http_url_to_repo } /gitlab-lfs/objects/ #{ sample_oid } " ,
'header' = > { }
}
}
} ] )
2015-11-20 05:59:32 -05:00
end
end
2015-10-12 10:42:14 -04:00
2015-11-20 05:59:32 -05:00
describe 'is accessing non-public project' do
before do
project . lfs_objects << lfs_object
end
2015-10-12 10:42:14 -04:00
2015-11-20 05:59:32 -05:00
it 'responds with authorization required' do
expect ( lfs_router_noauth . try_call . first ) . to eq ( 401 )
2015-10-12 10:42:14 -04:00
end
end
end
2015-11-20 05:59:32 -05:00
end
2015-10-12 10:42:14 -04:00
2015-11-20 05:59:32 -05:00
describe 'upload' do
2016-06-21 05:26:44 -04:00
before do
body = { 'operation' = > 'upload' ,
'objects' = > [
{ 'oid' = > sample_oid ,
'size' = > sample_size
} ]
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
end
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
describe 'when request is authenticated' do
2015-11-20 05:59:32 -05:00
describe 'when user has project push access' do
before do
@auth = authorize ( user )
env [ " HTTP_AUTHORIZATION " ] = @auth
2015-11-20 06:21:41 -05:00
project . team << [ user , :developer ]
2015-11-20 05:59:32 -05:00
end
context 'when pushing an lfs object that already exists' do
before do
public_project . lfs_objects << lfs_object
end
it " responds with status 200 and links the object to the project " do
response_body = lfs_router_auth . try_call . last
response = ActiveSupport :: JSON . decode ( response_body . first )
expect ( response [ 'objects' ] ) . to be_kind_of ( Array )
expect ( response [ 'objects' ] . first [ 'oid' ] ) . to eq ( sample_oid )
expect ( response [ 'objects' ] . first [ 'size' ] ) . to eq ( sample_size )
2016-05-23 19:37:59 -04:00
expect ( lfs_object . projects . pluck ( :id ) ) . not_to include ( project . id )
2015-11-20 05:59:32 -05:00
expect ( lfs_object . projects . pluck ( :id ) ) . to include ( public_project . id )
2015-11-20 06:21:41 -05:00
expect ( response [ 'objects' ] . first [ 'actions' ] [ 'upload' ] [ 'href' ] ) . to eq ( " #{ Gitlab . config . gitlab . url } / #{ project . path_with_namespace } .git/gitlab-lfs/objects/ #{ sample_oid } / #{ sample_size } " )
expect ( response [ 'objects' ] . first [ 'actions' ] [ 'upload' ] [ 'header' ] ) . to eq ( 'Authorization' = > @auth )
2015-11-20 05:59:32 -05:00
end
end
context 'when pushing a lfs object that does not exist' do
before do
2015-11-20 06:21:41 -05:00
body = { 'operation' = > 'upload' ,
'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078
} ]
} . to_json
2015-11-20 05:59:32 -05:00
env [ 'rack.input' ] = StringIO . new ( body )
end
it " responds with status 200 and upload hypermedia link " do
response = lfs_router_auth . try_call
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
expect ( response_body [ 'objects' ] ) . to be_kind_of ( Array )
expect ( response_body [ 'objects' ] . first [ 'oid' ] ) . to eq ( " 91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897 " )
expect ( response_body [ 'objects' ] . first [ 'size' ] ) . to eq ( 1575078 )
expect ( lfs_object . projects . pluck ( :id ) ) . not_to include ( project . id )
2015-11-20 06:21:41 -05:00
expect ( response_body [ 'objects' ] . first [ 'actions' ] [ 'upload' ] [ 'href' ] ) . to eq ( " #{ Gitlab . config . gitlab . url } / #{ project . path_with_namespace } .git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078 " )
expect ( response_body [ 'objects' ] . first [ 'actions' ] [ 'upload' ] [ 'header' ] ) . to eq ( 'Authorization' = > @auth )
2015-11-20 05:59:32 -05:00
end
end
context 'when pushing one new and one existing lfs object' do
before do
2015-11-20 06:21:41 -05:00
body = { 'operation' = > 'upload' ,
'objects' = > [
{ 'oid' = > '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' ,
'size' = > 1575078
} ,
{ 'oid' = > sample_oid ,
'size' = > sample_size
}
]
2015-11-20 05:59:32 -05:00
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
2015-11-20 06:21:41 -05:00
project . lfs_objects << lfs_object
2015-11-20 05:59:32 -05:00
end
it " responds with status 200 with upload hypermedia link for the new object " do
response = lfs_router_auth . try_call
expect ( response . first ) . to eq ( 200 )
response_body = ActiveSupport :: JSON . decode ( response . last . first )
expect ( response_body [ 'objects' ] ) . to be_kind_of ( Array )
expect ( response_body [ 'objects' ] . first [ 'oid' ] ) . to eq ( " 91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897 " )
expect ( response_body [ 'objects' ] . first [ 'size' ] ) . to eq ( 1575078 )
2015-11-20 06:21:41 -05:00
expect ( response_body [ 'objects' ] . first [ 'actions' ] [ 'upload' ] [ 'href' ] ) . to eq ( " #{ Gitlab . config . gitlab . url } / #{ project . path_with_namespace } .git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078 " )
expect ( response_body [ 'objects' ] . first [ 'actions' ] [ 'upload' ] [ 'header' ] ) . to eq ( " Authorization " = > @auth )
2015-11-20 05:59:32 -05:00
expect ( response_body [ 'objects' ] . last [ 'oid' ] ) . to eq ( sample_oid )
expect ( response_body [ 'objects' ] . last [ 'size' ] ) . to eq ( sample_size )
2016-05-23 19:37:59 -04:00
expect ( response_body [ 'objects' ] . last ) . not_to have_key ( 'actions' )
2015-11-20 05:59:32 -05:00
end
end
end
context 'when user does not have push access' do
it 'responds with 403' do
expect ( lfs_router_auth . try_call . first ) . to eq ( 403 )
end
end
2015-11-19 13:22:46 -05:00
2016-06-21 05:26:44 -04:00
context 'when CI is authorized' do
it 'responds with 401' do
expect ( lfs_router_ci_auth . try_call . first ) . to eq ( 401 )
end
2015-10-12 10:42:14 -04:00
end
2016-06-21 05:26:44 -04:00
end
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
context 'when user is not authenticated' do
2015-11-20 05:59:32 -05:00
context 'when user has push access' do
before do
project . team << [ user , :master ]
end
it " responds with status 401 " do
expect ( lfs_router_public_noauth . try_call . first ) . to eq ( 401 )
end
2015-10-12 10:42:14 -04:00
end
2015-11-20 05:59:32 -05:00
context 'when user does not have push access' do
it " responds with status 401 " do
expect ( lfs_router_public_noauth . try_call . first ) . to eq ( 401 )
end
2015-10-12 10:42:14 -04:00
end
end
2016-06-21 05:26:44 -04:00
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
2015-10-12 10:42:14 -04:00
end
2015-11-20 05:59:32 -05:00
describe 'unsupported' do
before do
2015-11-20 06:21:41 -05:00
body = { 'operation' = > 'other' ,
'objects' = > [
{ 'oid' = > sample_oid ,
'size' = > sample_size
} ]
2015-11-20 05:59:32 -05:00
} . to_json
env [ 'rack.input' ] = StringIO . new ( body )
end
it 'responds with status 404' do
expect ( lfs_router_public_noauth . try_call . first ) . to eq ( 404 )
end
end
2015-10-12 10:42:14 -04:00
end
describe 'when pushing a lfs object' do
before do
enable_lfs
env [ 'REQUEST_METHOD' ] = 'PUT'
end
2016-06-21 05:26:44 -04:00
shared_examples 'unauthorized' 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 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
2015-10-12 10:42:14 -04:00
before do
2016-06-21 05:26:44 -04:00
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 "
2015-10-12 10:42:14 -04:00
end
2016-06-21 05:26:44 -04:00
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
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
2015-10-12 10:42:14 -04:00
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
2016-06-21 05:26:44 -04:00
describe 'and user does not have push access' do
let ( :router ) { lfs_router_auth }
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'forbidden'
2015-10-12 10:42:14 -04:00
end
end
2016-06-21 05:26:44 -04:00
context 'when CI is authenticated' do
let ( :router ) { lfs_router_ci_auth }
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'unauthorized'
end
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
context 'for unauthenticated' do
let ( :router ) { new_lfs_router ( project ) }
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'unauthorized'
2015-10-12 10:42:14 -04:00
end
end
2016-06-21 05:26:44 -04:00
describe 'to a forked project' do
2015-10-12 10:42:14 -04:00
let ( :forked_project ) { fork_project ( public_project , user ) }
2016-06-21 05:26:44 -04:00
describe 'when user is authenticated' do
describe 'when user has push access to the project' do
before do
forked_project . team << [ user_two , :developer ]
end
2015-10-12 10:42:14 -04:00
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 200, location of lfs store and object details' do
json_response = ActiveSupport :: JSON . decode ( lfs_router_forked_auth . try_call . last . first )
expect ( lfs_router_forked_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 ( forked_project )
end
it 'responds with status 200 and lfs object is linked to the source project' do
expect ( lfs_router_forked_auth . try_call . first ) . to eq ( 200 )
expect ( lfs_object . projects . pluck ( :id ) ) . to include ( public_project . id )
end
end
end
2016-06-21 05:26:44 -04:00
describe 'and user does not have push access' do
let ( :router ) { lfs_router_forked_auth }
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'forbidden'
2015-10-12 10:42:14 -04:00
end
end
2016-06-21 05:26:44 -04:00
context 'when CI is authenticated' do
let ( :router ) { lfs_router_forked_ci_auth }
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'unauthorized'
end
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
context 'for unauthenticated' do
let ( :router ) { lfs_router_forked_noauth }
2015-10-12 10:42:14 -04:00
2016-06-21 05:26:44 -04:00
it_behaves_like 'unauthorized'
2015-10-12 10:42:14 -04:00
end
describe 'and second project not related to fork or a source project' do
let ( :second_project ) { create ( :project ) }
2016-06-03 07:57:40 -04:00
let ( :lfs_router_second_project ) { new_lfs_router ( second_project , user : user ) }
2015-10-12 10:42:14 -04:00
before do
public_project . lfs_objects << lfs_object
headers_for_upload_finalize ( second_project )
end
context 'when pushing the same lfs object to the second project' do
before do
second_project . team << [ user , :master ]
end
it 'responds with 200 and links the lfs object to the project' do
expect ( lfs_router_second_project . try_call . first ) . to eq ( 200 )
expect ( lfs_object . projects . pluck ( :id ) ) . to include ( second_project . id , public_project . id )
end
end
end
end
end
def enable_lfs
allow ( Gitlab . config . lfs ) . to receive ( :enabled ) . and_return ( true )
end
def authorize ( user )
ActionController :: HttpAuthentication :: Basic . encode_credentials ( user . username , user . password )
end
2016-06-03 07:57:40 -04:00
def new_lfs_router ( project , user : nil , ci : false )
Gitlab :: Lfs :: Router . new ( project , user , ci , request )
2015-10-12 10:42:14 -04:00
end
def header_for_upload_authorize ( project )
env [ " PATH_INFO " ] = " #{ project . repository . path_with_namespace } .git/gitlab-lfs/objects/ #{ sample_oid } / #{ sample_size } /authorize "
end
def headers_for_upload_finalize ( project )
env [ " PATH_INFO " ] = " #{ project . repository . path_with_namespace } .git/gitlab-lfs/objects/ #{ sample_oid } / #{ sample_size } "
env [ " HTTP_X_GITLAB_LFS_TMP " ] = " #{ sample_oid } 6e561c9d4 "
end
def fork_project ( project , user , object = nil )
allow ( RepositoryForkWorker ) . to receive ( :perform_async ) . and_return ( true )
Projects :: ForkService . new ( project , user , { } ) . execute
end
end