Class: Acu::Monitor

Inherits:
Object
  • Object
show all
Defined in:
lib/acu/monitor.rb

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.kwargs ⇒ Object (readonly)

Returns the value of attribute kwargs.



12
13
14
# File 'lib/acu/monitor.rb', line 12

def kwargs
  @kwargs
end

Class Method Details

.args(kwargs) ⇒ Object



14
15
16
# File 'lib/acu/monitor.rb', line 14

def args kwargs
  @kwargs = @kwargs.merge(kwargs)
end

.clear_args ⇒ Object



18
19
20
# File 'lib/acu/monitor.rb', line 18

def clear_args
  @kwargs = { }
end

.clear_cache ⇒ Object



122
123
124
125
# File 'lib/acu/monitor.rb', line 122

def clear_cache
  return if not Configs.get :use_cache
  Rails.cache.clear namespace: (Configs.get :cache_namespace)
end

.gaurd(by: { }) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/acu/monitor.rb', line 22

def gaurd by: { }
  # assign the args in class scope
  args by

  # fetch the request & process it
  _info = process Acu::Listeners.data[:request]

  # return if we hit the cache
  return if hit_cache _info

  rules = Rules.rules.select do |cond, _|
    flag = true;

    # check if this is a global rule!
    next true if cond.empty?

    {namespace: nil, controller: :namespace, action: :controller}.each do |current, parent|
      t = -1
      # either mentioned explicitly
      if cond[current] and not cond[current].empty?
        # hierarchical match `_info[current]` with `cond[current]` to support nested namespace (since v3.0.0)   
        cond[current].map { |c| c[:name].to_s }.each.with_index do |c, index|
          t = (c == eval("_info.#{current}")[index].to_s) ? 1 : 0
          break if t == 0
        end
      # or in `only|except` tags
      elsif parent and cond[parent] and not cond[parent].empty?
        # if nothing mentioned in parent, assume for all
        t = 1 if not cond[parent].map { |c| c[:only] or c[:except] }.all?
        # flag true if it checked in namespace's only tag
        {only: {on_true: 1, on_false: 0} , except: {on_true: 0, on_false: 1}}.each do |tag, val|
          # fetch all `tag` names
          tag_list = cond[parent].map { |c| c[tag] }.flatten - [nil]
          # if any tag is present?
          if not tag_list.empty? and tag_list.any?
            # if `current` is mentioned in `tag_list`? 
            case not (tag_list.map(&:to_s) & eval("_info.#{current}").map(&:to_s)).empty?
            when true
              t = val[:on_true]
              break
            when false
              t = val[:on_false]
            end
          end
        end
      end
      flag &= (t == 1) if t.between? 0, 1;
      break if not flag
    end
    flag
  end
  # flag so we can process all the related rule and it all passed this should be false
  # if any failed, and exception will be raised
  _granted = -1
  _entitled_entities = [];
  # for each mached rule
  rules.each do |_, rule|
    # for each entity and it's actions in the rule
    rule.each do |entity, action|
      # check it the current request can relay to the entity?
      if valid_for? entity
        _entitled_entities << entity.to_s
        # current entity is granted to have the access?
        if is_allowed? action
          # cache the permision for the entity
          cache_access _info, _entitled_entities[-1], Rules.GRANT_SYMBOL
          # grant the access if already not denied
          _granted = 1 if _granted == -1
        else
          # cache the permision for the entity
          cache_access _info, _entitled_entities[-1], Rules.DENY_SYMBOL
          # deny it, period!
          _granted = 0
        end
      end
    end
  end
  
  # if the access is granted? i.e if all the rules are satisfied with the request
  return if _granted == 1 and access_granted _info, _entitled_entities
  # if the access is denied? i.e at least one of rules are NOT satisfied with the request
  return if _granted == 0 and access_denied  _info, _entitled_entities
  # if we reached here it measn that have found no rule to deny/allow the request and we have to fallback to the defaults
  access_denied  _info, [:__ACU_BY_DEFAULT__], by_default: true if not Configs.get :allow_by_default
  access_granted _info, [:__ACU_BY_DEFAULT__], by_default: true
end

.valid_for?(entity) ⇒ Boolean

Returns:

  • (Boolean)

Raises:



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/acu/monitor.rb', line 109

def valid_for? entity
  # check for existance
  raise Errors::MissingEntity.new("whois(:#{entity})?") if not Rules.entities[entity]
  # fetch the entity's identity
  e = Rules.entities[entity]
  # fetch the related args to the entity from the `kwargs`
  kwargs = @kwargs.reject { |x| !e[:args].include?(x) }
  # if fetched args and pre-defined arg didn't match?
  raise Errors::MissingData.new("at least one of arguments for `whois(:#{entity})` is not provided!") if kwargs.length != e[:args].length
  # send varibles in order the have defined
  e[:callback].call(*e[:args].map { |i| kwargs[i] })
end