1 | """NDG XACML core package |
---|
2 | |
---|
3 | NERC DataGrid |
---|
4 | """ |
---|
5 | __author__ = "P J Kershaw" |
---|
6 | __date__ = "16/03/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$" |
---|
12 | from ndg.xacml.utils import TypedList |
---|
13 | |
---|
14 | |
---|
15 | class XacmlCoreBase(object): |
---|
16 | """Base class for all XACML types |
---|
17 | |
---|
18 | @cvar XACML_1_0_NS_PREFIX: XACML version 1.0 namespace prefix |
---|
19 | @type XACML_1_0_NS_PREFIX: string |
---|
20 | @cvar XACML_2_0_NS_PREFIX: XACML version 2.0 namespace prefix |
---|
21 | @type XACML_2_0_NS_PREFIX: string |
---|
22 | @cvar XMLNS: list of valid XACML namespaces |
---|
23 | @type XMLNS: tuple |
---|
24 | @cvar ELEMENT_LOCAL_NAME: XML element local name for the given type |
---|
25 | @type ELEMENT_LOCAL_NAME: NoneType but implement as string in derived |
---|
26 | classes |
---|
27 | |
---|
28 | @ivar __xmlns: XML namespace for the XACML type |
---|
29 | @type __xmlns: NoneType / basestring |
---|
30 | |
---|
31 | @ivar __elem: XML element |
---|
32 | @type __elem: NoneType / dependent on Python XML parser used |
---|
33 | """ |
---|
34 | XACML_1_0_NS_PREFIX = "urn:oasis:names:tc:xacml:1.0" |
---|
35 | XACML_2_0_NS_PREFIX = "urn:oasis:names:tc:xacml:2.0" |
---|
36 | |
---|
37 | XMLNS = (XACML_1_0_NS_PREFIX, XACML_2_0_NS_PREFIX) |
---|
38 | |
---|
39 | __slots__ = ('__xmlns', '__reader', '__writer', '__elem') |
---|
40 | |
---|
41 | ELEMENT_LOCAL_NAME = None |
---|
42 | |
---|
43 | def __init__(self): |
---|
44 | """Element local name check makes this a virtual method |
---|
45 | |
---|
46 | @raise NotImplementedError: derived classes must set |
---|
47 | ELEMENT_LOCAL_NAME to a string |
---|
48 | """ |
---|
49 | self.__xmlns = None |
---|
50 | self.__elem = None |
---|
51 | |
---|
52 | if not isinstance(self.__class__.ELEMENT_LOCAL_NAME, basestring): |
---|
53 | raise NotImplementedError('"ELEMENT_LOCAL_NAME" must be defined in ' |
---|
54 | 'a derived class') |
---|
55 | |
---|
56 | def _getXmlns(self): |
---|
57 | """Get XML Namespace for this XACML type |
---|
58 | @return: the XML namespace set |
---|
59 | @rtype: basestring/NoneType |
---|
60 | """ |
---|
61 | return self.__xmlns |
---|
62 | |
---|
63 | def _setXmlns(self, value): |
---|
64 | """Set XML Namespace for this XACML type |
---|
65 | @param value: the XML namespace to set |
---|
66 | @type value: basestring/NoneType |
---|
67 | """ |
---|
68 | if not isinstance(value, basestring): |
---|
69 | raise TypeError('Expecting string type for "xmlns" ' |
---|
70 | 'attribute; got %r' % type(value)) |
---|
71 | self.__xmlns = value |
---|
72 | |
---|
73 | xmlns = property(_getXmlns, _setXmlns, |
---|
74 | doc="XML Namespace for policy the document") |
---|
75 | |
---|
76 | @property |
---|
77 | def isValidXmlns(self): |
---|
78 | """Check XML namespace fits with the known XACML namespaces |
---|
79 | @return: True if valid, False otherwise |
---|
80 | @rtype: bool |
---|
81 | """ |
---|
82 | return self.xmlns in XacmlCoreBase.XMLNS |
---|
83 | |
---|
84 | @property |
---|
85 | def elem(self): |
---|
86 | """XML Node for as represented by parser/writer specified with the |
---|
87 | reader/writer attributes. Readers of context elements should set this |
---|
88 | element if a policy uses AttributeSelectors to do XPath queries into |
---|
89 | the request context |
---|
90 | """ |
---|
91 | return self.__elem |
---|
92 | |
---|
93 | @elem.setter |
---|
94 | def elem(self, value): |
---|
95 | """"XML Node for as represented by parser/writer specified with the |
---|
96 | reader/writer attributes |
---|
97 | |
---|
98 | @param value: XML node instance |
---|
99 | @type value: type (governed by reader/writer set for this XACML object) |
---|
100 | """ |
---|
101 | self.__elem = value |
---|
102 | |
---|
103 | |
---|
104 | class XacmlPolicyBase(XacmlCoreBase): |
---|
105 | """Base class for policy types |
---|
106 | |
---|
107 | @cvar XACML_2_0_POLICY_NS: XACML 2.0 policy XML namespace |
---|
108 | @type XACML_2_0_POLICY_NS: string |
---|
109 | """ |
---|
110 | XACML_2_0_POLICY_NS = (XacmlCoreBase.XACML_2_0_NS_PREFIX + |
---|
111 | ":policy:schema:os") |
---|
112 | __slots__ = () |
---|
113 | |
---|
114 | def __init__(self): |
---|
115 | """Initialise parent class xmlns attribute based on this classes' |
---|
116 | policy namespace |
---|
117 | """ |
---|
118 | super(XacmlPolicyBase, self).__init__() |
---|
119 | self.xmlns = XacmlPolicyBase.XACML_2_0_POLICY_NS |
---|
120 | |
---|
121 | |
---|
122 | class TargetChildBase(XacmlPolicyBase): |
---|
123 | """Abstract Base class for XACML Policy Subject, Resource, Action and |
---|
124 | Environment types: e.g. ndg.xacml.core.subject.Subject |
---|
125 | |
---|
126 | @cvar MATCH_TYPE: Set the type for match attributes in the derived class |
---|
127 | implementation e.g. ResourceMatch, SubjectMatch etc. |
---|
128 | @type MATCH_TYPE: NoneType - derived class must implement |
---|
129 | |
---|
130 | @ivar __matches: list of matches for this target |
---|
131 | @type __matches: ndg.xacml.core.utils.TypedList |
---|
132 | """ |
---|
133 | MATCH_TYPE = None |
---|
134 | |
---|
135 | __slots__ = ('__matches', ) |
---|
136 | |
---|
137 | def __init__(self): |
---|
138 | super(TargetChildBase, self).__init__() |
---|
139 | |
---|
140 | # Derived types can specify the type for matches via the MATCH_TYPE |
---|
141 | # class variable |
---|
142 | if self.__class__.MATCH_TYPE is None: |
---|
143 | raise NotImplementedError('Match type attribute must be specified ' |
---|
144 | 'in a derived class') |
---|
145 | self.__matches = TypedList(self.__class__.MATCH_TYPE) |
---|
146 | |
---|
147 | @property |
---|
148 | def matches(self): |
---|
149 | """Get matches list for this target |
---|
150 | @return: list of matches |
---|
151 | @rtype: ndg.xacml.core.utils.TypedList |
---|
152 | """ |
---|
153 | return self.__matches |
---|