summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/ability.rb39
-rw-r--r--app/policies/group_policy.rb45
2 files changed, 48 insertions, 36 deletions
diff --git a/app/models/ability.rb b/app/models/ability.rb
index c5392379b32..2360bf3d46c 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -73,7 +73,6 @@ class Ability
def abilities_by_subject_class(user:, subject:)
case subject
- when Group then group_abilities(user, subject)
when Namespace then namespace_abilities(user, subject)
when GroupMember then group_member_abilities(user, subject)
when ProjectMember then project_member_abilities(user, subject)
@@ -88,8 +87,8 @@ class Ability
def anonymous_abilities(subject)
if subject.respond_to?(:project)
ProjectPolicy.abilities(nil, subject.project)
- elsif subject.is_a?(Group) || subject.respond_to?(:group)
- anonymous_group_abilities(subject)
+ elsif subject.respond_to?(:group)
+ GroupPolicy.abilities(nil, subject.group)
elsif subject.is_a?(User)
anonymous_user_abilities
else
@@ -164,38 +163,6 @@ class Ability
ProjectPolicy.abilities(user, project).to_a
end
- def group_abilities(user, group)
- rules = []
- rules << :read_group if can_read_group?(user, group)
-
- owner = user.admin? || group.has_owner?(user)
- master = owner || group.has_master?(user)
-
- # Only group masters and group owners can create new projects
- if master
- rules += [
- :create_projects,
- :admin_milestones
- ]
- end
-
- # Only group owner and administrators can admin group
- if owner
- rules += [
- :admin_group,
- :admin_namespace,
- :admin_group_member,
- :change_visibility_level
- ]
- end
-
- if group.public? || (group.internal? && !user.external?)
- rules << :request_access if group.request_access_enabled && group.users.exclude?(user)
- end
-
- rules.flatten
- end
-
def can_read_group?(user, group)
return true if user.admin?
return true if group.public?
@@ -225,7 +192,7 @@ class Ability
group = subject.group
unless group.last_owner?(target_user)
- can_manage = group_abilities(user, group).include?(:admin_group_member)
+ can_manage = allowed?(user, :admin_group_member, group)
if can_manage
rules << :update_group_member
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
new file mode 100644
index 00000000000..97ff6233968
--- /dev/null
+++ b/app/policies/group_policy.rb
@@ -0,0 +1,45 @@
+class GroupPolicy < BasePolicy
+ def rules
+ can! :read_group if @subject.public?
+ return unless @user
+
+ globally_viewable = @subject.public? || (@subject.internal? && !@user.external?)
+ member = @subject.users.include?(@user)
+ owner = @user.admin? || @subject.has_owner?(@user)
+ master = owner || @subject.has_master?(@user)
+
+ can_read = false
+ can_read ||= globally_viewable
+ can_read ||= member
+ can_read ||= @user.admin?
+ can_read ||= GroupProjectsFinder.new(@subject).execute(@user).any?
+ can! :read_group if can_read
+
+ # 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
+ end
+
+ if globally_viewable && @subject.request_access_enabled && !member
+ can! :request_access
+ end
+ end
+
+ 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)
+
+ GroupProjectsFinder.new(@subject).execute(@user).any?
+ end
+end