source: TI12-security/trunk/ndg_saml/ndg/saml/saml2/core.py @ 6646

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/ndg_saml/ndg/saml/saml2/core.py@6646
Revision 6646, 100.8 KB checked in by pjkersha, 11 years ago (diff)

Fix to type checking message in Attribute class.

Line 
1"""SAML 2.0 core module
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__ = "BSD - see LICENSE file in top-level directory"
29__contact__ = "Philip.Kershaw@stfc.ac.uk"
30__revision__ = "$Id: $"
31from datetime import datetime
32from urlparse import urlsplit, urlunsplit
33import urllib
34
35from ndg.saml.common import SAMLObject, SAMLVersion
36from ndg.saml.common.xml import SAMLConstants, QName
37from ndg.saml.utils import TypedList
38
39
40class Attribute(SAMLObject):
41    '''SAML 2.0 Core Attribute.'''
42   
43    # Local name of the Attribute element.
44    DEFAULT_ELEMENT_LOCAL_NAME = "Attribute"
45
46    # Default element name.
47    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
48                                 DEFAULT_ELEMENT_LOCAL_NAME,
49                                 SAMLConstants.SAML20_PREFIX)
50
51    # Local name of the XSI type.
52    TYPE_LOCAL_NAME = "AttributeType"
53
54    # QName of the XSI type.
55    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
56                      TYPE_LOCAL_NAME,
57                      SAMLConstants.SAML20_PREFIX)
58
59    # Name of the Name attribute.
60    NAME_ATTRIB_NAME = "Name"
61
62    # Name for the NameFormat attribute.
63    NAME_FORMAT_ATTRIB_NAME = "NameFormat"
64
65    # Name of the FriendlyName attribute.
66    FRIENDLY_NAME_ATTRIB_NAME = "FriendlyName"
67
68    # Unspecified attribute format ID.
69    UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
70
71    # URI reference attribute format ID.
72    URI_REFERENCE = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
73
74    # Basic attribute format ID.
75    BASIC = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
76
77    __slots__ = (
78        '__name',
79        '__nameFormat',
80        '__friendlyName',
81        '__attributeValues'
82    )
83   
84    def __init__(self, **kw):
85        """Initialise Attribute Class attributes"""
86        super(Attribute, self).__init__(**kw)
87       
88        self.__name = None
89        self.__nameFormat = None
90        self.__friendlyName = None
91        self.__attributeValues = []
92
93    def __getstate__(self):
94        '''Enable pickling'''
95        _dict = super(Attribute, self).__getstate__()
96        for attrName in Attribute.__slots__:
97            # Ugly hack to allow for derived classes setting private member
98            # variables
99            if attrName.startswith('__'):
100                attrName = "_Attribute" + attrName
101               
102            _dict[attrName] = getattr(self, attrName)
103           
104        return _dict
105   
106    def _get_name(self):
107        return self.__name
108   
109    def _set_name(self, name):
110        if not isinstance(name, basestring):
111            raise TypeError("Expecting basestring type for name, got %r"% 
112                            type(name))
113       
114        self.__name = name
115       
116    name = property(fget=_get_name,
117                    fset=_set_name,
118                    doc="name of this attribute")
119   
120    def _get_nameFormat(self):
121        return self.__nameFormat
122   
123    def _set_nameFormat(self, nameFormat):
124        if not isinstance(nameFormat, basestring):
125            raise TypeError("Expecting basestring type for nameFormat, got %r"
126                            % type(nameFormat))
127           
128        self.__nameFormat = nameFormat
129       
130    nameFormat = property(fget=_get_nameFormat,
131                          fset=_set_nameFormat,
132                          doc="Get the name format of this attribute.")
133   
134    def _get_friendlyName(self):
135        return self.__friendlyName
136   
137    def _set_friendlyName(self, friendlyName):
138        if not isinstance(friendlyName, basestring):
139            raise TypeError("Expecting basestring type for friendlyName, got "
140                            "%r" % type(friendlyName))
141           
142        self.__friendlyName = friendlyName
143       
144    friendlyName = property(fget=_get_friendlyName,
145                            fset=_set_friendlyName,
146                            doc="the friendly name of this attribute.")
147   
148    def _get_attributeValues(self):
149        return self.__attributeValues
150   
151    def _set_attributeValues(self, attributeValues):
152        if not isinstance(attributeValues, (list, tuple)):
153            raise TypeError("Expecting basestring type for attributeValues, "
154                            "got %r" % type(attributeValues))
155           
156        self.__attributeValues = attributeValues
157       
158    attributeValues = property(fget=_get_attributeValues,
159                               fset=_set_attributeValues,
160                               doc="the list of attribute values for this "
161                               "attribute.")
162
163
164class Statement(SAMLObject):
165    '''SAML 2.0 Core Statement.  Abstract base class which all statement
166    types must implement.'''
167    __slots__ = ()
168   
169    # Element local name
170    DEFAULT_ELEMENT_LOCAL_NAME = "Statement"
171
172    # Default element name
173    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
174                                 DEFAULT_ELEMENT_LOCAL_NAME,
175                                 SAMLConstants.SAML20_PREFIX)
176
177    # Local name of the XSI type
178    TYPE_LOCAL_NAME = "StatementAbstractType"
179
180    # QName of the XSI type
181    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
182                      TYPE_LOCAL_NAME,
183                      SAMLConstants.SAML20_PREFIX)
184   
185           
186class AttributeStatement(Statement):
187    '''SAML 2.0 Core AttributeStatement'''
188   
189    # Element local name
190    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeStatement"
191   
192    # Default element name.
193    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
194                                 DEFAULT_ELEMENT_LOCAL_NAME, 
195                                 SAMLConstants.SAML20_PREFIX)
196   
197    # Local name of the XSI type.
198    TYPE_LOCAL_NAME = "AttributeStatementType" 
199       
200    # QName of the XSI type.
201    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
202                      TYPE_LOCAL_NAME, 
203                      SAMLConstants.SAML20_PREFIX)
204   
205    __slots__ = ('__attributes', '__encryptedAttributes')
206   
207    def __init__(self, **kw):
208        super(AttributeStatement, self).__init__(**kw)
209       
210        self.__attributes = TypedList(Attribute)
211        self.__encryptedAttributes = TypedList(Attribute)
212
213    def __getstate__(self):
214        '''Enable pickling'''
215        _dict = super(AttributeStatement, self).__getstate__()
216        for attrName in AttributeStatement.__slots__:
217            # Ugly hack to allow for derived classes setting private member
218            # variables
219            if attrName.startswith('__'):
220                attrName = "_AttributeStatement" + attrName
221               
222            _dict[attrName] = getattr(self, attrName)
223           
224        return _dict
225
226    def _get_attributes(self):
227        '''@return: the attributes expressed in this statement
228        '''
229        return self.__attributes
230
231    attributes = property(fget=_get_attributes)
232   
233    def _get_encryptedAttributes(self):
234       '''@return: the encrypted attribtues expressed in this statement
235       '''
236       return self.__encryptedAttributes
237   
238    encryptedAttributes = property(fget=_get_encryptedAttributes)
239
240
241class AuthnStatement(Statement):
242    '''SAML 2.0 Core AuthnStatement.  Currently implemented in abstract form
243    only
244    '''
245
246    # Element local name
247    DEFAULT_ELEMENT_LOCAL_NAME = "AuthnStatement"
248
249    # Default element name
250    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
251                                 DEFAULT_ELEMENT_LOCAL_NAME,
252                                 SAMLConstants.SAML20_PREFIX)
253
254    # Local name of the XSI type
255    TYPE_LOCAL_NAME = "AuthnStatementType"
256
257    # QName of the XSI type
258    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
259                      TYPE_LOCAL_NAME,
260                      SAMLConstants.SAML20_PREFIX)
261
262    # AuthnInstant attribute name
263    AUTHN_INSTANT_ATTRIB_NAME = "AuthnInstant"
264
265    # SessionIndex attribute name
266    SESSION_INDEX_ATTRIB_NAME = "SessionIndex"
267
268    # SessionNoOnOrAfter attribute name
269    SESSION_NOT_ON_OR_AFTER_ATTRIB_NAME = "SessionNotOnOrAfter"
270   
271    __slots__ = ()
272   
273    def _getAuthnInstant(self):
274        '''Gets the time when the authentication took place.
275       
276        @return: the time when the authentication took place
277        '''
278        raise NotImplementedError()
279
280    def _setAuthnInstant(self, value):
281        '''Sets the time when the authentication took place.
282       
283        @param value: the time when the authentication took place
284        '''
285        raise NotImplementedError()
286
287    def _getSessionIndex(self):
288        '''Get the session index between the principal and the authenticating
289        authority.
290       
291        @return: the session index between the principal and the authenticating
292        authority
293        '''
294        raise NotImplementedError()
295
296    def _setSessionIndex(self, value):
297        '''Sets the session index between the principal and the authenticating
298        authority.
299       
300        @param value: the session index between the principal and the
301        authenticating authority
302        '''
303        raise NotImplementedError()
304
305    def _getSessionNotOnOrAfter(self):
306        '''Get the time when the session between the principal and the SAML
307        authority ends.
308       
309        @return: the time when the session between the principal and the SAML
310        authority ends
311        '''
312        raise NotImplementedError()
313
314    def _setSessionNotOnOrAfter(self, value):
315        '''Set the time when the session between the principal and the SAML
316        authority ends.
317       
318        @param value: the time when the session between the
319        principal and the SAML authority ends
320        '''
321        raise NotImplementedError()
322
323    def _getSubjectLocality(self):
324        '''Get the DNS domain and IP address of the system where the principal
325        was authenticated.
326       
327        @return: the DNS domain and IP address of the system where the principal
328        was authenticated
329        '''
330        raise NotImplementedError()
331
332    def _setSubjectLocality(self, value):
333        '''Set the DNS domain and IP address of the system where the principal
334        was authenticated.
335       
336        @param value: the DNS domain and IP address of the system where
337        the principal was authenticated
338        '''
339        raise NotImplementedError()
340
341    def _getAuthnContext(self):
342        '''Gets the context used to authenticate the subject.
343       
344        @return: the context used to authenticate the subject
345        '''
346        raise NotImplementedError()
347
348    def _setAuthnContext(self, value):
349        '''Sets the context used to authenticate the subject.
350       
351        @param value: the context used to authenticate the subject
352        '''
353        raise NotImplementedError()
354
355
356class DecisionType(object):
357    """Define decision types for the authorisation decisions"""
358   
359    # "Permit" decision type
360    PERMIT_STR = "Permit"
361   
362    # "Deny" decision type
363    DENY_STR = "Deny"
364   
365    # "Indeterminate" decision type
366    INDETERMINATE_STR = "Indeterminate"
367       
368    TYPES = (PERMIT_STR, DENY_STR, INDETERMINATE_STR)
369   
370    __slots__ = ('__value',)
371   
372    def __init__(self, decisionType):
373        self.__value = None
374        self.value = decisionType
375
376    def __getstate__(self):
377        '''Enable pickling'''
378        _dict = {}
379        for attrName in DecisionType.__slots__:
380            # Ugly hack to allow for derived classes setting private member
381            # variables
382            if attrName.startswith('__'):
383                attrName = "_DecisionType" + attrName
384               
385            _dict[attrName] = getattr(self, attrName)
386           
387        return _dict
388 
389    def __setstate__(self, attrDict):
390        '''Enable pickling'''
391        for attrName, val in attrDict.items():
392            setattr(self, attrName, val)
393           
394    def _setValue(self, value):
395        if isinstance(value, DecisionType):
396            # Cast to string
397            value = str(value)
398           
399        elif not isinstance(value, basestring):
400            raise TypeError('Expecting string or DecisionType instance for '
401                            '"value" attribute; got %r instead' % type(value))
402           
403        if value not in self.__class__.TYPES:
404            raise AttributeError('Permissable decision types are %r; got '
405                                 '%r instead' % (DecisionType.TYPES, value))
406        self.__value = value
407       
408    def _getValue(self):
409        return self.__value
410   
411    value = property(fget=_getValue, fset=_setValue, doc="Decision value")
412   
413    def __str__(self):
414        return self.__value
415
416    def __eq__(self, decision):
417        return self.__value == decision.value
418
419
420class PermitDecisionType(DecisionType):
421    """Permit authorisation Decision"""
422    __slots__ = ()
423
424    def __init__(self):
425        super(PermitDecisionType, self).__init__(DecisionType.PERMIT_STR)
426       
427    def _setValue(self): 
428        raise AttributeError("can't set attribute")
429
430
431class DenyDecisionType(DecisionType):
432    """Deny authorisation Decision"""
433    __slots__ = ()
434   
435    def __init__(self):
436        super(DenyDecisionType, self).__init__(DecisionType.DENY_STR)
437       
438    def _setValue(self, value): 
439        raise AttributeError("can't set attribute")
440
441
442class IndeterminateDecisionType(DecisionType):
443    """Indeterminate authorisation Decision"""
444    __slots__ = ()
445   
446    def __init__(self):
447        super(IndeterminateDecisionType, self).__init__(
448                                            DecisionType.INDETERMINATE_STR)
449       
450    def _setValue(self, value): 
451        raise AttributeError("can't set attribute")
452
453# Add instances of each for convenience
454DecisionType.PERMIT = PermitDecisionType()
455DecisionType.DENY = DenyDecisionType()
456DecisionType.INDETERMINATE = IndeterminateDecisionType()
457
458
459class AuthzDecisionStatement(Statement):
460    '''SAML 2.0 Core AuthzDecisionStatement.  Currently implemented in abstract
461    form only'''
462   
463    # Element local name
464    DEFAULT_ELEMENT_LOCAL_NAME = "AuthzDecisionStatement"
465
466    # Default element name
467    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
468                                 DEFAULT_ELEMENT_LOCAL_NAME,
469                                 SAMLConstants.SAML20_PREFIX)
470
471    # Local name of the XSI type
472    TYPE_LOCAL_NAME = "AuthzDecisionStatementType"
473
474    # QName of the XSI type
475    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
476                      TYPE_LOCAL_NAME,
477                      SAMLConstants.SAML20_PREFIX)
478
479    # Resource attribute name
480    RESOURCE_ATTRIB_NAME = "Resource"
481
482    # Decision attribute name
483    DECISION_ATTRIB_NAME = "Decision"
484   
485    __slots__ = (
486        '__resource', 
487        '__decision', 
488        '__actions', 
489        '__evidence',
490        '__normalizeResource',
491        '__safeNormalizationChars')
492   
493    def __init__(self, 
494                 normalizeResource=True, 
495                 safeNormalizationChars='/%',
496                 **kw):
497        '''Create new authorisation decision statement
498        '''
499        super(AuthzDecisionStatement, self).__init__(**kw)
500
501        # Resource attribute value.
502        self.__resource = None 
503       
504        self.__decision = DecisionType.INDETERMINATE   
505        self.__actions = TypedList(Action)
506        self.__evidence = None
507       
508        # Tuning for normalization of resource URIs in property set method
509        self.normalizeResource = normalizeResource
510        self.safeNormalizationChars = safeNormalizationChars
511
512    def __getstate__(self):
513        '''Enable pickling'''
514        _dict = super(AuthzDecisionStatement, self).__getstate__()
515        for attrName in AuthzDecisionStatement.__slots__:
516            # Ugly hack to allow for derived classes setting private member
517            # variables
518            if attrName.startswith('__'):
519                attrName = "_AuthzDecisionStatement" + attrName
520               
521            _dict[attrName] = getattr(self, attrName)
522           
523        return _dict
524   
525    def _getNormalizeResource(self):
526        return self.__normalizeResource
527
528    def _setNormalizeResource(self, value):
529        if not isinstance(value, bool):
530            raise TypeError('Expecting bool type for "normalizeResource" '
531                            'attribute; got %r instead' % type(value))
532           
533        self.__normalizeResource = value
534
535    normalizeResource = property(_getNormalizeResource, 
536                                 _setNormalizeResource, 
537                                 doc="Flag to normalize new resource value "
538                                     "assigned to the \"resource\" property.  "
539                                     "The setting only applies for URIs "
540                                     'beginning with "http://" or "https://"')
541
542    def _getSafeNormalizationChars(self):
543        return self.__safeNormalizationChars
544
545    def _setSafeNormalizationChars(self, value):
546        if not isinstance(value, basestring):
547            raise TypeError('Expecting string type for "normalizeResource" '
548                            'attribute; got %r instead' % type(value))
549           
550        self.__safeNormalizationChars = value
551
552    safeNormalizationChars = property(_getSafeNormalizationChars, 
553                                      _setSafeNormalizationChars, 
554                                      doc="String containing a list of "
555                                          "characters that should not be "
556                                          "converted when Normalizing the "
557                                          "resource URI.  These are passed to "
558                                          "urllib.quote when the resource "
559                                          "property is set.  The default "
560                                          "characters are '/%'")
561
562    def _getResource(self):
563        '''Gets the Resource attrib value of this query.
564
565        @return: the Resource attrib value of this query'''
566        return self.__resource
567   
568    def _setResource(self, value):
569        '''Sets the Resource attrib value of this query normalizing the path
570        component, removing spurious port numbers (80 for HTTP and 443 for
571        HTTPS) and converting the host component to lower case.
572       
573        @param value: the new Resource attrib value of this query'''
574        if not isinstance(value, basestring):
575            raise TypeError('Expecting string type for "resource" attribute; '
576                            'got %r instead' % type(value))
577       
578        if (self.normalizeResource and 
579            value.startswith('http://') or value.startswith('https://')):
580            # Normalise the path, set the host name to lower case and remove
581            # port redundant numbers 80 and 443
582            splitResult = urlsplit(value)
583            uriComponents = list(splitResult)
584           
585            # hostname attribute is lowercase
586            uriComponents[1] = splitResult.hostname
587           
588            if splitResult.port is not None:
589                isHttpWithStdPort = (splitResult.port == 80 and 
590                                     splitResult.scheme == 'http')
591               
592                isHttpsWithStdPort = (splitResult.port == 443 and
593                                      splitResult.scheme == 'https')
594               
595                if not isHttpWithStdPort and not isHttpsWithStdPort:
596                    uriComponents[1] += ":%d" % splitResult.port
597           
598            uriComponents[2] = urllib.quote(splitResult.path, 
599                                            self.safeNormalizationChars)
600           
601            self.__resource = urlunsplit(uriComponents)
602        else:
603            self.__resource = value
604   
605    resource = property(fget=_getResource, fset=_setResource,
606                        doc="Resource for which authorisation was requested")
607
608    def _getDecision(self):
609        '''
610        Gets the decision of the authorization request.
611       
612        @return: the decision of the authorization request
613        '''
614        return self.__decision
615
616    def _setDecision(self, value):
617        '''
618        Sets the decision of the authorization request.
619       
620        @param value: the decision of the authorization request
621        '''
622        if not isinstance(value, DecisionType):
623            raise TypeError('Expecting %r type for "decision" attribute; '
624                            'got %r instead' % (DecisionType, type(value)))
625        self.__decision = value
626
627    decision = property(_getDecision, _setDecision, 
628                        doc="Authorization decision as a DecisionType instance")
629   
630    @property
631    def actions(self):
632        '''The actions for which authorisation is requested
633       
634        @return: the Actions of this statement'''
635        return self.__actions
636   
637    def _getEvidence(self):
638        '''Gets the Evidence of this statement.
639
640        @return: the Evidence of this statement'''
641        return self.__evidence
642
643    def _setEvidence(self, value):
644        '''Sets the Evidence of this query.
645        @param newEvidence: the new Evidence of this statement''' 
646        if not isinstance(value, Evidence):
647            raise TypeError('Expecting Evidence type for "evidence" '
648                            'attribute; got %r' % type(value))
649
650        self.__evidence = value 
651
652    evidence = property(fget=_getEvidence, fset=_setEvidence, 
653                        doc="A set of assertions which the Authority may use "
654                            "to base its authorisation decision on")
655   
656    def getOrderedChildren(self):
657        children = []
658
659        superChildren = super(AuthzDecisionStatement, self).getOrderedChildren()
660        if superChildren:
661            children.extend(superChildren)
662
663        children.extend(self.__actions)
664       
665        if self.__evidence is not None:
666            children.extend(self.__evidence)
667
668        if len(children) == 0:
669            return None
670
671        return tuple(children)
672       
673
674class Subject(SAMLObject):
675    '''Concrete implementation of @link org.opensaml.saml2.core.Subject.'''
676   
677    # Element local name.
678    DEFAULT_ELEMENT_LOCAL_NAME = "Subject"
679
680    # Default element name.
681    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
682                                 DEFAULT_ELEMENT_LOCAL_NAME,
683                                 SAMLConstants.SAML20_PREFIX)
684
685    # Local name of the XSI type.
686    TYPE_LOCAL_NAME = "SubjectType"
687
688    # QName of the XSI type.
689    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
690                      TYPE_LOCAL_NAME,
691                      SAMLConstants.SAML20_PREFIX)
692    __slots__ = (
693        '__baseID',
694        '__nameID',
695        '__encryptedID',
696        '__subjectConfirmations'
697    )
698   
699    def __init__(self, **kw):
700        super(Subject, self).__init__(**kw)
701       
702        # BaseID child element.
703        self.__baseID = None
704   
705        # NameID child element.
706        self.__nameID = None
707   
708        # EncryptedID child element.
709        self.__encryptedID = None
710   
711        # Subject Confirmations of the Subject.
712        self.__subjectConfirmations = []
713
714    def __getstate__(self):
715        '''Enable pickling'''
716        _dict = super(Subject, self).__getstate__()
717        for attrName in Subject.__slots__:
718            # Ugly hack to allow for derived classes setting private member
719            # variables
720            if attrName.startswith('__'):
721                attrName = "_Subject" + attrName
722               
723            _dict[attrName] = getattr(self, attrName)
724           
725        return _dict
726   
727    def _getBaseID(self): 
728        return self.__baseID
729
730    def _setBaseID(self, value):
731        if not isinstance(value, basestring):
732            raise TypeError("Expecting %r type for \"baseID\" got %r" %
733                            (basestring, value.__class__))
734        self.__baseID = value
735
736    baseID = property(fget=_getBaseID, 
737                      fset=_setBaseID, 
738                      doc="Base identifier")
739     
740    def _getNameID(self):
741        return self.__nameID
742   
743    def _setNameID(self, value):
744        if not isinstance(value, NameID):
745            raise TypeError("Expecting %r type for \"nameID\" got %r" %
746                            (NameID, type(value)))
747        self.__nameID = value
748
749    nameID = property(fget=_getNameID, 
750                      fset=_setNameID, 
751                      doc="Name identifier")
752   
753    def _getEncryptedID(self):
754        return self.__encryptedID
755   
756    def _setEncryptedID(self, value): 
757        self.__encryptedID = value
758
759    encryptedID = property(fget=_getEncryptedID, 
760                           fset=_setEncryptedID, 
761                           doc="EncryptedID's Docstring")
762   
763    def _getSubjectConfirmations(self): 
764        return self.__subjectConfirmations
765
766    subjectConfirmations = property(fget=_getSubjectConfirmations, 
767                                    doc="Subject Confirmations")   
768   
769    def getOrderedChildren(self): 
770        children = []
771
772        if self.baseID is not None:
773            children.append(self.baseID)
774       
775        if self.nameID is not None: 
776            children.append(self.nameID)
777       
778        if self.encryptedID is not None: 
779            children.append(self.encryptedID)
780       
781        children += self.subjectConfirmations
782
783        return tuple(children)
784
785
786class AbstractNameIDType(SAMLObject):
787    '''Abstract implementation of NameIDType'''
788
789    # SPNameQualifier attribute name.
790    SP_NAME_QUALIFIER_ATTRIB_NAME = "SPNameQualifier"
791
792    # Format attribute name.
793    FORMAT_ATTRIB_NAME = "Format"
794
795    # SPProviderID attribute name.
796    SPPROVIDED_ID_ATTRIB_NAME = "SPProvidedID"
797
798    # URI for unspecified name format.
799    UNSPECIFIED = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
800
801    # URI for email name format.
802    EMAIL = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
803
804    # URI for X509 subject name format.
805    X509_SUBJECT = "urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName"
806
807    # URI for windows domain qualified name name format.
808    WIN_DOMAIN_QUALIFIED = \
809        "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName"
810
811    # URI for kerberos name format.
812    KERBEROS = "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos"
813
814    # URI for SAML entity name format.
815    ENTITY = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
816
817    # URI for persistent name format.
818    PERSISTENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
819
820    # URI for transient name format.
821    TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
822
823    # Special URI used by NameIDPolicy to indicate a NameID should be encrypted
824    ENCRYPTED = "urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted"
825   
826    __slots__ = (
827        '__name',
828        '__nameQualifier',
829        '__spNameQualifier',
830        '__format',
831        '__spProvidedID',
832        '__value'
833    )
834   
835    def __init__(self, **kw): 
836        '''@param namespaceURI: the namespace the element is in
837        @param elementLocalName: the local name of the XML element this Object
838        represents
839        @param namespacePrefix: the prefix for the given namespace
840        '''
841        super(AbstractNameIDType, self).__init__(**kw)
842   
843        # Name of the Name ID.
844        self.__name = None
845       
846        # Name Qualifier of the Name ID.
847        self.__nameQualifier = None
848   
849        # SP Name Qualifier of the Name ID.
850        self.__spNameQualifier = None
851   
852        # Format of the Name ID.
853        self.__format = None
854   
855        # SP ProvidedID of the NameID.
856        self.__spProvidedID = None
857
858        self.__value = None
859
860    def __getstate__(self):
861        '''Enable pickling'''
862        _dict = super(AbstractNameIDType, self).__getstate__()
863        for attrName in AbstractNameIDType.__slots__:
864            # Ugly hack to allow for derived classes setting private member
865            # variables
866            if attrName.startswith('__'):
867                attrName = "_AbstractNameIDType" + attrName
868               
869            _dict[attrName] = getattr(self, attrName)
870           
871        return _dict
872             
873    def _getValue(self):
874        return self.__value
875       
876    def _setValue(self, value):
877        if not isinstance(value, basestring):
878            raise TypeError("\"value\" must be a basestring derived type, "
879                            "got %r" % value.__class__)
880           
881        self.__value = value
882
883    value = property(fget=_getValue, fset=_setValue, doc="string value") 
884   
885    def _getNameQualifier(self): 
886        return self.__nameQualifier
887   
888    def _setNameQualifier(self, value): 
889        self.__nameQualifier = value
890
891    nameQualifier = property(fget=_getNameQualifier, 
892                             fset=_setNameQualifier, 
893                             doc="Name qualifier")   
894
895    def _getSPNameQualifier(self): 
896        return self.__spNameQualifier
897   
898    def _setSPNameQualifier(self, value): 
899        self.__spNameQualifier = value
900
901    spNameQualifier = property(fget=_getSPNameQualifier, 
902                               fset=_setSPNameQualifier, 
903                               doc="SP Name qualifier")   
904   
905    def _getFormat(self):
906        return self.__format
907       
908    def _setFormat(self, format):
909        if not isinstance(format, basestring):
910            raise TypeError("\"format\" must be a basestring derived type, "
911                            "got %r" % format.__class__)
912           
913        self.__format = format
914
915    format = property(fget=_getFormat, fset=_setFormat, doc="Name format") 
916   
917    def _getSPProvidedID(self): 
918        return self.__spProvidedID
919   
920    def _setSPProvidedID(self, value): 
921        self.__spProvidedID = value
922
923    spProvidedID = property(fget=_getSPProvidedID, fset=_setSPProvidedID, 
924                            doc="SP Provided Identifier") 
925   
926    def getOrderedChildren(self): 
927        raise NotImplementedError()
928
929   
930class Issuer(AbstractNameIDType):
931    """SAML 2.0 Core Issuer type"""
932   
933    # Element local name.
934    DEFAULT_ELEMENT_LOCAL_NAME = "Issuer"
935
936    # Default element name.
937    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
938                                 DEFAULT_ELEMENT_LOCAL_NAME,
939                                 SAMLConstants.SAML20_PREFIX)
940
941    # Local name of the XSI type.
942    TYPE_LOCAL_NAME = "IssuerType"
943
944    # QName of the XSI type.
945    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
946                      TYPE_LOCAL_NAME,
947                      SAMLConstants.SAML20_PREFIX) 
948   
949    __slots__ = ()
950
951     
952class NameID(AbstractNameIDType):
953    '''SAML 2.0 Core NameID'''
954    # Element local name.
955    DEFAULT_ELEMENT_LOCAL_NAME = "NameID"
956
957    # Default element name.
958    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
959                                 DEFAULT_ELEMENT_LOCAL_NAME,
960                                 SAMLConstants.SAML20_PREFIX)
961
962    # Local name of the XSI type.
963    TYPE_LOCAL_NAME = "NameIDType"
964
965    # QName of the XSI type.
966    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
967                      TYPE_LOCAL_NAME,
968                      SAMLConstants.SAML20_PREFIX)
969   
970    __slots__ = ()
971   
972
973class Conditions(SAMLObject): 
974    '''SAML 2.0 Core Conditions.'''
975   
976    # Element local name.
977    DEFAULT_ELEMENT_LOCAL_NAME = "Conditions"
978
979    # Default element name.
980    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
981                                 DEFAULT_ELEMENT_LOCAL_NAME,
982                                 SAMLConstants.SAML20_PREFIX)
983
984    # Local name of the XSI type.
985    TYPE_LOCAL_NAME = "ConditionsType"
986
987    # QName of the XSI type.
988    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
989                      TYPE_LOCAL_NAME,
990                      SAMLConstants.SAML20_PREFIX)
991
992    # NotBefore attribute name.
993    NOT_BEFORE_ATTRIB_NAME = "NotBefore"
994
995    # NotOnOrAfter attribute name.
996    NOT_ON_OR_AFTER_ATTRIB_NAME = "NotOnOrAfter"
997
998    __slots__ = (
999        '__conditions',
1000        '__notBefore',
1001        '__notOnOrAfter'
1002    )
1003   
1004    def __init__(self, **kw):
1005        super(Conditions, self).__init__(**kw)
1006       
1007        # A Condition.
1008        self.__conditions = []
1009   
1010        # Not Before conditions.
1011        self.__notBefore = None
1012   
1013        # Not On Or After conditions.
1014        self.__notOnOrAfter = None
1015
1016    def __getstate__(self):
1017        '''Enable pickling'''
1018        _dict = super(Conditions, self).__getstate__()
1019        for attrName in Conditions.__slots__:
1020            # Ugly hack to allow for derived classes setting private member
1021            # variables
1022            if attrName.startswith('__'):
1023                attrName = "_Conditions" + attrName
1024               
1025            _dict[attrName] = getattr(self, attrName)
1026           
1027        return _dict
1028   
1029    def _getNotBefore(self):
1030        '''Get the date/time before which the assertion is invalid.
1031       
1032        @return: the date/time before which the assertion is invalid'''
1033        return self.__notBefore
1034   
1035    def _setNotBefore(self, value):
1036        '''Sets the date/time before which the assertion is invalid.
1037       
1038        @param value: the date/time before which the assertion is invalid
1039        '''
1040        if not isinstance(value, datetime):
1041            raise TypeError('Expecting "datetime" type for "notBefore", '
1042                            'got %r' % type(value))
1043        self.__notBefore = value
1044
1045    def _getNotOnOrAfter(self):
1046        '''Gets the date/time on, or after, which the assertion is invalid.
1047       
1048        @return: the date/time on, or after, which the assertion is invalid'
1049        '''
1050        return self.__notOnOrAfter
1051   
1052    def _setNotOnOrAfter(self, value):
1053        '''Sets the date/time on, or after, which the assertion is invalid.
1054       
1055        @param value: the date/time on, or after, which the assertion
1056        is invalid
1057        '''
1058        if not isinstance(value, datetime):
1059            raise TypeError('Expecting "datetime" type for "notOnOrAfter", '
1060                            'got %r' % type(value))
1061        self.__notOnOrAfter = value 
1062
1063    notBefore = property(_getNotBefore, _setNotBefore, 
1064                         doc="Not before time restriction")
1065
1066    notOnOrAfter = property(_getNotOnOrAfter, _setNotOnOrAfter, 
1067                            doc="Not on or after time restriction")
1068
1069    @property
1070    def conditions(self):
1071        '''All the conditions on the assertion.
1072       
1073        @return: all the conditions on the assertion
1074        '''
1075        return self.__conditions
1076   
1077    def _getAudienceRestrictions(self):
1078        '''Gets the audience restriction conditions for the assertion.
1079       
1080        @return: the audience restriction conditions for the assertion
1081        '''
1082        raise NotImplementedError()
1083
1084    def _getOneTimeUse(self):
1085        '''Gets the OneTimeUse condition for the assertion.
1086       
1087        @return: the OneTimeUse condition for the assertion
1088        '''
1089        raise NotImplementedError()
1090
1091    def _getProxyRestriction(self):   
1092        '''Gets the ProxyRestriction condition for the assertion.
1093       
1094        @return: the ProxyRestriction condition for the assertion
1095        '''
1096        raise NotImplementedError()
1097   
1098   
1099class Advice(SAMLObject):
1100    '''SAML 2.0 Core Advice.
1101    '''
1102
1103    # Element local name
1104    DEFAULT_ELEMENT_LOCAL_NAME = "Advice"
1105
1106    # Default element name.
1107    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1108                                 DEFAULT_ELEMENT_LOCAL_NAME,
1109                                 SAMLConstants.SAML20_PREFIX)
1110
1111    # Local name of the XSI type
1112    TYPE_LOCAL_NAME = "AdviceType"
1113
1114    # QName of the XSI type
1115    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1116                      TYPE_LOCAL_NAME,
1117                      SAMLConstants.SAML20_PREFIX)
1118
1119    __slots__ = ()
1120   
1121    def _getChildren(self, typeOrName=None):
1122        '''
1123        Gets the list of all child elements attached to this advice.
1124       
1125        @return: the list of all child elements attached to this advice
1126        '''
1127        raise NotImplementedError()
1128
1129    def _getAssertionIDReferences(self):
1130        '''Gets the list of AssertionID references used as advice.
1131       
1132        @return: the list of AssertionID references used as advice
1133        '''
1134        raise NotImplementedError()
1135
1136    def _getAssertionURIReferences(self):
1137        '''Gets the list of AssertionURI references used as advice.
1138       
1139        @return: the list of AssertionURI references used as advice
1140        '''
1141        raise NotImplementedError()
1142   
1143    def _getAssertions(self):
1144        '''Gets the list of Assertions used as advice.
1145       
1146        @return: the list of Assertions used as advice
1147        '''
1148        raise NotImplementedError()
1149   
1150    def _getEncryptedAssertions(self):
1151        '''Gets the list of EncryptedAssertions used as advice.
1152       
1153        @return: the list of EncryptedAssertions used as advice
1154        '''
1155        raise NotImplementedError()
1156       
1157
1158class Assertion(SAMLObject):
1159    """SAML 2.0 Attribute Assertion for use with NERC DataGrid   
1160    """   
1161    # Element local name.
1162    DEFAULT_ELEMENT_LOCAL_NAME = "Assertion"
1163
1164    # Default element name.
1165    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1166                                 DEFAULT_ELEMENT_LOCAL_NAME,
1167                                 SAMLConstants.SAML20_PREFIX)
1168
1169    # Local name of the XSI type.
1170    TYPE_LOCAL_NAME = "AssertionType"
1171
1172    # QName of the XSI type.
1173    TYPE_NAME = QName(SAMLConstants.SAML20_NS, TYPE_LOCAL_NAME,
1174                      SAMLConstants.SAML20_PREFIX)
1175
1176    # Version attribute name.
1177    VERSION_ATTRIB_NAME = "Version"
1178
1179    # IssueInstant attribute name.
1180    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
1181
1182    # ID attribute name.
1183    ID_ATTRIB_NAME = "ID"
1184
1185    __slots__ = (
1186        '__version',
1187        '__issueInstant',
1188        '__id',
1189        '__issuer',
1190        '__subject',
1191        '__conditions',
1192        '__advice',
1193        '__statements',
1194        '__authnStatements',
1195        '__authzDecisionStatements',
1196        '__attributeStatements'
1197    )
1198   
1199    def __init__(self):
1200        # Base class initialisation
1201        super(Assertion, self).__init__()
1202       
1203        self.__version = None
1204        self.__issueInstant = None
1205        self.__id = None
1206        self.__issuer = None
1207        self.__subject = None
1208       
1209        self.__conditions = None
1210        self.__advice = None
1211        self.__statements = TypedList(Statement)
1212       
1213        # TODO: Implement AuthnStatement and AuthzDecisionStatement classes
1214        self.__authnStatements = []
1215        self.__authzDecisionStatements = TypedList(AuthzDecisionStatement)
1216        self.__attributeStatements = TypedList(AttributeStatement)
1217
1218    def __getstate__(self):
1219        '''Enable pickling'''
1220        _dict = super(Assertion, self).__getstate__()
1221        for attrName in Assertion.__slots__:
1222            # Ugly hack to allow for derived classes setting private member
1223            # variables
1224            if attrName.startswith('__'):
1225                attrName = "_Assertion" + attrName
1226               
1227            _dict[attrName] = getattr(self, attrName)
1228           
1229        return _dict   
1230                 
1231    def _get_version(self):
1232        '''@return: the SAML Version of this assertion.
1233        '''
1234        return self.__version
1235   
1236    def _set_version(self, version):
1237        '''@param version: the SAML Version of this assertion
1238        '''
1239        if not isinstance(version, SAMLVersion):
1240            raise TypeError("Expecting SAMLVersion type got: %r" % 
1241                            version.__class__)
1242       
1243        self.__version = version
1244       
1245    version = property(fget=_get_version,
1246                       fset=_set_version,
1247                       doc="SAML Version of the assertion")
1248
1249    def _get_issueInstant(self):
1250        '''Gets the issue instance of this assertion.
1251       
1252        @return: the issue instance of this assertion'''
1253        return self.__issueInstant
1254   
1255    def _set_issueInstant(self, issueInstant):
1256        '''Sets the issue instance of this assertion.
1257       
1258        @param issueInstant: the issue instance of this assertion
1259        '''
1260        if not isinstance(issueInstant, datetime):
1261            raise TypeError('Expecting "datetime" type for "issueInstant", '
1262                            'got %r' % issueInstant.__class__)
1263           
1264        self.__issueInstant = issueInstant
1265       
1266    issueInstant = property(fget=_get_issueInstant, 
1267                            fset=_set_issueInstant,
1268                            doc="Issue instant of the assertion")
1269
1270    def _get_id(self):
1271        '''Sets the ID of this assertion.
1272       
1273        @return: the ID of this assertion
1274        '''
1275        return self.__id
1276   
1277    def _set_id(self, _id):
1278        '''Sets the ID of this assertion.
1279       
1280        @param _id: the ID of this assertion
1281        '''
1282        if not isinstance(_id, basestring):
1283            raise TypeError('Expecting basestring derived type for "id", got '
1284                            '%r' % _id.__class__)
1285        self.__id = _id
1286       
1287    id = property(fget=_get_id, fset=_set_id, doc="ID of assertion")
1288   
1289    def _set_issuer(self, issuer):
1290        """Set issuer"""
1291        if not isinstance(issuer, Issuer):
1292            raise TypeError("issuer must be %r, got %r" % (Issuer, 
1293                                                           type(issuer)))
1294        self.__issuer = issuer
1295   
1296    def _get_issuer(self):
1297        """Get the issuer name """
1298        return self.__issuer
1299
1300    issuer = property(fget=_get_issuer, 
1301                      fset=_set_issuer,
1302                      doc="Issuer of assertion")
1303   
1304    def _set_subject(self, subject):
1305        """Set subject string."""
1306        if not isinstance(subject, Subject):
1307            raise TypeError("subject must be %r, got %r" % (Subject, 
1308                                                            type(subject)))
1309
1310        self.__subject = subject
1311   
1312    def _get_subject(self):
1313        """Get subject string."""
1314        return self.__subject
1315
1316    subject = property(fget=_get_subject,
1317                       fset=_set_subject, 
1318                       doc="Attribute Assertion subject")
1319   
1320    def _get_conditions(self):
1321        """Get conditions string."""
1322        return self.__conditions
1323   
1324    def _set_conditions(self, value):
1325        """Get conditions string."""
1326        if not isinstance(value, Conditions):
1327            raise TypeError("Conditions must be %r, got %r" % (Conditions, 
1328                                                               type(value)))
1329
1330        self.__conditions = value
1331
1332    conditions = property(fget=_get_conditions,
1333                          fset=_set_conditions,
1334                          doc="Attribute Assertion conditions")
1335   
1336    def _set_advice(self, advice):
1337        """Set advice string."""
1338        if not isinstance(advice, basestring):
1339            raise TypeError("advice must be a string")
1340
1341        self.__advice = advice
1342   
1343    def _get_advice(self):
1344        """Get advice string."""
1345        return self.__advice
1346
1347    advice = property(fget=_get_advice,
1348                      fset=_set_advice, 
1349                      doc="Attribute Assertion advice")
1350   
1351    @property
1352    def statements(self):
1353        """Attribute Assertion statements"""
1354        return self.__statements
1355   
1356    @property
1357    def authnStatements(self):
1358        """Attribute Assertion authentication"""
1359        return self.__authnStatements
1360   
1361    @property
1362    def authzDecisionStatements(self):
1363        """Attribute Assertion authorisation decision statements"""
1364        return self.__authzDecisionStatements
1365   
1366    @property
1367    def attributeStatements(self):
1368        """Attribute Assertion attribute statements"""
1369        return self.__attributeStatements
1370   
1371
1372class AttributeValue(SAMLObject):
1373    """Base class for Attribute Value type"""
1374   
1375    # Element name, no namespace
1376    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeValue"
1377
1378    # Default element name
1379    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1380                                 DEFAULT_ELEMENT_LOCAL_NAME,
1381                                 SAMLConstants.SAML20_PREFIX)
1382    __slots__ = ()
1383
1384
1385class XSStringAttributeValue(AttributeValue):
1386    """XML XS:String Attribute Value type"""
1387   
1388    # Local name of the XSI type
1389    TYPE_LOCAL_NAME = "string"
1390       
1391    # QName of the XSI type
1392    TYPE_NAME = QName(SAMLConstants.XSD_NS, 
1393                      TYPE_LOCAL_NAME, 
1394                      SAMLConstants.XSD_PREFIX)
1395   
1396    DEFAULT_FORMAT = "%s#%s" % (SAMLConstants.XSD_NS, TYPE_LOCAL_NAME)
1397 
1398    __slots__ = ('__value',)
1399   
1400    def __init__(self, **kw):
1401        super(XSStringAttributeValue, self).__init__(**kw)
1402        self.__value = None
1403
1404    def __getstate__(self):
1405        '''Enable pickling'''
1406        _dict = super(XSStringAttributeValue, self).__getstate__()
1407        for attrName in XSStringAttributeValue.__slots__:
1408            # Ugly hack to allow for derived classes setting private member
1409            # variables
1410            if attrName.startswith('__'):
1411                attrName = "_XSStringAttributeValue" + attrName
1412               
1413            _dict[attrName] = getattr(self, attrName)
1414           
1415        return _dict
1416           
1417    def _getValue(self):
1418        return self.__value
1419       
1420    def _setValue(self, value):
1421        if not isinstance(value, basestring):
1422            raise TypeError("Input must be a basestring derived type, got %r" %
1423                            value.__class__)
1424           
1425        self.__value = value
1426
1427    value = property(fget=_getValue, fset=_setValue, doc="string value") 
1428
1429
1430class StatusDetail(SAMLObject):
1431    '''Implementation of SAML 2.0 StatusDetail'''
1432   
1433    # Local Name of StatusDetail.
1434    DEFAULT_ELEMENT_LOCAL_NAME = "StatusDetail"
1435
1436    # Default element name.
1437    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1438                                 DEFAULT_ELEMENT_LOCAL_NAME,
1439                                 SAMLConstants.SAML20P_PREFIX)
1440
1441    # Local name of the XSI type.
1442    TYPE_LOCAL_NAME = "StatusDetailType"
1443
1444    # QName of the XSI type.
1445    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1446                      TYPE_LOCAL_NAME,
1447                      SAMLConstants.SAML20P_PREFIX)
1448   
1449    __slots__ = ('__unknownChildren', )
1450   
1451    def __init__(self, **kw):
1452        super(StatusDetail, self).__init__(**kw)
1453       
1454        # child "any" elements.
1455        self.__unknownChildren = TypedList(SAMLObject)         
1456
1457    def __getstate__(self):
1458        '''Enable pickling'''
1459        _dict = super(StatusDetail, self).__getstate__()
1460        for attrName in StatusDetail.__slots__:
1461            # Ugly hack to allow for derived classes setting private member
1462            # variables
1463            if attrName.startswith('__'):
1464                attrName = "_StatusDetail" + attrName
1465               
1466            _dict[attrName] = getattr(self, attrName)
1467           
1468        return _dict
1469   
1470    def getUnknownXMLTypes(self, qname=None): 
1471        if qname is not None:
1472            if not isinstance(qname, QName):
1473                raise TypeError("\"qname\" must be a %r derived type, "
1474                                "got %r" % (QName, type(qname)))
1475               
1476            children = []
1477            for child in self.__unknownChildren:
1478                childQName = getattr(child, "qname", None)
1479                if childQName is not None:
1480                    if childQName.namespaceURI == qname.namespaceURI or \
1481                       childQName.localPart == qname.localPart:
1482                        children.append(child)
1483                       
1484            return children
1485        else:
1486            return self.__unknownChildren
1487   
1488    unknownChildren = property(fget=getUnknownXMLTypes,
1489                               doc="Child objects of Status Detail - may be "
1490                                   "any type")
1491   
1492
1493class StatusMessage(SAMLObject):
1494    '''Implementation of SAML 2.0 Status Message'''
1495
1496    DEFAULT_ELEMENT_LOCAL_NAME = "StatusMessage"
1497    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1498                                 DEFAULT_ELEMENT_LOCAL_NAME,
1499                                 SAMLConstants.SAML20P_PREFIX)
1500   
1501    __slots__ = ('__value', )
1502   
1503    def __init__(self, **kw):
1504        super(StatusMessage, self).__init__(**kw)
1505       
1506        # Value attribute URI.
1507        self.__value = None       
1508
1509    def __getstate__(self):
1510        '''Enable pickling'''
1511        _dict = super(StatusMessage, self).__getstate__()
1512        for attrName in StatusMessage.__slots__:
1513            # Ugly hack to allow for derived classes setting private member
1514            # variables
1515            if attrName.startswith('__'):
1516                attrName = "_StatusMessage" + attrName
1517               
1518            _dict[attrName] = getattr(self, attrName)
1519           
1520        return _dict
1521   
1522    def _getValue(self):
1523        return self.__value
1524       
1525    def _setValue(self, value):
1526        if not isinstance(value, basestring):
1527            raise TypeError("\"value\" must be a basestring derived type, "
1528                            "got %r" % type(value))
1529           
1530        self.__value = value
1531
1532    value = property(fget=_getValue, fset=_setValue, doc="Status message value")
1533
1534
1535class StatusCode(SAMLObject):
1536    '''Implementation of SAML 2.0 StatusCode.'''
1537   
1538    # Local Name of StatusCode.
1539    DEFAULT_ELEMENT_LOCAL_NAME = "StatusCode"
1540
1541    # Default element name.
1542    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1543                                 DEFAULT_ELEMENT_LOCAL_NAME,
1544                                 SAMLConstants.SAML20P_PREFIX)
1545
1546    # Local name of the XSI type.
1547    TYPE_LOCAL_NAME = "StatusCodeType"
1548
1549    # QName of the XSI type.
1550    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1551                      TYPE_LOCAL_NAME,
1552                      SAMLConstants.SAML20P_PREFIX)
1553
1554    # Local Name of the Value attribute.
1555    VALUE_ATTRIB_NAME = "Value"
1556
1557    # URI for Success status code.
1558    SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success"
1559
1560    # URI for Requester status code.
1561    REQUESTER_URI = "urn:oasis:names:tc:SAML:2.0:status:Requester"
1562
1563    # URI for Responder status code.
1564    RESPONDER_URI = "urn:oasis:names:tc:SAML:2.0:status:Responder"
1565
1566    # URI for VersionMismatch status code.
1567    VERSION_MISMATCH_URI = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
1568
1569    # URI for AuthnFailed status code.
1570    AUTHN_FAILED_URI = "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
1571
1572    # URI for InvalidAttrNameOrValue status code.
1573    INVALID_ATTR_NAME_VALUE_URI = \
1574                "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue"
1575
1576    # URI for InvalidNameIDPolicy status code.
1577    INVALID_NAMEID_POLICY_URI = \
1578                "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"
1579
1580    # URI for NoAuthnContext status code.
1581    NO_AUTHN_CONTEXT_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"
1582
1583    # URI for NoAvailableIDP status code.
1584    NO_AVAILABLE_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"
1585
1586    # URI for NoPassive status code.
1587    NO_PASSIVE_URI = "urn:oasis:names:tc:SAML:2.0:status:NoPassive"
1588
1589    # URI for NoSupportedIDP status code.
1590    NO_SUPPORTED_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"
1591
1592    # URI for PartialLogout status code.
1593    PARTIAL_LOGOUT_URI = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
1594
1595    # URI for ProxyCountExceeded status code.
1596    PROXY_COUNT_EXCEEDED_URI = \
1597                "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"
1598
1599    # URI for RequestDenied status code.
1600    REQUEST_DENIED_URI = "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"
1601
1602    # URI for RequestUnsupported status code.
1603    REQUEST_UNSUPPORTED_URI = \
1604                "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
1605
1606    # URI for RequestVersionDeprecated status code.
1607    REQUEST_VERSION_DEPRECATED_URI = \
1608                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
1609
1610    # URI for RequestVersionTooHigh status code.
1611    REQUEST_VERSION_TOO_HIGH_URI = \
1612                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
1613   
1614    # URI for RequestVersionTooLow status code.
1615    REQUEST_VERSION_TOO_LOW_URI = \
1616                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"
1617
1618    # URI for ResourceNotRecognized status code.
1619    RESOURCE_NOT_RECOGNIZED_URI = \
1620                "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"
1621
1622    # URI for TooManyResponses status code.
1623    TOO_MANY_RESPONSES = "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"
1624
1625    # URI for UnknownAttrProfile status code.
1626    UNKNOWN_ATTR_PROFILE_URI = \
1627                "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile"
1628
1629    # URI for UnknownPrincipal status code.
1630    UNKNOWN_PRINCIPAL_URI = \
1631                "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"
1632
1633    # URI for UnsupportedBinding status code.
1634    UNSUPPORTED_BINDING_URI = \
1635                "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"
1636
1637    __slots__ = ('__value', '__childStatusCode',)
1638   
1639    def __init__(self, **kw):
1640        super(StatusCode, self).__init__(**kw)
1641       
1642        # Value attribute URI.
1643        self.__value = None
1644   
1645        # Nested secondary StatusCode child element.
1646        self.__childStatusCode = None
1647
1648    def __getstate__(self):
1649        '''Enable pickling'''
1650        _dict = super(StatusCode, self).__getstate__()
1651        for attrName in StatusCode.__slots__:
1652            # Ugly hack to allow for derived classes setting private member
1653            # variables
1654            if attrName.startswith('__'):
1655                attrName = "_StatusCode" + attrName
1656               
1657            _dict[attrName] = getattr(self, attrName)
1658           
1659        return _dict
1660   
1661    def _getStatusCode(self): 
1662        return self.__childStatusCode
1663   
1664    def _setStatusCode(self, value):
1665        if not isinstance(value, StatusCode):
1666            raise TypeError('Child "statusCode" must be a %r derived type, '
1667                            "got %r" % (StatusCode, type(value)))
1668           
1669        self.__childStatusCode = value
1670
1671    value = property(fget=_getStatusCode, 
1672                     fset=_setStatusCode, 
1673                     doc="Child Status code")
1674             
1675    def _getValue(self):
1676        return self.__value
1677       
1678    def _setValue(self, value):
1679        if not isinstance(value, basestring):
1680            raise TypeError("\"value\" must be a basestring derived type, "
1681                            "got %r" % value.__class__)
1682           
1683        self.__value = value
1684
1685    value = property(fget=_getValue, fset=_setValue, doc="Status code value")
1686       
1687
1688class Status(SAMLObject): 
1689    '''SAML 2.0 Core Status'''
1690   
1691    # Local Name of Status.
1692    DEFAULT_ELEMENT_LOCAL_NAME = "Status"
1693
1694    # Default element name.
1695    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1696                                 DEFAULT_ELEMENT_LOCAL_NAME,
1697                                 SAMLConstants.SAML20P_PREFIX)
1698
1699    # Local name of the XSI type.
1700    TYPE_LOCAL_NAME = "StatusType"
1701
1702    # QName of the XSI type.
1703    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1704                      TYPE_LOCAL_NAME,
1705                      SAMLConstants.SAML20P_PREFIX)
1706
1707    __slots__ = ('__statusCode', '__statusMessage', '__statusDetail', )
1708   
1709    def __init__(self, **kw):
1710        super(Status, self).__init__(**kw)
1711       
1712        # StatusCode element.
1713        self.__statusCode = None
1714   
1715        # StatusMessage element.
1716        self.__statusMessage = None
1717   
1718        # StatusDetail element.
1719        self.__statusDetail = None
1720       
1721    def __getstate__(self):
1722        '''Enable pickling'''
1723        _dict = super(Status, self).__getstate__()
1724        for attrName in Status.__slots__:
1725            # Ugly hack to allow for derived classes setting private member
1726            # variables
1727            if attrName.startswith('__'):
1728                attrName = "_Status" + attrName
1729               
1730            _dict[attrName] = getattr(self, attrName)
1731           
1732        return _dict
1733   
1734    def _getStatusCode(self):
1735        '''
1736        Gets the Code of this Status.
1737       
1738        @return: Status StatusCode
1739        '''
1740        return self.__statusCode
1741
1742    def _setStatusCode(self, value):
1743        '''
1744        Sets the Code of this Status.
1745       
1746        @param value:         the Code of this Status
1747        '''
1748        if not isinstance(value, StatusCode):
1749            raise TypeError('"statusCode" must be a %r derived type, '
1750                            "got %r" % (StatusCode, type(value)))
1751           
1752        self.__statusCode = value
1753       
1754    statusCode = property(fget=_getStatusCode,
1755                          fset=_setStatusCode,
1756                          doc="status code object")
1757   
1758    def _getStatusMessage(self):
1759        '''
1760        Gets the Message of this Status.
1761       
1762        @return: Status StatusMessage
1763        '''
1764        return self.__statusMessage
1765
1766    def _setStatusMessage(self, value):
1767        '''
1768        Sets the Message of this Status.
1769       
1770        @param value: the Message of this Status
1771        '''
1772        if not isinstance(value, StatusMessage):
1773            raise TypeError('"statusMessage" must be a %r derived type, '
1774                            "got %r" % (StatusMessage, type(value)))
1775           
1776        self.__statusMessage = value
1777       
1778    statusMessage = property(fget=_getStatusMessage,
1779                             fset=_setStatusMessage,
1780                             doc="status message")
1781
1782    def _getStatusDetail(self):
1783        '''
1784        Gets the Detail of this Status.
1785       
1786        @return: Status StatusDetail
1787        '''
1788        return self.__statusDetail
1789   
1790    def _setStatusDetail(self, value):
1791        '''
1792        Sets the Detail of this Status.
1793       
1794        @param value: the Detail of this Status
1795        '''
1796        self.__statusDetail = value
1797       
1798    statusDetail = property(fget=_getStatusDetail,
1799                            fset=_setStatusDetail,
1800                            doc="status message")
1801
1802
1803class Action(SAMLObject): 
1804    '''SAML 2.0 Core Action'''
1805   
1806    # Element local name.
1807    DEFAULT_ELEMENT_LOCAL_NAME = "Action"
1808
1809    # Default element name.
1810    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1811                                 DEFAULT_ELEMENT_LOCAL_NAME,
1812                                 SAMLConstants.SAML20_PREFIX)
1813
1814    # Local name of the XSI type.
1815    TYPE_LOCAL_NAME = "ActionType"
1816
1817    # QName of the XSI type
1818    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1819                      TYPE_LOCAL_NAME,
1820                      SAMLConstants.SAML20_PREFIX)
1821
1822    # Name of the Namespace attribute.
1823    NAMESPACE_ATTRIB_NAME = "Namespace"
1824
1825    # Read/Write/Execute/Delete/Control action namespace.
1826    RWEDC_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:rwedc"
1827
1828    # Read/Write/Execute/Delete/Control negation action namespace.
1829    RWEDC_NEGATION_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:rwedc-negation"
1830
1831    # Get/Head/Put/Post action namespace.
1832    GHPP_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:ghpp"
1833
1834    # UNIX file permission action namespace.
1835    UNIX_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:unix"
1836
1837    ACTION_NS_IDENTIFIERS = (
1838        RWEDC_NS_URI,
1839        RWEDC_NEGATION_NS_URI,   
1840        GHPP_NS_URI,
1841        UNIX_NS_URI       
1842    )
1843   
1844    # Read action.
1845    READ_ACTION = "Read"
1846
1847    # Write action.
1848    WRITE_ACTION = "Write"
1849
1850    # Execute action.
1851    EXECUTE_ACTION = "Execute"
1852
1853    # Delete action.
1854    DELETE_ACTION = "Delete"
1855
1856    # Control action.
1857    CONTROL_ACTION = "Control"
1858
1859    # Negated Read action.
1860    NEG_READ_ACTION = "~Read"
1861
1862    # Negated Write action.
1863    NEG_WRITE_ACTION = "~Write"
1864
1865    # Negated Execute action.
1866    NEG_EXECUTE_ACTION = "~Execute"
1867
1868    # Negated Delete action.
1869    NEG_DELETE_ACTION = "~Delete"
1870
1871    # Negated Control action.
1872    NEG_CONTROL_ACTION = "~Control"
1873
1874    # HTTP GET action.
1875    HTTP_GET_ACTION = "GET"
1876
1877    # HTTP HEAD action.
1878    HTTP_HEAD_ACTION = "HEAD"
1879
1880    # HTTP PUT action.
1881    HTTP_PUT_ACTION = "PUT"
1882
1883    # HTTP POST action.
1884    HTTP_POST_ACTION = "POST"
1885   
1886    ACTION_TYPES = {
1887        RWEDC_NS_URI: (READ_ACTION, WRITE_ACTION, EXECUTE_ACTION, DELETE_ACTION,
1888                       CONTROL_ACTION),
1889        RWEDC_NEGATION_NS_URI: (READ_ACTION, WRITE_ACTION, EXECUTE_ACTION, 
1890                                DELETE_ACTION, CONTROL_ACTION, NEG_READ_ACTION, 
1891                                NEG_WRITE_ACTION, NEG_EXECUTE_ACTION, 
1892                                NEG_CONTROL_ACTION),   
1893        GHPP_NS_URI: (HTTP_GET_ACTION, HTTP_HEAD_ACTION, HTTP_PUT_ACTION,
1894                      HTTP_POST_ACTION),
1895                     
1896        # This namespace uses octal bitmask for file permissions
1897        UNIX_NS_URI: ()   
1898    }
1899   
1900    __slots__ = ('__namespace', '__value', '__actionTypes')
1901   
1902    def __init__(self, **kw):
1903        '''Create an authorization action type
1904        '''
1905        super(Action, self).__init__(**kw)
1906
1907        # URI of the Namespace of this action.  Default to read/write/negation
1908        # type - 2.7.4.2 SAML 2 Core Spec. 15 March 2005
1909        self.__namespace = Action.RWEDC_NEGATION_NS_URI
1910
1911        # Action value
1912        self.__value = None       
1913   
1914        self.__actionTypes = Action.ACTION_TYPES
1915       
1916    def __getstate__(self):
1917        '''Enable pickling'''
1918        _dict = super(Action, self).__getstate__()
1919        for attrName in Action.__slots__:
1920            # Ugly hack to allow for derived classes setting private member
1921            # variables
1922            if attrName.startswith('__'):
1923                attrName = "_Action" + attrName
1924               
1925            _dict[attrName] = getattr(self, attrName)
1926           
1927        return _dict
1928   
1929    def _getActionTypes(self):
1930        return self.__actionTypes
1931
1932    def _setActionTypes(self, value):
1933        if not isinstance(value, dict):
1934            raise TypeError('Expecting list or tuple type for "actionTypes" '
1935                            'attribute; got %r' % type(value))
1936           
1937        for k, v in value.items():
1938            if not isinstance(v, (tuple, type(None))):
1939                raise TypeError('Expecting None or tuple type for '
1940                                '"actionTypes" dictionary values; got %r for '
1941                                '%r key' % (type(value), k))
1942        self.__actionTypes = value
1943
1944    actionTypes = property(_getActionTypes, 
1945                           _setActionTypes, 
1946                           doc="Restrict vocabulary of action types")
1947       
1948    def _getNamespace(self):
1949        '''
1950        gets the namespace scope of the specified value.
1951       
1952        @return: the namespace scope of the specified value
1953        '''
1954        return self.__namespace
1955
1956    def _setNamespace(self, value):
1957        '''Sets the namespace scope of the specified value.
1958       
1959        @param value: the namespace scope of the specified value
1960        '''
1961        if not isinstance(value, basestring):
1962            raise TypeError('Expecting string type for "namespace" '
1963                            'attribute; got %r' % type(value))
1964           
1965        if value not in self.__actionTypes.keys():
1966            raise AttributeError('"namespace" action type %r not recognised. '
1967                                 'It must be one of these action types: %r' % 
1968                                 self.__actionTypes.keys())
1969           
1970        self.__namespace = value
1971
1972    namespace = property(_getNamespace, _setNamespace, doc="Action Namespace")
1973
1974    def _getValue(self):
1975        '''gets the URI of the action to be performed.
1976       
1977        @return: the URI of the action to be performed
1978        '''
1979        return self.__value
1980
1981    def _setValue(self, value):
1982        '''Sets the URI of the action to be performed.
1983       
1984        @param value: the URI of the value to be performed
1985        '''
1986        # int and oct allow for UNIX file permissions action type
1987        if not isinstance(value, (basestring, int)):
1988            raise TypeError('Expecting string or int type for "action" '
1989                            'attribute; got %r' % type(value))
1990           
1991        # Default to read/write/negation type - 2.7.4.2 SAML 2 Core Spec.
1992        # 15 March 2005
1993        allowedActions = self.__actionTypes.get(self.__namespace,
1994                                                Action.RWEDC_NEGATION_NS_URI)
1995       
1996        # Only apply restriction for action type that has a restricted
1997        # vocabulary - UNIX type is missed out of this because its an octal
1998        # mask
1999        if len(allowedActions) > 0 and value not in allowedActions:
2000            raise AttributeError('%r action not recognised; known actions for '
2001                                 'the %r namespace identifier are: %r.  ' 
2002                                 'If this is not as expected make sure to set '
2003                                 'the "namespace" attribute to an alternative '
2004                                 'value first or override completely by '
2005                                 'explicitly setting the "allowTypes" '
2006                                 'attribute' % 
2007                                 (value, self.__namespace, allowedActions))
2008        self.__value = value
2009
2010    value = property(_getValue, _setValue, doc="Action string")
2011       
2012
2013class RequestAbstractType(SAMLObject): 
2014    '''SAML 2.0 Core RequestAbstractType'''
2015   
2016    # Local name of the XSI type.
2017    TYPE_LOCAL_NAME = "RequestAbstractType"
2018
2019    # QName of the XSI type.
2020    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2021                      TYPE_LOCAL_NAME,
2022                      SAMLConstants.SAML20P_PREFIX)
2023
2024    # ID attribute name.
2025    ID_ATTRIB_NAME = "ID"
2026
2027    # Version attribute name.
2028    VERSION_ATTRIB_NAME = "Version"
2029
2030    # IssueInstant attribute name.
2031    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
2032
2033    # Destination attribute name.
2034    DESTINATION_ATTRIB_NAME = "Destination"
2035
2036    # Consent attribute name.
2037    CONSENT_ATTRIB_NAME = "Consent"
2038
2039    # Unspecified consent URI.
2040    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
2041
2042    # Obtained consent URI.
2043    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
2044
2045    # Prior consent URI.
2046    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
2047
2048    # Implicit consent URI.
2049    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
2050
2051    # Explicit consent URI.
2052    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
2053
2054    # Unavailable consent URI.
2055    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
2056
2057    # Inapplicable consent URI.
2058    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
2059     
2060    __slots__ = (
2061        '__version',
2062        '__id',
2063        '__issueInstant',
2064        '__destination',
2065        '__consent',
2066        '__issuer',
2067        '__extensions'
2068    )
2069   
2070    def __init__(self, **kw):
2071        '''Request abstract type
2072        @type kw: dict
2073        @param kw: see SAMLObject.__init__
2074        '''
2075        super(RequestAbstractType, self).__init__(**kw)
2076       
2077        # SAML Version of the request.
2078        self.__version = None
2079   
2080        # Unique identifier of the request.
2081        self.__id = None
2082   
2083        # Date/time request was issued.
2084        self.__issueInstant = None
2085   
2086        # URI of the request destination.
2087        self.__destination = None
2088   
2089        # URI of the SAML user consent type.
2090        self.__consent = None
2091   
2092        # URI of the SAML user consent type.
2093        self.__issuer = None
2094   
2095        # Extensions child element.
2096        self.__extensions = None
2097
2098    def __getstate__(self):
2099        '''Enable pickling'''
2100        _dict = super(RequestAbstractType, self).__getstate__()
2101        for attrName in RequestAbstractType.__slots__:
2102            # Ugly hack to allow for derived classes setting private member
2103            # variables
2104            if attrName.startswith('__'):
2105                attrName = "_RequestAbstractType" + attrName
2106               
2107            _dict[attrName] = getattr(self, attrName)
2108           
2109        return _dict
2110   
2111    def _get_version(self):
2112        '''@return: the SAML Version of this assertion.
2113        '''
2114        return self.__version
2115   
2116    def _set_version(self, version):
2117        '''@param version: the SAML Version of this assertion
2118        '''
2119        if not isinstance(version, SAMLVersion):
2120            raise TypeError("Expecting SAMLVersion type got: %r" % 
2121                            version.__class__)
2122       
2123        self.__version = version
2124       
2125    version = property(fget=_get_version,
2126                       fset=_set_version,
2127                       doc="SAML Version of the assertion")
2128
2129    def _get_issueInstant(self):
2130        '''Gets the date/time the request was issued
2131       
2132        @return: the issue instance of this request'''
2133        return self.__issueInstant
2134   
2135    def _set_issueInstant(self, value):
2136        '''Sets the date/time the request was issued
2137       
2138        @param value: the issue instance of this request
2139        '''
2140        if not isinstance(value, datetime):
2141            raise TypeError('Expecting "datetime" type for "issueInstant", '
2142                            'got %r' % type(value))
2143           
2144        self.__issueInstant = value
2145       
2146    issueInstant = property(fget=_get_issueInstant, 
2147                            fset=_set_issueInstant,
2148                            doc="Issue instant of the request") 
2149
2150    def _get_id(self):
2151        '''Sets the unique identifier for this request.
2152       
2153        @return: the ID of this request
2154        '''
2155        return self.__id
2156   
2157    def _set_id(self, value):
2158        '''Sets the unique identifier for this request
2159       
2160        @param value: the ID of this assertion
2161        '''
2162        if not isinstance(value, basestring):
2163            raise TypeError('Expecting basestring derived type for "id", got '
2164                            '%r' % type(value))
2165        self.__id = value
2166       
2167    id = property(fget=_get_id, fset=_set_id, doc="ID of request")
2168
2169    def _get_destination(self):
2170        '''Gets the URI of the destination of the request.
2171       
2172        @return: the URI of the destination of the request
2173        '''
2174        return self.__destination
2175   
2176    def _set_destination(self, value):
2177        '''Sets the URI of the destination of the request.
2178       
2179        @param value: the URI of the destination of the request'''
2180        if not isinstance(value, basestring):
2181            raise TypeError('Expecting basestring derived type for '
2182                            '"destination", got %r' % type(value))
2183        self.__destination = value
2184       
2185    destination = property(fget=_get_destination, 
2186                           fset=_set_destination,
2187                           doc="Destination of request")
2188     
2189    def _get_consent(self):
2190        '''Gets the consent obtained from the principal for sending this
2191        request.
2192       
2193        @return: the consent obtained from the principal for sending this
2194        request
2195        '''
2196        return self.__consent
2197       
2198    def _set_consent(self, value):
2199        '''Sets the consent obtained from the principal for sending this
2200        request.
2201       
2202        @param value: the new consent obtained from the principal for
2203        sending this request
2204        ''' 
2205        if not isinstance(value, basestring):
2206            raise TypeError('Expecting basestring derived type for "consent", '
2207                            'got %r' % type(value))
2208        self.__consent = value
2209             
2210    consent = property(fget=_get_consent, 
2211                       fset=_set_consent,
2212                       doc="Consent for request")
2213   
2214    def _set_issuer(self, issuer):
2215        """Set issuer of request"""
2216        if not isinstance(issuer, Issuer):
2217            raise TypeError('"issuer" must be a %r, got %r' % (Issuer, 
2218                                                               type(issuer)))
2219       
2220        self.__issuer = issuer
2221   
2222    def _get_issuer(self):
2223        """Get the issuer name """
2224        return self.__issuer
2225
2226    issuer = property(fget=_get_issuer, 
2227                      fset=_set_issuer,
2228                      doc="Issuer of request")
2229 
2230    def _get_extensions(self):
2231        '''Gets the Extensions of this request.
2232       
2233        @return: the Status of this request
2234        '''
2235        return self.__extensions
2236     
2237    def _set_extensions(self, value):
2238        '''Sets the Extensions of this request.
2239       
2240        @param value: the Extensions of this request
2241        '''
2242        self.__extensions = value
2243       
2244    extensions = property(fget=_get_extensions, 
2245                          fset=_set_extensions,
2246                          doc="Request extensions")
2247
2248
2249class SubjectQuery(RequestAbstractType):
2250    """SAML 2.0 Core Subject Query type"""
2251    __slots__ = ('__subject', )
2252   
2253    def __init__(self):
2254        super(SubjectQuery, self).__init__()
2255        self.__subject = None
2256
2257    def __getstate__(self):
2258        '''Enable pickling'''
2259        _dict = super(SubjectQuery, self).__getstate__()
2260        for attrName in SubjectQuery.__slots__:
2261            # Ugly hack to allow for derived classes setting private member
2262            # variables
2263            if attrName.startswith('__'):
2264                attrName = "_SubjectQuery" + attrName
2265               
2266            _dict[attrName] = getattr(self, attrName)
2267           
2268        return _dict
2269           
2270    def _getSubject(self):
2271        '''Gets the Subject of this request.
2272       
2273        @return: the Subject of this request'''   
2274        return self.__subject
2275   
2276    def _setSubject(self, value):
2277        '''Sets the Subject of this request.
2278       
2279        @param value: the Subject of this request'''
2280        if not isinstance(value, Subject):
2281            raise TypeError('Setting "subject", got %r, expecting %r' %
2282                            (Subject, type(value)))
2283           
2284        self.__subject = value
2285       
2286    subject = property(fget=_getSubject, fset=_setSubject, doc="Query subject")
2287   
2288   
2289class AttributeQuery(SubjectQuery):
2290    '''SAML 2.0 AttributeQuery'''
2291   
2292    # Element local name.
2293    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeQuery"
2294
2295    # Default element name.
2296    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2297                                 DEFAULT_ELEMENT_LOCAL_NAME,
2298                                 SAMLConstants.SAML20P_PREFIX)
2299
2300    # Local name of the XSI type.
2301    TYPE_LOCAL_NAME = "AttributeQueryType"
2302
2303    # QName of the XSI type.
2304    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2305                      TYPE_LOCAL_NAME,
2306                      SAMLConstants.SAML20P_PREFIX)
2307
2308    __slots__ = ('__attributes',)
2309   
2310    def __init__(self):
2311        super(AttributeQuery, self).__init__()
2312        self.__attributes = TypedList(Attribute)
2313
2314    def __getstate__(self):
2315        '''Enable pickling'''
2316        _dict = super(AttributeQuery, self).__getstate__()
2317        for attrName in AttributeQuery.__slots__:
2318            # Ugly hack to allow for derived classes setting private member
2319            # variables
2320            if attrName.startswith('__'):
2321                attrName = "_AttributeQuery" + attrName
2322               
2323            _dict[attrName] = getattr(self, attrName)
2324           
2325        return _dict
2326 
2327    def _getAttributes(self):
2328        '''Gets the Attributes of this query.
2329       
2330        @return: the list of Attributes of this query'''
2331        return self.__attributes
2332
2333    def _setAttributes(self, value):
2334        self.__attributes = value
2335
2336    attributes = property(fget=_getAttributes, 
2337                          fset=_setAttributes, 
2338                          doc="Attributes")
2339
2340
2341class Evidentiary(SAMLObject):
2342    """Base class for types set in an evidence object"""
2343    __slots__ = ()
2344
2345
2346class AssertionURIRef(Evidentiary):
2347    '''SAML 2.0 Core AssertionURIRef'''
2348    __slots__ = ('__assertionURI',)
2349   
2350    # Element local name
2351    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionURIRef"
2352
2353    # Default element name
2354    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
2355                                 DEFAULT_ELEMENT_LOCAL_NAME,
2356                                 SAMLConstants.SAML20_PREFIX)
2357   
2358    def __init__(self):
2359        '''Create assertion URI reference'''
2360        super(AssertionURIRef, self).__init__()
2361       
2362        # URI of the Assertion
2363        self.__assertionURI = None   
2364
2365    def __getstate__(self):
2366        '''Enable pickling'''
2367        _dict = super(AssertionURIRef, self).__getstate__()
2368        for attrName in AssertionURIRef.__slots__:
2369            # Ugly hack to allow for derived classes setting private member
2370            # variables
2371            if attrName.startswith('__'):
2372                attrName = "_AssertionURIRef" + attrName
2373               
2374            _dict[attrName] = getattr(self, attrName)
2375           
2376        return _dict
2377   
2378    def _getAssertionURI(self):
2379        return self.__assertionURI
2380
2381    def _setAssertionURI(self, value):
2382        if not isinstance(value, basestring):
2383            raise TypeError('Expecting string type for "assertionID" '
2384                            'attribute; got %r' % type(value))
2385        self.__assertionURI = value
2386
2387    def getOrderedChildren(self):
2388        return None
2389
2390    assertionURI = property(_getAssertionURI, _setAssertionURI, 
2391                            doc="Assertion URI")
2392   
2393   
2394class AssertionIDRef(Evidentiary):
2395    '''SAML 2.0 Core AssertionIDRef.'''
2396
2397    # Element local name.
2398    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionIDRef"
2399
2400    # Default element name.
2401    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
2402                                 DEFAULT_ELEMENT_LOCAL_NAME,
2403                                 SAMLConstants.SAML20_PREFIX)
2404   
2405    __slots__ = ("_AssertionID",)
2406   
2407    def __init__(self, namespaceURI, elementLocalName, namespacePrefix):
2408        '''
2409        @param namespaceURI: the namespace the element is in
2410        @param elementLocalName: the local name of the XML element this Object
2411        represents
2412        @param namespacePrefix: the prefix for the given namespace
2413        '''
2414        super(AssertionIDRef, self).__init__(namespaceURI, 
2415                                             elementLocalName, 
2416                                             namespacePrefix)
2417        self.__assertionID = None
2418
2419    def __getstate__(self):
2420        '''Enable pickling'''
2421        _dict = super(AssertionIDRef, self).__getstate__()
2422        for attrName in AssertionIDRef.__slots__:
2423            # Ugly hack to allow for derived classes setting private member
2424            # variables
2425            if attrName.startswith('__'):
2426                attrName = "_AssertionIDRef" + attrName
2427               
2428            _dict[attrName] = getattr(self, attrName)
2429           
2430        return _dict
2431       
2432    def _getAssertionID(self):
2433        '''Gets the ID of the assertion this references.
2434       
2435        @return: the ID of the assertion this references'''
2436        return self.__assertionID
2437       
2438    def _setAssertionID(self, value):
2439        '''Sets the ID of the assertion this references.
2440       
2441        @param value: the ID of the assertion this references'''
2442        if not isinstance(value, basestring):
2443            raise TypeError('Expecting string type for "assertionID" '
2444                            'attribute; got %r' % type(value))
2445        self.__assertionID = value
2446
2447    def getOrderedChildren(self):
2448        return None
2449
2450    assertionID = property(_getAssertionID, _setAssertionID, 
2451                           doc="Assertion ID")
2452       
2453   
2454class EncryptedElementType(SAMLObject):
2455    '''SAML 2.0 Core EncryptedElementType'''
2456   
2457    # Local name of the XSI type.
2458    TYPE_LOCAL_NAME = "EncryptedElementType"
2459       
2460    # QName of the XSI type.
2461    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
2462                      TYPE_LOCAL_NAME, 
2463                      SAMLConstants.SAML20_PREFIX)
2464   
2465    __slots__ = ()
2466   
2467    def _getEncryptedData(self):
2468        '''Get the EncryptedData child element.
2469       
2470        @return the EncryptedData child element'''
2471        raise NotImplementedError()
2472   
2473    def _setEncryptedData(self, value):
2474        '''Set the EncryptedData child element.
2475       
2476        @param newEncryptedData the new EncryptedData child element'''
2477        raise NotImplementedError()
2478   
2479    def _getEncryptedKeys(self):
2480        '''A list of EncryptedKey child elements.
2481       
2482        @return a list of EncryptedKey child elements'''
2483        raise NotImplementedError()
2484   
2485   
2486class EncryptedAssertion(EncryptedElementType, Evidentiary):
2487    '''SAML 2.0 Core EncryptedAssertion.'''
2488   
2489    # Element local name.
2490    DEFAULT_ELEMENT_LOCAL_NAME = "EncryptedAssertion"
2491
2492    # Default element name.
2493    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
2494                                 DEFAULT_ELEMENT_LOCAL_NAME,
2495                                 SAMLConstants.SAML20_PREFIX) 
2496    __slots__ = ()
2497     
2498   
2499class Evidence(SAMLObject):
2500    '''SAML 2.0 Core Evidence.'''
2501   
2502    # Element local name.
2503    DEFAULT_ELEMENT_LOCAL_NAME = "Evidence"
2504   
2505    # Default element name.
2506    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
2507                                 DEFAULT_ELEMENT_LOCAL_NAME, 
2508                                 SAMLConstants.SAML20_PREFIX)
2509   
2510    # Local name of the XSI type.
2511    TYPE_LOCAL_NAME = "EvidenceType" 
2512       
2513    # QName of the XSI type.
2514    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
2515                      TYPE_LOCAL_NAME, 
2516                      SAMLConstants.SAML20_PREFIX)
2517
2518    __slots__ = ('__values',)
2519   
2520    def __init__(self, **kw):
2521        '''Create an authorization evidence type
2522        '''
2523        super(Evidence, self).__init__(**kw)
2524
2525        # Assertion of the Evidence.
2526        self.__values = TypedList(Evidentiary) 
2527
2528    def __getstate__(self):
2529        '''Enable pickling'''
2530        _dict = super(Evidence, self).__getstate__()
2531        for attrName in Evidence.__slots__:
2532            # Ugly hack to allow for derived classes setting private member
2533            # variables
2534            if attrName.startswith('__'):
2535                attrName = "_Evidence" + attrName
2536               
2537            _dict[attrName] = getattr(self, attrName)
2538           
2539        return _dict   
2540         
2541    @property
2542    def assertionIDReferences(self):
2543        '''Gets the list of AssertionID references used as evidence.
2544   
2545        @return: the list of AssertionID references used as evidence'''
2546        return [i for i in self.__values
2547                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
2548                    AssertionIDRef.DEFAULT_ELEMENT_NAME)]
2549   
2550    @property
2551    def assertionURIReferences(self):
2552        '''Gets the list of AssertionURI references used as evidence.
2553       
2554        @return: the list of AssertionURI references used as evidence'''
2555        return [i for i in self.__values
2556                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
2557                    AssertionURIRef.DEFAULT_ELEMENT_NAME)]
2558   
2559    @property
2560    def assertions(self):
2561        '''Gets the list of Assertions used as evidence.
2562       
2563        @return: the list of Assertions used as evidence'''
2564        return [i for i in self.__values
2565                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
2566                    Assertion.DEFAULT_ELEMENT_NAME)]
2567   
2568    @property
2569    def encryptedAssertions(self):
2570        '''Gets the list of EncryptedAssertions used as evidence.
2571       
2572        @return: the list of EncryptedAssertions used as evidence'''
2573        return [i for i in self.__values
2574                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
2575                    EncryptedAssertion.DEFAULT_ELEMENT_NAME)]   
2576
2577    @property
2578    def values(self):
2579        '''Gets the list of all elements used as evidence.
2580       
2581        @return: the list of Evidentiary objects used as evidence'''
2582        return self.__values
2583   
2584    def getOrderedChildren(self):
2585        children = []
2586
2587        if len(self.__values) == 0:
2588            return None
2589
2590        children.extend(self.__values)
2591
2592        return tuple(children)
2593   
2594
2595class AuthzDecisionQuery(SubjectQuery):
2596    '''SAML 2.0 AuthzDecisionQuery.'''
2597
2598    # Element local name.
2599    DEFAULT_ELEMENT_LOCAL_NAME = "AuthzDecisionQuery"
2600
2601    # Default element name.
2602    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2603                                 DEFAULT_ELEMENT_LOCAL_NAME,
2604                                 SAMLConstants.SAML20P_PREFIX)
2605
2606    # Local name of the XSI type.
2607    TYPE_LOCAL_NAME = "AuthzDecisionQueryType"
2608
2609    # QName of the XSI type.
2610    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2611                      TYPE_LOCAL_NAME,
2612                      SAMLConstants.SAML20P_PREFIX)
2613
2614    # Resource attribute name.
2615    RESOURCE_ATTRIB_NAME = "Resource"
2616   
2617    __slots__ = (
2618       '__resource',
2619       '__evidence',
2620       '__actions',
2621       '__normalizeResource',
2622       '__safeNormalizationChars'
2623    )
2624   
2625    def __init__(self, normalizeResource=True, safeNormalizationChars='/%'):
2626        '''Create new authorisation decision query
2627        '''
2628        super(AuthzDecisionQuery, self).__init__()
2629
2630        # Resource attribute value.
2631        self.__resource = None
2632   
2633        # Evidence child element.
2634        self.__evidence = None
2635   
2636        # Action child elements.
2637        self.__actions = TypedList(Action)   
2638       
2639        # Tuning for normalization of resource URIs in property set method
2640        self.normalizeResource = normalizeResource
2641        self.safeNormalizationChars = safeNormalizationChars
2642
2643    def __getstate__(self):
2644        '''Enable pickling'''
2645        _dict = super(AuthzDecisionQuery, self).__getstate__()
2646        for attrName in AuthzDecisionQuery.__slots__:
2647            # Ugly hack to allow for derived classes setting private member
2648            # variables
2649            if attrName.startswith('__'):
2650                attrName = "_AuthzDecisionQuery" + attrName
2651               
2652            _dict[attrName] = getattr(self, attrName)
2653           
2654        return _dict
2655   
2656    def _getNormalizeResource(self):
2657        return self.__normalizeResource
2658
2659    def _setNormalizeResource(self, value):
2660        if not isinstance(value, bool):
2661            raise TypeError('Expecting bool type for "normalizeResource" '
2662                            'attribute; got %r instead' % type(value))
2663           
2664        self.__normalizeResource = value
2665
2666    normalizeResource = property(_getNormalizeResource, 
2667                                 _setNormalizeResource, 
2668                                 doc="Flag to normalize new resource value "
2669                                     "assigned to the \"resource\" property.  "
2670                                     "The setting only applies for URIs "
2671                                     'beginning with "http://" or "https://"')
2672
2673    def _getSafeNormalizationChars(self):
2674        return self.__safeNormalizationChars
2675
2676    def _setSafeNormalizationChars(self, value):
2677        if not isinstance(value, basestring):
2678            raise TypeError('Expecting string type for "normalizeResource" '
2679                            'attribute; got %r instead' % type(value))
2680           
2681        self.__safeNormalizationChars = value
2682
2683    safeNormalizationChars = property(_getSafeNormalizationChars, 
2684                                      _setSafeNormalizationChars, 
2685                                      doc="String containing a list of "
2686                                          "characters that should not be "
2687                                          "converted when Normalizing the "
2688                                          "resource URI.  These are passed to "
2689                                          "urllib.quote when the resource "
2690                                          "property is set.  The default "
2691                                          "characters are '/%'")
2692
2693    def _getResource(self):
2694        '''Gets the Resource attrib value of this query.
2695
2696        @return: the Resource attrib value of this query'''
2697        return self.__resource
2698   
2699    def _setResource(self, value):
2700        '''Sets the Resource attrib value of this query normalizing the path
2701        component, removing spurious port numbers (80 for HTTP and 443 for
2702        HTTPS) and converting the host component to lower case.
2703       
2704        @param value: the new Resource attrib value of this query'''
2705        if not isinstance(value, basestring):
2706            raise TypeError('Expecting string type for "resource" attribute; '
2707                            'got %r instead' % type(value))
2708       
2709        if (self.normalizeResource and 
2710            value.startswith('http://') or value.startswith('https://')):
2711            # Normalise the path, set the host name to lower case and remove
2712            # port redundant numbers 80 and 443
2713            splitResult = urlsplit(value)
2714            uriComponents = list(splitResult)
2715           
2716            # hostname attribute is lowercase
2717            uriComponents[1] = splitResult.hostname
2718           
2719            if splitResult.port is not None:
2720                isHttpWithStdPort = (splitResult.port == 80 and 
2721                                     splitResult.scheme == 'http')
2722               
2723                isHttpsWithStdPort = (splitResult.port == 443 and
2724                                      splitResult.scheme == 'https')
2725               
2726                if not isHttpWithStdPort and not isHttpsWithStdPort:
2727                    uriComponents[1] += ":%d" % splitResult.port
2728           
2729            uriComponents[2] = urllib.quote(splitResult.path, 
2730                                            self.safeNormalizationChars)
2731           
2732            self.__resource = urlunsplit(uriComponents)
2733        else:
2734            self.__resource = value
2735   
2736    resource = property(fget=_getResource, fset=_setResource,
2737                        doc="Resource for which authorisation is requested")
2738   
2739    @property
2740    def actions(self):
2741        '''The actions for which authorisation is requested
2742       
2743        @return: the Actions of this query'''
2744        return self.__actions
2745   
2746    def _getEvidence(self):
2747        '''Gets the Evidence of this query.
2748
2749        @return: the Evidence of this query'''
2750        return self.__evidence
2751
2752    def _setEvidence(self, value):
2753        '''Sets the Evidence of this query.
2754        @param newEvidence: the new Evidence of this query''' 
2755        if not isinstance(value, Evidence):
2756            raise TypeError('Expecting Evidence type for "evidence" '
2757                            'attribute; got %r' % type(value))
2758
2759        self.__evidence = value 
2760
2761    evidence = property(fget=_getEvidence, fset=_setEvidence, 
2762                        doc="A set of assertions which the Authority may use "
2763                            "to base its authorisation decision on")
2764   
2765    def getOrderedChildren(self):
2766        children = []
2767
2768        superChildren = super(AuthzDecisionQuery, self).getOrderedChildren()
2769        if superChildren:
2770            children.extend(superChildren)
2771
2772        children.extend(self.__actions)
2773       
2774        if self.__evidence is not None:
2775            children.extend(self.__evidence)
2776
2777        if len(children) == 0:
2778            return None
2779
2780        return tuple(children)
2781
2782
2783class StatusResponseType(SAMLObject):
2784    '''SAML 2.0 Core Status Response Type
2785    '''
2786
2787    # Local name of the XSI type.
2788    TYPE_LOCAL_NAME = "StatusResponseType"
2789
2790    # QName of the XSI type.
2791    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2792                      TYPE_LOCAL_NAME,
2793                      SAMLConstants.SAML20P_PREFIX)
2794
2795    # ID attribute name
2796    ID_ATTRIB_NAME = "ID"
2797
2798    # InResponseTo attribute name
2799    IN_RESPONSE_TO_ATTRIB_NAME = "InResponseTo"
2800
2801    # Version attribute name
2802    VERSION_ATTRIB_NAME = "Version"
2803
2804    # IssueInstant attribute name
2805    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
2806
2807    # Destination attribute name
2808    DESTINATION_ATTRIB_NAME = "Destination"
2809
2810    # Consent attribute name.
2811    CONSENT_ATTRIB_NAME = "Consent"
2812
2813    # Unspecified consent URI
2814    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
2815
2816    # Obtained consent URI
2817    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
2818
2819    # Prior consent URI
2820    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
2821
2822    # Implicit consent URI
2823    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
2824
2825    # Explicit consent URI
2826    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
2827
2828    # Unavailable consent URI
2829    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
2830
2831    # Inapplicable consent URI
2832    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
2833
2834    __slots__ = (   
2835        '__version',
2836        '__id',
2837        '__inResponseTo',
2838        '__issueInstant',
2839        '__destination',
2840        '__consent',
2841        '__issuer',
2842        '__status',
2843        '__extensions'               
2844    )
2845   
2846    def __init__(self, **kw):
2847        super(StatusResponseType, self).__init__(**kw)
2848       
2849        self.__version = SAMLVersion(SAMLVersion.VERSION_20)
2850        self.__id = None
2851        self.__inResponseTo = None
2852        self.__issueInstant = None
2853        self.__destination = None
2854        self.__consent = None
2855        self.__issuer = None
2856        self.__status = None
2857        self.__extensions = None
2858
2859    def __getstate__(self):
2860        '''Enable pickling'''
2861        _dict = super(StatusResponseType, self).__getstate__()
2862        for attrName in StatusResponseType.__slots__:
2863            # Ugly hack to allow for derived classes setting private member
2864            # variables
2865            if attrName.startswith('__'):
2866                attrName = "_StatusResponseType" + attrName
2867               
2868            _dict[attrName] = getattr(self, attrName)
2869           
2870        return _dict
2871   
2872    def _get_version(self):
2873        '''@return: the SAML Version of this response.
2874        '''
2875        return self.__version
2876   
2877    def _set_version(self, version):
2878        '''@param version: the SAML Version of this response
2879        '''
2880        if not isinstance(version, SAMLVersion):
2881            raise TypeError("Expecting SAMLVersion type got: %r" % 
2882                            version.__class__)
2883       
2884        self.__version = version
2885       
2886    version = property(fget=_get_version,
2887                       fset=_set_version,
2888                       doc="SAML Version of the response")
2889
2890    def _get_id(self):
2891        '''Sets the ID of this response.
2892       
2893        @return: the ID of this response
2894        '''
2895        return self.__id
2896   
2897    def _set_id(self, value):
2898        '''Sets the ID of this response.
2899       
2900        @param value: the ID of this response
2901        '''
2902        if not isinstance(value, basestring):
2903            raise TypeError('Expecting basestring derived type for "id", got '
2904                            '%r' % type(value))
2905        self.__id = value
2906       
2907    id = property(fget=_get_id, fset=_set_id, doc="ID of response")
2908
2909    def _getInResponseTo(self):
2910        '''Get the unique request identifier for which this is a response
2911       
2912        @return: the unique identifier of the originating
2913        request
2914        '''
2915        return self.__inResponseTo
2916   
2917    def _setInResponseTo(self, value):
2918        '''Set the unique request identifier for which this is a response
2919       
2920        @param value: the unique identifier of the originating
2921        request
2922        '''
2923        if not isinstance(value, basestring):
2924            raise TypeError('Expecting basestring derived type for '
2925                            '"inResponseTo", got %r' % type(value))
2926        self.__inResponseTo = value
2927       
2928    inResponseTo = property(fget=_getInResponseTo, 
2929                            fset=_setInResponseTo,
2930                            doc="unique request identifier for which this is "
2931                                "a response")
2932
2933    def _get_issueInstant(self):
2934        '''Gets the issue instance of this response.
2935       
2936        @return: the issue instance of this response'''
2937        return self.__issueInstant
2938   
2939    def _set_issueInstant(self, issueInstant):
2940        '''Sets the issue instance of this response.
2941       
2942        @param newIssueInstance: the issue instance of this response
2943        '''
2944        if not isinstance(issueInstant, datetime):
2945            raise TypeError('Expecting "datetime" type for "issueInstant", '
2946                            'got %r' % issueInstant.__class__)
2947           
2948        self.__issueInstant = issueInstant
2949       
2950    issueInstant = property(fget=_get_issueInstant, 
2951                            fset=_set_issueInstant,
2952                            doc="Issue instant of the response")
2953
2954    def _get_destination(self):
2955        '''Gets the URI of the destination of the response.
2956       
2957        @return: the URI of the destination of the response
2958        '''
2959        return self.__destination
2960   
2961    def _set_destination(self, value):
2962        '''Sets the URI of the destination of the response.
2963       
2964        @param value: the URI of the destination of the response'''
2965        if not isinstance(value, basestring):
2966            raise TypeError('Expecting basestring derived type for '
2967                            '"destination", got %r' % type(value))
2968        self.__destination = value
2969       
2970    destination = property(fget=_get_destination, 
2971                           fset=_set_destination,
2972                           doc="Destination of response")
2973     
2974    def _get_consent(self):
2975        '''Gets the consent obtained from the principal for sending this
2976        response.
2977       
2978        @return: the consent obtained from the principal for sending this
2979        response
2980        '''
2981        return self.__consent
2982       
2983    def _set_consent(self, value):
2984        '''Sets the consent obtained from the principal for sending this
2985        response.
2986       
2987        @param value: the new consent obtained from the principal for
2988        sending this response
2989        ''' 
2990        if not isinstance(value, basestring):
2991            raise TypeError('Expecting basestring derived type for "consent", '
2992                            'got %r' % type(value))
2993        self.__consent = value
2994             
2995    consent = property(fget=_get_consent, 
2996                       fset=_set_consent,
2997                       doc="Consent for response")
2998   
2999    def _set_issuer(self, issuer):
3000        """Set issuer of response"""
3001        if not isinstance(issuer, Issuer):
3002            raise TypeError('"issuer" must be a %r, got %r' % (Issuer,
3003                                                               type(issuer)))
3004        self.__issuer = issuer
3005   
3006    def _get_issuer(self):
3007        """Get the issuer name """
3008        return self.__issuer
3009
3010    issuer = property(fget=_get_issuer, 
3011                      fset=_set_issuer,
3012                      doc="Issuer of response")
3013   
3014    def _getStatus(self):
3015        '''Gets the Status of this response.
3016       
3017        @return: the Status of this response
3018        '''
3019        return self.__status
3020
3021    def _setStatus(self, value):
3022        '''Sets the Status of this response.
3023       
3024        @param newStatus: the Status of this response
3025        '''
3026        if not isinstance(value, Status):
3027            raise TypeError('"status" must be a %r, got %r' % (Status,
3028                                                               type(value)))
3029        self.__status = value
3030       
3031    status = property(fget=_getStatus, fset=_setStatus, doc="Response status")   
3032       
3033    def _get_extensions(self):
3034        '''Gets the Extensions of this response.
3035       
3036        @return: the Status of this response
3037        '''
3038        return self.__extensions
3039     
3040    def _set_extensions(self, value):
3041        '''Sets the Extensions of this response.
3042       
3043        @param value: the Extensions of this response
3044        '''
3045        if not isinstance(value, (list, tuple)):
3046            raise TypeError('Expecting list or tuple for "extensions", got %r'
3047                            % type(value))
3048        self.__extensions = value
3049       
3050    extensions = property(fget=_get_extensions, 
3051                          fset=_set_extensions,
3052                          doc="Response extensions")   
3053
3054
3055class Response(StatusResponseType):
3056    '''SAML2 Core Response'''
3057   
3058    # Element local name.
3059    DEFAULT_ELEMENT_LOCAL_NAME = "Response"
3060   
3061    # Default element name.
3062    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
3063                                 DEFAULT_ELEMENT_LOCAL_NAME, 
3064                                 SAMLConstants.SAML20P_PREFIX)
3065   
3066    # Local name of the XSI type.
3067    TYPE_LOCAL_NAME = "ResponseType"
3068       
3069    # QName of the XSI type.
3070    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
3071                      TYPE_LOCAL_NAME, 
3072                      SAMLConstants.SAML20P_PREFIX)
3073   
3074    __slots__ = ('__indexedChildren',)
3075   
3076    def __init__(self, **kw):
3077        '''''' 
3078        super(Response, self).__init__(**kw)
3079       
3080        # Assertion child elements
3081        self.__indexedChildren = []
3082
3083    def __getstate__(self):
3084        '''Enable pickling'''
3085        _dict = super(Response, self).__getstate__()
3086        for attrName in Response.__slots__:
3087            # Ugly hack to allow for derived classes setting private member
3088            # variables
3089            if attrName.startswith('__'):
3090                attrName = "_Response" + attrName
3091               
3092            _dict[attrName] = getattr(self, attrName)
3093           
3094        return _dict
3095       
3096    @property
3097    def assertions(self): 
3098        "Assertions contained in this response"
3099        return self.__indexedChildren
Note: See TracBrowser for help on using the repository browser.