Module: Hydra::PolicyAwareAbility

Included in:
Ability
Defined in:
lib/hydra/policy_aware_ability.rb

Overview

Repeats access controls evaluation methods, but checks against a governing “Policy” object (or “Collection” object) that provides inherited access controls.

Instance Method Summary collapse

Instance Method Details

#edit_groups_from_policy(policy_pid) ⇒ Object

Returns the list of groups granted edit access by the policy object identified by policy_pid



76
77
78
79
80
81
82
# File 'lib/hydra/policy_aware_ability.rb', line 76

def edit_groups_from_policy(policy_pid)
  policy_permissions = policy_permissions_doc(policy_pid)
  edit_group_field = Hydra.config[:permissions][:inheritable][:edit][:group]
  eg = ((policy_permissions == nil || policy_permissions.fetch(edit_group_field,nil) == nil) ? [] : policy_permissions.fetch(edit_group_field,nil))
  logger.debug("[CANCAN] -policy- edit_groups: #{eg.inspect}")
  return eg
end

#edit_persons_from_policy(policy_pid) ⇒ Object

Returns the list of individuals granted edit access by the policy object identified by policy_pid



95
96
97
98
99
100
101
# File 'lib/hydra/policy_aware_ability.rb', line 95

def edit_persons_from_policy(policy_pid)
  policy_permissions = policy_permissions_doc(policy_pid)
  edit_person_field = Hydra.config[:permissions][:inheritable][:edit][:individual]
  ep = ((policy_permissions == nil || policy_permissions.fetch(edit_person_field,nil) == nil) ? [] : policy_permissions.fetch(edit_person_field,nil))
  logger.debug("[CANCAN] -policy- edit_persons: #{ep.inspect}")
  return ep
end

#policy_permissions_doc(policy_pid) ⇒ Object

Returns the permissions solr document for policy_pid The document is stored in an instance variable, so calling this multiple times will only query solr once. To force reload, set @policy_permissions_solr_cache to {}



42
43
44
45
# File 'lib/hydra/policy_aware_ability.rb', line 42

def policy_permissions_doc(policy_pid)
  @policy_permissions_solr_cache ||= {}
  @policy_permissions_solr_cache[policy_pid] ||= get_permissions_solr_response_for_doc_id(policy_pid)
end

#policy_pid_for(object_pid) ⇒ Object

Returns the pid of policy object (is_governed_by) for the specified object Assumes that the policy object is associated by an is_governed_by relationship (Whis is stored as “is_governed_by_s” in object’s solr document) Returns nil if no policy associated with the object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/hydra/policy_aware_ability.rb', line 27

def policy_pid_for(object_pid)
  return @policy_pid if @policy_pid
  #is_governed_by_ssim
  solr_result = ActiveFedora::Base.find_with_conditions({:id=>object_pid}, :fl=>ActiveFedora::SolrService.solr_name('is_governed_by', :symbol))
  begin
    @policy_pid = value_from_solr_field(solr_result, ActiveFedora::SolrService.solr_name('is_governed_by', :symbol)).first.gsub("info:fedora/", "")
  rescue NoMethodError
    @policy_pid = nil
  end
  return @policy_pid
end

#read_groups_from_policy(policy_pid) ⇒ Object

Returns the list of groups granted read access by the policy object identified by policy_pid Note: edit implies read, so read_groups is the union of edit and read groups



86
87
88
89
90
91
92
# File 'lib/hydra/policy_aware_ability.rb', line 86

def read_groups_from_policy(policy_pid)
  policy_permissions = policy_permissions_doc(policy_pid)
  read_group_field = Hydra.config[:permissions][:inheritable][:read][:group]
  rg = edit_groups_from_policy(policy_pid) | ((policy_permissions == nil || policy_permissions.fetch(read_group_field,nil) == nil) ? [] : policy_permissions.fetch(read_group_field,nil))
  logger.debug("[CANCAN] -policy- read_groups: #{rg.inspect}")
  return rg
end

#read_persons_from_policy(policy_pid) ⇒ Object

Returns the list of individuals granted read access by the policy object identified by policy_pid Noate: edit implies read, so read_persons is the union of edit and read persons



105
106
107
108
109
110
111
# File 'lib/hydra/policy_aware_ability.rb', line 105

def read_persons_from_policy(policy_pid)
  policy_permissions = policy_permissions_doc(policy_pid)
  read_individual_field = Hydra.config[:permissions][:inheritable][:read][:individual]
  rp = edit_persons_from_policy(policy_pid) | ((policy_permissions == nil || policy_permissions.fetch(read_individual_field,nil) == nil) ? [] : policy_permissions.fetch(read_individual_field,nil))
  logger.debug("[CANCAN] -policy- read_persons: #{rp.inspect}")
  return rp
end

#test_edit(pid) ⇒ Object

Extends Hydra::Ability.test_edit to try policy controls if object-level controls deny access



5
6
7
8
9
10
11
12
# File 'lib/hydra/policy_aware_ability.rb', line 5

def test_edit(pid)
  result = super
  if result 
    return result
  else
    return test_edit_from_policy(pid)
  end
end

#test_edit_from_policy(object_pid) ⇒ Object

Tests whether the object’s governing policy object grants edit access for the current user



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/hydra/policy_aware_ability.rb', line 48

def test_edit_from_policy(object_pid)
  policy_pid = policy_pid_for(object_pid)
  if policy_pid.nil?
    return false
  else
    logger.debug("[CANCAN] -policy- Does the POLICY #{policy_pid} provide EDIT permissions for #{current_user.user_key}?")
    group_intersection = user_groups & edit_groups_from_policy( policy_pid )
    result = !group_intersection.empty? || edit_persons_from_policy( policy_pid ).include?(current_user.user_key)
    logger.debug("[CANCAN] -policy- decision: #{result}")
    return result
  end
end

#test_read(pid) ⇒ Object

Extends Hydra::Ability.test_read to try policy controls if object-level controls deny access



15
16
17
18
19
20
21
22
# File 'lib/hydra/policy_aware_ability.rb', line 15

def test_read(pid)
  result = super
  if result 
    return result
  else
    return test_read_from_policy(pid)
  end
end

#test_read_from_policy(object_pid) ⇒ Object

Tests whether the object’s governing policy object grants read access for the current user



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/hydra/policy_aware_ability.rb', line 62

def test_read_from_policy(object_pid)
  policy_pid = policy_pid_for(object_pid)
  if policy_pid.nil?
    return false
  else
    logger.debug("[CANCAN] -policy- Does the POLICY #{policy_pid} provide READ permissions for #{current_user.user_key}?")
    group_intersection = user_groups & read_groups_from_policy( policy_pid )
    result = !group_intersection.empty? || read_persons_from_policy( policy_pid ).include?(current_user.user_key)
    logger.debug("[CANCAN] -policy- decision: #{result}")
    result
  end
end