2016-08-12 22:27:42 +00:00
require 'spec_helper'
2017-07-10 14:24:02 +00:00
describe Gitlab :: Checks :: ChangeAccess do
2016-08-12 22:27:42 +00:00
describe '#exec' do
let ( :user ) { create ( :user ) }
2017-01-24 23:42:12 +00:00
let ( :project ) { create ( :project , :repository ) }
2016-08-12 22:27:42 +00:00
let ( :user_access ) { Gitlab :: UserAccess . new ( user , project : project ) }
2017-04-03 23:05:51 +00:00
let ( :oldrev ) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
let ( :newrev ) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
let ( :ref ) { 'refs/heads/master' }
let ( :changes ) { { oldrev : oldrev , newrev : newrev , ref : ref } }
2017-03-13 11:31:27 +00:00
let ( :protocol ) { 'ssh' }
2018-10-22 14:49:20 +00:00
let ( :timeout ) { Gitlab :: GitAccess :: INTERNAL_TIMEOUT }
let ( :logger ) { Gitlab :: Checks :: TimedLogger . new ( timeout : timeout ) }
2016-08-12 22:27:42 +00:00
2017-10-17 11:45:59 +00:00
subject ( :change_access ) do
2017-03-13 11:31:27 +00:00
described_class . new (
changes ,
project : project ,
user_access : user_access ,
2018-10-22 14:49:20 +00:00
protocol : protocol ,
logger : logger
2017-08-25 01:30:12 +00:00
)
end
2017-06-14 18:18:56 +00:00
before do
project . add_developer ( user )
end
2016-08-12 22:27:42 +00:00
context 'without failed checks' do
2017-05-19 19:58:45 +00:00
it " doesn't raise an error " do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . not_to raise_error
2016-08-12 22:27:42 +00:00
end
end
2018-10-22 14:49:20 +00:00
context 'when time limit was reached' do
it 'raises a TimeoutError' do
logger = Gitlab :: Checks :: TimedLogger . new ( start_time : timeout . ago , timeout : timeout )
access = described_class . new ( changes ,
project : project ,
user_access : user_access ,
protocol : protocol ,
logger : logger )
expect { access . exec } . to raise_error ( Gitlab :: Checks :: TimedLogger :: TimeoutError )
end
end
2018-02-26 12:32:42 +00:00
context 'when the user is not allowed to push to the repo' do
2017-05-19 19:58:45 +00:00
it 'raises an error' do
2018-03-06 22:30:47 +00:00
expect ( user_access ) . to receive ( :can_do_action? ) . with ( :push_code ) . and_return ( false )
expect ( user_access ) . to receive ( :can_push_to_branch? ) . with ( 'master' ) . and_return ( false )
2016-08-12 22:27:42 +00:00
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You are not allowed to push code to this project.' )
2016-08-12 22:27:42 +00:00
end
end
context 'tags check' do
2017-04-03 23:05:51 +00:00
let ( :ref ) { 'refs/tags/v1.0.0' }
2016-08-12 22:27:42 +00:00
2017-05-19 19:58:45 +00:00
it 'raises an error if the user is not allowed to update tags' do
2018-03-06 22:30:47 +00:00
allow ( user_access ) . to receive ( :can_do_action? ) . with ( :push_code ) . and_return ( true )
2016-08-12 22:27:42 +00:00
expect ( user_access ) . to receive ( :can_do_action? ) . with ( :admin_project ) . and_return ( false )
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You are not allowed to change existing tags on this project.' )
2016-08-12 22:27:42 +00:00
end
2017-03-31 16:57:29 +00:00
context 'with protected tag' do
let! ( :protected_tag ) { create ( :protected_tag , project : project , name : 'v*' ) }
2018-06-04 01:25:38 +00:00
context 'as maintainer' do
2017-06-14 18:18:56 +00:00
before do
2018-07-11 14:36:08 +00:00
project . add_maintainer ( user )
2017-06-14 18:18:56 +00:00
end
2017-03-31 16:57:29 +00:00
2017-04-03 23:05:51 +00:00
context 'deletion' do
let ( :oldrev ) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
let ( :newrev ) { '0000000000000000000000000000000000000000' }
it 'is prevented' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , / cannot be deleted / )
2017-04-03 23:05:51 +00:00
end
2017-03-31 16:57:29 +00:00
end
2017-04-03 23:05:51 +00:00
context 'update' do
let ( :oldrev ) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
let ( :newrev ) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
2017-03-31 16:57:29 +00:00
2017-04-03 23:05:51 +00:00
it 'is prevented' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , / cannot be updated / )
2017-04-03 23:05:51 +00:00
end
end
2017-03-31 16:57:29 +00:00
end
2017-04-03 23:05:51 +00:00
context 'creation' do
let ( :oldrev ) { '0000000000000000000000000000000000000000' }
let ( :newrev ) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
let ( :ref ) { 'refs/tags/v9.1.0' }
2017-03-31 16:57:29 +00:00
2017-04-03 23:05:51 +00:00
it 'prevents creation below access level' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , / allowed to create this tag as it is protected / )
2017-04-03 23:05:51 +00:00
end
context 'when user has access' do
2017-04-04 02:37:22 +00:00
let! ( :protected_tag ) { create ( :protected_tag , :developers_can_create , project : project , name : 'v*' ) }
2017-03-31 16:57:29 +00:00
2017-04-03 23:05:51 +00:00
it 'allows tag creation' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . not_to raise_error
2017-04-03 23:05:51 +00:00
end
2017-03-31 16:57:29 +00:00
end
end
end
2016-08-12 22:27:42 +00:00
end
2017-05-08 07:41:58 +00:00
context 'branches check' do
context 'trying to delete the default branch' do
let ( :newrev ) { '0000000000000000000000000000000000000000' }
let ( :ref ) { 'refs/heads/master' }
2016-08-12 22:27:42 +00:00
2017-05-19 19:58:45 +00:00
it 'raises an error' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'The default branch of a project cannot be deleted.' )
2017-05-08 07:41:58 +00:00
end
2016-08-12 22:27:42 +00:00
end
2017-05-08 07:41:58 +00:00
context 'protected branches check' do
before do
allow ( ProtectedBranch ) . to receive ( :protected? ) . with ( project , 'master' ) . and_return ( true )
allow ( ProtectedBranch ) . to receive ( :protected? ) . with ( project , 'feature' ) . and_return ( true )
end
2016-08-12 22:27:42 +00:00
2017-05-19 19:58:45 +00:00
it 'raises an error if the user is not allowed to do forced pushes to protected branches' do
2017-05-08 07:41:58 +00:00
expect ( Gitlab :: Checks :: ForcePush ) . to receive ( :force_push? ) . and_return ( true )
2016-08-12 22:27:42 +00:00
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You are not allowed to force push code to a protected branch on this project.' )
2017-05-08 07:41:58 +00:00
end
2016-08-12 22:27:42 +00:00
2017-05-19 19:58:45 +00:00
it 'raises an error if the user is not allowed to merge to protected branches' do
2017-05-08 07:41:58 +00:00
expect_any_instance_of ( Gitlab :: Checks :: MatchingMergeRequest ) . to receive ( :match? ) . and_return ( true )
expect ( user_access ) . to receive ( :can_merge_to_branch? ) . and_return ( false )
expect ( user_access ) . to receive ( :can_push_to_branch? ) . and_return ( false )
2016-08-12 22:27:42 +00:00
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You are not allowed to merge code into protected branches on this project.' )
2017-05-08 07:41:58 +00:00
end
2017-05-19 19:58:45 +00:00
it 'raises an error if the user is not allowed to push to protected branches' do
2017-05-08 07:41:58 +00:00
expect ( user_access ) . to receive ( :can_push_to_branch? ) . and_return ( false )
2016-08-12 22:27:42 +00:00
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You are not allowed to push code to protected branches on this project.' )
2017-05-08 07:41:58 +00:00
end
2018-07-10 08:42:38 +00:00
context 'when project repository is empty' do
let ( :project ) { create ( :project ) }
it 'raises an error if the user is not allowed to push to protected branches' do
expect ( user_access ) . to receive ( :can_push_to_branch? ) . and_return ( false )
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , / Ask a project Owner or Maintainer to create a default branch / )
end
end
2017-05-08 07:41:58 +00:00
context 'branch deletion' do
let ( :newrev ) { '0000000000000000000000000000000000000000' }
let ( :ref ) { 'refs/heads/feature' }
context 'if the user is not allowed to delete protected branches' do
2017-05-19 19:58:45 +00:00
it 'raises an error' do
2018-06-04 01:25:38 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You are not allowed to delete protected branches from this project. Only a project maintainer or owner can delete a protected branch.' )
2017-05-08 07:41:58 +00:00
end
end
context 'if the user is allowed to delete protected branches' do
before do
2018-07-11 14:36:08 +00:00
project . add_maintainer ( user )
2017-05-08 07:41:58 +00:00
end
context 'through the web interface' do
let ( :protocol ) { 'web' }
it 'allows branch deletion' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . not_to raise_error
2017-05-08 07:41:58 +00:00
end
end
context 'over SSH or HTTP' do
2017-05-19 19:58:45 +00:00
it 'raises an error' do
2017-10-17 11:45:59 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , 'You can only delete protected branches using the web interface.' )
2017-05-08 07:41:58 +00:00
end
end
end
2016-08-12 22:27:42 +00:00
end
end
end
2017-08-25 01:30:12 +00:00
context 'LFS integrity check' do
2017-11-08 12:27:01 +00:00
it 'fails if any LFS blobs are missing' do
allow_any_instance_of ( Gitlab :: Checks :: LfsIntegrity ) . to receive ( :objects_missing? ) . and_return ( true )
2017-08-25 01:30:12 +00:00
2017-11-08 12:27:01 +00:00
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , / LFS objects are missing / )
2017-08-25 01:30:12 +00:00
end
2017-11-08 12:27:01 +00:00
it 'succeeds if LFS objects have already been uploaded' do
allow_any_instance_of ( Gitlab :: Checks :: LfsIntegrity ) . to receive ( :objects_missing? ) . and_return ( false )
2017-08-25 01:30:12 +00:00
2017-11-08 12:27:01 +00:00
expect { subject . exec } . not_to raise_error
2017-08-25 01:30:12 +00:00
end
end
2018-02-07 13:00:53 +00:00
context 'LFS file lock check' do
let ( :owner ) { create ( :user ) }
let! ( :lock ) { create ( :lfs_file_lock , user : owner , project : project , path : 'README' ) }
before do
allow ( project . repository ) . to receive ( :new_commits ) . and_return (
project . repository . commits_between ( 'be93687618e4b132087f430a4d8fc3a609c9b77c' , '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' )
)
end
context 'with LFS not enabled' do
it 'skips the validation' do
2018-02-15 05:21:17 +00:00
expect_any_instance_of ( Gitlab :: Checks :: CommitCheck ) . not_to receive ( :validate )
2018-02-07 13:00:53 +00:00
subject . exec
end
end
context 'with LFS enabled' do
before do
allow ( project ) . to receive ( :lfs_enabled? ) . and_return ( true )
end
context 'when change is sent by a different user' do
it 'raises an error if the user is not allowed to update the file' do
expect { subject . exec } . to raise_error ( Gitlab :: GitAccess :: UnauthorizedError , " The path 'README' is locked in Git LFS by #{ lock . user . name } " )
end
end
2018-02-15 05:21:17 +00:00
context 'when change is sent by the author of the lock' do
2018-02-07 13:00:53 +00:00
let ( :user ) { owner }
it " doesn't raise any error " do
expect { subject . exec } . not_to raise_error
end
end
end
end
2016-08-12 22:27:42 +00:00
end
end