diff options
Diffstat (limited to 'app/policies/group_policy.rb')
-rw-r--r-- | app/policies/group_policy.rb | 126 |
1 files changed, 82 insertions, 44 deletions
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index fb07298c6c2..c9cb730c4e9 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -1,50 +1,88 @@ class GroupPolicy < BasePolicy - def rules - can! :read_group if @subject.public? - return unless @user - - globally_viewable = @subject.public? || (@subject.internal? && !@user.external?) - access_level = @subject.max_member_access_for_user(@user) - owner = access_level >= GroupMember::OWNER - master = access_level >= GroupMember::MASTER - reporter = access_level >= GroupMember::REPORTER - - can_read = false - can_read ||= globally_viewable - can_read ||= access_level >= GroupMember::GUEST - can_read ||= GroupProjectsFinder.new(group: @subject, current_user: @user).execute.any? - can! :read_group if can_read - - if reporter - can! :admin_label - end - - # Only group masters and group owners can create new projects - if master - can! :create_projects - can! :admin_milestones - end - - # Only group owner and administrators can admin group - if owner - can! :admin_group - can! :admin_namespace - can! :admin_group_member - can! :change_visibility_level - can! :create_subgroup if @user.can_create_group - end - - if globally_viewable && @subject.request_access_enabled && access_level == GroupMember::NO_ACCESS - can! :request_access - end - end + desc "Group is public" + with_options scope: :subject, score: 0 + condition(:public_group) { @subject.public? } + + with_score 0 + condition(:logged_in_viewable) { @user && @subject.internal? && !@user.external? } + + condition(:has_access) { access_level != GroupMember::NO_ACCESS } + + condition(:guest) { access_level >= GroupMember::GUEST } + condition(:developer) { access_level >= GroupMember::DEVELOPER } + condition(:owner) { access_level >= GroupMember::OWNER } + condition(:master) { access_level >= GroupMember::MASTER } + condition(:reporter) { access_level >= GroupMember::REPORTER } - def can_read_group? - return true if @subject.public? - return true if @user.admin? - return true if @subject.internal? && !@user.external? - return true if @subject.users.include?(@user) + condition(:nested_groups_supported, scope: :global) { Group.supports_nested_groups? } + condition(:has_parent, scope: :subject) { @subject.has_parent? } + condition(:share_with_group_locked, scope: :subject) { @subject.share_with_group_lock? } + condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? } + 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).execute.any? end + + with_options scope: :subject, score: 0 + condition(:request_access_enabled) { @subject.request_access_enabled } + + rule { public_group }.policy do + enable :read_group + enable :read_list + enable :read_label + end + + rule { logged_in_viewable }.enable :read_group + + rule { guest }.policy do + enable :read_group + enable :upload_file + enable :read_label + end + + rule { admin } .enable :read_group + rule { has_projects } .enable :read_group + + rule { has_access }.enable :read_namespace + + rule { developer }.enable :admin_milestones + + rule { reporter }.policy do + enable :admin_label + enable :admin_list + enable :admin_issue + end + + rule { master }.policy do + enable :create_projects + enable :admin_pipeline + enable :admin_build + end + + rule { owner }.policy do + enable :admin_group + enable :admin_namespace + enable :admin_group_member + enable :change_visibility_level + end + + rule { owner & nested_groups_supported }.enable :create_subgroup + + rule { public_group | logged_in_viewable }.enable :view_globally + + rule { default }.enable(:request_access) + + rule { ~request_access_enabled }.prevent :request_access + rule { ~can?(:view_globally) }.prevent :request_access + rule { has_access }.prevent :request_access + + rule { owner & (~share_with_group_locked | ~has_parent | ~parent_share_with_group_locked | can_change_parent_share_with_group_lock) }.enable :change_share_with_group_lock + + def access_level + return GroupMember::NO_ACCESS if @user.nil? + + @access_level ||= @subject.max_member_access_for_user(@user) + end end |