diff --git a/db/migrate/20230712214613_add_read_dependency_to_member_roles.rb b/db/migrate/20230712214613_add_read_dependency_to_member_roles.rb new file mode 100644 index 0000000000000000000000000000000000000000..c6c9f3a061173b942bb99ec1125765c7a0d5aa20 --- /dev/null +++ b/db/migrate/20230712214613_add_read_dependency_to_member_roles.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddReadDependencyToMemberRoles < Gitlab::Database::Migration[2.1] + def change + add_column :member_roles, :read_dependency, :boolean, default: false, null: false + end +end diff --git a/db/schema_migrations/20230712214613 b/db/schema_migrations/20230712214613 new file mode 100644 index 0000000000000000000000000000000000000000..f9afbe825d699a2bcb6674677640b69a0fbfa67a --- /dev/null +++ b/db/schema_migrations/20230712214613 @@ -0,0 +1 @@ +56415a907d3bba749b9d42b5f37919981e779f0422c86793028d128350875f2d \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 633b2943d1aa6691a4d691cd3cefe1addc09783c..1daa1ed99b6632045ad5c71e5e903107cbee51c3 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -17885,7 +17885,8 @@ CREATE TABLE member_roles ( base_access_level integer NOT NULL, read_code boolean DEFAULT false, read_vulnerability boolean DEFAULT false NOT NULL, - admin_vulnerability boolean DEFAULT false NOT NULL + admin_vulnerability boolean DEFAULT false NOT NULL, + read_dependency boolean DEFAULT false NOT NULL ); CREATE SEQUENCE member_roles_id_seq diff --git a/ee/app/models/members/member_role.rb b/ee/app/models/members/member_role.rb index 2138bb6327dfc2349b0aebef8b83e926a7bc237f..ca93374ab721d696db938b2c0cb0b37e435066e8 100644 --- a/ee/app/models/members/member_role.rb +++ b/ee/app/models/members/member_role.rb @@ -5,6 +5,10 @@ class MemberRole < ApplicationRecord # rubocop:disable Gitlab/NamespacedClass ALL_CUSTOMIZABLE_PERMISSIONS = { read_code: { description: 'Permission to read code', minimal_level: Gitlab::Access::GUEST }, + read_dependency: { + description: 'Permission to read dependency', + minimal_level: Gitlab::Access::GUEST + }, read_vulnerability: { descripition: 'Permission to read vulnerability', minimal_level: Gitlab::Access::GUEST }, admin_vulnerability: { diff --git a/ee/app/policies/ee/project_policy.rb b/ee/app/policies/ee/project_policy.rb index 2cede9edbb9dbfbd39840c0e9a0191751e78a6cf..26ed4b6f19fb9cd825cf55c341cfa017e79a6ece 100644 --- a/ee/app/policies/ee/project_policy.rb +++ b/ee/app/policies/ee/project_policy.rb @@ -233,6 +233,13 @@ module ProjectPolicy @user.custom_permission_for?(project, :admin_vulnerability) end + desc "Custom role on project that enables read dependency" + condition(:role_enables_read_dependency) do + next unless @user.is_a?(User) + + @user.custom_permission_for?(project, :read_dependency) + end + with_scope :subject condition(:suggested_reviewers_available) do @subject.can_suggest_reviewers? @@ -606,6 +613,9 @@ module ProjectPolicy rule { custom_roles_allowed & role_enables_admin_vulnerability }.policy do enable :admin_vulnerability end + rule { custom_roles_allowed & role_enables_read_dependency & dependency_scanning_enabled }.policy do + enable :read_dependencies + end rule { can?(:create_issue) & okrs_enabled }.policy do enable :create_objective diff --git a/ee/spec/policies/project_policy_spec.rb b/ee/spec/policies/project_policy_spec.rb index 61e55788aec491e0c7a25817762b86047134c8b7..92b7fe1bfeb144e2921aa1b49f36be0c6da47f05 100644 --- a/ee/spec/policies/project_policy_spec.rb +++ b/ee/spec/policies/project_policy_spec.rb @@ -2459,6 +2459,7 @@ def expect_private_project_permissions_as_if_non_member let(:member_role_abilities) { {} } let(:allowed_abilities) { [] } let(:current_user) { guest } + let(:licensed_features) { {} } def create_member_role(member, abilities = member_role_abilities) params = abilities.merge(namespace: project.group) @@ -2483,7 +2484,7 @@ def create_member_role(member, abilities = member_role_abilities) context 'with custom_roles license enabled' do before do - stub_licensed_features(custom_roles: true) + stub_licensed_features(licensed_features.merge(custom_roles: true)) end context 'custom role for parent group' do @@ -2552,6 +2553,22 @@ def create_member_role(member, abilities = member_role_abilities) it_behaves_like 'custom roles abilities' end + + context 'for a member role with read_dependency true' do + let(:member_role_abilities) { { read_dependency: true } } + let(:allowed_abilities) { [:read_dependencies] } + let(:licensed_features) { { dependency_scanning: true } } + + it_behaves_like 'custom roles abilities' + end + + context 'for a member role with read_dependency false' do + let(:member_role_abilities) { { read_dependency: false } } + let(:allowed_abilities) { [] } + let(:licensed_features) { { dependency_scanning: true } } + + it_behaves_like 'custom roles abilities' + end end describe 'permissions for suggested reviewers bot', :saas do diff --git a/ee/spec/requests/api/member_roles_spec.rb b/ee/spec/requests/api/member_roles_spec.rb index 8d1b6a99408b69b7ab44292d0f51578ee37d6a41..2703e217bab8ce2a62650d4ee6d2bdb43e7fb1af 100644 --- a/ee/spec/requests/api/member_roles_spec.rb +++ b/ee/spec/requests/api/member_roles_spec.rb @@ -23,6 +23,7 @@ namespace: group_with_member_roles, base_access_level: ::Gitlab::Access::REPORTER, read_code: false, + read_dependency: false, read_vulnerability: true ) end @@ -33,6 +34,7 @@ namespace: group_with_member_roles, base_access_level: ::Gitlab::Access::REPORTER, read_code: true, + read_dependency: true, read_vulnerability: false ) end @@ -95,6 +97,7 @@ "id" => member_role_1.id, "base_access_level" => ::Gitlab::Access::REPORTER, "read_code" => false, + "read_dependency" => false, "read_vulnerability" => true, "admin_vulnerability" => false, "group_id" => group_id @@ -103,6 +106,7 @@ "id" => member_role_2.id, "base_access_level" => ::Gitlab::Access::REPORTER, "read_code" => true, + "read_dependency" => true, "read_vulnerability" => false, "admin_vulnerability" => false, "group_id" => group_id