Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
6bc22d95
Commit
6bc22d95
authored
Jun 21, 2016
by
Kamil Trzcinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add test coverage to LFS fetching
parent
2f545a15
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
242 additions
and
289 deletions
+242
-289
lib/gitlab/lfs/router.rb
lib/gitlab/lfs/router.rb
+2
-0
spec/lib/gitlab/lfs/lfs_router_spec.rb
spec/lib/gitlab/lfs/lfs_router_spec.rb
+240
-289
No files found.
lib/gitlab/lfs/router.rb
View file @
6bc22d95
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
...
...
spec/lib/gitlab/lfs/lfs_router_spec.rb
View file @
6bc22d95
...
@@ -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 authenticat
ed'
do
context
'when CI is authoriz
ed'
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
,
:mast
er
]
forked_project
.
team
<<
[
user_two
,
:develop
er
]
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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment