source: TI12-security/trunk/ndg_security_saml/saml/saml2/core.py @ 6602

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