Class: AccessAllow::AccessManager

Inherits:
Object
  • Object
show all
Defined in:
lib/access_allow/access_manager.rb

Constant Summary collapse

VIOLATION_TYPES =
%i[severe hidden redirect not_permitted].freeze

Instance Method Summary collapse

Constructor Details

#initializeAccessManager

Returns a new instance of AccessManager.



7
8
9
10
11
12
13
# File 'lib/access_allow/access_manager.rb', line 7

def initialize
  @required_rules = []
  @action_rules = []
  @named_rules_map = {}
  @all_actions_rules = []
  @no_match_rule = {violation: :severe}
end

Instance Method Details

#add_allow_rule(rule, to, with = nil, as = nil) ⇒ Object



24
25
26
# File 'lib/access_allow/access_manager.rb', line 24

def add_allow_rule(rule, to, with = nil, as = nil)
  insert_access_rule(parse_rule(rule, to: to, with: with, as: as))
end

#add_required_rule(rule, violation, with = nil, handler = nil) ⇒ Object



28
29
30
31
32
33
# File 'lib/access_allow/access_manager.rb', line 28

def add_required_rule(rule, violation, with = nil, handler = nil)
  unless VIOLATION_TYPES.include?(violation)
    raise StandardError, "You must provide a valid violation type"
  end
  insert_required_rule(rule, with, violation, handler)
end

#allow?(rules, user, current_controller) ⇒ Boolean

Evaluate specific rules. Ie we dont check action match, we just find if there are any checks that pass for the current context. Used in view helper. The rules are defined with access_allow and a name or alias.

Returns:

  • (Boolean)


70
71
72
73
74
75
76
77
# File 'lib/access_allow/access_manager.rb', line 70

def allow?(rules, user, current_controller)
  Array
    .wrap(rules)
    .any? do |rule|
      rule_configs = named_rules_map[rule]
      rule_configs&.any? { |config| execute_rule(config, user, current_controller) }
    end
end

#allow_action?(user, controller, current_action) ⇒ Boolean

Compare against all configured rules which have actions

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/access_allow/access_manager.rb', line 52

def allow_action?(user, controller, current_action)
  # Required checks must all pass
  required_rules.each do |config|
    permitted_or_violation = execute_required_rule(config, user, controller, current_action)
    return permitted_or_violation unless permitted_or_violation == true
  end

  # Check action rules
  allowed =
    action_rules.any? { |config| execute_rule(config, user, controller, current_action) }
  return true if allowed

  # return no-match
  no_match_rule
end

#configure_no_match(violation_type, &block) ⇒ Object



35
36
37
38
39
# File 'lib/access_allow/access_manager.rb', line 35

def configure_no_match(violation_type, &block)
  rule = {violation: violation_type}
  rule[:handler] = block if block
  @no_match_rule = rule
end

#initialize_clone(parent_manager) ⇒ Object

When initialising an access manager for a controller make sure to clone the current parent controllers rules



16
17
18
19
20
21
22
# File 'lib/access_allow/access_manager.rb', line 16

def initialize_clone(parent_manager)
  @required_rules = parent_manager.required_rules.deep_dup
  @action_rules = parent_manager.action_rules.deep_dup
  @named_rules_map = parent_manager.named_rules_map.deep_dup
  @all_actions_rules = parent_manager.all_actions_rules.deep_dup
  @no_match_rule = parent_manager.no_match_rule.deep_dup
end

#named_rule_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/access_allow/access_manager.rb', line 85

def named_rule_exists?(name)
  !named_rules_map[name].nil?
end

#no_match_violationObject

Introspection methods



81
82
83
# File 'lib/access_allow/access_manager.rb', line 81

def no_match_violation
  no_match_rule[:violation]
end

#required_check_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


89
90
91
92
93
# File 'lib/access_allow/access_manager.rb', line 89

def required_check_exists?(name)
  required_rules.any? do |r|
    r[:rules_set][:all]&.include?(name) || r[:rules_set][:any]&.include?(name)
  end
end