source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/policy.py @ 6777

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

Added matching functions component.

Line 
1"""NDG Security Policy type definition
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "24/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: $"
12from ndg.xacml.utils import TypedList
13from ndg.xacml.parsers import AbstractReaderFactory, AbstractReader
14from ndg.xacml.core import XacmlCoreBase
15from ndg.xacml.core.policydefaults import PolicyDefaults
16from ndg.xacml.core.target import Target
17from ndg.xacml.core.rule import Rule
18from ndg.xacml.core.obligation import Obligation
19
20
21class PolicyParseError(Exception):
22    """Error reading policy attributes from file"""
23
24
25class InvalidPolicyXmlNsError(PolicyParseError):
26    """Invalid XML namespace for policy document"""
27
28
29class Policy(XacmlCoreBase):
30    """NDG MSI Policy.""" 
31    DEFAULT_XACML_VERSION = "1.0"
32    ELEMENT_LOCAL_NAME = "Policy"
33    POLICY_ID_ATTRIB_NAME = "PolicyId"
34    RULE_COMBINING_ALG_ID_ATTRIB_NAME = "RuleCombiningAlgId"
35    VERSION_ATTRIB_NAME = "Version"
36
37    DESCRIPTION_LOCAL_NAME = "Description"
38    POLICY_DEFAULTS_LOCAL_NAME = "PolicyDefaults"
39    COMBINER_PARAMETERS_LOCAL_NAME = "CombinerParameters"
40    RULE_COMBINER_PARAMETERS_LOCAL_NAME = "RuleCombinerParameters"
41    OBLIGATIONS_LOCAL_NAME = "Obligations"
42   
43    # Plan to support permit overrides in a future release
44    RULE_COMBINING_ALG_IDS = (
45    "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides",
46    "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides",
47    )
48    __slots__ = (
49        '__policyId',
50        '__version',
51        '__ruleCombiningAlgId',
52        '__description',
53        '__policyDefaults',
54        '__target',
55        '__attr',
56        '__obligations'
57    )
58   
59    def __init__(self):
60        super(Policy, self).__init__()
61        self.__policyId = None
62        self.__version = None
63        self.__ruleCombiningAlgId = None
64        self.__description = None
65        self.__target = None
66       
67        # Attr should eventually allow a choice of Rule, CombinerParameter,
68        # RuleCombinerParameter and VariableDefinition but only Rule type is
69        # currently supported
70        self.__attr = TypedList(Rule)
71       
72        self.__obligations = TypedList(Obligation)
73
74    @classmethod
75    def fromSource(cls, source, readerFactory):
76        """Create a new policy from the input source parsing it using a
77        reader from the required reader factory e.g. ETreeReaderFactory to use
78        ElementTree based parsing
79       
80        @param source: source from which to read the policy - file path,
81        file object, XML node or other dependent on the reader factory selected
82        @type source: string, file, XML node type
83        @param readerFactory: factory class returns reader class used to parse
84        the policy
85        @type readerFactory: ndg.xacml.parsers.AbstractReaderFactory
86        @return: new policy instance
87        @rtype: ndg.xacml.core.policy.Policy
88        """
89        if not issubclass(readerFactory, AbstractReaderFactory):
90            raise TypeError('Expecting %r derived class for reader factory '
91                            'method; got %r' % (AbstractReaderFactory, 
92                                                readerFactory))
93           
94        reader = readerFactory.getReader(cls)
95        if not issubclass(reader, AbstractReader):
96            raise TypeError('Expecting %r derived class for reader class; '
97                            'got %r' % (AbstractReader, reader))
98           
99        return reader.parse(source)
100       
101    def _getPolicyId(self):
102        return self.__policyId
103
104    def _setPolicyId(self, value):
105        if not isinstance(value, basestring):
106            raise TypeError('Expecting string type for "policyId" '
107                            'attribute; got %r' % type(value))
108           
109        self.__policyId = value
110
111    policyId = property(_getPolicyId, _setPolicyId, None, "Policy Id")
112
113    def _getVersion(self):
114        return self.__version
115
116    def _setVersion(self, value):
117        if not isinstance(value, basestring):
118            raise TypeError('Expecting string type for "version" '
119                            'attribute; got %r' % type(value))
120           
121        self.__version = value
122
123    version = property(_getVersion, _setVersion, None, "Policy Version")
124
125    def _getRuleCombiningAlgId(self):
126        return self.__ruleCombiningAlgId
127
128    def _setRuleCombiningAlgId(self, value):
129        if not isinstance(value, basestring):
130            raise TypeError('Expecting string type for "ruleCombiningAlgId" '
131                            'attribute; got %r' % type(value))
132           
133        if value not in Policy.RULE_COMBINING_ALG_IDS:
134            raise AttributeError('%r rule combining algorithm is invalid.  '
135                                 'Only these algorithms are currently '
136                                 'supported %r' % 
137                                 (value, Policy.RULE_COMBINING_ALG_IDS))
138        self.__ruleCombiningAlgId = value
139
140    ruleCombiningAlgId = property(_getRuleCombiningAlgId, 
141                                  _setRuleCombiningAlgId, None, 
142                                  doc="Rule Combining Algorithm Id")
143
144
145    @property
146    def combinerParameters(self):
147        raise NotImplementedError()
148   
149    @property
150    def ruleCombinerParameters(self):
151        raise NotImplementedError()
152   
153    @property
154    def variableDefinitions(self):
155        raise NotImplementedError()
156   
157    @property
158    def rules(self):
159        return self.__attr
160   
161    @property
162    def obligations(self):
163        return self.__obligations
164
165    def _getTarget(self):
166        return self.__target
167
168    def _setTarget(self, value):
169        if not isinstance(value, Target):
170            raise TypeError('Expecting Target for "target" '
171                            'attribute; got %r' % type(value))
172        self.__target = value
173
174    target = property(_getTarget, _setTarget, doc="list of Policy targets")
175
176    def _getDescription(self):
177        return self.__description
178
179    def _setDescription(self, value):
180        if not isinstance(value, basestring):
181            raise TypeError('Expecting string type for "description" '
182                            'attribute; got %r' % type(value))
183        self.__description = value
184
185    description = property(_getDescription, _setDescription, 
186                           doc="Policy Description text")
187
188    def _getPolicyDefaults(self):
189        return self.__policyDefaults
190
191    def _setPolicyDefaults(self, value):
192        if not isinstance(value, PolicyDefaults):
193            raise TypeError('Expecting string type for "policyDefaults" '
194                            'attribute; got %r' % type(value))
195           
196        self.__policyDefaults = value
197
198    policyDefaults = property(_getPolicyDefaults, 
199                              _setPolicyDefaults, 
200                              None, 
201                              "Policy PolicyDefaults element")   
202    def parse(self):
203        """Parse the policy file set in policyFilePath attribute
204        """
205        elem = ElementTree.parse(self.policyFilePath)
206        root = elem.getroot()
207       
208        self.xmlns = QName.getNs(root.tag)
209        if not self.isValidXmlns:
210            raise InvalidPolicyXmlNsError("Namespace %r is recognised; valid "
211                                          "namespaces are: %r" %
212                                          (self.xmlns, Policy.XMLNS))
213           
214        for elem in root:
215            localName = QName.getLocalPart(elem.tag)
216            if localName == Policy.DESCRIPTION_LOCALNAME:
217                self.description = elem.text.strip()
218               
219            elif localName == Policy.TARGET_LOCALNAME:
220                self.targets.append(Target.Parse(elem))
221               
222            else:
223                raise PolicyParseError("Invalid policy attribute: %s" % 
224                                        localName)
225               
226    @classmethod
227    def Parse(cls, policyFilePath):
228        policy = cls(policyFilePath=policyFilePath)
229        policy.parse()
230        return policy
Note: See TracBrowser for help on using the repository browser.