summaryrefslogtreecommitdiff
path: root/spec/requests/api/nuget_group_packages_spec.rb
blob: 9de612f7bc72e60084219b60240f4ebbd3578282 (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# frozen_string_literal: true
require 'spec_helper'

RSpec.describe API::NugetGroupPackages, feature_category: :package_registry do
  include_context 'nuget api setup'

  using RSpec::Parameterized::TableSyntax

  let_it_be_with_reload(:group) { create(:group) }
  let_it_be_with_reload(:subgroup) { create(:group, parent: group) }
  let_it_be_with_reload(:project) { create(:project, namespace: subgroup) }
  let_it_be(:deploy_token) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
  let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token, group: group) }

  let(:snowplow_gitlab_standard_context) { { namespace: project.group, property: 'i_package_nuget_user' } }
  let(:target_type) { 'groups' }

  shared_examples 'handling all endpoints' do
    describe 'GET /api/v4/groups/:id/-/packages/nuget' do
      it_behaves_like 'handling nuget service requests', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do
        let(:url) { "/groups/#{target.id}/-/packages/nuget/index.json" }
      end
    end

    describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/index' do
      it_behaves_like 'handling nuget metadata requests with package name', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do
        let(:url) { "/groups/#{target.id}/-/packages/nuget/metadata/#{package_name}/index.json" }
      end
    end

    describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/*package_version' do
      it_behaves_like 'handling nuget metadata requests with package name and package version', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do
        let(:url) { "/groups/#{target.id}/-/packages/nuget/metadata/#{package_name}/#{package.version}.json" }
      end
    end

    describe 'GET /api/v4/groups/:id/-/packages/nuget/query' do
      it_behaves_like 'handling nuget search requests', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do
        let(:url) { "/groups/#{target.id}/-/packages/nuget/query?#{query_parameters.to_query}" }
      end
    end
  end

  context 'with a subgroup' do
    # Bug: deploy tokens at parent group will not see the subgroup.
    # https://gitlab.com/gitlab-org/gitlab/-/issues/285495
    let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token, group: subgroup) }

    let(:target) { subgroup }

    it_behaves_like 'handling all endpoints'

    def update_visibility_to(visibility)
      project.update!(visibility_level: visibility)
      subgroup.update!(visibility_level: visibility)
    end
  end

  context 'a group' do
    let(:target) { group }
    let(:snowplow_gitlab_standard_context) { { namespace: target, property: 'i_package_nuget_user' } }

    it_behaves_like 'handling all endpoints'

    context 'with dummy packages and anonymous request' do
      let_it_be(:package_name) { 'Dummy.Package' }
      let_it_be(:packages) { create_list(:nuget_package, 5, :with_metadatum, name: package_name, project: project) }
      let_it_be(:tags) { packages.each { |pkg| create(:packages_tag, package: pkg, name: 'test') } }

      let(:search_term) { 'umm' }
      let(:take) { 26 }
      let(:skip) { 0 }
      let(:include_prereleases) { true }
      let(:query_parameters) { { q: search_term, take: take, skip: skip, prerelease: include_prereleases }.compact }

      subject { get api(url), headers: {} }

      shared_examples 'handling mixed visibilities' do
        where(:group_visibility, :subgroup_visibility, :expected_status) do
          'PUBLIC'   | 'PUBLIC'   | :unauthorized
          'PUBLIC'   | 'INTERNAL' | :unauthorized
          'PUBLIC'   | 'PRIVATE'  | :unauthorized
          'INTERNAL' | 'INTERNAL' | :unauthorized
          'INTERNAL' | 'PRIVATE'  | :unauthorized
          'PRIVATE'  | 'PRIVATE'  | :unauthorized
        end

        with_them do
          before do
            project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
            subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false))
            group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false))
          end

          it_behaves_like 'returning response status', params[:expected_status]
        end
      end

      describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/index' do
        it_behaves_like 'handling mixed visibilities' do
          let(:url) { "/groups/#{target.id}/-/packages/nuget/metadata/#{package_name}/index.json" }
        end
      end

      describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/*package_version' do
        it_behaves_like 'handling mixed visibilities' do
          let(:url) { "/groups/#{target.id}/-/packages/nuget/metadata/#{package_name}/#{packages.first.version}.json" }
        end
      end

      describe 'GET /api/v4/groups/:id/-/packages/nuget/query' do
        it_behaves_like 'handling mixed visibilities' do
          let(:url) { "/groups/#{target.id}/-/packages/nuget/query?#{query_parameters.to_query}" }
        end
      end
    end

    context 'with a reporter of subgroup' do
      let_it_be(:package_name) { 'Dummy.Package' }
      let_it_be(:package) { create(:nuget_package, :with_metadatum, name: package_name, project: project) }

      let(:headers) { basic_auth_header(user.username, personal_access_token.token) }

      subject { get api(url), headers: headers }

      before do
        subgroup.add_reporter(user)
        project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
        subgroup.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
        group.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
      end

      describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/index' do
        let(:url) { "/groups/#{group.id}/-/packages/nuget/metadata/#{package_name}/index.json" }

        it_behaves_like 'returning response status', :forbidden
      end

      describe 'GET /api/v4/groups/:id/-/packages/nuget/metadata/*package_name/*package_version' do
        let(:url) { "/groups/#{group.id}/-/packages/nuget/metadata/#{package_name}/#{package.version}.json" }

        it_behaves_like 'returning response status', :forbidden
      end

      describe 'GET /api/v4/groups/:id/-/packages/nuget/query' do
        let(:search_term) { 'uMmy' }
        let(:take) { 26 }
        let(:skip) { 0 }
        let(:include_prereleases) { false }
        let(:query_parameters) { { q: search_term, take: take, skip: skip, prerelease: include_prereleases }.compact }
        let(:url) { "/groups/#{group.id}/-/packages/nuget/query?#{query_parameters.to_query}" }

        it_behaves_like 'returning response status', :forbidden
      end
    end

    def update_visibility_to(visibility)
      project.update!(visibility_level: visibility)
      subgroup.update!(visibility_level: visibility)
      group.update!(visibility_level: visibility)
    end
  end
end