change_access_spec.rb 6.32 KB
Newer Older
1 2
require 'spec_helper'

3
describe Gitlab::Checks::ChangeAccess do
4 5
  describe '#exec' do
    let(:user) { create(:user) }
6
    let(:project) { create(:project, :repository) }
7
    let(:user_access) { Gitlab::UserAccess.new(user, project: project) }
8 9 10 11
    let(:oldrev) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
    let(:newrev) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
    let(:ref) { 'refs/heads/master' }
    let(:changes) { { oldrev: oldrev, newrev: newrev, ref: ref } }
12
    let(:protocol) { 'ssh' }
13

14 15 16 17 18 19 20 21
    subject do
      described_class.new(
        changes,
        project: project,
        user_access: user_access,
        protocol: protocol
      ).exec
    end
22

23 24 25
    before do
      project.add_developer(user)
    end
26 27

    context 'without failed checks' do
28 29
      it "doesn't raise an error" do
        expect { subject }.not_to raise_error
30 31 32 33
      end
    end

    context 'when the user is not allowed to push code' do
34
      it 'raises an error' do
35 36
        expect(user_access).to receive(:can_do_action?).with(:push_code).and_return(false)

37
        expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You are not allowed to push code to this project.')
38 39 40 41
      end
    end

    context 'tags check' do
42
      let(:ref) { 'refs/tags/v1.0.0' }
43

44
      it 'raises an error if the user is not allowed to update tags' do
45
        allow(user_access).to receive(:can_do_action?).with(:push_code).and_return(true)
46 47
        expect(user_access).to receive(:can_do_action?).with(:admin_project).and_return(false)

48
        expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You are not allowed to change existing tags on this project.')
49
      end
50 51 52 53

      context 'with protected tag' do
        let!(:protected_tag) { create(:protected_tag, project: project, name: 'v*') }

54
        context 'as master' do
55 56 57
          before do
            project.add_master(user)
          end
58

59 60 61 62 63
          context 'deletion' do
            let(:oldrev) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
            let(:newrev) { '0000000000000000000000000000000000000000' }

            it 'is prevented' do
64
              expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, /cannot be deleted/)
65
            end
66 67
          end

68 69 70
          context 'update' do
            let(:oldrev) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
            let(:newrev) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
71

72
            it 'is prevented' do
73
              expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, /cannot be updated/)
74 75
            end
          end
76 77
        end

78 79 80 81
        context 'creation' do
          let(:oldrev) { '0000000000000000000000000000000000000000' }
          let(:newrev) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
          let(:ref) { 'refs/tags/v9.1.0' }
82

83
          it 'prevents creation below access level' do
84
            expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, /allowed to create this tag as it is protected/)
85 86 87
          end

          context 'when user has access' do
88
            let!(:protected_tag) { create(:protected_tag, :developers_can_create, project: project, name: 'v*') }
89

90
            it 'allows tag creation' do
91
              expect { subject }.not_to raise_error
92
            end
93 94 95
          end
        end
      end
96 97
    end

98 99 100 101
    context 'branches check' do
      context 'trying to delete the default branch' do
        let(:newrev) { '0000000000000000000000000000000000000000' }
        let(:ref) { 'refs/heads/master' }
102

103 104
        it 'raises an error' do
          expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'The default branch of a project cannot be deleted.')
105
        end
106 107
      end

108 109 110 111 112
      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
113

114
        it 'raises an error if the user is not allowed to do forced pushes to protected branches' do
115
          expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true)
116

117
          expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You are not allowed to force push code to a protected branch on this project.')
118
        end
119

120
        it 'raises an error if the user is not allowed to merge to protected branches' do
121 122 123
          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)
124

125
          expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You are not allowed to merge code into protected branches on this project.')
126 127
        end

128
        it 'raises an error if the user is not allowed to push to protected branches' do
129
          expect(user_access).to receive(:can_push_to_branch?).and_return(false)
130

131
          expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You are not allowed to push code to protected branches on this project.')
132 133 134 135 136 137 138
        end

        context 'branch deletion' do
          let(:newrev) { '0000000000000000000000000000000000000000' }
          let(:ref) { 'refs/heads/feature' }

          context 'if the user is not allowed to delete protected branches' do
139 140
            it 'raises an error' do
              expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You are not allowed to delete protected branches from this project. Only a project master or owner can delete a protected branch.')
141 142 143 144 145 146 147 148 149 150 151 152
            end
          end

          context 'if the user is allowed to delete protected branches' do
            before do
              project.add_master(user)
            end

            context 'through the web interface' do
              let(:protocol) { 'web' }

              it 'allows branch deletion' do
153
                expect { subject }.not_to raise_error
154 155 156 157
              end
            end

            context 'over SSH or HTTP' do
158 159
              it 'raises an error' do
                expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, 'You can only delete protected branches using the web interface.')
160 161 162
              end
            end
          end
163 164 165 166 167
        end
      end
    end
  end
end