source: TI12-security/trunk/ndg_saml/ndg/saml/common/__init__.py @ 6900

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/ndg_saml/ndg/saml/common/__init__.py@6900
Revision 6900, 10.7 KB checked in by pjkersha, 9 years ago (diff)

Incomplete - task 6: Put NDG SAML package on PyPI

  • add documentation folder and Makefile for epydoc
  • updating epydoc for all modules and packages.
Line 
1"""SAML 2.0 common package
2
3Implementation of SAML 2.0 for NDG Security
4
5NERC DataGrid Project
6
7This implementation is adapted from the Java OpenSAML implementation.  The
8copyright and licence information are included here:
9
10Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
11
12Licensed under the Apache License, Version 2.0 (the "License");
13you may not use this file except in compliance with the License.
14You may obtain a copy of the License at
15
16http://www.apache.org/licenses/LICENSE-2.0
17
18Unless required by applicable law or agreed to in writing, software
19distributed under the License is distributed on an "AS IS" BASIS,
20WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21See the License for the specific language governing permissions and
22limitations under the License.
23"""
24__author__ = "P J Kershaw"
25__date__ = "11/08/09"
26__copyright__ = "(C) 2009 Science and Technology Facilities Council"
27__contact__ = "Philip.Kershaw@stfc.ac.uk"
28__license__ = "http://www.apache.org/licenses/LICENSE-2.0"
29__contact__ = "Philip.Kershaw@stfc.ac.uk"
30__revision__ = "$Id$"
31from ndg.saml.common.xml import SAMLConstants, QName
32 
33
34class SAMLObject(object):
35    """Base class for all SAML types
36   
37    @cvar DEFAULT_ELEMENT_LOCAL_NAME: default XML element name - derived classes
38    must specify
39    @type DEFAULT_ELEMENT_LOCAL_NAME: None
40    @ivar __qname: qualified name for XML element
41    @type __qname: ndg.saml.common.xml.QName
42    """
43    DEFAULT_ELEMENT_LOCAL_NAME = None
44    __slots__ = ('__qname',)
45   
46    def __init__(self,
47                 namespaceURI=SAMLConstants.SAML20_NS, 
48                 elementLocalName=None, 
49                 namespacePrefix=SAMLConstants.SAML20_PREFIX):
50        '''
51        @param namespaceURI: the namespace the element is in
52        @type namespaceURI: basestring
53        @param elementLocalName: the local name of the XML element this Object
54        represents, defaults to DEFAULT_ELEMENT_LOCAL_NAME.  Ensure that this
55        is set to a valid string in derived classes rather the None base class
56        setting
57        @type elementLocalName: NoneType/basestring
58        @param namespacePrefix: the prefix for the given namespace
59        @type namespacePrefix: basestring
60        '''
61        if elementLocalName is None:
62            elementLocalName = self.__class__.DEFAULT_ELEMENT_LOCAL_NAME
63           
64        self.__qname = QName(namespaceURI, 
65                             elementLocalName, 
66                             namespacePrefix)
67           
68    @property
69    def qname(self):
70        """Qualified Name for this type
71        @return: qualified name
72        @rtype: ndg.saml.common.xml.QName
73        """
74        return self.__qname
75           
76    @classmethod
77    def fromXML(cls, xmlObject):
78        '''Parse from an XML representation into a SAML object.  Abstract method
79        - derived types should implement
80       
81        @type xmlObject: XML class e.g. ElementTree or 4Suite XML type
82        @param xmlObject: XML representation of SAML Object
83        @rtype: saml.saml2.common.SAMLObject derived type
84        @return: SAML object
85        '''
86        raise NotImplementedError()
87   
88    @classmethod
89    def toXML(cls, samlObject):
90        '''Convert the input SAML object into an XML representation.  Abstract
91        method - derived types should implement
92        @type samlObject: saml.saml2.common.SAMLObject derived type
93        @param samlObject: SAML object
94        @rtype: XML class e.g. ElementTree or 4Suite XML
95        @return: XML representation of SAML Object
96        '''
97        raise NotImplementedError()
98
99    def __getstate__(self):
100        '''Enable pickling
101       
102        @return: object's attribute dictionary
103        @rtype: dict
104        '''
105        _dict = {}
106        for attrName in SAMLObject.__slots__:
107            # Ugly hack to allow for derived classes setting private member
108            # variables
109            if attrName.startswith('__'):
110                attrName = "_SAMLObject" + attrName
111               
112            try:
113                _dict[attrName] = getattr(self, attrName)
114            except:
115                pass
116           
117        return _dict
118 
119    def __setstate__(self, attrDict):
120        '''Enable pickling
121       
122        @param attrDict: object's attribute dictionary
123        @type attrDict: dict
124        '''
125        for attrName, val in attrDict.items():
126            setattr(self, attrName, val)
127           
128
129class SAMLVersion(object):
130    """Version helper class
131   
132    @cvar VERSION_10: SAML Version 1.0 identifier
133    @type VERSION_10: tuple
134    @cvar VERSION_11: SAML Version 1.1 identifier
135    @type VERSION_11: tuple
136    @cvar VERSION_20: SAML Version 2.0 identifier
137    @type VERSION_20: tuple
138    @cvar KNOWN_VERSIONS: list of known SAML version identifiers
139    @type KNOWN_VERSIONS: tuple
140    @ivar __version: SAML version for the given class instance
141    @type __version: tuple
142    """
143   
144    VERSION_10 = (1, 0)
145    VERSION_11 = (1, 1)
146    VERSION_20 = (2, 0)
147    KNOWN_VERSIONS = (VERSION_10, VERSION_11, VERSION_20)
148   
149    __slots__ = ('__version', )
150   
151    def __init__(self, version):
152        """Instantiate from a given input version
153        @param version: SAML version to set
154        @type version: basestring or tuple or list
155        @raise TypeError: unexpected type for version input
156        """
157        if isinstance(version, basestring):
158            self.__version = SAMLVersion.valueOf(version)
159        elif isinstance(version, (tuple, list)):
160            self.__version = tuple(version)
161        else:
162            raise TypeError("Expecting string, tuple or list type for SAML "
163                            "version initialiser; got %r" % version)
164           
165    def __getstate__(self):
166        '''Enable pickling
167       
168        @return: object's attribute dictionary
169        @rtype: dict
170        '''
171        _dict = {}
172        for attrName in SAMLVersion.__slots__:
173            # Ugly hack to allow for derived classes setting private member
174            # variables
175            if attrName.startswith('__'):
176                attrName = "_SAMLVersion" + attrName
177               
178            _dict[attrName] = getattr(self, attrName)
179           
180        return _dict
181 
182    def __setstate__(self, attrDict):
183        '''Enable pickling
184       
185        @param attrDict: object's attribute dictionary
186        @type attrDict: dict
187        '''
188        for attrName, val in attrDict.items():
189            setattr(self, attrName, val)
190   
191    def __str__(self):
192        """
193        @return: string representation of SAML version
194        @rtype: string
195        """
196        return ".".join([str(i) for i in self.__version])
197   
198    def __eq__(self, version):
199        """Test for equality against an input version string, tuple or list
200       
201        @param version: SAML version to test
202        @type version: SAMLVersion, basestring, tuple or list
203        @raise TypeError: unexpected type for version input
204        """
205        if isinstance(version, SAMLVersion):
206            return str(self) == str(version)
207         
208        elif isinstance(version, basestring):
209            return self.__version == SAMLVersion.valueOf(version)
210       
211        elif isinstance(version, (tuple, list)):
212            return self.__version == tuple(version)
213        else:
214            raise TypeError("Expecting string, tuple or list type for SAML "
215                            "version comparison; got %r" % version)
216           
217    def __ne__(self, version):
218        """Test True for this instance version not equal to input version
219       
220        @param version: SAML version to test
221        @type version: SAMLVersion, basestring, tuple or list
222        @raise TypeError: unexpected type for version input
223        """
224        return not self.__eq__(version)
225           
226    def __gt__(self, version):               
227        """Test True for this instance version greater than input version
228       
229        @param version: SAML version to test
230        @type version: SAMLVersion, basestring, tuple or list
231        @raise TypeError: unexpected type for version input
232        """
233        if isinstance(version, basestring):
234            return self.__version > SAMLVersion.valueOf(version)
235        elif isinstance(version, (tuple, list)):
236            return self.__version > tuple(version)
237        else:
238            raise TypeError("Expecting string, tuple or list type for SAML "
239                            "version comparison; got %r" % version)
240           
241    def __lt__(self, version):
242        """Test True for this instance version less than input version
243       
244        @param version: SAML version to test
245        @type version: SAMLVersion, basestring, tuple or list
246        @raise TypeError: unexpected type for version input
247        """
248        if isinstance(version, basestring):
249            return self.__version < SAMLVersion.valueOf(version)
250        elif isinstance(version, (tuple, list)):
251            return self.__version < tuple(version)
252        else:
253            raise TypeError("Expecting string, tuple or list type for SAML "
254                            "version comparison; got %r" % version)
255           
256    def __ge__(self, version):               
257        """Test True for this instance version greater or equal to the input
258        version
259       
260        @param version: SAML version to test
261        @type version: SAMLVersion, basestring, tuple or list
262        @raise TypeError: unexpected type for version input
263        """
264        if isinstance(version, basestring):
265            return self.__version >= SAMLVersion.valueOf(version)
266        elif isinstance(version, (tuple, list)):
267            return self.__version >= tuple(version)
268        else:
269            raise TypeError("Expecting string, tuple or list type for SAML "
270                            "version comparison; got %r" % version)
271           
272    def __le__(self, version):               
273        """Test True for this instance version less than or equal to input
274        version
275       
276        @param version: SAML version to test
277        @type version: SAMLVersion, basestring, tuple or list
278        @raise TypeError: unexpected type for version input
279        """
280        if isinstance(version, basestring):
281            return self.__version <= SAMLVersion.valueOf(version)
282        elif isinstance(version, (tuple, list)):
283            return self.__version <= tuple(version)
284        else:
285            raise TypeError("Expecting string, tuple or list type for SAML "
286                            "version comparison; got %r" % version)
287   
288    @staticmethod
289    def valueOf(version):
290        """Parse input string into version tuple
291        @type version: basestring
292        @param version: SAML version
293        @rtype: tuple
294        @return: SAML version tuple"""
295        return tuple([int(i) for i in version.split(".")])
Note: See TracBrowser for help on using the repository browser.