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

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

started unit testing for SAML AuthzDecisionQuery?

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