diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-21 03:13:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-21 03:13:46 +0300 |
commit | 4aa6fba6d825b88d23ff37668e78c851bec102b0 (patch) | |
tree | 2588fec6fc68f27fbfc23e89daf9b9af34d5466b /spec/lib | |
parent | faf60c19a9a1a29ce07d1b51ea3a69466e7129f3 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/lib')
-rw-r--r-- | spec/lib/api/entities/group_spec.rb | 24 | ||||
-rw-r--r-- | spec/lib/api/helpers_spec.rb | 61 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/sbom/cyclonedx_properties_spec.rb | 225 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb | 50 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/sbom/source/trivy_spec.rb | 25 |
5 files changed, 299 insertions, 86 deletions
diff --git a/spec/lib/api/entities/group_spec.rb b/spec/lib/api/entities/group_spec.rb new file mode 100644 index 00000000000..270ac323c7d --- /dev/null +++ b/spec/lib/api/entities/group_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe API::Entities::Group, feature_category: :groups_and_projects do + let_it_be(:group) do + base_group = create(:group) { |g| create(:project_statistics, namespace_id: g.id) } + Group.with_statistics.find(base_group.id) + end + + subject(:json) { described_class.new(group, { with_custom_attributes: true, statistics: true }).as_json } + + it 'returns expected data' do + expect(json.keys).to( + include( + :organization_id, :path, :description, :visibility, :share_with_group_lock, :require_two_factor_authentication, + :two_factor_grace_period, :project_creation_level, :auto_devops_enabled, + :subgroup_creation_level, :emails_disabled, :emails_enabled, :lfs_enabled, :default_branch_protection, + :default_branch_protection_defaults, :avatar_url, :request_access_enabled, :full_name, :full_path, :created_at, + :parent_id, :organization_id, :shared_runners_setting, :custom_attributes, :statistics + ) + ) + end +end diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb index c76694b60d3..eb7727529cc 100644 --- a/spec/lib/api/helpers_spec.rb +++ b/spec/lib/api/helpers_spec.rb @@ -406,6 +406,37 @@ RSpec.describe API::Helpers, feature_category: :shared do end end + describe '#find_organization!' do + let_it_be(:organization) { create(:organization) } + let_it_be(:user) { create(:user) } + + before do + allow(helper).to receive(:current_user).and_return(user) + allow(helper).to receive(:initial_current_user).and_return(user) + end + + context 'when user is authenticated' do + it 'returns requested organization' do + expect(helper.find_organization!(organization.id)).to eq(organization) + end + end + + context 'when user is not authenticated' do + let(:user) { nil } + + it 'returns requested organization' do + expect(helper.find_organization!(organization.id)).to eq(organization) + end + end + + context 'when organization does not exist' do + it 'returns nil' do + expect(helper).to receive(:render_api_error!).with('404 Organization Not Found', 404) + expect(helper.find_organization!(non_existing_record_id)).to be_nil + end + end + end + describe '#find_group!' do let_it_be(:group) { create(:group, :public) } let_it_be(:user) { create(:user) } @@ -457,7 +488,7 @@ RSpec.describe API::Helpers, feature_category: :shared do end end - context 'support for IDs and paths as arguments' do + context 'with support for IDs and paths as arguments' do let_it_be(:group) { create(:group) } let(:user) { group.first_owner } @@ -503,6 +534,34 @@ RSpec.describe API::Helpers, feature_category: :shared do it_behaves_like 'group finder' end end + + context 'with support for organization as an argument' do + let_it_be(:group) { create(:group) } + let_it_be(:organization) { create(:organization) } + + before do + allow(helper).to receive(:current_user).and_return(group.first_owner) + allow(helper).to receive(:job_token_authentication?).and_return(false) + allow(helper).to receive(:authenticate_non_public?).and_return(false) + end + + subject { helper.find_group!(group.id, organization) } + + context 'when group exists in the organization' do + before do + group.update!(organization: organization) + end + + it { is_expected.to eq(group) } + end + + context 'when group does not exist in the organization' do + it 'returns nil' do + expect(helper).to receive(:render_api_error!).with('404 Group Not Found', 404) + is_expected.to be_nil + end + end + end end describe '#find_group_by_full_path!' do diff --git a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_properties_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_properties_spec.rb index 2c57106b07c..9718d16756c 100644 --- a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_properties_spec.rb +++ b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_properties_spec.rb @@ -3,118 +3,173 @@ require 'fast_spec_helper' RSpec.describe Gitlab::Ci::Parsers::Sbom::CyclonedxProperties, feature_category: :dependency_management do - subject(:parse_source_from_properties) { described_class.parse_source(properties) } + shared_examples 'handling invalid properties' do + context 'when properties are nil' do + let(:properties) { nil } - context 'when properties are nil' do - let(:properties) { nil } + it { is_expected.to be_nil } + end + + context 'when report does not have valid properties' do + let(:properties) { ['name' => 'foo', 'value' => 'bar'] } - it { is_expected.to be_nil } + it { is_expected.to be_nil } + end end - context 'when report does not have gitlab properties' do - let(:properties) { ['name' => 'foo', 'value' => 'bar'] } + describe '#parse_source' do + subject(:parse_source_from_properties) { described_class.parse_source(properties) } - it { is_expected.to be_nil } - end + it_behaves_like 'handling invalid properties' - context 'when schema_version is missing' do - let(:properties) do - [ - { 'name' => 'gitlab:dependency_scanning:dependency_file', 'value' => 'package-lock.json' }, - { 'name' => 'gitlab:dependency_scanning:package_manager_name', 'value' => 'npm' }, - { 'name' => 'gitlab:dependency_scanning:language', 'value' => 'JavaScript' } - ] - end + context 'when schema_version is missing' do + let(:properties) do + [ + { 'name' => 'gitlab:dependency_scanning:dependency_file', 'value' => 'package-lock.json' }, + { 'name' => 'gitlab:dependency_scanning:package_manager_name', 'value' => 'npm' }, + { 'name' => 'gitlab:dependency_scanning:language', 'value' => 'JavaScript' } + ] + end - it { is_expected.to be_nil } - end + it { is_expected.to be_nil } + end - context 'when schema version is unsupported' do - let(:properties) do - [ - { 'name' => 'gitlab:meta:schema_version', 'value' => '2' }, - { 'name' => 'gitlab:dependency_scanning:dependency_file', 'value' => 'package-lock.json' }, - { 'name' => 'gitlab:dependency_scanning:package_manager_name', 'value' => 'npm' }, - { 'name' => 'gitlab:dependency_scanning:language', 'value' => 'JavaScript' } - ] + context 'when schema version is unsupported' do + let(:properties) do + [ + { 'name' => 'gitlab:meta:schema_version', 'value' => '2' }, + { 'name' => 'gitlab:dependency_scanning:dependency_file', 'value' => 'package-lock.json' }, + { 'name' => 'gitlab:dependency_scanning:package_manager_name', 'value' => 'npm' }, + { 'name' => 'gitlab:dependency_scanning:language', 'value' => 'JavaScript' } + ] + end + + it { is_expected.to be_nil } end - it { is_expected.to be_nil } - end + context 'when no dependency_scanning or container_scanning properties are present' do + let(:properties) do + [ + { 'name' => 'gitlab:meta:schema_version', 'value' => '1' }, + { 'name' => 'gitlab::aquasecurity:trivy:FilePath', 'value' => '1' } + ] + end - context 'when no dependency_scanning or container_scanning properties are present' do - let(:properties) do - [ - { 'name' => 'gitlab:meta:schema_version', 'value' => '1' } - ] + it 'does not call source parsers' do + expect(Gitlab::Ci::Parsers::Sbom::Source::DependencyScanning).not_to receive(:source) + expect(Gitlab::Ci::Parsers::Sbom::Source::ContainerScanning).not_to receive(:source) + + parse_source_from_properties + end end - it 'does not call source parsers' do - expect(Gitlab::Ci::Parsers::Sbom::Source::DependencyScanning).not_to receive(:source) - expect(Gitlab::Ci::Parsers::Sbom::Source::ContainerScanning).not_to receive(:source) + context 'when dependency_scanning properties are present' do + let(:properties) do + [ + { 'name' => 'gitlab:meta:schema_version', 'value' => '1' }, + { 'name' => 'gitlab:dependency_scanning:category', 'value' => 'development' }, + { 'name' => 'gitlab:dependency_scanning:input_file:path', 'value' => 'package-lock.json' }, + { 'name' => 'gitlab:dependency_scanning:source_file:path', 'value' => 'package.json' }, + { 'name' => 'gitlab:dependency_scanning:package_manager:name', 'value' => 'npm' }, + { 'name' => 'gitlab:dependency_scanning:language:name', 'value' => 'JavaScript' }, + { 'name' => 'gitlab:dependency_scanning:unsupported_property', 'value' => 'Should be ignored' } + ] + end + + let(:expected_input) do + { + 'category' => 'development', + 'input_file' => { 'path' => 'package-lock.json' }, + 'source_file' => { 'path' => 'package.json' }, + 'package_manager' => { 'name' => 'npm' }, + 'language' => { 'name' => 'JavaScript' } + } + end - parse_source_from_properties - end - end + it 'passes only supported properties to the dependency scanning parser' do + expect(Gitlab::Ci::Parsers::Sbom::Source::DependencyScanning).to receive(:source).with(expected_input) - context 'when dependency_scanning properties are present' do - let(:properties) do - [ - { 'name' => 'gitlab:meta:schema_version', 'value' => '1' }, - { 'name' => 'gitlab:dependency_scanning:category', 'value' => 'development' }, - { 'name' => 'gitlab:dependency_scanning:input_file:path', 'value' => 'package-lock.json' }, - { 'name' => 'gitlab:dependency_scanning:source_file:path', 'value' => 'package.json' }, - { 'name' => 'gitlab:dependency_scanning:package_manager:name', 'value' => 'npm' }, - { 'name' => 'gitlab:dependency_scanning:language:name', 'value' => 'JavaScript' }, - { 'name' => 'gitlab:dependency_scanning:unsupported_property', 'value' => 'Should be ignored' } - ] + parse_source_from_properties + end end - let(:expected_input) do - { - 'category' => 'development', - 'input_file' => { 'path' => 'package-lock.json' }, - 'source_file' => { 'path' => 'package.json' }, - 'package_manager' => { 'name' => 'npm' }, - 'language' => { 'name' => 'JavaScript' } - } - end + context 'when container_scanning properties are present' do + let(:properties) do + [ + { 'name' => 'gitlab:meta:schema_version', 'value' => '1' }, + { 'name' => 'gitlab:container_scanning:image:name', 'value' => 'photon' }, + { 'name' => 'gitlab:container_scanning:image:tag', 'value' => '5.0-20231007' }, + { 'name' => 'gitlab:container_scanning:operating_system:name', 'value' => 'Photon OS' }, + { 'name' => 'gitlab:container_scanning:operating_system:version', 'value' => '5.0' } + ] + end + + let(:expected_input) do + { + 'image' => { + 'name' => 'photon', + 'tag' => '5.0-20231007' + }, + 'operating_system' => { + 'name' => 'Photon OS', + 'version' => '5.0' + } + } + end - it 'passes only supported properties to the dependency scanning parser' do - expect(Gitlab::Ci::Parsers::Sbom::Source::DependencyScanning).to receive(:source).with(expected_input) + it 'passes only supported properties to the container scanning parser' do + expect(Gitlab::Ci::Parsers::Sbom::Source::ContainerScanning).to receive(:source).with(expected_input) - parse_source_from_properties + parse_source_from_properties + end end end - context 'when container_scanning properties are present' do - let(:properties) do - [ - { 'name' => 'gitlab:meta:schema_version', 'value' => '1' }, - { 'name' => 'gitlab:container_scanning:image:name', 'value' => 'photon' }, - { 'name' => 'gitlab:container_scanning:image:tag', 'value' => '5.0-20231007' }, - { 'name' => 'gitlab:container_scanning:operating_system:name', 'value' => 'Photon OS' }, - { 'name' => 'gitlab:container_scanning:operating_system:version', 'value' => '5.0' } - ] + describe '#parse_trivy_source' do + subject(:parse_trivy_source_from_properties) { described_class.parse_trivy_source(properties) } + + it_behaves_like 'handling invalid properties' + + context 'when no trivy properties are present' do + let(:properties) do + [ + { 'name' => 'gitlab:meta:schema_version', 'value' => '1' }, + { 'name' => 'gitlab::aquasecurity:trivy:FilePath', 'value' => '1' } + ] + end + + it 'does not call source parsers' do + expect(Gitlab::Ci::Parsers::Sbom::Source::Trivy).not_to receive(:source) + + parse_trivy_source_from_properties + end end - let(:expected_input) do - { - 'image' => { - 'name' => 'photon', - 'tag' => '5.0-20231007' - }, - 'operating_system' => { - 'name' => 'Photon OS', - 'version' => '5.0' + context 'when trivy properties are present' do + let(:properties) do + [ + { 'name' => 'aquasecurity:trivy:PkgID', 'value' => 'sha256:47ce8fad8..' }, + { 'name' => 'aquasecurity:trivy:LayerDigest', + 'value' => 'registry.test.com/atiwari71/container-scanning-test/main@sha256:e14a4bcf..' }, + { 'name' => 'aquasecurity:trivy:LayerDiffID', 'value' => 'sha256:94dd7d531fa..' }, + { 'name' => 'aquasecurity:trivy:SrcEpoch', 'value' => 'sha256:5d20c808c..' } + ] + end + + let(:expected_input) do + { + 'PkgID' => 'sha256:47ce8fad8..', + 'LayerDigest' => 'registry.test.com/atiwari71/container-scanning-test/main@sha256:e14a4bcf..', + 'LayerDiffID' => 'sha256:94dd7d531fa..', + 'SrcEpoch' => 'sha256:5d20c808c..' } - } - end + end - it 'passes only supported properties to the container scanning parser' do - expect(Gitlab::Ci::Parsers::Sbom::Source::ContainerScanning).to receive(:source).with(expected_input) + it 'passes only supported properties to the container scanning parser' do + expect(Gitlab::Ci::Parsers::Sbom::Source::Trivy).to receive(:source).with(expected_input) - parse_source_from_properties + parse_trivy_source_from_properties + end end end end diff --git a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb index 9c8402faf77..6a6fe59bce1 100644 --- a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb +++ b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb @@ -125,6 +125,56 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen parse! end + context 'when component is trivy type' do + let(:parsed_properties) do + { + 'PkgID' => 'adduser@3.134', + 'PkgType' => 'debian' + } + end + + let(:components) do + [ + { + # Trivy component + "bom-ref" => "0eda252d-d8a4-4250-b816-b6314f029063", + "type" => "library", + "name" => "analyzer", + "purl" => "pkg:gem/activesupport@5.1.4", + "properties" => [ + { + "name" => "aquasecurity:trivy:PkgID", + "value" => "apt@2.6.1" + }, + { + "name" => "aquasecurity:trivy:PkgType", + "value" => "debian" + } + ] + } + ] + end + + before do + allow(properties_parser).to receive(:parse_trivy_source).and_return(parsed_properties) + stub_const('Gitlab::Ci::Parsers::Sbom::CyclonedxProperties', properties_parser) + end + + it 'adds each component, ignoring unused attributes' do + expect(report).to receive(:add_component) + .with( + an_object_having_attributes( + component_type: "library", + properties: parsed_properties, + purl: an_object_having_attributes( + type: "gem" + ) + ) + ) + parse! + end + end + context 'when a component has an invalid purl' do before do components.push( diff --git a/spec/lib/gitlab/ci/parsers/sbom/source/trivy_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/source/trivy_spec.rb new file mode 100644 index 00000000000..460ca4f28a1 --- /dev/null +++ b/spec/lib/gitlab/ci/parsers/sbom/source/trivy_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +RSpec.describe Gitlab::Ci::Parsers::Sbom::Source::Trivy, feature_category: :dependency_management do + subject { described_class.source(property_data) } + + context 'when all property data is present' do + let(:property_data) do + { + 'PkgID' => 'sha256:47ce8fad8..', + 'LayerDigest' => 'registry.test.com/atiwari71/container-scanning-test/main@sha256:e14a4bcf..', + 'LayerDiffID' => 'sha256:94dd7d531fa..', + 'SrcEpoch' => 'sha256:5d20c808c..' + } + end + + it 'returns expected source data' do + is_expected.to have_attributes( + source_type: :trivy, + data: property_data + ) + end + end +end |