Class: PolicyMachineStorageAdapter::ActiveRecord

Inherits:
Object
  • Object
show all
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

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

Returns:

  • (Boolean)


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.

Returns:

  • (Boolean)


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