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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg_security_saml/saml/saml2/core.py@5663
Revision 5663, 68.0 KB checked in by pjkersha, 11 years ago (diff)
  • Working unit tests for SAML Attribute Query WSGI interface with SOAP binding
  • integrated with Attribute Authority via AttributeAuthorityMiddleware?.
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
32
33from saml.common import SAMLObject, SAMLVersion
34from saml.common.xml import SAMLConstants, QName
35from saml.utils import TypedList
36
37
38class Attribute(SAMLObject):
39    '''SAML 2.0 Core Attribute.'''
40   
41    # Local name of the Attribute element.
42    DEFAULT_ELEMENT_LOCAL_NAME = "Attribute"
43
44    # Default element name.
45    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
46                                 DEFAULT_ELEMENT_LOCAL_NAME,
47                                 SAMLConstants.SAML20_PREFIX)
48
49    # Local name of the XSI type.
50    TYPE_LOCAL_NAME = "AttributeType"
51
52    # QName of the XSI type.
53    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
54                      TYPE_LOCAL_NAME,
55                      SAMLConstants.SAML20_PREFIX)
56
57    # Name of the Name attribute.
58    NAME_ATTRIB_NAME = "Name"
59
60    # Name for the NameFormat attribute.
61    NAME_FORMAT_ATTRIB_NAME = "NameFormat"
62
63    # Name of the FriendlyName attribute.
64    FRIENDLY_NAME_ATTRIB_NAME = "FriendlyName"
65
66    # Unspecified attribute format ID.
67    UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
68
69    # URI reference attribute format ID.
70    URI_REFERENCE = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
71
72    # Basic attribute format ID.
73    BASIC = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
74
75    def __init__(self):
76        """Initialise Attribute Class attributes"""
77        self.__name = None
78        self.__nameFormat = None
79        self.__friendlyName = None
80        self.__attributeValues = []
81
82    def _get_name(self):
83        return self.__name
84   
85    def _set_name(self, name):
86        if not isinstance(name, basestring):
87            raise TypeError("Expecting basestring type for name, got %r"% name)
88       
89        self.__name = name
90       
91    name = property(fget=_get_name,
92                    fset=_set_name,
93                    doc="name of this attribute")
94   
95    def _get_nameFormat(self):
96        return self.__nameFormat
97   
98    def _set_nameFormat(self, nameFormat):
99        if not isinstance(nameFormat, basestring):
100            raise TypeError("Expecting basestring type for nameFormat, got %r"
101                            % nameFormat)
102           
103        self.__nameFormat = nameFormat
104       
105    nameFormat = property(fget=_get_nameFormat,
106                          fset=_set_nameFormat,
107                          doc="Get the name format of this attribute.")
108   
109    def _get_friendlyName(self):
110        return self.__friendlyName
111   
112    def _set_friendlyName(self, friendlyName):
113        if not isinstance(friendlyName, basestring):
114            raise TypeError("Expecting basestring type for friendlyName, got "
115                            "%r" % friendlyName)
116           
117        self.__friendlyName = friendlyName
118       
119    friendlyName = property(fget=_get_friendlyName,
120                            fset=_set_friendlyName,
121                            doc="the friendly name of this attribute.")
122   
123    def _get_attributeValues(self):
124        return self.__attributeValues
125   
126    def _set_attributeValues(self, attributeValues):
127        if not isinstance(attributeValues, (list, tuple)):
128            raise TypeError("Expecting basestring type for attributeValues, "
129                            "got %r" % attributeValues)
130           
131        self.__attributeValues = attributeValues
132       
133    attributeValues = property(fget=_get_attributeValues,
134                               fset=_set_attributeValues,
135                               doc="the list of attribute values for this "
136                               "attribute.")
137
138
139class Statement(SAMLObject):
140    '''SAML 2.0 Core Statement.  Abstract base class which all statement
141    types must implement.'''
142   
143    # Element local name
144    DEFAULT_ELEMENT_LOCAL_NAME = "Statement"
145
146    # Default element name
147    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
148                                 DEFAULT_ELEMENT_LOCAL_NAME,
149                                 SAMLConstants.SAML20_PREFIX)
150
151    # Local name of the XSI type
152    TYPE_LOCAL_NAME = "StatementAbstractType"
153
154    # QName of the XSI type
155    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
156                      TYPE_LOCAL_NAME,
157                      SAMLConstants.SAML20_PREFIX)
158   
159           
160class AttributeStatement(Statement):
161    '''SAML 2.0 Core AttributeStatement'''
162
163    def __init__(self):
164        self.__attributes = TypedList(Attribute)
165        self.__encryptedAttributes = TypedList(Attribute)
166
167    # Element local name
168    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeStatement"
169   
170    # Default element name.
171    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
172                                 DEFAULT_ELEMENT_LOCAL_NAME, 
173                                 SAMLConstants.SAML20_PREFIX)
174   
175    # Local name of the XSI type.
176    TYPE_LOCAL_NAME = "AttributeStatementType" 
177       
178    # QName of the XSI type.
179    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
180                      TYPE_LOCAL_NAME, 
181                      SAMLConstants.SAML20_PREFIX)
182
183    def _get_attributes(self):
184        '''@return the attributes expressed in this statement
185        '''
186        return self.__attributes
187
188    attributes = property(fget=_get_attributes)
189   
190    def _get_encryptedAttributes(self):
191       '''@return the encrypted attribtues expressed in this statement
192       '''
193       return self.__encryptedAttributes
194   
195    encryptedAttributes = property(fget=_get_encryptedAttributes)
196
197
198class AuthnStatement(Statement):
199    '''SAML 2.0 Core AuthnStatement.  Currently implemented in abstract form
200    only
201    '''
202
203    # Element local name
204    DEFAULT_ELEMENT_LOCAL_NAME = "AuthnStatement"
205
206    # Default element name
207    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
208                                 DEFAULT_ELEMENT_LOCAL_NAME,
209                                 SAMLConstants.SAML20_PREFIX)
210
211    # Local name of the XSI type
212    TYPE_LOCAL_NAME = "AuthnStatementType"
213
214    # QName of the XSI type
215    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
216                      TYPE_LOCAL_NAME,
217                      SAMLConstants.SAML20_PREFIX)
218
219    # AuthnInstant attribute name
220    AUTHN_INSTANT_ATTRIB_NAME = "AuthnInstant"
221
222    # SessionIndex attribute name
223    SESSION_INDEX_ATTRIB_NAME = "SessionIndex"
224
225    # SessionNoOnOrAfter attribute name
226    SESSION_NOT_ON_OR_AFTER_ATTRIB_NAME = "SessionNotOnOrAfter"
227
228    def _getAuthnInstant(self):
229        '''Gets the time when the authentication took place.
230       
231        @return the time when the authentication took place
232        '''
233        raise NotImplementedError()
234
235    def _setAuthnInstant(self, value):
236        '''Sets the time when the authentication took place.
237       
238        @param newAuthnInstant the time when the authentication took place
239        '''
240        raise NotImplementedError()
241
242    def _getSessionIndex(self):
243        '''Get the session index between the principal and the authenticating
244        authority.
245       
246        @return the session index between the principal and the authenticating
247        authority
248        '''
249        raise NotImplementedError()
250
251    def _setSessionIndex(self, value):
252        '''Sets the session index between the principal and the authenticating
253        authority.
254       
255        @param newIndex the session index between the principal and the
256        authenticating authority
257        '''
258        raise NotImplementedError()
259
260    def _getSessionNotOnOrAfter(self):
261        '''Get the time when the session between the principal and the SAML
262        authority ends.
263       
264        @return the time when the session between the principal and the SAML
265        authority ends
266        '''
267        raise NotImplementedError()
268
269    def _setSessionNotOnOrAfter(self, value):
270        '''Set the time when the session between the principal and the SAML
271        authority ends.
272       
273        @param newSessionNotOnOrAfter the time when the session between the
274        principal and the SAML authority ends
275        '''
276        raise NotImplementedError()
277
278    def _getSubjectLocality(self):
279        '''Get the DNS domain and IP address of the system where the principal
280        was authenticated.
281       
282        @return the DNS domain and IP address of the system where the principal
283        was authenticated
284        '''
285        raise NotImplementedError()
286
287    def _setSubjectLocality(self, value):
288        '''Set the DNS domain and IP address of the system where the principal
289        was authenticated.
290       
291        @param newLocality the DNS domain and IP address of the system where
292        the principal was authenticated
293        '''
294        raise NotImplementedError()
295
296    def _getAuthnContext(self):
297        '''Gets the context used to authenticate the subject.
298       
299        @return the context used to authenticate the subject
300        '''
301        raise NotImplementedError()
302
303    def _setAuthnContext(self, value):
304        '''Sets the context used to authenticate the subject.
305       
306        @param newAuthnContext the context used to authenticate the subject
307        '''
308        raise NotImplementedError()
309           
310
311class AuthzDecisionStatement(Statement):
312    '''SAML 2.0 Core AuthzDecisionStatement.  Currently implemented in abstract
313    form only'''
314   
315    # Element local name
316    DEFAULT_ELEMENT_LOCAL_NAME = "AuthzDecisionStatement"
317
318    # Default element name
319    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
320                                 DEFAULT_ELEMENT_LOCAL_NAME,
321                                 SAMLConstants.SAML20_PREFIX)
322
323    # Local name of the XSI type
324    TYPE_LOCAL_NAME = "AuthzDecisionStatementType"
325
326    # QName of the XSI type
327    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
328                      TYPE_LOCAL_NAME,
329                      SAMLConstants.SAML20_PREFIX)
330
331    # Resource attribute name
332    RESOURCE_ATTRIB_NAME = "Resource"
333
334    # Decision attribute name
335    DECISION_ATTRIB_NAME = "Decision"
336
337    def _getResource(self):
338        '''
339        Get URI of the resource to which authorization is saught.
340       
341        @return URI of the resource to which authorization is saught
342        '''
343        raise NotImplementedError()
344
345    def _setResource(self, value):
346        '''
347        Sets URI of the resource to which authorization is saught.
348       
349        @param newResourceURI URI of the resource to which authorization is
350        saught
351        '''
352        raise NotImplementedError()
353
354    def _getDecision(self):
355        '''
356        Gets the decision of the authorization request.
357       
358        @return the decision of the authorization request
359        '''
360        raise NotImplementedError()
361
362    def _setDecision(self, value):
363        '''
364        Sets the decision of the authorization request.
365       
366        @param newDecision the decision of the authorization request
367        '''
368        raise NotImplementedError()
369
370    def _getActions(self):
371        '''
372        Gets the actions authorized to be performed.
373       
374        @return the actions authorized to be performed
375        '''
376        raise NotImplementedError()
377
378
379    def _getEvidence(self):
380        '''
381        Get the SAML assertion the authority relied on when making the
382        authorization decision.
383       
384        @return the SAML assertion the authority relied on when making the
385        authorization decision
386        '''
387        raise NotImplementedError()
388
389    def _setEvidence(self, value):
390        '''
391        Sets the SAML assertion the authority relied on when making the
392        authorization decision.
393       
394        @param newEvidence the SAML assertion the authority relied on when
395        making the authorization decision
396        '''
397        raise NotImplementedError()
398       
399
400class Subject(SAMLObject):
401    '''Concrete implementation of @link org.opensaml.saml2.core.Subject.'''
402   
403    # Element local name.
404    DEFAULT_ELEMENT_LOCAL_NAME = "Subject"
405
406    # Default element name.
407    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
408                                 DEFAULT_ELEMENT_LOCAL_NAME,
409                                 SAMLConstants.SAML20_PREFIX)
410
411    # Local name of the XSI type.
412    TYPE_LOCAL_NAME = "SubjectType"
413
414    # QName of the XSI type.
415    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
416                      TYPE_LOCAL_NAME,
417                      SAMLConstants.SAML20_PREFIX)
418
419    def __init__(self, 
420                 namespaceURI=SAMLConstants.SAML20_NS, 
421                 elementLocalName=DEFAULT_ELEMENT_LOCAL_NAME, 
422                 namespacePrefix=SAMLConstants.SAML20_PREFIX):
423        '''@param namespaceURI the namespace the element is in
424        @param elementLocalName the local name of the XML element this Object
425        represents
426        @param namespacePrefix the prefix for the given namespace
427        '''
428        self.__qname = QName(namespaceURI, 
429                             elementLocalName, 
430                             namespacePrefix)
431       
432        # BaseID child element.
433        self.__baseID = None
434   
435        # NameID child element.
436        self.__nameID = None
437   
438        # EncryptedID child element.
439        self.__encryptedID = None
440   
441        # Subject Confirmations of the Subject.
442        self.__subjectConfirmations = []
443   
444    def _get_qname(self):
445        return self.__qname
446   
447    qname = property(fget=_get_qname, doc="Qualified Name for Subject")
448   
449    def _getBaseID(self): 
450        return self.__baseID
451
452    def _setBaseID(self, value):
453        if not isinstance(value, basestring):
454            raise TypeError("Expecting %r type for \"baseID\" got %r" %
455                            (basestring, value.__class__))
456        self.__baseID = value
457
458    baseID = property(fget=_getBaseID, 
459                      fset=_setBaseID, 
460                      doc="Base identifier")
461     
462    def _getNameID(self):
463        return self.__nameID
464   
465    def _setNameID(self, value):
466        if not isinstance(value, NameID):
467            raise TypeError("Expecting %r type for \"nameID\" got %r" %
468                            (NameID, type(value)))
469        self.__nameID = value
470
471    nameID = property(fget=_getNameID, 
472                      fset=_setNameID, 
473                      doc="Name identifier")
474   
475    def _getEncryptedID(self):
476        return self.__encryptedID
477   
478    def _setEncryptedID(self, value): 
479        self.__encryptedID = value
480
481    encryptedID = property(fget=_getEncryptedID, 
482                           fset=_setEncryptedID, 
483                           doc="EncryptedID's Docstring")   
484    def _getSubjectConfirmations(self): 
485        return self.__subjectConfirmations
486
487    subjectConfirmations = property(fget=_getSubjectConfirmations, 
488                                    doc="Subject Confirmations")   
489    def getOrderedChildren(self): 
490        children = []
491
492        if self.baseID is not None:
493            children.append(self.baseID)
494       
495        if self.nameID is not None: 
496            children.append(self.nameID)
497       
498        if self.encryptedID is not None: 
499            children.append(self.encryptedID)
500       
501        children += self.subjectConfirmations
502
503        return tuple(children)
504
505
506class AbstractNameIDType(SAMLObject):
507    '''Abstract implementation of NameIDType'''
508
509    # SPNameQualifier attribute name.
510    SP_NAME_QUALIFIER_ATTRIB_NAME = "SPNameQualifier"
511
512    # Format attribute name.
513    FORMAT_ATTRIB_NAME = "Format"
514
515    # SPProviderID attribute name.
516    SPPROVIDED_ID_ATTRIB_NAME = "SPProvidedID"
517
518    # URI for unspecified name format.
519    UNSPECIFIED = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
520
521    # URI for email name format.
522    EMAIL = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
523
524    # URI for X509 subject name format.
525    X509_SUBJECT = "urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName"
526
527    # URI for windows domain qualified name name format.
528    WIN_DOMAIN_QUALIFIED = \
529        "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName"
530
531    # URI for kerberos name format.
532    KERBEROS = "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos"
533
534    # URI for SAML entity name format.
535    ENTITY = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
536
537    # URI for persistent name format.
538    PERSISTENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
539
540    # URI for transient name format.
541    TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
542
543    # Special URI used by NameIDPolicy to indicate a NameID should be encrypted
544    ENCRYPTED = "urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted"
545   
546    def __init__(self, namespaceURI, elementLocalName, namespacePrefix): 
547        '''@param namespaceURI the namespace the element is in
548        @param elementLocalName the local name of the XML element this Object
549        represents
550        @param namespacePrefix the prefix for the given namespace
551        '''
552        self.__qname = QName(namespaceURI, elementLocalName, namespacePrefix)
553   
554        # Name of the Name ID.
555        self.__name = None
556       
557        # Name Qualifier of the Name ID.
558        self.__nameQualifier = None
559   
560        # SP Name Qualifier of the Name ID.
561        self.__spNameQualifier = None
562   
563        # Format of the Name ID.
564        self.__format = None
565   
566        # SP ProvidedID of the NameID.
567        self.__spProvidedID = None
568
569        self.__value = None
570       
571    def _getQName(self):
572        return self.__qname
573       
574    def _setQName(self, value):
575        if not isinstance(value, QName):
576            raise TypeError("\"qname\" must be a %r derived type, "
577                            "got %r" % (QName, type(value)))
578           
579        self.__qname = value
580
581    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
582             
583    def _getValue(self):
584        return self.__value
585       
586    def _setValue(self, value):
587        if not isinstance(value, basestring):
588            raise TypeError("\"value\" must be a basestring derived type, "
589                            "got %r" % value.__class__)
590           
591        self.__value = value
592
593    value = property(fget=_getValue, fset=_setValue, doc="string value") 
594   
595    def _getNameQualifier(self): 
596        return self.__nameQualifier
597   
598    def _setNameQualifier(self, value): 
599        self.__nameQualifier = value
600
601    nameQualifier = property(fget=_getNameQualifier, 
602                             fset=_setNameQualifier, 
603                             doc="Name qualifier")   
604
605    def _getSPNameQualifier(self): 
606        return self.__spNameQualifier
607   
608    def _setSPNameQualifier(self, value): 
609        self.__spNameQualifier = value
610
611    spNameQualifier = property(fget=_getSPNameQualifier, 
612                               fset=_setSPNameQualifier, 
613                               doc="SP Name qualifier")   
614   
615    def _getFormat(self):
616        return self.__format
617       
618    def _setFormat(self, format):
619        if not isinstance(format, basestring):
620            raise TypeError("\"format\" must be a basestring derived type, "
621                            "got %r" % format.__class__)
622           
623        self.__format = format
624
625    format = property(fget=_getFormat, fset=_setFormat, doc="Name format") 
626   
627    def _getSPProvidedID(self): 
628        return self.__spProvidedID
629   
630    def _setSPProvidedID(self, value): 
631        self.__spProvidedID = value
632
633    spProvidedID = property(fget=_getSPProvidedID, fset=_setSPProvidedID, 
634                            doc="SP Provided Identifier") 
635   
636    def getOrderedChildren(self): 
637        raise NotImplementedError()
638
639   
640class Issuer(AbstractNameIDType):
641    """SAML 2.0 Core Issuer type"""
642   
643    # Element local name.
644    DEFAULT_ELEMENT_LOCAL_NAME = "Issuer"
645
646    # Default element name.
647    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
648                                 DEFAULT_ELEMENT_LOCAL_NAME,
649                                 SAMLConstants.SAML20_PREFIX)
650
651    # Local name of the XSI type.
652    TYPE_LOCAL_NAME = "IssuerType"
653
654    # QName of the XSI type.
655    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
656                      TYPE_LOCAL_NAME,
657                      SAMLConstants.SAML20_PREFIX) 
658   
659    def __init__(self, 
660                 namespaceURI=SAMLConstants.SAML20_NS, 
661                 localPart=DEFAULT_ELEMENT_LOCAL_NAME, 
662                 namespacePrefix=SAMLConstants.SAML20_PREFIX):
663        super(Issuer, self).__init__(namespaceURI,
664                                     localPart,
665                                     namespacePrefix)
666
667     
668class NameID(AbstractNameIDType):
669    '''SAML 2.0 Core NameID'''
670    # Element local name.
671    DEFAULT_ELEMENT_LOCAL_NAME = "NameID"
672
673    # Default element name.
674    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
675                                 DEFAULT_ELEMENT_LOCAL_NAME,
676                                 SAMLConstants.SAML20_PREFIX)
677
678    # Local name of the XSI type.
679    TYPE_LOCAL_NAME = "NameIDType"
680
681    # QName of the XSI type.
682    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
683                      TYPE_LOCAL_NAME,
684                      SAMLConstants.SAML20_PREFIX)
685   
686    def __init__(self, 
687                 namespaceURI=SAMLConstants.SAML20_NS, 
688                 localPart=DEFAULT_ELEMENT_LOCAL_NAME, 
689                 namespacePrefix=SAMLConstants.SAML20_PREFIX):
690        super(NameID, self).__init__(namespaceURI,
691                                     localPart,
692                                     namespacePrefix)
693
694
695class Conditions(SAMLObject): 
696    '''SAML 2.0 Core Conditions.'''
697   
698    # Element local name.
699    DEFAULT_ELEMENT_LOCAL_NAME = "Conditions"
700
701    # Default element name.
702    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
703                                 DEFAULT_ELEMENT_LOCAL_NAME,
704                                 SAMLConstants.SAML20_PREFIX)
705
706    # Local name of the XSI type.
707    TYPE_LOCAL_NAME = "ConditionsType"
708
709    # QName of the XSI type.
710    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
711                      TYPE_LOCAL_NAME,
712                      SAMLConstants.SAML20_PREFIX)
713
714    # NotBefore attribute name.
715    NOT_BEFORE_ATTRIB_NAME = "NotBefore"
716
717    # NotOnOrAfter attribute name.
718    NOT_ON_OR_AFTER_ATTRIB_NAME = "NotOnOrAfter"
719
720    def __init__(self):
721       
722        # A Condition.
723        self.__conditions = []
724   
725        # Not Before conditions.
726        self.__notBefore = None
727   
728        # Not On Or After conditions.
729        self.__notOnOrAfter = None
730
731    def _getNotBefore(self):
732        '''Get the date/time before which the assertion is invalid.
733       
734        @return the date/time before which the assertion is invalid'''
735        return self.__notBefore
736   
737    def _setNotBefore(self, value):
738        '''Sets the date/time before which the assertion is invalid.
739       
740        @param newNotBefore the date/time before which the assertion is invalid
741        '''
742        if not isinstance(value, datetime):
743            raise TypeError('Expecting "datetime" type for "notBefore", '
744                            'got %r' % type(value))
745        self.__notBefore = value
746
747    def _getNotOnOrAfter(self):
748        '''Gets the date/time on, or after, which the assertion is invalid.
749       
750        @return the date/time on, or after, which the assertion is invalid'
751        '''
752        return self.__notBefore
753   
754    def _setNotOnOrAfter(self, value):
755        '''Sets the date/time on, or after, which the assertion is invalid.
756       
757        @param newNotOnOrAfter the date/time on, or after, which the assertion
758        is invalid
759        '''
760        if not isinstance(value, datetime):
761            raise TypeError('Expecting "datetime" type for "notOnOrAfter", '
762                            'got %r' % type(value))
763        self.__notOnOrAfter = value 
764
765    def _getConditions(self):
766        '''Gets all the conditions on the assertion.
767       
768        @return all the conditions on the assertion
769        '''
770        return self.__conditions
771   
772    conditions = property(fget=_getConditions,
773                          doc="List of conditions")
774   
775    def _getAudienceRestrictions(self):
776        '''Gets the audience restriction conditions for the assertion.
777       
778        @return the audience restriction conditions for the assertion
779        '''
780        raise NotImplementedError()
781
782    def _getOneTimeUse(self):
783        '''Gets the OneTimeUse condition for the assertion.
784       
785        @return the OneTimeUse condition for the assertion
786        '''
787        raise NotImplementedError()
788
789    def _getProxyRestriction(self):   
790        '''Gets the ProxyRestriction condition for the assertion.
791       
792        @return the ProxyRestriction condition for the assertion
793        '''
794        raise NotImplementedError()
795   
796   
797class Advice(SAMLObject):
798    '''SAML 2.0 Core Advice.
799    '''
800
801    # Element local name
802    DEFAULT_ELEMENT_LOCAL_NAME = "Advice"
803
804    # Default element name.
805    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
806                                 DEFAULT_ELEMENT_LOCAL_NAME,
807                                 SAMLConstants.SAML20_PREFIX)
808
809    # Local name of the XSI type
810    TYPE_LOCAL_NAME = "AdviceType"
811
812    # QName of the XSI type
813    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
814                      TYPE_LOCAL_NAME,
815                      SAMLConstants.SAML20_PREFIX)
816
817    def _getChildren(self, typeOrName=None):
818        '''
819        Gets the list of all child elements attached to this advice.
820       
821        @return the list of all child elements attached to this advice
822        '''
823        raise NotImplementedError()
824
825    def _getAssertionIDReferences(self):
826        '''Gets the list of AssertionID references used as advice.
827       
828        @return the list of AssertionID references used as advice
829        '''
830        raise NotImplementedError()
831
832    def _getAssertionURIReferences(self):
833        '''Gets the list of AssertionURI references used as advice.
834       
835        @return the list of AssertionURI references used as advice
836        '''
837        raise NotImplementedError()
838   
839    def _getAssertions(self):
840        '''Gets the list of Assertions used as advice.
841       
842        @return the list of Assertions used as advice
843        '''
844        raise NotImplementedError()
845   
846    def _getEncryptedAssertions(self):
847        '''Gets the list of EncryptedAssertions used as advice.
848       
849        @return the list of EncryptedAssertions used as advice
850        '''
851        raise NotImplementedError()
852       
853
854class Assertion(SAMLObject):
855    """SAML 2.0 Attribute Assertion for use with NERC DataGrid   
856    """   
857    ns = "urn:oasis:names:tc:SAML:1.0:assertion"
858    nsPfx = "saml"
859    issuer = 'http:#badc.nerc.ac.uk'
860    attributeName = "urn:mace:dir:attribute-def:eduPersonAffiliation"
861    attributeNS = "urn:mace:shibboleth:1.0:attributeNamespace:uri"
862
863    # Element local name.
864    DEFAULT_ELEMENT_LOCAL_NAME = "Assertion"
865
866    # Default element name.
867    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
868                                 DEFAULT_ELEMENT_LOCAL_NAME,
869                                 SAMLConstants.SAML20_PREFIX)
870
871    # Local name of the XSI type.
872    TYPE_LOCAL_NAME = "AssertionType"
873
874    # QName of the XSI type.
875    TYPE_NAME = QName(SAMLConstants.SAML20_NS, TYPE_LOCAL_NAME,
876                      SAMLConstants.SAML20_PREFIX)
877
878    # Version attribute name.
879    VERSION_ATTRIB_NAME = "Version"
880
881    # IssueInstant attribute name.
882    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
883
884    # ID attribute name.
885    ID_ATTRIB_NAME = "ID"
886
887    def __init__(self):
888        # Base class initialisation
889        super(Assertion, self).__init__()
890       
891        self.__version = None
892        self.__issueInstant = None
893        self.__id = None
894        self.__issuer = None
895        self.__subject = None
896       
897        self.__conditions = None
898        self.__advice = None
899        self.__statements = TypedList(Statement)
900       
901        # TODO: Implement AuthnStatement and AuthzDecisionStatement classes
902        self.__authnStatements = []
903        self.__authzDecisionStatements = []
904        self.__attributeStatements = TypedList(AttributeStatement)
905       
906    def _get_version(self):
907        '''@return the SAML Version of this assertion.
908        '''
909        return self.__version
910   
911    def _set_version(self, version):
912        '''@param version the SAML Version of this assertion
913        '''
914        if not isinstance(version, SAMLVersion):
915            raise TypeError("Expecting SAMLVersion type got: %r" % 
916                            version.__class__)
917       
918        self.__version = version
919       
920    version = property(fget=_get_version,
921                       fset=_set_version,
922                       doc="SAML Version of the assertion")
923
924    def _get_issueInstant(self):
925        '''Gets the issue instance of this assertion.
926       
927        @return the issue instance of this assertion'''
928        return self.__issueInstant
929   
930    def _set_issueInstant(self, issueInstant):
931        '''Sets the issue instance of this assertion.
932       
933        @param newIssueInstance the issue instance of this assertion
934        '''
935        if not isinstance(issueInstant, datetime):
936            raise TypeError('Expecting "datetime" type for "issueInstant", '
937                            'got %r' % issueInstant.__class__)
938           
939        self.__issueInstant = issueInstant
940       
941    issueInstant = property(fget=_get_issueInstant, 
942                            fset=_set_issueInstant,
943                            doc="Issue instant of the assertion")
944
945    def _get_id(self):
946        '''Sets the ID of this assertion.
947       
948        @return the ID of this assertion
949        '''
950        return self.__id
951   
952    def _set_id(self, _id):
953        '''Sets the ID of this assertion.
954       
955        @param newID the ID of this assertion
956        '''
957        if not isinstance(_id, basestring):
958            raise TypeError('Expecting basestring derived type for "id", got '
959                            '%r' % _id.__class__)
960        self.__id = _id
961       
962    id = property(fget=_get_id, fset=_set_id, doc="ID of assertion")
963   
964    def _set_issuer(self, issuer):
965        """Set issuer"""
966        if not isinstance(issuer, Issuer):
967            raise TypeError("issuer must be %r, got %r" % (Issuer, 
968                                                           type(issuer)))
969        self.__issuer = issuer
970   
971    def _get_issuer(self):
972        """Get the issuer name """
973        return self.__issuer
974
975    issuer = property(fget=_get_issuer, 
976                      fset=_set_issuer,
977                      doc="Issuer of assertion")
978   
979    def _set_subject(self, subject):
980        """Set subject string."""
981        if not isinstance(subject, Subject):
982            raise TypeError("subject must be %r, got %r" % (Subject, 
983                                                            type(subject)))
984
985        self.__subject = subject
986   
987    def _get_subject(self):
988        """Get subject string."""
989        return self.__subject
990
991    subject = property(fget=_get_subject,
992                       fset=_set_subject, 
993                       doc="Attribute Assertion subject")
994   
995    def _get_conditions(self):
996        """Get conditions string."""
997        return self.__conditions
998   
999    def _set_conditions(self, value):
1000        """Get conditions string."""
1001        if not isinstance(value, Conditions):
1002            raise TypeError("Conditions must be %r, got %r" % (Conditions, 
1003                                                               type(value)))
1004
1005        self.__conditions = value
1006
1007    conditions = property(fget=_get_conditions,
1008                          fset=_set_conditions,
1009                          doc="Attribute Assertion conditions")
1010   
1011    def _set_advice(self, advice):
1012        """Set advice string."""
1013        if not isinstance(advice, basestring):
1014            raise TypeError("advice must be a string")
1015
1016        self.__advice = advice
1017   
1018    def _get_advice(self):
1019        """Get advice string."""
1020        return self.__advice
1021
1022    advice = property(fget=_get_advice,
1023                      fset=_set_advice, 
1024                      doc="Attribute Assertion advice")
1025   
1026    def _get_statements(self):
1027        """Get statements string."""
1028        return self.__statements
1029
1030    statements = property(fget=_get_statements,
1031                          doc="Attribute Assertion statements")
1032   
1033    def _get_authnStatements(self):
1034        """Get authnStatements string."""
1035        return self.__authnStatements
1036
1037    authnStatements = property(fget=_get_authnStatements,
1038                               doc="Attribute Assertion authentication "
1039                                   "statements")
1040   
1041    def _get_authzDecisionStatements(self):
1042        """Get authorisation decision statements."""
1043        return self.__authzDecisionStatements
1044
1045    authzDecisionStatements = property(fget=_get_authzDecisionStatements,
1046                                       doc="Attribute Assertion authorisation "
1047                                           "decision statements")
1048   
1049    def _get_attributeStatements(self):
1050        """Get attributeStatements string."""
1051        return self.__attributeStatements
1052
1053    attributeStatements = property(fget=_get_attributeStatements,
1054                                   doc="Attribute Assertion attribute "
1055                                       "statements")
1056   
1057
1058class AttributeValue(SAMLObject):
1059    """Base class for Attribute Value type"""
1060   
1061    # Element name, no namespace
1062    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeValue"
1063
1064    # Default element name
1065    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1066                                 DEFAULT_ELEMENT_LOCAL_NAME,
1067                                 SAMLConstants.SAML20_PREFIX)
1068
1069
1070class XSStringAttributeValue(AttributeValue):
1071    """XML XS:String Attribute Value type"""
1072   
1073    # Local name of the XSI type
1074    TYPE_LOCAL_NAME = "string"
1075       
1076    # QName of the XSI type
1077    TYPE_NAME = QName(SAMLConstants.XSD_NS, 
1078                      TYPE_LOCAL_NAME, 
1079                      SAMLConstants.XSD_PREFIX)
1080 
1081    def __init__(self):
1082        self.__value = None
1083       
1084    def _getValue(self):
1085        return self.__value
1086       
1087    def _setValue(self, value):
1088        if not isinstance(value, basestring):
1089            raise TypeError("Input must be a basestring derived type, got %r" %
1090                            value.__class__)
1091           
1092        self.__value = value
1093
1094    value = property(fget=_getValue, fset=_setValue, doc="string value") 
1095   
1096
1097# TODO: Move this class out of the SAML package back into ndg.security.common
1098class XSGroupRoleAttributeValue(AttributeValue): 
1099    '''ESG Specific Group/Role attribute value.  ESG attribute permissions are
1100    organised into group/role pairs
1101    '''
1102    DEFAULT_NS = "http://www.earthsystemgrid.org"
1103    DEFAULT_PREFIX = "esg"
1104    TYPE_LOCAL_NAME = "groupRole"
1105   
1106    GROUP_ATTRIB_NAME = "group"
1107    ROLE_ATTRIB_NAME = "role"
1108   
1109    # QName of the XSI type
1110    TYPE_NAME = QName(DEFAULT_NS, 
1111                      TYPE_LOCAL_NAME, 
1112                      DEFAULT_PREFIX)
1113     
1114    def __init__(self, 
1115                 namespaceURI=DEFAULT_NS, 
1116                 elementLocalName=TYPE_LOCAL_NAME, 
1117                 namespacePrefix=DEFAULT_PREFIX):
1118        '''@param namespaceURI: the namespace the element is in
1119        @param elementLocalName: the local name of the XML element this Object
1120        represents
1121        @param namespacePrefix: the prefix for the given namespace'''
1122        self.__namespaceURI = namespaceURI
1123        self.__elementLocalName = elementLocalName
1124        self.__namespacePrefix = namespacePrefix
1125        self.__group = None
1126        self.__role = None       
1127
1128    def _getNamespaceURI(self):
1129        return self.__namespaceURI
1130
1131    def _setNamespaceURI(self, value):
1132        if not isinstance(value, basestring):
1133            raise TypeError("Expecting %r type for namespaceURI got %r" %
1134                            (basestring, value.__class__))
1135        self.__namespaceURI = value
1136
1137    def _getElementLocalName(self):
1138        return self.__elementLocalName
1139
1140    def _setElementLocalName(self, value):
1141        if not isinstance(value, basestring):
1142            raise TypeError("Expecting %r type for elementLocalName got %r" %
1143                            (basestring, value.__class__))
1144        self.__elementLocalName = value
1145
1146    def _getNamespacePrefix(self):
1147        return self.__namespacePrefix
1148
1149    def _setNamespacePrefix(self, value):
1150        if not isinstance(value, basestring):
1151            raise TypeError("Expecting %r type for namespacePrefix got %r" %
1152                            (basestring, value.__class__))
1153        self.__namespacePrefix = value
1154
1155    namespaceURI = property(fget=_getNamespaceURI, 
1156                            fset=_setNamespaceURI, 
1157                            doc="the namespace the element is in")
1158
1159    elementLocalName = property(fget=_getElementLocalName, 
1160                                fset=_setElementLocalName, 
1161                                doc="the local name of the XML element this "
1162                                    "Object represents")
1163
1164    namespacePrefix = property(fget=_getNamespacePrefix, 
1165                               fset=_setNamespacePrefix, 
1166                               doc="the prefix for the given namespace")
1167
1168    def _getGroup(self):
1169        return self.__group
1170     
1171    def _setGroup(self, group): 
1172        self.__group = group
1173     
1174    group = property(fget=_getGroup, fset=_setGroup)
1175     
1176    def _getRole(self):
1177        return self.__role
1178     
1179    def _setRole(self, role):
1180        self.__role = role
1181     
1182    role = property(fget=_getRole, fset=_setRole)
1183
1184    def getOrderedChildren(self):
1185        # no children
1186        return None
1187
1188
1189class StatusDetail(SAMLObject):
1190    '''Implementation of SAML 2.0 StatusDetail'''
1191   
1192    # Local Name of StatusDetail.
1193    DEFAULT_ELEMENT_LOCAL_NAME = "StatusDetail"
1194
1195    # Default element name.
1196    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1197                                 DEFAULT_ELEMENT_LOCAL_NAME,
1198                                 SAMLConstants.SAML20P_PREFIX)
1199
1200    # Local name of the XSI type.
1201    TYPE_LOCAL_NAME = "StatusDetailType"
1202
1203    # QName of the XSI type.
1204    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1205                      TYPE_LOCAL_NAME,
1206                      SAMLConstants.SAML20P_PREFIX)
1207   
1208    def __init__(self):
1209        # child "any" elements.
1210        self.__unknownChildren = TypedList(SAMLObject)         
1211        self.__qname = QName(StatusDetail.DEFAULT_ELEMENT_NAME.namespaceURI,
1212                             StatusDetail.DEFAULT_ELEMENT_NAME,
1213                             StatusDetail.DEFAULT_ELEMENT_NAME.prefix)
1214   
1215    def getUnknownXMLTypes(self, qname=None): 
1216        if qname is not None:
1217            if not isinstance(qname, QName):
1218                raise TypeError("\"qname\" must be a %r derived type, "
1219                                "got %r" % (QName, type(qname)))
1220               
1221            children = []
1222            for child in self.__unknownChildren:
1223                childQName = getattr(child, "qname", None)
1224                if childQName is not None:
1225                    if childQName.namespaceURI == qname.namespaceURI or \
1226                       childQName.localPart == qname.localPart:
1227                        children.append(child)
1228                       
1229            return children
1230        else:
1231            return self.__unknownChildren
1232   
1233    unknownChildren = property(fget=getUnknownXMLTypes,
1234                               doc="Child objects of Status Detail - may be "
1235                                   "any type")
1236               
1237    def _getQName(self):
1238        return self.__qname
1239       
1240    def _setQName(self, value):
1241        if not isinstance(value, QName):
1242            raise TypeError("\"qname\" must be a %r derived type, "
1243                            "got %r" % (QName, type(value)))
1244           
1245        self.__qname = value
1246
1247    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1248   
1249
1250class StatusMessage(SAMLObject):
1251    '''Implementation of SAML 2.0 Status Message'''
1252
1253    def __init__(self):
1254        # Value attribute URI.
1255        self.__value = None       
1256        self.__qname = None
1257             
1258    def _getValue(self):
1259        return self.__value
1260       
1261    def _setValue(self, value):
1262        if not isinstance(value, basestring):
1263            raise TypeError("\"value\" must be a basestring derived type, "
1264                            "got %r" % value.__class__)
1265           
1266        self.__value = value
1267
1268    value = property(fget=_getValue, fset=_setValue, 
1269                     doc="Status message value")
1270               
1271    def _getQName(self):
1272        return self.__qname
1273       
1274    def _setQName(self, value):
1275        if not isinstance(value, QName):
1276            raise TypeError("\"qname\" must be a %r derived type, "
1277                            "got %r" % (QName, type(value)))
1278           
1279        self.__qname = value
1280
1281    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1282
1283
1284class StatusCode(SAMLObject):
1285    '''Implementation of SAML 2.0 StatusCode.'''
1286   
1287    # Local Name of StatusCode.
1288    DEFAULT_ELEMENT_LOCAL_NAME = "StatusCode"
1289
1290    # Default element name.
1291    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1292                                 DEFAULT_ELEMENT_LOCAL_NAME,
1293                                 SAMLConstants.SAML20P_PREFIX)
1294
1295    # Local name of the XSI type.
1296    TYPE_LOCAL_NAME = "StatusCodeType"
1297
1298    # QName of the XSI type.
1299    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1300                      TYPE_LOCAL_NAME,
1301                      SAMLConstants.SAML20P_PREFIX)
1302
1303    # Local Name of the Value attribute.
1304    VALUE_ATTRIB_NAME = "Value"
1305
1306    # URI for Success status code.
1307    SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success"
1308
1309    # URI for Requester status code.
1310    REQUESTER_URI = "urn:oasis:names:tc:SAML:2.0:status:Requester"
1311
1312    # URI for Responder status code.
1313    RESPONDER_URI = "urn:oasis:names:tc:SAML:2.0:status:Responder"
1314
1315    # URI for VersionMismatch status code.
1316    VERSION_MISMATCH_URI = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
1317
1318    # URI for AuthnFailed status code.
1319    AUTHN_FAILED_URI = "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
1320
1321    # URI for InvalidAttrNameOrValue status code.
1322    INVALID_ATTR_NAME_VALUE_URI = \
1323                "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue"
1324
1325    # URI for InvalidNameIDPolicy status code.
1326    INVALID_NAMEID_POLICY_URI = \
1327                "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"
1328
1329    # URI for NoAuthnContext status code.
1330    NO_AUTHN_CONTEXT_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"
1331
1332    # URI for NoAvailableIDP status code.
1333    NO_AVAILABLE_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"
1334
1335    # URI for NoPassive status code.
1336    NO_PASSIVE_URI = "urn:oasis:names:tc:SAML:2.0:status:NoPassive"
1337
1338    # URI for NoSupportedIDP status code.
1339    NO_SUPPORTED_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"
1340
1341    # URI for PartialLogout status code.
1342    PARTIAL_LOGOUT_URI = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
1343
1344    # URI for ProxyCountExceeded status code.
1345    PROXY_COUNT_EXCEEDED_URI = \
1346                "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"
1347
1348    # URI for RequestDenied status code.
1349    REQUEST_DENIED_URI = "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"
1350
1351    # URI for RequestUnsupported status code.
1352    REQUEST_UNSUPPORTED_URI = \
1353                "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
1354
1355    # URI for RequestVersionDeprecated status code.
1356    REQUEST_VERSION_DEPRECATED_URI = \
1357                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
1358
1359    # URI for RequestVersionTooHigh status code.
1360    REQUEST_VERSION_TOO_HIGH_URI = \
1361                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
1362   
1363    # URI for RequestVersionTooLow status code.
1364    REQUEST_VERSION_TOO_LOW_URI = \
1365                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"
1366
1367    # URI for ResourceNotRecognized status code.
1368    RESOURCE_NOT_RECOGNIZED_URI = \
1369                "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"
1370
1371    # URI for TooManyResponses status code.
1372    TOO_MANY_RESPONSES = "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"
1373
1374    # URI for UnknownAttrProfile status code.
1375    UNKNOWN_ATTR_PROFILE_URI = \
1376                "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile"
1377
1378    # URI for UnknownPrincipal status code.
1379    UNKNOWN_PRINCIPAL_URI = \
1380                "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"
1381
1382    # URI for UnsupportedBinding status code.
1383    UNSUPPORTED_BINDING_URI = \
1384                "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"
1385
1386    def __init__(self):
1387        # Value attribute URI.
1388        self.__value = None
1389   
1390        # Nested secondary StatusCode child element.
1391        self.__childStatusCode = None
1392       
1393        self.__qname = QName(StatusCode.DEFAULT_ELEMENT_NAME.namespaceURI,
1394                             StatusCode.DEFAULT_ELEMENT_NAME.localPart,
1395                             StatusCode.DEFAULT_ELEMENT_NAME.prefix)
1396
1397    def _getStatusCode(self): 
1398        return self.__childStatusCode
1399   
1400    def _setStatusCode(self, value):
1401        if not isinstance(value, StatusCode):
1402            raise TypeError('Child "statusCode" must be a %r derived type, '
1403                            "got %r" % (StatusCode, type(value)))
1404           
1405        self.__childStatusCode = value
1406
1407    value = property(fget=_getStatusCode, 
1408                     fset=_setStatusCode, 
1409                     doc="Child Status code")
1410             
1411    def _getValue(self):
1412        return self.__value
1413       
1414    def _setValue(self, value):
1415        if not isinstance(value, basestring):
1416            raise TypeError("\"value\" must be a basestring derived type, "
1417                            "got %r" % value.__class__)
1418           
1419        self.__value = value
1420
1421    value = property(fget=_getValue, fset=_setValue, doc="Status code value")
1422               
1423    def _getQName(self):
1424        return self.__qname
1425       
1426    def _setQName(self, value):
1427        if not isinstance(value, QName):
1428            raise TypeError("\"qname\" must be a %r derived type, "
1429                            "got %r" % (QName, type(value)))
1430           
1431        self.__qname = value
1432
1433    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1434       
1435
1436class Status(SAMLObject): 
1437    '''SAML 2.0 Core Status'''
1438   
1439    # Local Name of Status.
1440    DEFAULT_ELEMENT_LOCAL_NAME = "Status"
1441
1442    # Default element name.
1443    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1444                                 DEFAULT_ELEMENT_LOCAL_NAME,
1445                                 SAMLConstants.SAML20P_PREFIX)
1446
1447    # Local name of the XSI type.
1448    TYPE_LOCAL_NAME = "StatusType"
1449
1450    # QName of the XSI type.
1451    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1452                      TYPE_LOCAL_NAME,
1453                      SAMLConstants.SAML20P_PREFIX)
1454
1455    def __init__(self):
1456        # StatusCode element.
1457        self.__statusCode = None
1458   
1459        # StatusMessage element.
1460        self.__statusMessage = None
1461   
1462        # StatusDetail element.
1463        self.__statusDetail = None
1464       
1465        self.__qname = QName(Status.DEFAULT_ELEMENT_NAME.namespaceURI,
1466                             Status.DEFAULT_ELEMENT_NAME.localPart,
1467                             Status.DEFAULT_ELEMENT_NAME.prefix)
1468               
1469    def _getQName(self):
1470        return self.__qname
1471       
1472    def _setQName(self, value):
1473        if not isinstance(value, QName):
1474            raise TypeError("\"qname\" must be a %r derived type, "
1475                            "got %r" % (QName, type(value)))
1476           
1477        self.__qname = value
1478
1479    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1480       
1481    def _getStatusCode(self):
1482        '''
1483        Gets the Code of this Status.
1484       
1485        @return Status StatusCode
1486        '''
1487        return self.__statusCode
1488
1489    def _setStatusCode(self, value):
1490        '''
1491        Sets the Code of this Status.
1492       
1493        @param newStatusCode the Code of this Status
1494        '''
1495        if not isinstance(value, StatusCode):
1496            raise TypeError('"statusCode" must be a %r derived type, '
1497                            "got %r" % (StatusCode, type(value)))
1498           
1499        self.__statusCode = value
1500       
1501    statusCode = property(fget=_getStatusCode,
1502                          fset=_setStatusCode,
1503                          doc="status code object")
1504   
1505    def _getStatusMessage(self):
1506        '''
1507        Gets the Message of this Status.
1508       
1509        @return Status StatusMessage
1510        '''
1511        return self.__statusMessage
1512
1513    def _setStatusMessage(self, value):
1514        '''
1515        Sets the Message of this Status.
1516       
1517        @param newStatusMessage the Message of this Status
1518        '''
1519        if not isinstance(value, basestring):
1520            raise TypeError('"statusMessage" must be a %r derived type, '
1521                            "got %r" % (basestring, type(value)))
1522           
1523        self.__statusMessage = value
1524       
1525    statusMessage = property(fget=_getStatusMessage,
1526                             fset=_setStatusMessage,
1527                             doc="status message")
1528
1529    def _getStatusDetail(self):
1530        '''
1531        Gets the Detail of this Status.
1532       
1533        @return Status StatusDetail
1534        '''
1535        return self.__statusDetail
1536   
1537    def _setStatusDetail(self, value):
1538        '''
1539        Sets the Detail of this Status.
1540       
1541        @param newStatusDetail the Detail of this Status
1542        '''
1543        self.__statusDetail = value
1544       
1545    statusDetail = property(fget=_getStatusDetail,
1546                            fset=_setStatusDetail,
1547                            doc="status message")
1548
1549
1550class RequestAbstractType(SAMLObject): 
1551    '''SAML 2.0 Core RequestAbstractType'''
1552   
1553    # Local name of the XSI type.
1554    TYPE_LOCAL_NAME = "RequestAbstractType"
1555
1556    # QName of the XSI type.
1557    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1558                      TYPE_LOCAL_NAME,
1559                      SAMLConstants.SAML20P_PREFIX)
1560
1561    # ID attribute name.
1562    ID_ATTRIB_NAME = "ID"
1563
1564    # Version attribute name.
1565    VERSION_ATTRIB_NAME = "Version"
1566
1567    # IssueInstant attribute name.
1568    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
1569
1570    # Destination attribute name.
1571    DESTINATION_ATTRIB_NAME = "Destination"
1572
1573    # Consent attribute name.
1574    CONSENT_ATTRIB_NAME = "Consent"
1575
1576    # Unspecified consent URI.
1577    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
1578
1579    # Obtained consent URI.
1580    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
1581
1582    # Prior consent URI.
1583    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
1584
1585    # Implicit consent URI.
1586    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
1587
1588    # Explicit consent URI.
1589    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
1590
1591    # Unavailable consent URI.
1592    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
1593
1594    # Inapplicable consent URI.
1595    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable" 
1596
1597    def __init__(self):
1598        # SAML Version of the request.
1599        self.__version = None
1600   
1601        # Unique identifier of the request.
1602        self.__id = None
1603   
1604        # Date/time request was issued.
1605        self.__issueInstant = None
1606   
1607        # URI of the request destination.
1608        self.__destination = None
1609   
1610        # URI of the SAML user consent type.
1611        self.__consent = None
1612   
1613        # URI of the SAML user consent type.
1614        self.__issuer = None
1615   
1616        # Extensions child element.
1617        self.__extensions = None
1618       
1619    def _get_version(self):
1620        '''@return the SAML Version of this assertion.
1621        '''
1622        return self.__version
1623   
1624    def _set_version(self, version):
1625        '''@param version the SAML Version of this assertion
1626        '''
1627        if not isinstance(version, SAMLVersion):
1628            raise TypeError("Expecting SAMLVersion type got: %r" % 
1629                            version.__class__)
1630       
1631        self.__version = version
1632       
1633    version = property(fget=_get_version,
1634                       fset=_set_version,
1635                       doc="SAML Version of the assertion")
1636
1637    def _get_issueInstant(self):
1638        '''Gets the date/time the request was issued
1639       
1640        @return the issue instance of this request'''
1641        return self.__issueInstant
1642   
1643    def _set_issueInstant(self, value):
1644        '''Sets the date/time the request was issued
1645       
1646        @param value the issue instance of this request
1647        '''
1648        if not isinstance(value, datetime):
1649            raise TypeError('Expecting "datetime" type for "issueInstant", '
1650                            'got %r' % type(value))
1651           
1652        self.__issueInstant = value
1653       
1654    issueInstant = property(fget=_get_issueInstant, 
1655                            fset=_set_issueInstant,
1656                            doc="Issue instant of the request") 
1657
1658    def _get_id(self):
1659        '''Sets the unique identifier for this request.
1660       
1661        @return the ID of this request
1662        '''
1663        return self.__id
1664   
1665    def _set_id(self, value):
1666        '''Sets the unique identifier for this request
1667       
1668        @param newID the ID of this assertion
1669        '''
1670        if not isinstance(value, basestring):
1671            raise TypeError('Expecting basestring derived type for "id", got '
1672                            '%r' % type(value))
1673        self.__id = value
1674       
1675    id = property(fget=_get_id, fset=_set_id, doc="ID of request")
1676
1677    def _get_destination(self):
1678        '''Gets the URI of the destination of the request.
1679       
1680        @return the URI of the destination of the request
1681        '''
1682        return self.__destination
1683   
1684    def _set_destination(self, value):
1685        '''Sets the URI of the destination of the request.
1686       
1687        @param newDestination the URI of the destination of the request'''
1688        if not isinstance(value, basestring):
1689            raise TypeError('Expecting basestring derived type for '
1690                            '"destination", got %r' % type(value))
1691        self.__destination = value
1692       
1693    destination = property(fget=_get_destination, 
1694                           fset=_set_destination,
1695                           doc="Destination of request")
1696     
1697    def _get_consent(self):
1698        '''Gets the consent obtained from the principal for sending this
1699        request.
1700       
1701        @return: the consent obtained from the principal for sending this
1702        request
1703        '''
1704        return self.__consent
1705       
1706    def _set_consent(self, value):
1707        '''Sets the consent obtained from the principal for sending this
1708        request.
1709       
1710        @param value: the new consent obtained from the principal for
1711        sending this request
1712        ''' 
1713        if not isinstance(value, basestring):
1714            raise TypeError('Expecting basestring derived type for "consent", '
1715                            'got %r' % type(value))
1716        self.__consent = value
1717             
1718    consent = property(fget=_get_consent, 
1719                       fset=_set_consent,
1720                       doc="Consent for request")
1721   
1722    def _set_issuer(self, issuer):
1723        """Set issuer of request"""
1724        if not isinstance(issuer, Issuer):
1725            raise TypeError('"issuer" must be a %r, got %r' % (Issuer, 
1726                                                               type(issuer)))
1727       
1728        self.__issuer = issuer
1729   
1730    def _get_issuer(self):
1731        """Get the issuer name """
1732        return self.__issuer
1733
1734    issuer = property(fget=_get_issuer, 
1735                      fset=_set_issuer,
1736                      doc="Issuer of request")
1737 
1738    def _get_extensions(self):
1739        '''Gets the Extensions of this request.
1740       
1741        @return: the Status of this request
1742        '''
1743        return self.__extensions
1744     
1745    def _set_extensions(self, value):
1746        '''Sets the Extensions of this request.
1747       
1748        @param value: the Extensions of this request
1749        '''
1750        self.__extensions = value
1751       
1752    extensions = property(fget=_get_extensions, 
1753                          fset=_set_extensions,
1754                          doc="Request extensions")
1755
1756
1757class SubjectQuery(RequestAbstractType):
1758    """SAML 2.0 Core Subject Query type"""
1759   
1760    def __init__(self):
1761        self.__subject = None
1762       
1763    def _getSubject(self):
1764        '''Gets the Subject of this request.
1765       
1766        @return the Subject of this request'''   
1767        return self.__subject
1768   
1769    def _setSubject(self, value):
1770        '''Sets the Subject of this request.
1771       
1772        @param newSubject the Subject of this request'''
1773        if not isinstance(value, Subject):
1774            raise TypeError('Setting "subject", got %r, expecting %r' %
1775                            (Subject, type(value)))
1776           
1777        self.__subject = value
1778       
1779    subject = property(fget=_getSubject, fset=_setSubject, doc="Query subject")
1780   
1781   
1782class AttributeQuery(SubjectQuery):
1783    '''SAML 2.0 AttributeQuery'''
1784   
1785    # Element local name.
1786    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeQuery"
1787
1788    # Default element name.
1789    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1790                                 DEFAULT_ELEMENT_LOCAL_NAME,
1791                                 SAMLConstants.SAML20P_PREFIX)
1792
1793    # Local name of the XSI type.
1794    TYPE_LOCAL_NAME = "AttributeQueryType"
1795
1796    # QName of the XSI type.
1797    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1798                      TYPE_LOCAL_NAME,
1799                      SAMLConstants.SAML20P_PREFIX)
1800
1801    def __init__(self):
1802        self.__attributes = TypedList(Attribute)
1803 
1804    def _getAttributes(self):
1805        '''Gets the Attributes of this query.
1806       
1807        @return the list of Attributes of this query'''
1808        return self.__attributes
1809
1810    def _setAttributes(self, value):
1811        self.__attributes = value
1812
1813    attributes = property(fget=_getAttributes, 
1814                          fset=_setAttributes, 
1815                          doc="Attributes")
1816
1817
1818class StatusResponseType(SAMLObject):
1819    '''SAML 2.0 Core Status Response Type
1820    '''
1821
1822    # Local name of the XSI type.
1823    TYPE_LOCAL_NAME = "StatusResponseType"
1824
1825    # QName of the XSI type.
1826    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1827                      TYPE_LOCAL_NAME,
1828                      SAMLConstants.SAML20P_PREFIX)
1829
1830    # ID attribute name
1831    ID_ATTRIB_NAME = "ID"
1832
1833    # InResponseTo attribute name
1834    IN_RESPONSE_TO_ATTRIB_NAME = "InResponseTo"
1835
1836    # Version attribute name
1837    VERSION_ATTRIB_NAME = "Version"
1838
1839    # IssueInstant attribute name
1840    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
1841
1842    # Destination attribute name
1843    DESTINATION_ATTRIB_NAME = "Destination"
1844
1845    # Consent attribute name.
1846    CONSENT_ATTRIB_NAME = "Consent"
1847
1848    # Unspecified consent URI
1849    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
1850
1851    # Obtained consent URI
1852    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
1853
1854    # Prior consent URI
1855    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
1856
1857    # Implicit consent URI
1858    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
1859
1860    # Explicit consent URI
1861    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
1862
1863    # Unavailable consent URI
1864    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
1865
1866    # Inapplicable consent URI
1867    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
1868
1869    def __init__(self):
1870        self.__qname = None
1871       
1872        self.__version = SAMLVersion(SAMLVersion.VERSION_20)
1873        self.__id = None
1874        self.__inResponseTo = None
1875        self.__issueInstant = None
1876        self.__destination = None
1877        self.__consent = None
1878        self.__issuer = None
1879        self.__status = None
1880        self.__extensions = None
1881       
1882    def _getQName(self):
1883        return self.__qname
1884       
1885    def _setQName(self, value):
1886        if not isinstance(value, QName):
1887            raise TypeError("\"qname\" must be a %r derived type, "
1888                            "got %r" % (QName, type(value)))
1889           
1890        self.__qname = value
1891
1892    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1893
1894    def _get_version(self):
1895        '''@return the SAML Version of this response.
1896        '''
1897        return self.__version
1898   
1899    def _set_version(self, version):
1900        '''@param version the SAML Version of this response
1901        '''
1902        if not isinstance(version, SAMLVersion):
1903            raise TypeError("Expecting SAMLVersion type got: %r" % 
1904                            version.__class__)
1905       
1906        self.__version = version
1907       
1908    version = property(fget=_get_version,
1909                       fset=_set_version,
1910                       doc="SAML Version of the response")
1911
1912    def _get_id(self):
1913        '''Sets the ID of this response.
1914       
1915        @return the ID of this response
1916        '''
1917        return self.__id
1918   
1919    def _set_id(self, value):
1920        '''Sets the ID of this response.
1921       
1922        @param value: the ID of this response
1923        '''
1924        if not isinstance(value, basestring):
1925            raise TypeError('Expecting basestring derived type for "id", got '
1926                            '%r' % type(value))
1927        self.__id = value
1928       
1929    id = property(fget=_get_id, fset=_set_id, doc="ID of response")
1930
1931    def _getInResponseTo(self):
1932        '''Get the unique request identifier for which this is a response
1933       
1934        @return value: the unique identifier of the originating
1935        request
1936        '''
1937        return self.__inResponseTo
1938   
1939    def _setInResponseTo(self, value):
1940        '''Set the unique request identifier for which this is a response
1941       
1942        @param value: the unique identifier of the originating
1943        request
1944        '''
1945        if not isinstance(value, basestring):
1946            raise TypeError('Expecting basestring derived type for '
1947                            '"inResponseTo", got %r' % type(value))
1948        self.__inResponseTo = value
1949       
1950    inResponseTo = property(fget=_getInResponseTo, 
1951                            fset=_setInResponseTo,
1952                            doc="unique request identifier for which this is "
1953                                "a response")
1954
1955    def _get_issueInstant(self):
1956        '''Gets the issue instance of this response.
1957       
1958        @return the issue instance of this response'''
1959        return self.__issueInstant
1960   
1961    def _set_issueInstant(self, issueInstant):
1962        '''Sets the issue instance of this response.
1963       
1964        @param newIssueInstance the issue instance of this response
1965        '''
1966        if not isinstance(issueInstant, datetime):
1967            raise TypeError('Expecting "datetime" type for "issueInstant", '
1968                            'got %r' % issueInstant.__class__)
1969           
1970        self.__issueInstant = issueInstant
1971       
1972    issueInstant = property(fget=_get_issueInstant, 
1973                            fset=_set_issueInstant,
1974                            doc="Issue instant of the response")
1975
1976    def _get_destination(self):
1977        '''Gets the URI of the destination of the response.
1978       
1979        @return the URI of the destination of the response
1980        '''
1981        return self.__destination
1982   
1983    def _set_destination(self, value):
1984        '''Sets the URI of the destination of the response.
1985       
1986        @param value: the URI of the destination of the response'''
1987        if not isinstance(value, basestring):
1988            raise TypeError('Expecting basestring derived type for '
1989                            '"destination", got %r' % type(value))
1990        self.__destination = value
1991       
1992    destination = property(fget=_get_destination, 
1993                           fset=_set_destination,
1994                           doc="Destination of response")
1995     
1996    def _get_consent(self):
1997        '''Gets the consent obtained from the principal for sending this
1998        response.
1999       
2000        @return: the consent obtained from the principal for sending this
2001        response
2002        '''
2003        return self.__consent
2004       
2005    def _set_consent(self, value):
2006        '''Sets the consent obtained from the principal for sending this
2007        response.
2008       
2009        @param value: the new consent obtained from the principal for
2010        sending this response
2011        ''' 
2012        if not isinstance(value, basestring):
2013            raise TypeError('Expecting basestring derived type for "consent", '
2014                            'got %r' % type(value))
2015        self.__consent = value
2016             
2017    consent = property(fget=_get_consent, 
2018                       fset=_set_consent,
2019                       doc="Consent for response")
2020   
2021    def _set_issuer(self, issuer):
2022        """Set issuer of response"""
2023        if not isinstance(issuer, Issuer):
2024            raise TypeError('"issuer" must be a %r, got %r' % (Issuer,
2025                                                               type(issuer)))
2026        self.__issuer = issuer
2027   
2028    def _get_issuer(self):
2029        """Get the issuer name """
2030        return self.__issuer
2031
2032    issuer = property(fget=_get_issuer, 
2033                      fset=_set_issuer,
2034                      doc="Issuer of response")
2035   
2036    def _getStatus(self):
2037        '''Gets the Status of this response.
2038       
2039        @return the Status of this response
2040        '''
2041        return self.__status
2042
2043    def _setStatus(self, value):
2044        '''Sets the Status of this response.
2045       
2046        @param newStatus the Status of this response
2047        '''
2048        if not isinstance(value, Status):
2049            raise TypeError('"status" must be a %r, got %r' % (Status,
2050                                                               type(value)))
2051        self.__status = value
2052       
2053    status = property(fget=_getStatus, fset=_setStatus, doc="Response status")   
2054       
2055    def _get_extensions(self):
2056        '''Gets the Extensions of this response.
2057       
2058        @return: the Status of this response
2059        '''
2060        return self.__extensions
2061     
2062    def _set_extensions(self, value):
2063        '''Sets the Extensions of this response.
2064       
2065        @param value: the Extensions of this response
2066        '''
2067        if not isinstance(value, (list, tuple)):
2068            raise TypeError('Expecting list or tuple for "extensions", got %r'
2069                            % type(value))
2070        self.__extensions = value
2071       
2072    extensions = property(fget=_get_extensions, 
2073                          fset=_set_extensions,
2074                          doc="Response extensions")   
2075
2076
2077class Response(StatusResponseType):
2078    '''SAML2 Core Response'''
2079   
2080    # Element local name.
2081    DEFAULT_ELEMENT_LOCAL_NAME = "Response"
2082   
2083    # Default element name.
2084    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2085                                 DEFAULT_ELEMENT_LOCAL_NAME, 
2086                                 SAMLConstants.SAML20P_PREFIX)
2087   
2088    # Local name of the XSI type.
2089    TYPE_LOCAL_NAME = "ResponseType"
2090       
2091    # QName of the XSI type.
2092    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2093                      TYPE_LOCAL_NAME, 
2094                      SAMLConstants.SAML20P_PREFIX)
2095   
2096    def __init__(self):
2097        '''''' 
2098        super(Response, self).__init__()
2099       
2100        # Assertion child elements
2101        self.__indexedChildren = []
2102   
2103    def _getAssertions(self): 
2104        return self.__indexedChildren
2105   
2106    assertions = property(fget=_getAssertions,
2107                          doc="Assertions contained in this response")
Note: See TracBrowser for help on using the repository browser.