diff options
Diffstat (limited to 'app/policies')
-rw-r--r-- | app/policies/alert_management/alert_policy.rb | 7 | ||||
-rw-r--r-- | app/policies/ci/build_policy.rb | 10 | ||||
-rw-r--r-- | app/policies/ci/freeze_period_policy.rb | 7 | ||||
-rw-r--r-- | app/policies/concerns/policy_actor.rb | 37 | ||||
-rw-r--r-- | app/policies/design_management/design_at_version_policy.rb | 8 | ||||
-rw-r--r-- | app/policies/design_management/design_collection_policy.rb | 7 | ||||
-rw-r--r-- | app/policies/design_management/design_policy.rb | 8 | ||||
-rw-r--r-- | app/policies/design_management/version_policy.rb | 8 | ||||
-rw-r--r-- | app/policies/global_policy.rb | 10 | ||||
-rw-r--r-- | app/policies/group_policy.rb | 35 | ||||
-rw-r--r-- | app/policies/issue_policy.rb | 16 | ||||
-rw-r--r-- | app/policies/project_policy.rb | 101 | ||||
-rw-r--r-- | app/policies/wiki_page_policy.rb | 2 |
13 files changed, 212 insertions, 44 deletions
diff --git a/app/policies/alert_management/alert_policy.rb b/app/policies/alert_management/alert_policy.rb new file mode 100644 index 00000000000..85fafcde2cc --- /dev/null +++ b/app/policies/alert_management/alert_policy.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module AlertManagement + class AlertPolicy < ::BasePolicy + delegate { @subject.project } + end +end diff --git a/app/policies/ci/build_policy.rb b/app/policies/ci/build_policy.rb index ebb99270b9a..12892a69257 100644 --- a/app/policies/ci/build_policy.rb +++ b/app/policies/ci/build_policy.rb @@ -12,6 +12,14 @@ module Ci end end + condition(:unprotected_ref) do + if @subject.tag? + !ProtectedTag.protected?(@subject.project, @subject.ref) + else + !ProtectedBranch.protected?(@subject.project, @subject.ref) + end + end + condition(:owner_of_job) do @subject.triggered_by?(@user) end @@ -34,7 +42,7 @@ module Ci prevent :erase_build end - rule { can?(:admin_build) | (can?(:update_build) & owner_of_job) }.enable :erase_build + rule { can?(:admin_build) | (can?(:update_build) & owner_of_job & unprotected_ref) }.enable :erase_build rule { can?(:public_access) & branch_allows_collaboration }.policy do enable :update_build diff --git a/app/policies/ci/freeze_period_policy.rb b/app/policies/ci/freeze_period_policy.rb new file mode 100644 index 00000000000..60e53a7b2f9 --- /dev/null +++ b/app/policies/ci/freeze_period_policy.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Ci + class FreezePeriodPolicy < BasePolicy + delegate { @subject.resource_parent } + end +end diff --git a/app/policies/concerns/policy_actor.rb b/app/policies/concerns/policy_actor.rb index 406677d7b56..f910e04d015 100644 --- a/app/policies/concerns/policy_actor.rb +++ b/app/policies/concerns/policy_actor.rb @@ -1,8 +1,15 @@ # frozen_string_literal: true -# Include this module if we want to pass something else than the user to -# check policies. This defines several methods which the policy checker -# would call and check. +# Include this module to have an object respond to user messages without being +# a user. +# +# Use Case 1: +# Pass something else than the user to check policies. This defines several +# methods which the policy checker would call and check. +# +# Use Case 2: +# Access the API with non-user object such as deploy tokens. This defines +# several methods which the API auth flow would call. module PolicyActor extend ActiveSupport::Concern @@ -37,6 +44,30 @@ module PolicyActor def alert_bot? false end + + def deactivated? + false + end + + def confirmation_required_on_sign_in? + false + end + + def can?(action, subject = :global) + Ability.allowed?(self, action, subject) + end + + def preferred_language + nil + end + + def requires_ldap_check? + false + end + + def try_obtain_ldap_lease + nil + end end PolicyActor.prepend_if_ee('EE::PolicyActor') diff --git a/app/policies/design_management/design_at_version_policy.rb b/app/policies/design_management/design_at_version_policy.rb new file mode 100644 index 00000000000..9decbc0c4b2 --- /dev/null +++ b/app/policies/design_management/design_at_version_policy.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module DesignManagement + class DesignAtVersionPolicy < ::BasePolicy + delegate { @subject.version } + delegate { @subject.design } + end +end diff --git a/app/policies/design_management/design_collection_policy.rb b/app/policies/design_management/design_collection_policy.rb new file mode 100644 index 00000000000..6a833da27cc --- /dev/null +++ b/app/policies/design_management/design_collection_policy.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module DesignManagement + class DesignCollectionPolicy < DesignPolicy + # Delegates everything to the `issue` just like the `DesignPolicy` + end +end diff --git a/app/policies/design_management/design_policy.rb b/app/policies/design_management/design_policy.rb new file mode 100644 index 00000000000..57846095f80 --- /dev/null +++ b/app/policies/design_management/design_policy.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module DesignManagement + class DesignPolicy < ::BasePolicy + # The IssuePolicy will delegate to the ProjectPolicy + delegate { @subject.issue } + end +end diff --git a/app/policies/design_management/version_policy.rb b/app/policies/design_management/version_policy.rb new file mode 100644 index 00000000000..1c59ceaea98 --- /dev/null +++ b/app/policies/design_management/version_policy.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module DesignManagement + class VersionPolicy < ::BasePolicy + # The IssuePolicy will delegate to the ProjectPolicy + delegate { @subject.issue } + end +end diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 9353b361c2a..03f5a863421 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -18,6 +18,7 @@ class GlobalPolicy < BasePolicy condition(:private_instance_statistics, score: 0) { Gitlab::CurrentSettings.instance_statistics_visibility_private? } condition(:project_bot, scope: :user) { @user&.project_bot? } + condition(:migration_bot, scope: :user) { @user&.migration_bot? } rule { admin | (~private_instance_statistics & ~anonymous) } .enable :read_instance_statistics @@ -48,11 +49,14 @@ class GlobalPolicy < BasePolicy rule { blocked | internal }.policy do prevent :log_in prevent :access_api - prevent :access_git prevent :receive_notifications prevent :use_slash_commands end + rule { blocked | (internal & ~migration_bot) }.policy do + prevent :access_git + end + rule { project_bot }.policy do prevent :log_in prevent :receive_notifications @@ -74,6 +78,10 @@ class GlobalPolicy < BasePolicy enable :create_group end + rule { can?(:create_group) }.policy do + enable :create_group_with_default_branch_protection + end + rule { can_create_fork }.policy do enable :create_fork end diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 728c4b76498..136ac4cce63 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class GroupPolicy < BasePolicy - include CrudPolicyHelpers include FindGroupProjects desc "Group is public" @@ -43,23 +42,15 @@ class GroupPolicy < BasePolicy @subject.subgroup_creation_level == ::Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS end - desc "Group has wiki disabled" - condition(:wiki_disabled, score: 32) { !feature_available?(:wiki) } - rule { public_group }.policy do enable :read_group enable :read_package - enable :read_wiki end - rule { logged_in_viewable }.policy do - enable :read_group - enable :read_wiki - end + rule { logged_in_viewable }.enable :read_group rule { guest }.policy do enable :read_group - enable :read_wiki enable :upload_file end @@ -87,13 +78,11 @@ class GroupPolicy < BasePolicy enable :create_metrics_dashboard_annotation enable :delete_metrics_dashboard_annotation enable :update_metrics_dashboard_annotation - enable :create_wiki end rule { reporter }.policy do enable :reporter_access enable :read_container_image - enable :download_wiki_code enable :admin_label enable :admin_list enable :admin_issue @@ -112,7 +101,6 @@ class GroupPolicy < BasePolicy enable :destroy_deploy_token enable :read_deploy_token enable :create_deploy_token - enable :admin_wiki end rule { owner }.policy do @@ -123,6 +111,7 @@ class GroupPolicy < BasePolicy enable :set_note_created_at enable :set_emails_disabled + enable :update_default_branch_protection end rule { can?(:read_nested_project_resources) }.policy do @@ -158,11 +147,6 @@ class GroupPolicy < BasePolicy rule { maintainer & can?(:create_projects) }.enable :transfer_projects - rule { wiki_disabled }.policy do - prevent(*create_read_update_admin_destroy(:wiki)) - prevent(:download_wiki_code) - end - def access_level return GroupMember::NO_ACCESS if @user.nil? @@ -172,21 +156,6 @@ class GroupPolicy < BasePolicy def lookup_access_level! @subject.max_member_access_for_user(@user) end - - # TODO: Extract this into a helper shared with ProjectPolicy, once we implement group-level features. - # https://gitlab.com/gitlab-org/gitlab/-/issues/208412 - def feature_available?(feature) - return false unless feature == :wiki - - case @subject.wiki_access_level - when ProjectFeature::DISABLED - false - when ProjectFeature::PRIVATE - admin? || access_level >= ProjectFeature.required_minimum_access_level(feature) - else - true - end - end end GroupPolicy.prepend_if_ee('EE::GroupPolicy') diff --git a/app/policies/issue_policy.rb b/app/policies/issue_policy.rb index 20df823c737..28baa0d8338 100644 --- a/app/policies/issue_policy.rb +++ b/app/policies/issue_policy.rb @@ -15,6 +15,9 @@ class IssuePolicy < IssuablePolicy desc "Issue is confidential" condition(:confidential, scope: :subject) { @subject.confidential? } + desc "Issue has moved" + condition(:moved) { @subject.moved? } + rule { confidential & ~can_read_confidential }.policy do prevent(*create_read_update_admin_destroy(:issue)) prevent :read_issue_iid @@ -25,6 +28,15 @@ class IssuePolicy < IssuablePolicy rule { locked }.policy do prevent :reopen_issue end -end -IssuePolicy.prepend_if_ee('::EE::IssuePolicy') + rule { ~can?(:read_issue) }.policy do + prevent :read_design + prevent :create_design + prevent :destroy_design + end + + rule { locked | moved }.policy do + prevent :create_design + prevent :destroy_design + end +end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 7454343a357..a24c0471d6c 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -11,6 +11,7 @@ class ProjectPolicy < BasePolicy milestone snippet wiki + design note pipeline pipeline_schedule @@ -83,11 +84,26 @@ class ProjectPolicy < BasePolicy project.merge_requests_allowing_push_to_user(user).any? end + desc "Deploy token with read_package_registry scope" + condition(:read_package_registry_deploy_token) do + user.is_a?(DeployToken) && user.has_access_to?(project) && user.read_package_registry + end + + desc "Deploy token with write_package_registry scope" + condition(:write_package_registry_deploy_token) do + user.is_a?(DeployToken) && user.has_access_to?(project) && user.write_package_registry + end + with_scope :subject condition(:forking_allowed) do @subject.feature_available?(:forking, @user) end + with_scope :subject + condition(:metrics_dashboard_allowed) do + feature_available?(:metrics_dashboard) + end + with_scope :global condition(:mirror_available, score: 0) do ::Gitlab::CurrentSettings.current_application_settings.mirror_available @@ -102,6 +118,11 @@ class ProjectPolicy < BasePolicy ) end + with_scope :subject + condition(:design_management_disabled) do + !@subject.design_management_enabled? + end + # We aren't checking `:read_issue` or `:read_merge_request` in this case # because it could be possible for a user to see an issuable-iid # (`:read_issue_iid` or `:read_merge_request_iid`) but then wouldn't be @@ -134,6 +155,7 @@ class ProjectPolicy < BasePolicy wiki builds pages + metrics_dashboard ] features.each do |f| @@ -174,6 +196,7 @@ class ProjectPolicy < BasePolicy enable :set_issue_updated_at enable :set_note_created_at enable :set_emails_disabled + enable :set_show_default_award_emojis end rule { can?(:guest_access) }.policy do @@ -218,6 +241,7 @@ class ProjectPolicy < BasePolicy enable :read_build enable :read_container_image enable :read_pipeline + enable :read_pipeline_schedule enable :read_environment enable :read_deployment enable :read_merge_request @@ -225,6 +249,7 @@ class ProjectPolicy < BasePolicy enable :update_sentry_issue enable :read_prometheus enable :read_metrics_dashboard_annotation + enable :metrics_dashboard end # We define `:public_user_access` separately because there are cases in gitlab-ee @@ -247,6 +272,21 @@ class ProjectPolicy < BasePolicy enable :fork_project end + rule { metrics_dashboard_disabled }.policy do + prevent(:metrics_dashboard) + end + + rule { can?(:metrics_dashboard) }.policy do + enable :read_prometheus + enable :read_environment + enable :read_deployment + end + + rule { ~anonymous & can?(:metrics_dashboard) }.policy do + enable :create_metrics_user_starred_dashboard + enable :read_metrics_user_starred_dashboard + end + rule { owner | admin | guest | group_member }.prevent :request_access rule { ~request_access_enabled }.prevent :request_access @@ -262,7 +302,6 @@ class ProjectPolicy < BasePolicy enable :update_commit_status enable :create_build enable :update_build - enable :read_pipeline_schedule enable :create_merge_request_from enable :create_wiki enable :push_code @@ -277,9 +316,14 @@ class ProjectPolicy < BasePolicy enable :update_deployment enable :create_release enable :update_release + enable :daily_statistics enable :create_metrics_dashboard_annotation enable :delete_metrics_dashboard_annotation enable :update_metrics_dashboard_annotation + enable :read_alert_management_alert + enable :update_alert_management_alert + enable :create_design + enable :destroy_design end rule { can?(:developer_access) & user_confirmed? }.policy do @@ -315,7 +359,6 @@ class ProjectPolicy < BasePolicy enable :create_environment_terminal enable :destroy_release enable :destroy_artifacts - enable :daily_statistics enable :admin_operations enable :read_deploy_token enable :create_deploy_token @@ -323,6 +366,18 @@ class ProjectPolicy < BasePolicy enable :destroy_deploy_token enable :read_prometheus_alerts enable :admin_terraform_state + enable :create_freeze_period + enable :read_freeze_period + enable :update_freeze_period + enable :destroy_freeze_period + end + + rule { public_project & metrics_dashboard_allowed }.policy do + enable :metrics_dashboard + end + + rule { internal_access & metrics_dashboard_allowed }.policy do + enable :metrics_dashboard end rule { (mirror_available & can?(:admin_project)) | admin }.enable :admin_remote_mirror @@ -374,11 +429,27 @@ class ProjectPolicy < BasePolicy rule { builds_disabled | repository_disabled }.policy do prevent(*create_read_update_admin_destroy(:build)) prevent(*create_read_update_admin_destroy(:pipeline_schedule)) - prevent(*create_read_update_admin_destroy(:environment)) prevent(*create_read_update_admin_destroy(:cluster)) prevent(*create_read_update_admin_destroy(:deployment)) end + # Enabling `read_environment` specifically for the condition of `metrics_dashboard_allowed` is + # necessary due to the route for metrics dashboard requiring an environment id. + # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/213833 when + # environments and metrics are decoupled and these rules will be removed. + + rule { (builds_disabled | repository_disabled) & ~metrics_dashboard_allowed}.policy do + prevent(*create_read_update_admin_destroy(:environment)) + end + + rule { (builds_disabled | repository_disabled) & metrics_dashboard_allowed}.policy do + prevent :create_environment + prevent :update_environment + prevent :admin_environment + prevent :destroy_environment + enable :read_environment + end + # There's two separate cases when builds_disabled is true: # 1. When internal CI is disabled - builds_disabled && internal_builds_disabled # - We do not prevent the user from accessing Pipelines to allow them to access external CI @@ -395,6 +466,7 @@ class ProjectPolicy < BasePolicy prevent :fork_project prevent :read_commit_status prevent :read_pipeline + prevent :read_pipeline_schedule prevent(*create_read_update_admin_destroy(:release)) end @@ -421,6 +493,7 @@ class ProjectPolicy < BasePolicy enable :read_merge_request enable :read_note enable :read_pipeline + enable :read_pipeline_schedule enable :read_commit_status enable :read_container_image enable :download_code @@ -439,6 +512,7 @@ class ProjectPolicy < BasePolicy rule { public_builds & can?(:guest_access) }.policy do enable :read_pipeline + enable :read_pipeline_schedule end # These rules are included to allow maintainers of projects to push to certain @@ -481,6 +555,27 @@ class ProjectPolicy < BasePolicy rule { admin }.enable :change_repository_storage + rule { can?(:read_issue) }.policy do + enable :read_design + end + + # Design abilities could also be prevented in the issue policy. + rule { design_management_disabled }.policy do + prevent :read_design + prevent :create_design + prevent :destroy_design + end + + rule { read_package_registry_deploy_token }.policy do + enable :read_package + enable :read_project + end + + rule { write_package_registry_deploy_token }.policy do + enable :create_package + enable :read_project + end + private def team_member? diff --git a/app/policies/wiki_page_policy.rb b/app/policies/wiki_page_policy.rb index 468632c9085..f284fd9f5df 100644 --- a/app/policies/wiki_page_policy.rb +++ b/app/policies/wiki_page_policy.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class WikiPagePolicy < BasePolicy - delegate { @subject.wiki.project } + delegate { @subject.wiki.container } rule { can?(:read_wiki) }.enable :read_wiki_page end |