source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/pdp.py @ 6822

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/pdp.py@6822
Revision 6822, 6.6 KB checked in by pjkersha, 10 years ago (diff)

Added rule combining algorithm module with class factory and implementation for permit overrides algorithm.

Line 
1"""NDG Security Policy Decision Point type definition
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "25/02/10"
7__copyright__ = "(C) 2010 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: $"
12import logging
13log = logging.getLogger(__name__)
14
15import traceback
16
17from ndg.xacml.core.context.exceptions import XacmlContextError
18from ndg.xacml.core.context.pdpinterface import PDPInterface
19from ndg.xacml.core.policy import Policy
20from ndg.xacml.core.context.request import Request
21from ndg.xacml.core.context.response import Response
22from ndg.xacml.core.context.result import Result, Decision
23from ndg.xacml.core.context.result import StatusCode
24
25
26class PDPError(XacmlContextError):
27    """Base class for PDP class exceptions"""
28     
29   
30class UnsupportedElementError(PDPError):
31    """Element type is not supported in this implementation"""
32    def __init__(self, *arg, **kw):
33        super(UnsupportedElementError, self).__init__(*arg, **kw)
34        self.response.results[0
35                            ].status.statusCode.value = StatusCode.SYNTAX_ERROR
36
37
38class UnsupportedStdElementError(UnsupportedElementError):
39    """Element type is part of the XACML spec. but is not supported in this
40    implementation""" 
41   
42   
43class PDP(PDPInterface):
44    """A XACML Policy Decision Point implementation.  It supports the use of a
45    single policy but not policy sets
46    """
47    __slots__ = ('__policy', '__request')
48   
49    def __init__(self, policy=None):
50        """
51        @param policy: policy object for PDP to use to apply access control
52        decisions, may be omitted.
53        @type policy: ndg.xacml.core.policy.Policy / None
54        """
55        self.__policy = None
56        if policy is not None:
57            self.policy = policy
58           
59        self.__request = None
60
61    @classmethod
62    def fromPolicySource(cls, source, readerFactory):
63        """Create a new PDP instance with a given policy
64        @param source: source for policy
65        @type source: type (dependent on the reader set, it could be for example
66        a file path string, file object, XML element instance)
67        @param readerFactory: reader factory returns the reader to use to read
68        this policy
69        @type readerFactory: ndg.xacml.parsers.AbstractReader derived type
70        """           
71        pdp = cls()
72        pdp.policy = Policy.fromSource(source, readerFactory)
73        return pdp
74   
75    @property
76    def policy(self):
77        """policy object for PDP to use to apply access control decisions"""
78        return self.__policy
79   
80    @policy.setter
81    def policy(self, value):
82        '''policy object for PDP to use to apply access control decisions'''
83        if not isinstance(value, Policy):
84            raise TypeError('Expecting %r derived type for "policy" input; got '
85                            '%r instead' % (Policy, type(value)))
86        self.__policy = value
87
88    @property
89    def request(self):
90        """request context"""
91        return self.__request
92   
93    @request.setter
94    def request(self, value):
95        '''request context'''
96        if not isinstance(value, Request):
97            raise TypeError('Expecting %r derived type for "request" '
98                            'input; got %r instead' % (Request, 
99                                                       type(value)))
100        self.__request = value
101                                       
102    def evaluate(self, request):
103        """Make an access control decision for the given request based on the
104        policy set
105       
106        @param request: XACML request context
107        @type request: ndg.xacml.core.context.request.Request
108        @return: XACML response instance
109        @rtype: ndg.xacml.core.context.response.Response
110        """
111        response = Response()
112        result = Result.createInitialised(decision=Decision.NOT_APPLICABLE)
113        response.results.append(result)
114       
115        try:
116            self.request = request
117           
118        except AttributeError, e:
119            log.error(str(e))
120            result.decision = Decision.INDETERMINATE
121            return response
122           
123        # Exception block around all rule processing in order to set
124        # INDETERMINATE response from any exceptions raised
125        try:
126            log.debug('Checking policy %r target for match with request...',
127                      self.policy.policyId)
128           
129            target = self.policy.target
130           
131            # If no target is set, ALL requests are counted as matches
132            if target is not None:
133                if not target.match(request):
134                    # The target didn't match so the whole policy does not apply
135                    # to this request
136                    log.debug('No match for policy target setting %r decision',
137                              Decision.NOT_APPLICABLE_STR)
138                   
139                    result.decision = Decision.NOT_APPLICABLE
140                    return response
141           
142            log.debug('Request matches the Policy %r target', 
143                      self.policy.policyId)
144           
145            # Check rules
146#            ruleDecisions = [False]*len(self.policy.rules)
147#            for i, rule in enumerate(self.policy.rules):
148#                ruleDecisions[i] = rule.evaluate(request)
149               
150            # Apply the rule combining algorithm here combining the
151            # effects from the rules evaluated into an overall decision
152            result.decision = self.policy.ruleCombiningAlg.evaluate(
153                                                            self.policy.rules,
154                                                            request)
155        except PDPError, e:
156            log.error('Exception raised evaluating request context, returning '
157                      '%r decision:%s', 
158                      e.response.results[0].decision, 
159                      traceback.format_exc())
160           
161            result = e.response.results[0]
162           
163        except Exception:
164            # Catch all so that nothing is handled from within the scope of this
165            # method
166            log.error('No PDPError type exception raised evaluating request '
167                      'context, returning %r decision:%s', 
168                      Decision.INDETERMINATE_STR, 
169                      traceback.format_exc()) 
170                       
171            result.decision = Decision.INDETERMINATE
172            result.status.statusCode.value = StatusCode.PROCESSING_ERROR
173           
174        return response
175
176
177
Note: See TracBrowser for help on using the repository browser.