Package ndg :: Package xacml :: Package core :: Module policy_combining_alg
[hide private]

Source Code for Module ndg.xacml.core.policy_combining_alg

  1  """NDG XACML Policy Combining Algorithm definitions 
  2   
  3  NERC DataGrid 
  4  """ 
  5  __author__ = "R B Wilkinson" 
  6  __date__ = "01/11/11" 
  7  __copyright__ = "(C) 2011 Science and Technology Facilities Council" 
  8  __contact__ = "Philip.Kershaw@stfc.ac.uk" 
  9  __license__ = "BSD - see LICENSE file in top-level directory" 
 10  __contact__ = "Philip.Kershaw@stfc.ac.uk" 
 11  __revision__ = "$Id$" 
 12  import logging 
 13  log = logging.getLogger(__name__) 
 14   
 15  from abc import abstractmethod 
 16   
 17  from ndg.xacml.core.context.result import Decision 
 18   
 19   
 20  # Policy combining algorithms from the XACML spec. 
 21  ALGORITHMS = ( 
 22  'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:deny-overrides', 
 23  'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides', 
 24  'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable', 
 25  'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:only-one-applicable', 
 26  'urn:oasis:names:tc:xacml:1.1:policy-combining-algorithm:ordered-deny-overrides', 
 27  'urn:oasis:names:tc:xacml:1.1:policy-combining-algorithm:ordered-permit-overrides', 
 28  ) 
29 30 31 -class PolicyCombiningAlgInterface(object):
32 """Interface class for XAML policy combining algorithms""" 33 34 @abstractmethod
35 - def evaluate(self, policies, context):
36 """Combine the results from evaluating policies or policy sets to make 37 an access control decision. Derived classes must implement this 38 method. This implementation returns indeterminate result. 39 40 @param policies: policies and/or policy sets. Decisions from these 41 will be put together into a single decision by this algorithm. 42 @type policies: TypedList(<ndg.xacml.core.policybase.PolicyBase>) 43 @param context: request context to apply to the rules 44 @type context: ndg.xacml.core.request.Request 45 @return: resulting overall access control decision 46 @rtype: ndg.xacml.core.context.result.Decision 47 """ 48 return Decision.INDETERMINATE
49
50 51 -class DenyOverridesPolicyCombiningAlg(PolicyCombiningAlgInterface):
52 """Deny overrides policy combining algorithm""" 53
54 - def evaluate(self, policies, context):
55 """Combine the input policy results to make an access control decision. 56 Implementation taken directly from XACML 2.0 spec. pseudo code - 57 Section C.1 Deny Overrides 58 59 @param policies: policies and/or policy sets. Decisions from these 60 will be put together into a single decision by this algorithm. 61 @type policies: TypedList(<ndg.xacml.core.policybase.PolicyBase>) 62 @param context: request context to apply to the rules 63 @type context: ndg.xacml.core.request.Request 64 @return: resulting overall access control decision 65 @rtype: ndg.xacml.core.context.result.Decision 66 """ 67 atLeastOnePermit = False 68 69 for policy in policies: 70 decision = policy.evaluate(context) 71 if decision == Decision.DENY: 72 return Decision.DENY 73 74 if decision == Decision.PERMIT: 75 atLeastOnePermit = True 76 continue 77 78 if decision == Decision.NOT_APPLICABLE: 79 continue 80 81 if decision == Decision.INDETERMINATE: 82 return Decision.DENY 83 84 if atLeastOnePermit: 85 return Decision.PERMIT 86 87 return Decision.NOT_APPLICABLE
88
89 -class PermitOverridesPolicyCombiningAlg(PolicyCombiningAlgInterface):
90 """Implementation of permit overrides XACML policy combining algorithm""" 91
92 - def evaluate(self, policies, context):
93 """Combine the input policy results to make an access control decision. 94 Implementation taken directly from XACML 2.0 spec. pseudo code - 95 Section C.3 Permit Overrides 96 97 @param policies: policies and/or policy sets. Decisions from these 98 will be put together into a single decision by this algorithm. 99 @type policies: TypedList(<ndg.xacml.core.policybase.PolicyBase>) 100 @param context: request context to apply to the rules 101 @type context: ndg.xacml.core.request.Request 102 @return: resulting overall access control decision 103 @rtype: ndg.xacml.core.context.result.Decision 104 """ 105 atLeastOneError = False 106 atLeastOneDeny = False 107 108 for policy in policies: 109 decision = policy.evaluate(context) 110 if decision == Decision.DENY: 111 atLeastOneDeny = True 112 continue 113 114 if decision == Decision.PERMIT: 115 log.debug("Policy %r permits, returning overall permit" 116 " decision", policy.ident) 117 return Decision.PERMIT 118 119 if decision == Decision.NOT_APPLICABLE: 120 continue 121 122 if decision == Decision.INDETERMINATE: 123 atLeastOneError = True 124 continue 125 126 if atLeastOneDeny: 127 log.debug('At least one policy with a deny decision found, ' 128 'returning overall deny decision') 129 return Decision.DENY 130 131 if atLeastOneError: 132 log.debug('At least one policy with an error found, returning ' 133 'overall indeterminate decision') 134 return Decision.INDETERMINATE 135 136 log.debug('No policies were applicable to the request, returning ' 137 'overall not applicable decision') 138 return Decision.NOT_APPLICABLE
139
140 141 -class FirstApplicablePolicyCombiningAlg(PolicyCombiningAlgInterface):
142 """Implementation of first applicable XACML policy combining algorithm""" 143
144 - def evaluate(self, policies, context):
145 """Combine the results from evaluating policies or policy sets to make 146 an access control decision. Implementation taken directly from XACML 147 2.0 spec. pseudo code - Section C.5 First Applicable 148 149 @param policies: policies and/or policy sets. Decisions from these 150 will be put together into a single decision by this algorithm. 151 @type policies: TypedList(<ndg.xacml.core.policybase.PolicyBase>) 152 @param context: request context to apply to the rules 153 @type context: ndg.xacml.core.request.Request 154 @return: resulting overall access control decision 155 @rtype: ndg.xacml.core.context.result.Decision 156 """ 157 for policy in policies: 158 decision = policy.evaluate(context) 159 if decision == Decision.DENY: 160 log.debug("Policy %r denies, returning overall deny decision", 161 policy.ident) 162 return Decision.DENY 163 164 if decision == Decision.PERMIT: 165 log.debug("Policy %r permits, returning overall permit " 166 "decision", 167 policy.ident) 168 return Decision.PERMIT 169 170 if decision == Decision.NOT_APPLICABLE: 171 continue 172 173 if decision == Decision.INDETERMINATE: 174 log.debug("Policy %r is indeterminate, returning overall " 175 "indeterminate decision", policy.ident) 176 return Decision.INDETERMINATE 177 178 log.debug('No policies were applicable to the request, returning ' 179 'overall not applicable decision') 180 return Decision.NOT_APPLICABLE
181
182 183 -class PolicyCombiningAlgClassFactory(object):
184 """Class Factory mapping Policy Combining Algorithm identifiers to their 185 class implementations""" 186 187 # All algorithms are not implemented by default(!) 188 DEFAULT_MAP = {}.fromkeys(ALGORITHMS, NotImplemented) 189 190 # Permit overrides is the only one currently implemented 191 DEFAULT_MAP.update({ 192 'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:deny-overrides': 193 DenyOverridesPolicyCombiningAlg, 194 'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides': 195 PermitOverridesPolicyCombiningAlg, 196 'urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable': 197 FirstApplicablePolicyCombiningAlg 198 }) 199 __slots__ = ('__map',) 200
201 - def __init__(self, map=DEFAULT_MAP):
202 """Initialise mapping of identifiers to class implementations 203 204 @param map: mapping of policy combining algorithms IDs to classes. Set 205 this to override the default taken from the DEFAULT_MAP class variable 206 """ 207 self.__map = map
208
209 - def __call__(self, identifier):
210 """Return the class for a given Policy Combining Algorithm identifier 211 @param identifier: XACML policy combining algorithm urn 212 @type identifier: basestring 213 @return: policy combining class corresponding to the given input 214 identifier 215 @rtype: PolicyCombiningAlgInterface derived type or NoneType if no match 216 is found or NotImplementedType if the identifier corresponds to a valid 217 XACML policy combining algorithm but is not supported in this 218 implementation 219 """ 220 return self.__map.get(identifier)
221