summaryrefslogtreecommitdiff
path: root/app/policies
diff options
context:
space:
mode:
Diffstat (limited to 'app/policies')
-rw-r--r--app/policies/alert_management/alert_policy.rb7
-rw-r--r--app/policies/ci/build_policy.rb10
-rw-r--r--app/policies/ci/freeze_period_policy.rb7
-rw-r--r--app/policies/concerns/policy_actor.rb37
-rw-r--r--app/policies/design_management/design_at_version_policy.rb8
-rw-r--r--app/policies/design_management/design_collection_policy.rb7
-rw-r--r--app/policies/design_management/design_policy.rb8
-rw-r--r--app/policies/design_management/version_policy.rb8
-rw-r--r--app/policies/global_policy.rb10
-rw-r--r--app/policies/group_policy.rb35
-rw-r--r--app/policies/issue_policy.rb16
-rw-r--r--app/policies/project_policy.rb101
-rw-r--r--app/policies/wiki_page_policy.rb2
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