source: TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/authz/xacml/policy.py @ 6643

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg-security/TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/authz/xacml/policy.py@6643
Revision 6643, 6.6 KB checked in by pjkersha, 11 years ago (diff)

Contd port of MSI Policy + PDP implementation to XACML 2.0

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