class PolicyMachineStorageAdapter::InMemory
Constants
- POLICY_ELEMENT_TYPES
Public Instance Methods
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.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 106 def add_association(user_attribute, operation_set, object_attribute, policy_machine_uuid) # TODO: scope by policy machine uuid associations[user_attribute.unique_identifier + object_attribute.unique_identifier] = [user_attribute, operation_set, object_attribute] true end
Assign src to dst in policy machine
# File lib/policy_machine_storage_adapters/in_memory.rb, line 44 def assign(src, dst) assert_persisted_policy_element(src) assert_persisted_policy_element(dst) assignments << [src, dst] true end
Return all associations in which the given operation is included Returns an array of arrays. Each sub-array is of the form
- user_attribute, operation_set, object_attribute
# File lib/policy_machine_storage_adapters/in_memory.rb, line 118 def associations_with(operation) matching = associations.values.select do |assoc| assoc[1].include?(operation) end matching.map{ |m| [m[0], m[1], m[2]] } end
Determine if there is a path from src to dst in the policy machine
# File lib/policy_machine_storage_adapters/in_memory.rb, line 55 def connected?(src, dst) assert_persisted_policy_element(src) assert_persisted_policy_element(dst) return true if src == dst distances = dijkstra(src, dst) distances.nil? ? false : true end
Remove a persisted policy element
# File lib/policy_machine_storage_adapters/in_memory.rb, line 84 def delete(element) assignments.delete_if{ |assgn| assgn.include?(element) } associations.delete_if { |_,assoc| assoc.include?(element) } policy_elements.delete(element) end
Determine if the given node is in the policy machine or not.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 99 def element_in_machine?(pe) policy_elements.member?( pe ) end
Return array of all policy classes which contain the given object_attribute (or object). Return empty array if no such policy classes found.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 129 def policy_classes_for_object_attribute(object_attribute) find_all_of_type_policy_class.select do |pc| connected?(object_attribute, pc) end end
Execute the passed-in block transactionally: any error raised out of the block causes all the block’s changes to be rolled back.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 147 def transaction old_state = dup instance_variables.each do |var| value = instance_variable_get(var) if (value.respond_to?(:dup)) old_state.instance_variable_set(var, value.dup) end end begin yield rescue Exception instance_variables.each do |var| value = old_state.instance_variable_get(var) instance_variable_set(var, value) end raise end end
Disconnect two policy elements in the machine
# File lib/policy_machine_storage_adapters/in_memory.rb, line 68 def unassign(src, dst) assert_persisted_policy_element(src) assert_persisted_policy_element(dst) assignment = assignments.find{|assgn| assgn[0] == src && assgn[1] == dst} if assignment assignments.delete(assignment) true else false end end
Update a persisted policy element
# File lib/policy_machine_storage_adapters/in_memory.rb, line 93 def update(element, changes_hash) element.send(:extra_attributes).merge!(changes_hash) end
Return array of all user attributes which contain the given user. Return empty array if no such user attributes are found.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 138 def user_attributes_for_user(user) find_all_of_type_user_attribute.select do |user_attribute| connected?(user, user_attribute) end end
Private Instance Methods
Raise argument error if argument is not suitable for consumption in public methods.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 173 def assert_persisted_policy_element(arg) raise(ArgumentError, "arg must be a PersistedPolicyElement; got #{arg.class.name}") unless arg.is_a?(PersistedPolicyElement) raise(ArgumentError, "arg must be persisted") unless element_in_machine?(arg) end
The policy element assignments in the persisted policy machine.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 184 def assignments @assignments ||= [] end
All persisted associations
# File lib/policy_machine_storage_adapters/in_memory.rb, line 189 def associations @associations ||= {} end
# File lib/policy_machine_storage_adapters/in_memory.rb, line 193 def dijkstra(src, dst = nil) nodes = policy_elements distances = {} previouses = {} nodes.each do |vertex| distances[vertex] = nil # Infinity previouses[vertex] = nil end distances[src] = 0 vertices = nodes.clone until vertices.empty? nearest_vertex = vertices.inject do |a, b| next b unless distances[a] next a unless distances[b] next a if distances[a] < distances[b] b end break unless distances[nearest_vertex] # Infinity if dst and nearest_vertex == dst return distances[dst] end neighbors = neighbors(nearest_vertex) neighbors.each do |vertex| alt = distances[nearest_vertex] + 1 if distances[vertex].nil? or alt < distances[vertex] distances[vertex] = alt previouses[vertices] = nearest_vertex # decrease-key v in Q # ??? end end vertices.delete nearest_vertex end return nil end
Find all nodes which are directly connected to node
# File lib/policy_machine_storage_adapters/in_memory.rb, line 232 def neighbors(pe) neighbors = [] assignments.each do |assignment| neighbors.push assignment[1] if assignment[0] == pe end return neighbors.uniq end
The policy elements in the persisted policy machine.
# File lib/policy_machine_storage_adapters/in_memory.rb, line 179 def policy_elements @policy_elements ||= [] end