diff --git a/app/validators/json_schemas/member_role_permissions.json b/app/validators/json_schemas/member_role_permissions.json index 843bcbc4f6c9e08b19faa1dacec5ada90515e6bd..4a1f170d7672908a586b2604d27cf0fa80a63be1 100644 --- a/app/validators/json_schemas/member_role_permissions.json +++ b/app/validators/json_schemas/member_role_permissions.json @@ -55,6 +55,9 @@ "read_code": { "type": "boolean" }, + "read_crm_contact": { + "type": "boolean" + }, "read_dependency": { "type": "boolean" }, diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index f3490b641e30a7635363d593d388a787715bfb85..5ee5f05f5a69426a8c786dc7fc5edb3a6ca22f36 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -34469,6 +34469,7 @@ Member role permission. | `MANAGE_PROJECT_ACCESS_TOKENS` | Create, read, update, and delete project access tokens. When creating a token, users with this custom permission must select a role for that token that has the same or fewer permissions as the default role used as the base for the custom role. | | `MANAGE_SECURITY_POLICY_LINK` | Allows linking security policy projects. | | `READ_CODE` | Allows read-only access to the source code in the user interface. Does not allow users to edit or download repository archives, clone or pull repositories, view source code in an IDE, or view merge requests for private projects. You can download individual files because read-only access inherently grants the ability to make a local copy of the file. | +| `READ_CRM_CONTACT` | Read CRM contact. | | `READ_DEPENDENCY` | Allows read-only access to the dependencies and licenses. | | `READ_VULNERABILITY` | Read vulnerability reports and security dashboards. | | `REMOVE_GROUP` | Ability to delete or restore a group. This ability does not allow deleting top level groups. Review the Retention period settings to prevent accidental deletion. | diff --git a/doc/user/custom_roles/abilities.md b/doc/user/custom_roles/abilities.md index 5567c1289647088804cfdfdc278d6cbc1166bda3..57fb1eae4bcaffc20f8bfb8c7c728ce45a7ed0ea 100644 --- a/doc/user/custom_roles/abilities.md +++ b/doc/user/custom_roles/abilities.md @@ -95,6 +95,12 @@ These requirements are documented in the `Required permission` column in the fol | [`manage_group_access_tokens`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140115) | | Create, read, update, and delete group access tokens. When creating a token, users with this custom permission must select a role for that token that has the same or fewer permissions as the default role used as the base for the custom role. | GitLab [16.8](https://gitlab.com/gitlab-org/gitlab/-/issues/428353) | | | | [`manage_project_access_tokens`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/132342) | | Create, read, update, and delete project access tokens. When creating a token, users with this custom permission must select a role for that token that has the same or fewer permissions as the default role used as the base for the custom role. | GitLab [16.5](https://gitlab.com/gitlab-org/gitlab/-/issues/421778) | `manage_project_access_tokens` | GitLab [16.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141294) | +## Team planning + +| Name | Required permission | Description | Introduced in | Feature flag | Enabled in | +|:-----|:------------|:------------------|:---------|:--------------|:---------| +| [`read_crm_contact`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154017) | | Read CRM contact. | GitLab [17.1](https://gitlab.com/gitlab-org/gitlab/-/issues/443268) | | | + ## Vulnerability management | Name | Required permission | Description | Introduced in | Feature flag | Enabled in | diff --git a/ee/app/policies/ee/group_policy.rb b/ee/app/policies/ee/group_policy.rb index 478c47e8b00b0e3637ef5dd661880e4f4239a7bf..87ba40e4478aa5578f0178570871f2fce3bfb1ea 100644 --- a/ee/app/policies/ee/group_policy.rb +++ b/ee/app/policies/ee/group_policy.rb @@ -513,6 +513,8 @@ module GroupPolicy enable :read_billable_member end + rule { custom_role_enables_read_crm_contact }.enable(:read_crm_contact) + rule { custom_role_enables_admin_group_member & service_accounts_available }.policy do enable :admin_service_account_member end diff --git a/ee/config/custom_abilities/read_crm_contact.yml b/ee/config/custom_abilities/read_crm_contact.yml new file mode 100644 index 0000000000000000000000000000000000000000..8a0787b7eaf7e7432fc39c8faf587505b029a3c8 --- /dev/null +++ b/ee/config/custom_abilities/read_crm_contact.yml @@ -0,0 +1,11 @@ +--- +name: read_crm_contact +description: Read CRM contact. +introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/443268 +introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154017 +feature_category: team_planning +milestone: '17.1' +group_ability: true +project_ability: false +requirements: [] +available_from_access_level: 20 diff --git a/ee/spec/policies/group_policy_spec.rb b/ee/spec/policies/group_policy_spec.rb index e35e04778a3f8dcd6adf25ece8e5f60eb7a1b6d4..d8c1cf54348310c2bc5fdbefd01079e338ee7cab 100644 --- a/ee/spec/policies/group_policy_spec.rb +++ b/ee/spec/policies/group_policy_spec.rb @@ -3695,6 +3695,13 @@ def create_member_role(member, abilities = member_role_abilities) it_behaves_like 'custom roles abilities' end + + context 'for a member role with read_crm_contact true' do + let(:member_role_abilities) { { read_crm_contact: true } } + let(:allowed_abilities) { [:read_crm_contact] } + + it_behaves_like 'custom roles abilities' + end end context 'for :read_limit_alert' do diff --git a/ee/spec/requests/custom_roles/read_crm_contact/request_spec.rb b/ee/spec/requests/custom_roles/read_crm_contact/request_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b38b01cfe5b11986594e94110603d0a0b2789885 --- /dev/null +++ b/ee/spec/requests/custom_roles/read_crm_contact/request_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User with read_crm_contact custom role', feature_category: :team_planning do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:role) { create(:member_role, :guest, :read_crm_contact, namespace: group) } + let_it_be(:membership) { create(:group_member, :guest, member_role: role, user: user, group: group) } + + before do + stub_licensed_features(custom_roles: true) + + sign_in(user) + end + + describe Groups::Crm::ContactsController do + describe '#index' do + it 'allows access' do + get group_crm_contacts_path(group) + + expect(response).to have_gitlab_http_status(:ok) + end + + context 'when crm is disabled' do + let_it_be(:group) { create(:group, :crm_disabled) } + + it 'does not circumvent disabled feature' do + get group_crm_contacts_path(group) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end +end