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 62 |
# 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 allow_deny.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
186 187 188 |
# File 'lib/verifica/acl.rb', line 186 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
77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/verifica/acl.rb', line 77 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?
92 93 94 |
# File 'lib/verifica/acl.rb', line 92 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.
127 128 129 130 131 |
# File 'lib/verifica/acl.rb', line 127 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.
104 105 106 107 |
# File 'lib/verifica/acl.rb', line 104 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
149 150 151 152 153 |
# File 'lib/verifica/acl.rb', line 149 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.
117 118 119 120 |
# File 'lib/verifica/acl.rb', line 117 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
.
170 171 172 |
# File 'lib/verifica/acl.rb', line 170 def empty? @aces.empty? end |
#eql?(other) ⇒ Boolean
190 191 192 193 |
# File 'lib/verifica/acl.rb', line 190 def eql?(other) self.class == other.class && @aces == other.aces end |
#hash ⇒ Object
195 196 197 |
# File 'lib/verifica/acl.rb', line 195 def hash [self.class, @aces].hash end |
#length ⇒ Integer Also known as: size
Returns the count of entries in self
.
177 178 179 |
# File 'lib/verifica/acl.rb', line 177 def length @aces.length end |
#to_a ⇒ Array<Ace>
Returns a new array representing self
.
163 164 165 |
# File 'lib/verifica/acl.rb', line 163 def to_a @aces.to_a end |
#to_s ⇒ Object
182 183 184 |
# File 'lib/verifica/acl.rb', line 182 def to_s @aces.map(&:to_h).to_s end |