Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/permissions/custom_roles.md')
-rw-r--r--doc/development/permissions/custom_roles.md120
1 files changed, 107 insertions, 13 deletions
diff --git a/doc/development/permissions/custom_roles.md b/doc/development/permissions/custom_roles.md
index 9d02c0c6f39..53589658f56 100644
--- a/doc/development/permissions/custom_roles.md
+++ b/doc/development/permissions/custom_roles.md
@@ -34,7 +34,7 @@ Like static roles, custom roles are [inherited](../../user/project/members/index
- A Group or project membership can be associated with any custom role that is defined on the root-level group of the group or project.
- The `member_roles` table includes individual permissions and a `base_access_level` value.
- The `base_access_level` must be a [valid access level](../../api/access_requests.md#valid-access-levels).
-The `base_access_level` determines which abilities are included in the custom role. For example, if the `base_access_level` is `10`, the custom role will include any abilities that a static Guest role would receive, plus any additional abilities that are enabled by the `member_roles` record by setting an attribute, such as `read_code`, to true.
+ The `base_access_level` determines which abilities are included in the custom role. For example, if the `base_access_level` is `10`, the custom role will include any abilities that a static Guest role would receive, plus any additional abilities that are enabled by the `member_roles` record by setting an attribute, such as `read_code`, to true.
- A custom role can enable additional abilities for a `base_access_level` but it cannot disable a permission. As a result, custom roles are "additive only". The rationale for this choice is [in this comment](https://gitlab.com/gitlab-org/gitlab/-/issues/352891#note_1059561579).
- Custom role abilities are supported at project level and group level.
@@ -169,7 +169,7 @@ For example, you see in `GroupPolicy` that there is an ability called
than adding a row to the `member_roles` table for each ability, consider
renaming them to `read_security_dashboard` and adding `read_security_dashboard`
to the `member_roles` table. This is more expected because it means that
-enabling `read_security_dashboard` on the parent group will enable the custom
+enabling `read_security_dashboard` on the parent group will enable the custom role.
For example, `GroupPolicy` has an ability called `read_group_security_dashboard` and `ProjectPolicy` has an ability
called `read_project_security_dashboard`. If you would like to make both customizable, rather than adding a row to the
`member_roles` table for each ability, consider renaming them to `read_security_dashboard` and adding
@@ -183,23 +183,116 @@ security dashboard.
To add a new ability to a custom role:
- Generate YAML file by running `./ee/bin/custom-ability` generator
-- Add a new column to `member_roles` table, for example in [this change in merge request 114734](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114734/diffs#diff-content-5c53d6f1c29a272a87eecea3f62d017ab6635275).
-- Add the ability to the `MemberRole` model, `ALL_CUSTOMIZABLE_PERMISSIONS` hash, for example in [this change in merge request 121534](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121534/diffs#ce5ec769500a53ce2b603467d9984fc2b33ca71d_8_8). There are following possible keys in the `ALL_CUSTOMIZABLE_PERMISSIONS` hash:
-
- - `description` - description of the ability.
- - `minimal_level` - minimal level a user has to have in order to be able to be assigned to the ability.
- - `requirement` - required ability for the ability defined in the hash, in case the requirement is `false`, the ability can not be `true`.
-
+- Add a new column to `member_roles` table, either manually or by running `custom_roles:code` generator, eg. by running `rails generate gitlab:custom_roles:code --ability new_ability_name`. The ability parameter is case sensitive and has to exactly match the permission name from the YAML file.
- Add the ability to the respective Policy for example in [this change in merge request 114734](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114734/diffs#diff-content-edcbe28bdecbd848d4d9efdc5b5e9bddd2a7299e).
-- Update the specs.
+- Update the specs. Don't forget to add a spec to `ee/spec/requests/custom_roles` - the spec template file was pre-generated if you used the code generator
+- Compile the documentation by running `bundle exec rake gitlab:custom_roles:compile_docs`
+- Update the GraphQL documentation by running `bundle exec rake gitlab:graphql:compile_docs`
Examples of merge requests adding new abilities to custom roles:
- [Read code](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106256)
- [Read vulnerability](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114734)
-- [Admin vulnerability](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121534) - this is the newest MR implementing a new custom role ability. Some changes from the previous MRs are not necessary anymore (such as a change of the Preloader query or adding a method to `User` model).
+- [Admin vulnerability](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121534)
+
+The above merge requests don't use YAML files and code generators. Some of the changes are not needed anymore. We will update the documentation once we have a permission implemented using the generators.
+
+If you have any concerns, put the new ability behind a feature flag.
+
+#### Documenting handling the feature flag
+
+- When you introduce a new custom ability under a feature flag, add the `feature_flag` attribute to the appropriate ability YAML file.
+- When you enable the ability by default, add the `feature_flag_enabled_milestone` and `feature_flag_enabled_mr` attributes to the appropriate ability YAML file and regenerate the documentation.
+- You do not have to include these attributes in the YAML file if the feature flag is enabled by default in the same release as the ability is introduced.
+
+#### Testing
+
+Unit tests are preferred to test out changes to any policies affected by the
+addition of new custom permissions. Custom Roles is an Ultimate tier feature so
+these tests can be found in the `ee/spec/policies` directory. The [spec file](https://gitlab.com/gitlab-org/gitlab/-/blob/13baa4e8c92a56260591a5bf0a58d3339890ee10/ee/spec/policies/project_policy_spec.rb#L2726-2740) for
+the `ProjectPolicy` contains shared examples that can be used to test out the
+following conditions:
+
+- when the `custom_roles` licensed feature is not enabled
+- when the `custom_roles` licensed feature is enabled
+ - when a user is a member of a custom role via an inherited group member
+ - when a user is a member of a custom role via a direct group member
+ - when a user is a member of a custom role via a direct project membership
+
+Below is an example for testing out `ProjectPolicy` related changes.
+
+```ruby
+ context 'for a role with `custom_permission` enabled' do
+ let(:member_role_abilities) { { custom_permission: true } }
+ let(:allowed_abilities) { [:custom_permission] }
+
+ it_behaves_like 'custom roles abilities'
+ end
+```
+
+Request specs are preferred to test out any endpoint that allow access via a custom role permission.
+This includes controllers, REST API, and GraphQL. Examples of request specs can be found in `ee/spec/requests/custom_roles/`. In this directory you will find a sub-directory named after each permission that can be enabled via a custom role.
+The `custom_roles` licensed feature must be enabled to test this functionality.
+
+Below is an example of the typical setup that is required to test out a
+Rails Controller endpoint.
+
+```ruby
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, :in_group) }
+ let_it_be(:role) { create(:member_role, :guest, namespace: project.group, custom_permission: true) }
+ let_it_be(:membership) { create(:project_member, :guest, member_role: role, user: user, project: project) }
+
+ before do
+ stub_licensed_features(custom_roles: true)
+ sign_in(user)
+ end
+
+ describe MyController do
+ describe '#show' do
+ it 'allows access' do
+ get my_controller_path(project)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:show)
+ end
+ end
+ end
+```
+
+Below is an example of the typical setup that is required to test out a GraphQL
+mutation.
+
+```ruby
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, :in_group) }
+ let_it_be(:role) { create(:member_role, :guest, namespace: project.group, custom_permission: true) }
+ let_it_be(:membership) { create(:project_member, :guest, member_role: role, user: user, project: project) }
+
+ before do
+ stub_licensed_features(custom_roles: true)
+ end
+
+ describe MyMutation do
+ include GraphqlHelpers
+
+ describe '#show' do
+ it 'allows access' do
+ post_graphql_mutation(graphql_mutation(:my_mutation, {
+ example: "Example"
+ }), current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ mutation_response = graphql_mutation_response(:my_mutation)
+ expect(mutation_response).to be_present
+ expect(mutation_response["errors"]).to be_empty
+ end
+ end
+ end
+```
-You should make sure a new custom roles ability is under a feature flag.
+[`GITLAB_DEBUG_POLICIES=true`](#finding-existing-abilities-checks) can be used
+to troubleshoot runtime policy decisions.
## Custom abilities definition
@@ -213,6 +306,7 @@ To add a new custom ability:
- Use the `ee/bin/custom-ability` CLI to create the YAML definition automatically.
- Perform manual steps to create a new file in `ee/config/custom_abilities/` with the filename matching the name of the ability name.
1. Add contents to the file that conform to the [schema](#schema) defined in `ee/config/custom_abilities/types/type_schema.json`.
+1. Add [tests](#testing) for the new ability in `ee/spec/requests/custom_roles/` with a new directory named after the ability name.
### Schema
@@ -222,7 +316,7 @@ To add a new custom ability:
| `description` | yes | Human-readable description of the custom ability. |
| `feature_category` | yes | Name of the feature category. For example, `vulnerability_management`. |
| `introduced_by_issue` | yes | Issue URL that proposed the addition of this custom ability. |
-| `introduced_by_mr` | yes | MR URL that added this custom ability. |
+| `introduced_by_mr` | no | MR URL that added this custom ability. |
| `milestone` | yes | Milestone in which this custom ability was added. |
| `group_ability` | yes | Indicate whether this ability is checked on group level. |
| `project_ability` | yes | Indicate whether this ability is checked on project level. |