diff options
-rw-r--r-- | app/models/ability.rb | 39 | ||||
-rw-r--r-- | app/policies/group_policy.rb | 45 |
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 |