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

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