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

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

Added more !ETree readers for the different types.

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