Module: Hydra::PolicyAwareAbility

Extended by:
ActiveSupport::Concern
Includes:
Blacklight::AccessControls::Ability, 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.

Constant Summary collapse

IS_GOVERNED_BY_SOLR_FIELD =
"isGovernedBy_ssim".freeze

Instance Method Summary collapse

Methods included from Ability

#create_permissions, #custom_permissions, #discover_permissions, #download_permissions, #edit_permissions, #hydra_default_permissions, #initialize, #read_permissions, user_class

Instance Method Details

#edit_groups_from_policy(policy_id) ⇒ Object

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



68
69
70
71
72
73
74
# File 'lib/hydra/policy_aware_ability.rb', line 68

def edit_groups_from_policy(policy_id)
  policy_permissions = policy_permissions_doc(policy_id)
  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))
  Rails.logger.debug("[CANCAN] -policy- edit_groups: #{eg.inspect}")
  return eg
end

#edit_users_from_policy(policy_id) ⇒ Object

Returns the list of users granted edit access by the policy object identified by policy_id



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

def edit_users_from_policy(policy_id)
  policy_permissions = policy_permissions_doc(policy_id)
  edit_user_field = Hydra.config.permissions.inheritable[:edit][:individual]
  eu = ((policy_permissions == nil || policy_permissions.fetch(edit_user_field,nil) == nil) ? [] : policy_permissions.fetch(edit_user_field,nil))
  Rails.logger.debug("[CANCAN] -policy- edit_users: #{eu.inspect}")
  return eu
end

#governed_by_solr_fieldObject



31
32
33
34
35
# File 'lib/hydra/policy_aware_ability.rb', line 31

def governed_by_solr_field
  # TODO the solr key could be derived if we knew the class of the object:
  #   ModsAsset.reflect_on_association(:admin_policy).solr_key
  IS_GOVERNED_BY_SOLR_FIELD
end

#policy_id_for(object_id) ⇒ Object

Returns the id of policy object (isGovernedBy_ssim) for the specified object Assumes that the policy object is associated by an isGovernedBy relationship (which is stored as “isGovernedBy_ssim” in object’s solr document) Returns nil if no policy associated with the object



23
24
25
26
27
28
29
# File 'lib/hydra/policy_aware_ability.rb', line 23

def policy_id_for(object_id)
  policy_id = policy_id_cache[object_id]
  return policy_id if policy_id
  solr_result = ActiveFedora::Base.search_with_conditions({ id: object_id }, fl: governed_by_solr_field).first
  return unless solr_result
  policy_id_cache[object_id] = policy_id = Array(solr_result[governed_by_solr_field]).first
end

#policy_permissions_doc(policy_id) ⇒ Object

Returns the permissions solr document for policy_id 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 {}



40
41
42
43
# File 'lib/hydra/policy_aware_ability.rb', line 40

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

#read_groups_from_policy(policy_id) ⇒ Object

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



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

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

#read_users_from_policy(policy_id) ⇒ Object

Returns the list of users granted read access by the policy object identified by policy_id Note: edit implies read, so read_users is the union of edit and read users



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

def read_users_from_policy(policy_id)
  policy_permissions = policy_permissions_doc(policy_id)
  read_user_field = Hydra.config.permissions.inheritable[:read][:individual]
  ru = edit_users_from_policy(policy_id) | ((policy_permissions == nil || policy_permissions.fetch(read_user_field, nil) == nil) ? [] : policy_permissions.fetch(read_user_field, nil))
  Rails.logger.debug("[CANCAN] -policy- read_users: #{ru.inspect}")
  return ru
end

#test_edit(id) ⇒ Object

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



10
11
12
# File 'lib/hydra/policy_aware_ability.rb', line 10

def test_edit(id)
  super || test_edit_from_policy(id)
end

#test_edit_from_policy(object_id) ⇒ Object

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



46
47
48
49
50
51
52
53
54
# File 'lib/hydra/policy_aware_ability.rb', line 46

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

#test_read(id) ⇒ Object

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



15
16
17
# File 'lib/hydra/policy_aware_ability.rb', line 15

def test_read(id)
  super || test_read_from_policy(id)
end

#test_read_from_policy(object_id) ⇒ Object

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



57
58
59
60
61
62
63
64
65
# File 'lib/hydra/policy_aware_ability.rb', line 57

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