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

Source Code for Module ndg.xacml.core.policybase

  1  """NDG Security Policy and PolicySet base class 
  2   
  3  NERC DataGrid 
  4  """ 
  5  __author__ = "P J Kershaw" 
  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   
 13  from abc import ABCMeta, abstractmethod, abstractproperty 
 14  import traceback 
 15  import logging 
 16  log = logging.getLogger(__name__) 
 17   
 18  from ndg.xacml.finder.policyfinderbase import PolicyFinderBase 
 19  from ndg.xacml.parsers import AbstractReaderFactory, AbstractReader 
 20  from ndg.xacml.parsers.common import Common 
 21  from ndg.xacml.core import XacmlCoreBase 
 22   
 23  # Evaluation of a request context 
 24  from ndg.xacml.core.context.response import Response 
 25  from ndg.xacml.core.context.result import Result, Decision 
 26  from ndg.xacml.core.context.exceptions import XacmlContextError 
27 28 29 -class PolicyBase(XacmlCoreBase):
30 __metaclass__ = ABCMeta 31 ''' 32 Base class for Policy and PolicySet, each of which can be nested within 33 PolicySets and evaluated with policy combining algorithms. 34 ''' 35 36 __slots__ = () 37
38 - def __init__(self):
39 super(PolicyBase, self).__init__()
40 41 @abstractproperty
42 - def ident(self):
43 """Subclasses return the identifier appropriate to the class. 44 """ 45 return None
46 47 @classmethod
48 - def fromSource(cls, source, readerFactory, finder):
49 """Create a new policy or policy set from the input source parsing it 50 using a reader from the required reader factory e.g. ETreeReaderFactory 51 to use ElementTree based parsing. 52 53 @param source: source from which to read the policy - file path, 54 file object, XML node or other dependent on the reader factory selected 55 @type source: string, file, XML node type 56 @param readerFactory: factory class returns reader class used to parse 57 the policy 58 @type readerFactory: ndg.xacml.parsers.AbstractReaderFactory 59 @param finder: policy finder 60 @type finder: ndg.xacml.finder.PolicyFinderBase subclass 61 @return: new policy instance 62 @rtype: ndg.xacml.core.policy.Policy 63 """ 64 if not issubclass(readerFactory, AbstractReaderFactory): 65 raise TypeError('Expecting %r derived class for reader factory ' 66 'method; got %r' % (AbstractReaderFactory, 67 readerFactory)) 68 69 reader = readerFactory.getReader(cls) 70 if not issubclass(reader, AbstractReader): 71 raise TypeError('Expecting %r derived class for reader class; ' 72 'got %r' % (AbstractReader, reader)) 73 74 if not isinstance(finder, PolicyFinderBase): 75 raise TypeError('Expecting %r derived object for policy finder; ' 76 'got %r' % (PolicyFinderBase, type(finder))) 77 finder.setReader(reader) 78 79 common = Common(finder) 80 return reader.parse(source, common)
81 82 @classmethod
83 - def fromNestedSource(cls, source, common):
84 """Create a new policy or policy set from the input source parsing it 85 using a reader from the required reader factory e.g. ETreeReaderFactory 86 to use ElementTree based parsing. 87 88 @param source: source from which to read the policy - file path, 89 file object, XML node or other dependent on the reader factory selected 90 @type source: string, file, XML node type 91 @param readerFactory: factory class returns reader class used to parse 92 the policy 93 @type readerFactory: ndg.xacml.parsers.AbstractReaderFactory 94 @return: new policy instance 95 @rtype: ndg.xacml.core.policy.Policy 96 """ 97 reader = common.policyFinder.reader 98 return reader.parse(source, common)
99
100 - def evaluateResponse(self, request):
101 """Make an access control decision for the given request based on this 102 policy or policy set, returning a response object. 103 104 @param request: XACML request context 105 @type request: ndg.xacml.core.context.request.Request 106 @return: XACML response instance 107 @rtype: ndg.xacml.core.context.response.Response 108 """ 109 response = Response() 110 result = Result.createInitialised(decision=Decision.NOT_APPLICABLE) 111 response.results.append(result) 112 113 try: 114 result.decision = self.evaluate(request) 115 except XacmlContextError, e: 116 log.error('Exception raised evaluating request context, returning ' 117 '%r decision:%s', 118 e.response.results[0].decision, 119 traceback.format_exc()) 120 121 result = e.response.results[0] 122 123 return response
124
125 - def evaluate(self, context):
126 """Evaluate the decision for this policy or policy set and context. 127 128 @param context: XACML request context 129 @type context: ndg.xacml.core.context.request.Request 130 @return: XACML response instance 131 @rtype: ndg.xacml.core.context.result.Decision 132 @raise XacmlContextError: error evaluating input request context 133 """ 134 # Exception block around all rule processing in order to set 135 # INDETERMINATE response from any exceptions raised 136 try: 137 log.debug('Evaluating %s %r ...', self.ELEMENT_LOCAL_NAME, 138 self.ident) 139 140 # Instantiation implicitly sets to default value of Indeterminate. 141 decision = Decision() 142 143 # Check for a policy(set) target. 144 if self.target is not None: 145 targetMatch = self.target.match(context) 146 if targetMatch: 147 log.debug('Match to request context for target in %s ' 148 '%r', self.ELEMENT_LOCAL_NAME, self.ident) 149 else: 150 log.debug('No target set in %s %r', self.ELEMENT_LOCAL_NAME, 151 self.ident) 152 targetMatch = True 153 154 if not targetMatch: 155 log.debug('No match to request context for target in %s ' 156 '%r returning NotApplicable status', 157 self.ELEMENT_LOCAL_NAME, self.ident) 158 decision = Decision.NOT_APPLICABLE 159 return decision 160 161 # Apply the rule combining algorithm here combining the 162 # effects from the rules evaluated into an overall decision 163 decision = self.evaluateCombiningAlgorithm(context) 164 165 except Exception: 166 # Catch all so that nothing is handled from within the scope of this 167 # method 168 log.error('No PDPError type exception raised evaluating request ' 169 'context, returning %r decision:%s', 170 Decision.INDETERMINATE_STR, 171 traceback.format_exc()) 172 173 decision = Decision.INDETERMINATE 174 175 return decision
176 177 @abstractmethod
178 - def evaluateCombiningAlgorithm(self, context):
179 """Evaluates the appropriate combining algorithm for this policy or 180 policy set. 181 @param context: the request context 182 @type context: ndg.xacml.core.request.Request 183 @return: result of the evaluation - the decision for this rule 184 @rtype: ndg.xacml.core.context.result.Decision 185 """ 186 return Decision.INDETERMINATE
187