Class: Verifica::Acl
- Inherits:
-
Object
- Object
- Verifica::Acl
- Defined in:
- lib/verifica/acl.rb
Overview
Access Control List (ACL)
Access Control List consists of Access Control Entities (ACEs) and defines which actions are allowed or denied for particular Security Identifiers (SIDs).
ACL is typically associated with a resource (e.g. Post, Comment, Order) and specifies which users (or external services, or API clients) are allowed to do what actions on the given resource.
Class Method Summary collapse
-
.build {|builder| ... } ⇒ Acl
Creates a new AclBuilder and yields it to the given block.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#action_allowed?(action, sids) ⇒ Boolean
Checks whether the action is allowed for given Security Identifiers.
-
#action_denied?(action, sids) ⇒ Boolean
The opposite of #action_allowed?.
-
#allowed_actions(sids) ⇒ Array<Symbol>
Array of actions allowed for given Security Identifiers or empty array if none.
-
#allowed_sids(action) ⇒ Array<String>
Array of Security Identifiers allowed for a given action or empty array if none.
-
#build {|builder| ... } ⇒ Acl
Creates a new AclBuilder, adds existing entries to it and yields it to the given block.
-
#denied_sids(action) ⇒ Array<String>
Array of Security Identifiers denied for a given action or empty array if none.
-
#empty? ⇒ Boolean
True if there are no entries in
self
. - #eql?(other) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(aces) ⇒ Acl
constructor
Creates a new Access Control List with immutable state.
-
#length ⇒ Integer
(also: #size)
The count of entries in
self
. -
#to_a ⇒ Array<Ace>
A new array representing
self
. - #to_s ⇒ Object
Constructor Details
#initialize(aces) ⇒ Acl
Use build instead of this constructor directly.
Creates a new Access Control List with immutable state.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/verifica/acl.rb', line 48 def initialize(aces) @aces = Set.new(aces).freeze @allow_deny_by_action = prepare_index.freeze @allowed_actions = Set.new @allow_deny_by_action.each do |action, allow_deny| @allowed_actions.add(action) unless allow_deny[:allowed_sids].empty? allow_deny[:allowed_sids].freeze allow_deny[:denied_sids].freeze end @allowed_actions.freeze freeze end |
Class Method Details
.build {|builder| ... } ⇒ Acl
Creates a new Verifica::AclBuilder and yields it to the given block.
33 34 35 36 37 |
# File 'lib/verifica/acl.rb', line 33 def self.build builder = AclBuilder.new yield builder builder.build end |
Instance Method Details
#==(other) ⇒ Object
185 186 187 |
# File 'lib/verifica/acl.rb', line 185 def ==(other) eql?(other) end |
#action_allowed?(action, sids) ⇒ Boolean
Checks whether the action is allowed for given Security Identifiers. For action to be allowed all 3 conditions should be met:
-
ACL and SIDs are not empty
-
ACL contains at least one entry that allow given action for any of the SIDs
-
ACL contains no entries that deny given action for any of the SIDs
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/verifica/acl.rb', line 76 def action_allowed?(action, sids) return false if empty? || sids.empty? action = action.to_sym allow_deny = @allow_deny_by_action[action] return false if allow_deny.nil? || !@allowed_actions.include?(action) sids = sids.to_set allow_deny[:allowed_sids].intersect?(sids) && !allow_deny[:denied_sids].intersect?(sids) end |
#action_denied?(action, sids) ⇒ Boolean
The opposite of #action_allowed?
91 92 93 |
# File 'lib/verifica/acl.rb', line 91 def action_denied?(action, sids) !action_allowed?(action, sids) end |
#allowed_actions(sids) ⇒ Array<Symbol>
Returns array of actions allowed for given Security Identifiers or empty array if none.
126 127 128 129 130 |
# File 'lib/verifica/acl.rb', line 126 def allowed_actions(sids) return EMPTY_ARRAY if sids.empty? @allowed_actions.select { |action| action_allowed?(action, sids) } end |
#allowed_sids(action) ⇒ Array<String>
Checking allowed SIDs isn’t enough to determine whether the action is allowed. You need to always check #denied_sids as well.
Returns array of Security Identifiers allowed for a given action or empty array if none.
103 104 105 106 |
# File 'lib/verifica/acl.rb', line 103 def allowed_sids(action) sids = @allow_deny_by_action.dig(action.to_sym, :allowed_sids) sids.nil? ? EMPTY_ARRAY : sids.to_a end |
#build {|builder| ... } ⇒ Acl
Creates a new Verifica::AclBuilder, adds existing entries to it and yields it to the given block. Use this method to extend an existing ACL with additional entries
148 149 150 151 152 |
# File 'lib/verifica/acl.rb', line 148 def build builder = AclBuilder.new(to_a) yield builder builder.build end |
#denied_sids(action) ⇒ Array<String>
Checking denied SIDs isn’t enough to determine whether the action is allowed. You need to always check #allowed_sids as well.
Returns array of Security Identifiers denied for a given action or empty array if none.
116 117 118 119 |
# File 'lib/verifica/acl.rb', line 116 def denied_sids(action) sids = @allow_deny_by_action.dig(action.to_sym, :denied_sids) sids.nil? ? EMPTY_ARRAY : sids.to_a end |
#empty? ⇒ Boolean
Returns true if there are no entries in self
.
169 170 171 |
# File 'lib/verifica/acl.rb', line 169 def empty? @aces.empty? end |
#eql?(other) ⇒ Boolean
189 190 191 192 |
# File 'lib/verifica/acl.rb', line 189 def eql?(other) self.class == other.class && @aces == other.aces end |
#hash ⇒ Object
194 195 196 |
# File 'lib/verifica/acl.rb', line 194 def hash [self.class, @aces].hash end |
#length ⇒ Integer Also known as: size
Returns the count of entries in self
.
176 177 178 |
# File 'lib/verifica/acl.rb', line 176 def length @aces.length end |
#to_a ⇒ Array<Ace>
Returns a new array representing self
.
162 163 164 |
# File 'lib/verifica/acl.rb', line 162 def to_a @aces.to_a end |
#to_s ⇒ Object
181 182 183 |
# File 'lib/verifica/acl.rb', line 181 def to_s @aces.map(&:to_h).to_s end |