diff options
Diffstat (limited to 'app/policies')
-rw-r--r-- | app/policies/base_policy.rb | 9 | ||||
-rw-r--r-- | app/policies/ci/pipeline_policy.rb | 12 | ||||
-rw-r--r-- | app/policies/clusters/cluster_policy.rb | 1 | ||||
-rw-r--r-- | app/policies/clusters/instance_policy.rb | 21 | ||||
-rw-r--r-- | app/policies/global_policy.rb | 5 | ||||
-rw-r--r-- | app/policies/group_policy.rb | 21 | ||||
-rw-r--r-- | app/policies/identity_provider_policy.rb | 15 | ||||
-rw-r--r-- | app/policies/issuable_policy.rb | 1 | ||||
-rw-r--r-- | app/policies/merge_request_policy.rb | 3 | ||||
-rw-r--r-- | app/policies/personal_snippet_policy.rb | 13 | ||||
-rw-r--r-- | app/policies/project_policy.rb | 40 |
11 files changed, 127 insertions, 14 deletions
diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb index 72de04203a6..5dd2279ef99 100644 --- a/app/policies/base_policy.rb +++ b/app/policies/base_policy.rb @@ -22,6 +22,13 @@ class BasePolicy < DeclarativePolicy::Base Gitlab::CurrentSettings.current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC) end - # This is prevented in some cases in `gitlab-ee` + condition(:external_authorization_enabled, scope: :global, score: 0) do + ::Gitlab::ExternalAuthorization.perform_check? + end + + rule { external_authorization_enabled & ~full_private_access }.policy do + prevent :read_cross_project + end + rule { default }.enable :read_cross_project end diff --git a/app/policies/ci/pipeline_policy.rb b/app/policies/ci/pipeline_policy.rb index 2c90b8a73cd..662c29a0973 100644 --- a/app/policies/ci/pipeline_policy.rb +++ b/app/policies/ci/pipeline_policy.rb @@ -14,6 +14,10 @@ module Ci @subject.external? end + condition(:triggerer_of_pipeline) do + @subject.triggered_by?(@user) + end + # Disallow users without permissions from accessing internal pipelines rule { ~can?(:read_build) & ~external_pipeline }.policy do prevent :read_pipeline @@ -29,6 +33,14 @@ module Ci enable :destroy_pipeline end + rule { can?(:admin_pipeline) }.policy do + enable :read_pipeline_variable + end + + rule { can?(:update_pipeline) & triggerer_of_pipeline }.policy do + enable :read_pipeline_variable + end + def ref_protected?(user, project, tag, ref) access = ::Gitlab::UserAccess.new(user, project: project) diff --git a/app/policies/clusters/cluster_policy.rb b/app/policies/clusters/cluster_policy.rb index d6d590687e2..316bd39f7a3 100644 --- a/app/policies/clusters/cluster_policy.rb +++ b/app/policies/clusters/cluster_policy.rb @@ -6,5 +6,6 @@ module Clusters delegate { cluster.group } delegate { cluster.project } + delegate { cluster.instance } end end diff --git a/app/policies/clusters/instance_policy.rb b/app/policies/clusters/instance_policy.rb new file mode 100644 index 00000000000..e1045c85e6d --- /dev/null +++ b/app/policies/clusters/instance_policy.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Clusters + class InstancePolicy < BasePolicy + include ClusterableActions + + condition(:has_clusters, scope: :subject) { clusterable_has_clusters? } + condition(:can_have_multiple_clusters) { multiple_clusters_available? } + condition(:instance_clusters_enabled) { Instance.enabled? } + + rule { admin & instance_clusters_enabled }.policy do + enable :read_cluster + enable :add_cluster + enable :create_cluster + enable :update_cluster + enable :admin_cluster + end + + rule { ~can_have_multiple_clusters & has_clusters }.prevent :add_cluster + end +end diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 16c58730878..e85397422e6 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -44,7 +44,6 @@ class GlobalPolicy < BasePolicy prevent :access_api prevent :access_git prevent :receive_notifications - prevent :use_quick_actions end rule { required_terms_not_accepted }.policy do @@ -68,6 +67,10 @@ class GlobalPolicy < BasePolicy enable :read_users_list end + rule { ~anonymous }.policy do + enable :read_instance_metadata + end + rule { admin }.policy do enable :read_custom_attribute enable :update_custom_attribute diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 298769c0eb8..ea86858181d 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -26,7 +26,7 @@ class GroupPolicy < BasePolicy condition(:can_change_parent_share_with_group_lock) { can?(:change_share_with_group_lock, @subject.parent) } condition(:has_projects) do - GroupProjectsFinder.new(group: @subject, current_user: @user, options: { include_subgroups: true }).execute.any? + GroupProjectsFinder.new(group: @subject, current_user: @user, options: { include_subgroups: true, only_owned: true }).execute.any? end condition(:has_clusters, scope: :subject) { clusterable_has_clusters? } @@ -35,6 +35,14 @@ class GroupPolicy < BasePolicy with_options scope: :subject, score: 0 condition(:request_access_enabled) { @subject.request_access_enabled } + condition(:create_projects_disabled) do + @subject.project_creation_level == ::Gitlab::Access::NO_ONE_PROJECT_ACCESS + end + + condition(:developer_maintainer_access) do + @subject.project_creation_level == ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS + end + rule { public_group }.policy do enable :read_group enable :read_list @@ -53,9 +61,9 @@ class GroupPolicy < BasePolicy rule { admin }.enable :read_group rule { has_projects }.policy do - enable :read_group enable :read_list enable :read_label + enable :read_group end rule { has_access }.enable :read_namespace @@ -115,9 +123,16 @@ class GroupPolicy < BasePolicy rule { ~can_have_multiple_clusters & has_clusters }.prevent :add_cluster + rule { developer & developer_maintainer_access }.enable :create_projects + rule { create_projects_disabled }.prevent :create_projects + def access_level return GroupMember::NO_ACCESS if @user.nil? - @access_level ||= @subject.max_member_access_for_user(@user) + @access_level ||= lookup_access_level! + end + + def lookup_access_level! + @subject.max_member_access_for_user(@user) end end diff --git a/app/policies/identity_provider_policy.rb b/app/policies/identity_provider_policy.rb new file mode 100644 index 00000000000..d34cdd5bdd4 --- /dev/null +++ b/app/policies/identity_provider_policy.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class IdentityProviderPolicy < BasePolicy + desc "Provider is SAML or CAS3" + condition(:protected_provider, scope: :subject, score: 0) { %w(saml cas3).include?(@subject.to_s) } + + rule { anonymous }.prevent_all + + rule { default }.policy do + enable :unlink + enable :link + end + + rule { protected_provider }.prevent(:unlink) +end diff --git a/app/policies/issuable_policy.rb b/app/policies/issuable_policy.rb index ecb2797d1d9..537319addc2 100644 --- a/app/policies/issuable_policy.rb +++ b/app/policies/issuable_policy.rb @@ -17,6 +17,7 @@ class IssuablePolicy < BasePolicy enable :reopen_issue enable :read_merge_request enable :update_merge_request + enable :reopen_merge_request end rule { locked & ~is_project_member }.policy do diff --git a/app/policies/merge_request_policy.rb b/app/policies/merge_request_policy.rb index a2950951d03..a3692857ff4 100644 --- a/app/policies/merge_request_policy.rb +++ b/app/policies/merge_request_policy.rb @@ -1,4 +1,7 @@ # frozen_string_literal: true class MergeRequestPolicy < IssuablePolicy + rule { locked }.policy do + prevent :reopen_merge_request + end end diff --git a/app/policies/personal_snippet_policy.rb b/app/policies/personal_snippet_policy.rb index 2b5cca76c20..40dd49b4afd 100644 --- a/app/policies/personal_snippet_policy.rb +++ b/app/policies/personal_snippet_policy.rb @@ -7,7 +7,7 @@ class PersonalSnippetPolicy < BasePolicy rule { public_snippet }.policy do enable :read_personal_snippet - enable :comment_personal_snippet + enable :create_note end rule { is_author }.policy do @@ -15,7 +15,7 @@ class PersonalSnippetPolicy < BasePolicy enable :update_personal_snippet enable :destroy_personal_snippet enable :admin_personal_snippet - enable :comment_personal_snippet + enable :create_note end rule { ~anonymous }.enable :create_personal_snippet @@ -23,15 +23,12 @@ class PersonalSnippetPolicy < BasePolicy rule { internal_snippet & ~external_user }.policy do enable :read_personal_snippet - enable :comment_personal_snippet + enable :create_note end - rule { anonymous }.prevent :comment_personal_snippet + rule { anonymous }.prevent :create_note - rule { can?(:comment_personal_snippet) }.policy do - enable :create_note - enable :award_emoji - end + rule { can?(:create_note) }.enable :award_emoji rule { full_private_access }.enable :read_personal_snippet end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 533782104ac..3218c04b219 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -89,6 +89,15 @@ class ProjectPolicy < BasePolicy ::Gitlab::CurrentSettings.current_application_settings.mirror_available end + with_scope :subject + condition(:classification_label_authorized, score: 32) do + ::Gitlab::ExternalAuthorization.access_allowed?( + @user, + @subject.external_authorization_classification_label, + @subject.full_path + ) + 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 @@ -187,6 +196,7 @@ class ProjectPolicy < BasePolicy rule { can?(:reporter_access) }.policy do enable :download_code + enable :read_statistics enable :download_wiki_code enable :fork_project enable :create_project_snippet @@ -203,6 +213,7 @@ class ProjectPolicy < BasePolicy enable :read_deployment enable :read_merge_request enable :read_sentry_issue + enable :read_prometheus end # We define `:public_user_access` separately because there are cases in gitlab-ee @@ -231,6 +242,7 @@ class ProjectPolicy < BasePolicy enable :admin_merge_request enable :admin_milestone enable :update_merge_request + enable :reopen_merge_request enable :create_commit_status enable :update_commit_status enable :create_build @@ -278,6 +290,7 @@ class ProjectPolicy < BasePolicy enable :admin_cluster enable :create_environment_terminal enable :destroy_release + enable :destroy_artifacts enable :daily_statistics end @@ -300,6 +313,8 @@ class ProjectPolicy < BasePolicy rule { issues_disabled }.policy do prevent(*create_read_update_admin_destroy(:issue)) + prevent(*create_read_update_admin_destroy(:board)) + prevent(*create_read_update_admin_destroy(:list)) end rule { merge_requests_disabled | repository_disabled }.policy do @@ -411,6 +426,25 @@ class ProjectPolicy < BasePolicy rule { ~can_have_multiple_clusters & has_clusters }.prevent :add_cluster + rule { ~can?(:read_cross_project) & ~classification_label_authorized }.policy do + # Preventing access here still allows the projects to be listed. Listing + # projects doesn't check the `:read_project` ability. But instead counts + # on the `project_authorizations` table. + # + # All other actions should explicitly check read project, which would + # trigger the `classification_label_authorized` condition. + # + # `:read_project_for_iids` is not prevented by this condition, as it is + # used for cross-project reference checks. + prevent :guest_access + prevent :public_access + prevent :public_user_access + prevent :reporter_access + prevent :developer_access + prevent :maintainer_access + prevent :owner_access + end + private def team_member? @@ -454,6 +488,10 @@ class ProjectPolicy < BasePolicy def team_access_level return -1 if @user.nil? + lookup_access_level! + end + + def lookup_access_level! # NOTE: max_member_access has its own cache project.team.max_member_access(@user.id) end @@ -463,7 +501,7 @@ class ProjectPolicy < BasePolicy when ProjectFeature::DISABLED false when ProjectFeature::PRIVATE - guest? || admin? + admin? || team_access_level >= ProjectFeature.required_minimum_access_level(feature) else true end |