summaryrefslogtreecommitdiff
path: root/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb
blob: 9b2d054f4fcda62a7a9a4649052b4e3d293ea08b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
require 'spec_helper'

describe ControllerWithCrossProjectAccessCheck do
  let(:user) { create(:user) }

  before do
    sign_in user
  end

  render_views

  context 'When reading cross project is not allowed' do
    before do
      allow(Ability).to receive(:allowed).and_call_original
      allow(Ability).to receive(:allowed?)
                          .with(user, :read_cross_project, :global)
                          .and_return(false)
    end

    describe '#requires_cross_project_access' do
      controller(ApplicationController) do
        # `described_class` is not available in this context
        include ControllerWithCrossProjectAccessCheck # rubocop:disable RSpec/DescribedClass

        requires_cross_project_access :index, show: false,
                                              unless: -> { unless_condition },
                                              if: -> { if_condition }

        def index
          head :ok
        end

        def show
          head :ok
        end

        def unless_condition
          false
        end

        def if_condition
          true
        end
      end

      it 'renders a 403 with trying to access a cross project page' do
        message = "This page is unavailable because you are not allowed to read "\
                  "information across multiple projects."

        get :index

        expect(response).to have_gitlab_http_status(403)
        expect(response.body).to match(/#{message}/)
      end

      it 'is skipped when the `if` condition returns false' do
        expect(controller).to receive(:if_condition).and_return(false)

        get :index

        expect(response).to have_gitlab_http_status(200)
      end

      it 'is skipped when the `unless` condition returns true' do
        expect(controller).to receive(:unless_condition).and_return(true)

        get :index

        expect(response).to have_gitlab_http_status(200)
      end

      it 'correctly renders an action that does not require cross project access' do
        get :show, params: { id: 'nothing' }

        expect(response).to have_gitlab_http_status(200)
      end
    end

    describe '#skip_cross_project_access_check' do
      controller(ApplicationController) do
        # `described_class` is not available in this context
        include ControllerWithCrossProjectAccessCheck # rubocop:disable RSpec/DescribedClass

        requires_cross_project_access

        skip_cross_project_access_check index: true, show: false,
                                        unless: -> { unless_condition },
                                        if: -> { if_condition }

        def index
          head :ok
        end

        def show
          head :ok
        end

        def edit
          head :ok
        end

        def unless_condition
          false
        end

        def if_condition
          true
        end
      end

      it 'renders a success when the check is skipped' do
        get :index

        expect(response).to have_gitlab_http_status(200)
      end

      it 'is executed when the `if` condition returns false' do
        expect(controller).to receive(:if_condition).and_return(false)

        get :index

        expect(response).to have_gitlab_http_status(403)
      end

      it 'is executed when the `unless` condition returns true' do
        expect(controller).to receive(:unless_condition).and_return(true)

        get :index

        expect(response).to have_gitlab_http_status(403)
      end

      it 'does not skip the check on an action that is not skipped' do
        get :show, params: { id: 'hello' }

        expect(response).to have_gitlab_http_status(403)
      end

      it 'does not skip the check on an action that was not defined to skip' do
        get :edit, params: { id: 'hello' }

        expect(response).to have_gitlab_http_status(403)
      end
    end
  end
end