Class: PolicyMachineStorageAdapter::ActiveRecord
- Inherits:
-
Object
- Object
- PolicyMachineStorageAdapter::ActiveRecord
- Defined in:
- lib/policy_machine_storage_adapters/active_record.rb
Defined Under Namespace
Classes: Assignment, Object, ObjectAttribute, Operation, PolicyClass, PolicyElement, PolicyElementAssociation, TransitiveClosure, User, UserAttribute
Constant Summary collapse
- POLICY_ELEMENT_TYPES =
%w(user user_attribute object object_attribute operation policy_class)
Instance Method Summary collapse
-
#add_association(user_attribute, operation_set, object_attribute, policy_machine_uuid) ⇒ Object
Add the given association to the policy map.
-
#assign(src, dst) ⇒ Object
Assign src to dst in policy machine.
-
#associations_with(operation) ⇒ Object
Return an array of all associations in which the given operation is included.
- #class_for_type(pe_type) ⇒ Object
-
#connected?(src, dst) ⇒ Boolean
Determine if there is a path from src to dst in the policy machine.
-
#delete(element) ⇒ Object
Remove a persisted policy element.
-
#element_in_machine?(pe) ⇒ Boolean
Determine if the given node is in the policy machine or not.
-
#policy_classes_for_object_attribute(object_attribute) ⇒ Object
Return array of all policy classes which contain the given object_attribute (or object).
-
#scoped_privileges(user_or_attribute, object_or_attribute) ⇒ Object
Optimized version of PolicyMachine#scoped_privileges Returns all operations the user has on the object.
-
#transaction(&block) ⇒ Object
Execute the passed-in block transactionally: any error raised out of the block causes all the block’s changes to be rolled back.
-
#unassign(src, dst) ⇒ Object
Disconnect two policy elements in the machine The two policy elements must be persisted policy elements; otherwise the method should raise an ArgumentError.
-
#update(element, changes_hash) ⇒ Object
Update the extra_attributes of a persisted policy element.
-
#user_attributes_for_user(user) ⇒ Object
Return array of all user attributes which contain the given user.
Instance Method Details
#add_association(user_attribute, operation_set, object_attribute, policy_machine_uuid) ⇒ Object
Add the given association to the policy map. If an association between user_attribute and object_attribute already exists, then replace it with that given in the arguments. Returns true if the association was added and false otherwise.
258 259 260 261 262 263 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 258 def add_association(user_attribute, operation_set, object_attribute, policy_machine_uuid) PolicyElementAssociation.where( user_attribute_id: user_attribute.id, object_attribute_id: object_attribute.id ).first_or_create.operations = operation_set.to_a end |
#assign(src, dst) ⇒ Object
Assign src to dst in policy machine. The two policy elements must be persisted policy elements Returns true if the assignment occurred, false otherwise.
193 194 195 196 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 193 def assign(src, dst) assert_persisted_policy_element(src, dst) src.children << dst end |
#associations_with(operation) ⇒ Object
Return an array of all associations in which the given operation is included. Each element of the array should itself be an array in which the first element is the user_attribute member of the association, the second element is a Ruby Set, each element of which is an operation, the third element is the object_attribute member of the association. If no associations are found then the empty array should be returned.
273 274 275 276 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 273 def associations_with(operation) assocs = operation.policy_element_associations.all(include: [:user_attribute, :operations, :object_attribute]) assocs.map { |assoc| [assoc.user_attribute, Set.new(assoc.operations), assoc.object_attribute] } end |
#class_for_type(pe_type) ⇒ Object
183 184 185 186 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 183 def class_for_type(pe_type) @pe_type_class_hash ||= Hash.new { |h,k| h[k] = "PolicyMachineStorageAdapter::ActiveRecord::#{k.camelize}".constantize } @pe_type_class_hash[pe_type] end |
#connected?(src, dst) ⇒ Boolean
Determine if there is a path from src to dst in the policy machine. The two policy elements must be persisted policy elements; otherwise the method should raise an ArgumentError. Returns true if there is a such a path and false otherwise. Should return true if src == dst
205 206 207 208 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 205 def connected?(src, dst) assert_persisted_policy_element(src, dst) src == dst || Assignment.transitive_closure?(src, dst) end |
#delete(element) ⇒ Object
Remove a persisted policy element. This should remove its assignments and associations but must not cascade to any connected policy elements. Returns true if the delete succeeded.
230 231 232 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 230 def delete(element) element.destroy end |
#element_in_machine?(pe) ⇒ Boolean
Determine if the given node is in the policy machine or not. Returns true or false accordingly. TODO: This seems wrong.
249 250 251 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 249 def element_in_machine?(pe) pe.persisted? end |
#policy_classes_for_object_attribute(object_attribute) ⇒ Object
Return array of all policy classes which contain the given object_attribute (or object). Return empty array if no such policy classes found.
281 282 283 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 281 def policy_classes_for_object_attribute(object_attribute) object_attribute.descendants.where(type: class_for_type('policy_class')) end |
#scoped_privileges(user_or_attribute, object_or_attribute) ⇒ Object
Optimized version of PolicyMachine#scoped_privileges Returns all operations the user has on the object
301 302 303 304 305 306 307 308 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 301 def scoped_privileges(user_or_attribute, object_or_attribute) policy_classes_containing_object = policy_classes_for_object_attribute(object_or_attribute) if policy_classes_containing_object.count < 2 scoped_privileges_single_policy_class(user_or_attribute, object_or_attribute) else scoped_privileges_multiple_policy_classes(user_or_attribute, object_or_attribute, policy_classes_containing_object) end end |
#transaction(&block) ⇒ Object
Execute the passed-in block transactionally: any error raised out of the block causes all the block’s changes to be rolled back.
295 296 297 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 295 def transaction(&block) PolicyElement.transaction(&block) end |
#unassign(src, dst) ⇒ Object
Disconnect two policy elements in the machine The two policy elements must be persisted policy elements; otherwise the method should raise an ArgumentError. Returns true if unassignment occurred and false otherwise. Generally, false will be returned if the assignment didn’t exist in the PM in the first place.
218 219 220 221 222 223 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 218 def unassign(src, dst) assert_persisted_policy_element(src, dst) if assignment = src.assignments.where(child_id: dst.id).first assignment.destroy end end |
#update(element, changes_hash) ⇒ Object
Update the extra_attributes of a persisted policy element. This should only affect attributes corresponding to the keys passed in. Returns true if the update succeeded or was redundant.
239 240 241 242 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 239 def update(element, changes_hash) changes_hash.each { |k,v| element.send("#{k}=",v) } element.save end |
#user_attributes_for_user(user) ⇒ Object
Return array of all user attributes which contain the given user. Return empty array if no such user attributes are found.
288 289 290 |
# File 'lib/policy_machine_storage_adapters/active_record.rb', line 288 def user_attributes_for_user(user) user.descendants.where(type: class_for_type('user_attribute')) end |