gitlab-org--gitlab-foss/app/policies/base_policy.rb

124 lines
2.2 KiB
Ruby
Raw Normal View History

class BasePolicy
class RuleSet
attr_reader :can_set, :cannot_set
def initialize(can_set, cannot_set)
@can_set = can_set
@cannot_set = cannot_set
end
2017-02-22 17:51:46 +00:00
delegate :size, to: :to_set
2016-08-30 18:42:23 +00:00
def self.empty
new(Set.new, Set.new)
end
def self.none
empty.freeze
end
def can?(ability)
@can_set.include?(ability) && !@cannot_set.include?(ability)
end
def include?(ability)
can?(ability)
end
def to_set
@can_set - @cannot_set
end
def merge(other)
@can_set.merge(other.can_set)
@cannot_set.merge(other.cannot_set)
end
def can!(*abilities)
@can_set.merge(abilities)
end
def cannot!(*abilities)
@cannot_set.merge(abilities)
end
def freeze
@can_set.freeze
@cannot_set.freeze
super
end
end
2016-08-12 18:36:16 +00:00
def self.abilities(user, subject)
new(user, subject).abilities
end
2016-08-16 18:10:34 +00:00
def self.class_for(subject)
return GlobalPolicy if subject == :global
raise ArgumentError, 'no policy for nil' if subject.nil?
2016-08-16 23:29:19 +00:00
if subject.class.try(:presenter?)
subject = subject.subject
end
subject.class.ancestors.each do |klass|
next unless klass.name
begin
policy_class = "#{klass.name}Policy".constantize
2016-08-30 22:55:28 +00:00
# NOTE: the < operator here tests whether policy_class
# inherits from BasePolicy
return policy_class if policy_class < BasePolicy
rescue NameError
nil
end
end
raise "no policy for #{subject.class.name}"
2016-08-16 18:10:34 +00:00
end
2016-08-12 18:36:16 +00:00
attr_reader :user, :subject
def initialize(user, subject)
@user = user
@subject = subject
end
def abilities
return RuleSet.none if @user && @user.blocked?
2016-08-12 18:36:16 +00:00
return anonymous_abilities if @user.nil?
collect_rules { rules }
end
def anonymous_abilities
collect_rules { anonymous_rules }
end
2016-08-16 18:10:34 +00:00
def anonymous_rules
rules
end
def delegate!(new_subject)
@rule_set.merge(Ability.allowed(@user, new_subject))
end
2016-08-16 19:05:44 +00:00
def can?(rule)
@rule_set.can?(rule)
2016-08-16 19:05:44 +00:00
end
def can!(*rules)
@rule_set.can!(*rules)
end
def cannot!(*rules)
@rule_set.cannot!(*rules)
end
2016-08-12 18:36:16 +00:00
private
def collect_rules(&b)
@rule_set = RuleSet.empty
2016-08-12 18:36:16 +00:00
yield
@rule_set
2016-08-12 18:36:16 +00:00
end
end