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

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

saml.xml.etree: important fixes to ElementTree based Status element serialisation and de-serialisation
ndg.security.server.attributeauthority: added clockSkew parameter to provide some leeway in SAML attribute query clock checks. Also added StatusMessage? element for additional error info in responses.
ndg.security.common.soap.client: added check of HTTP Content-type in SOAP responses.

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    DEFAULT_ELEMENT_LOCAL_NAME = "StatusMessage"
1254    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1255                                 DEFAULT_ELEMENT_LOCAL_NAME,
1256                                 SAMLConstants.SAML20P_PREFIX)
1257   
1258    def __init__(self):
1259        # Value attribute URI.
1260        self.__value = None       
1261        self.__qname = QName(StatusMessage.DEFAULT_ELEMENT_NAME.namespaceURI,
1262                             StatusMessage.DEFAULT_ELEMENT_NAME.localPart,
1263                             StatusMessage.DEFAULT_ELEMENT_NAME.prefix)
1264             
1265    def _getValue(self):
1266        return self.__value
1267       
1268    def _setValue(self, value):
1269        if not isinstance(value, basestring):
1270            raise TypeError("\"value\" must be a basestring derived type, "
1271                            "got %r" % type(value))
1272           
1273        self.__value = value
1274
1275    value = property(fget=_getValue, fset=_setValue, 
1276                     doc="Status message value")
1277               
1278    def _getQName(self):
1279        return self.__qname
1280       
1281    def _setQName(self, value):
1282        if not isinstance(value, QName):
1283            raise TypeError("\"qname\" must be a %r derived type, "
1284                            "got %r" % (QName, type(value)))
1285           
1286        self.__qname = value
1287
1288    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1289
1290
1291class StatusCode(SAMLObject):
1292    '''Implementation of SAML 2.0 StatusCode.'''
1293   
1294    # Local Name of StatusCode.
1295    DEFAULT_ELEMENT_LOCAL_NAME = "StatusCode"
1296
1297    # Default element name.
1298    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1299                                 DEFAULT_ELEMENT_LOCAL_NAME,
1300                                 SAMLConstants.SAML20P_PREFIX)
1301
1302    # Local name of the XSI type.
1303    TYPE_LOCAL_NAME = "StatusCodeType"
1304
1305    # QName of the XSI type.
1306    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1307                      TYPE_LOCAL_NAME,
1308                      SAMLConstants.SAML20P_PREFIX)
1309
1310    # Local Name of the Value attribute.
1311    VALUE_ATTRIB_NAME = "Value"
1312
1313    # URI for Success status code.
1314    SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success"
1315
1316    # URI for Requester status code.
1317    REQUESTER_URI = "urn:oasis:names:tc:SAML:2.0:status:Requester"
1318
1319    # URI for Responder status code.
1320    RESPONDER_URI = "urn:oasis:names:tc:SAML:2.0:status:Responder"
1321
1322    # URI for VersionMismatch status code.
1323    VERSION_MISMATCH_URI = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
1324
1325    # URI for AuthnFailed status code.
1326    AUTHN_FAILED_URI = "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
1327
1328    # URI for InvalidAttrNameOrValue status code.
1329    INVALID_ATTR_NAME_VALUE_URI = \
1330                "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue"
1331
1332    # URI for InvalidNameIDPolicy status code.
1333    INVALID_NAMEID_POLICY_URI = \
1334                "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"
1335
1336    # URI for NoAuthnContext status code.
1337    NO_AUTHN_CONTEXT_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"
1338
1339    # URI for NoAvailableIDP status code.
1340    NO_AVAILABLE_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"
1341
1342    # URI for NoPassive status code.
1343    NO_PASSIVE_URI = "urn:oasis:names:tc:SAML:2.0:status:NoPassive"
1344
1345    # URI for NoSupportedIDP status code.
1346    NO_SUPPORTED_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"
1347
1348    # URI for PartialLogout status code.
1349    PARTIAL_LOGOUT_URI = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
1350
1351    # URI for ProxyCountExceeded status code.
1352    PROXY_COUNT_EXCEEDED_URI = \
1353                "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"
1354
1355    # URI for RequestDenied status code.
1356    REQUEST_DENIED_URI = "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"
1357
1358    # URI for RequestUnsupported status code.
1359    REQUEST_UNSUPPORTED_URI = \
1360                "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
1361
1362    # URI for RequestVersionDeprecated status code.
1363    REQUEST_VERSION_DEPRECATED_URI = \
1364                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
1365
1366    # URI for RequestVersionTooHigh status code.
1367    REQUEST_VERSION_TOO_HIGH_URI = \
1368                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
1369   
1370    # URI for RequestVersionTooLow status code.
1371    REQUEST_VERSION_TOO_LOW_URI = \
1372                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"
1373
1374    # URI for ResourceNotRecognized status code.
1375    RESOURCE_NOT_RECOGNIZED_URI = \
1376                "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"
1377
1378    # URI for TooManyResponses status code.
1379    TOO_MANY_RESPONSES = "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"
1380
1381    # URI for UnknownAttrProfile status code.
1382    UNKNOWN_ATTR_PROFILE_URI = \
1383                "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile"
1384
1385    # URI for UnknownPrincipal status code.
1386    UNKNOWN_PRINCIPAL_URI = \
1387                "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"
1388
1389    # URI for UnsupportedBinding status code.
1390    UNSUPPORTED_BINDING_URI = \
1391                "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"
1392
1393    def __init__(self):
1394        # Value attribute URI.
1395        self.__value = None
1396   
1397        # Nested secondary StatusCode child element.
1398        self.__childStatusCode = None
1399       
1400        self.__qname = QName(StatusCode.DEFAULT_ELEMENT_NAME.namespaceURI,
1401                             StatusCode.DEFAULT_ELEMENT_NAME.localPart,
1402                             StatusCode.DEFAULT_ELEMENT_NAME.prefix)
1403
1404    def _getStatusCode(self): 
1405        return self.__childStatusCode
1406   
1407    def _setStatusCode(self, value):
1408        if not isinstance(value, StatusCode):
1409            raise TypeError('Child "statusCode" must be a %r derived type, '
1410                            "got %r" % (StatusCode, type(value)))
1411           
1412        self.__childStatusCode = value
1413
1414    value = property(fget=_getStatusCode, 
1415                     fset=_setStatusCode, 
1416                     doc="Child Status code")
1417             
1418    def _getValue(self):
1419        return self.__value
1420       
1421    def _setValue(self, value):
1422        if not isinstance(value, basestring):
1423            raise TypeError("\"value\" must be a basestring derived type, "
1424                            "got %r" % value.__class__)
1425           
1426        self.__value = value
1427
1428    value = property(fget=_getValue, fset=_setValue, doc="Status code value")
1429               
1430    def _getQName(self):
1431        return self.__qname
1432       
1433    def _setQName(self, value):
1434        if not isinstance(value, QName):
1435            raise TypeError("\"qname\" must be a %r derived type, "
1436                            "got %r" % (QName, type(value)))
1437           
1438        self.__qname = value
1439
1440    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1441       
1442
1443class Status(SAMLObject): 
1444    '''SAML 2.0 Core Status'''
1445   
1446    # Local Name of Status.
1447    DEFAULT_ELEMENT_LOCAL_NAME = "Status"
1448
1449    # Default element name.
1450    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1451                                 DEFAULT_ELEMENT_LOCAL_NAME,
1452                                 SAMLConstants.SAML20P_PREFIX)
1453
1454    # Local name of the XSI type.
1455    TYPE_LOCAL_NAME = "StatusType"
1456
1457    # QName of the XSI type.
1458    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1459                      TYPE_LOCAL_NAME,
1460                      SAMLConstants.SAML20P_PREFIX)
1461
1462    def __init__(self):
1463        # StatusCode element.
1464        self.__statusCode = None
1465   
1466        # StatusMessage element.
1467        self.__statusMessage = None
1468   
1469        # StatusDetail element.
1470        self.__statusDetail = None
1471       
1472        self.__qname = QName(Status.DEFAULT_ELEMENT_NAME.namespaceURI,
1473                             Status.DEFAULT_ELEMENT_NAME.localPart,
1474                             Status.DEFAULT_ELEMENT_NAME.prefix)
1475               
1476    def _getQName(self):
1477        return self.__qname
1478       
1479    def _setQName(self, value):
1480        if not isinstance(value, QName):
1481            raise TypeError("\"qname\" must be a %r derived type, "
1482                            "got %r" % (QName, type(value)))
1483           
1484        self.__qname = value
1485
1486    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1487       
1488    def _getStatusCode(self):
1489        '''
1490        Gets the Code of this Status.
1491       
1492        @return Status StatusCode
1493        '''
1494        return self.__statusCode
1495
1496    def _setStatusCode(self, value):
1497        '''
1498        Sets the Code of this Status.
1499       
1500        @param newStatusCode the Code of this Status
1501        '''
1502        if not isinstance(value, StatusCode):
1503            raise TypeError('"statusCode" must be a %r derived type, '
1504                            "got %r" % (StatusCode, type(value)))
1505           
1506        self.__statusCode = value
1507       
1508    statusCode = property(fget=_getStatusCode,
1509                          fset=_setStatusCode,
1510                          doc="status code object")
1511   
1512    def _getStatusMessage(self):
1513        '''
1514        Gets the Message of this Status.
1515       
1516        @return Status StatusMessage
1517        '''
1518        return self.__statusMessage
1519
1520    def _setStatusMessage(self, value):
1521        '''
1522        Sets the Message of this Status.
1523       
1524        @param newStatusMessage the Message of this Status
1525        '''
1526        if not isinstance(value, StatusMessage):
1527            raise TypeError('"statusMessage" must be a %r derived type, '
1528                            "got %r" % (StatusMessage, type(value)))
1529           
1530        self.__statusMessage = value
1531       
1532    statusMessage = property(fget=_getStatusMessage,
1533                             fset=_setStatusMessage,
1534                             doc="status message")
1535
1536    def _getStatusDetail(self):
1537        '''
1538        Gets the Detail of this Status.
1539       
1540        @return Status StatusDetail
1541        '''
1542        return self.__statusDetail
1543   
1544    def _setStatusDetail(self, value):
1545        '''
1546        Sets the Detail of this Status.
1547       
1548        @param newStatusDetail the Detail of this Status
1549        '''
1550        self.__statusDetail = value
1551       
1552    statusDetail = property(fget=_getStatusDetail,
1553                            fset=_setStatusDetail,
1554                            doc="status message")
1555
1556
1557class RequestAbstractType(SAMLObject): 
1558    '''SAML 2.0 Core RequestAbstractType'''
1559   
1560    # Local name of the XSI type.
1561    TYPE_LOCAL_NAME = "RequestAbstractType"
1562
1563    # QName of the XSI type.
1564    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1565                      TYPE_LOCAL_NAME,
1566                      SAMLConstants.SAML20P_PREFIX)
1567
1568    # ID attribute name.
1569    ID_ATTRIB_NAME = "ID"
1570
1571    # Version attribute name.
1572    VERSION_ATTRIB_NAME = "Version"
1573
1574    # IssueInstant attribute name.
1575    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
1576
1577    # Destination attribute name.
1578    DESTINATION_ATTRIB_NAME = "Destination"
1579
1580    # Consent attribute name.
1581    CONSENT_ATTRIB_NAME = "Consent"
1582
1583    # Unspecified consent URI.
1584    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
1585
1586    # Obtained consent URI.
1587    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
1588
1589    # Prior consent URI.
1590    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
1591
1592    # Implicit consent URI.
1593    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
1594
1595    # Explicit consent URI.
1596    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
1597
1598    # Unavailable consent URI.
1599    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
1600
1601    # Inapplicable consent URI.
1602    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable" 
1603
1604    def __init__(self):
1605        # SAML Version of the request.
1606        self.__version = None
1607   
1608        # Unique identifier of the request.
1609        self.__id = None
1610   
1611        # Date/time request was issued.
1612        self.__issueInstant = None
1613   
1614        # URI of the request destination.
1615        self.__destination = None
1616   
1617        # URI of the SAML user consent type.
1618        self.__consent = None
1619   
1620        # URI of the SAML user consent type.
1621        self.__issuer = None
1622   
1623        # Extensions child element.
1624        self.__extensions = None
1625       
1626    def _get_version(self):
1627        '''@return the SAML Version of this assertion.
1628        '''
1629        return self.__version
1630   
1631    def _set_version(self, version):
1632        '''@param version the SAML Version of this assertion
1633        '''
1634        if not isinstance(version, SAMLVersion):
1635            raise TypeError("Expecting SAMLVersion type got: %r" % 
1636                            version.__class__)
1637       
1638        self.__version = version
1639       
1640    version = property(fget=_get_version,
1641                       fset=_set_version,
1642                       doc="SAML Version of the assertion")
1643
1644    def _get_issueInstant(self):
1645        '''Gets the date/time the request was issued
1646       
1647        @return the issue instance of this request'''
1648        return self.__issueInstant
1649   
1650    def _set_issueInstant(self, value):
1651        '''Sets the date/time the request was issued
1652       
1653        @param value the issue instance of this request
1654        '''
1655        if not isinstance(value, datetime):
1656            raise TypeError('Expecting "datetime" type for "issueInstant", '
1657                            'got %r' % type(value))
1658           
1659        self.__issueInstant = value
1660       
1661    issueInstant = property(fget=_get_issueInstant, 
1662                            fset=_set_issueInstant,
1663                            doc="Issue instant of the request") 
1664
1665    def _get_id(self):
1666        '''Sets the unique identifier for this request.
1667       
1668        @return the ID of this request
1669        '''
1670        return self.__id
1671   
1672    def _set_id(self, value):
1673        '''Sets the unique identifier for this request
1674       
1675        @param newID the ID of this assertion
1676        '''
1677        if not isinstance(value, basestring):
1678            raise TypeError('Expecting basestring derived type for "id", got '
1679                            '%r' % type(value))
1680        self.__id = value
1681       
1682    id = property(fget=_get_id, fset=_set_id, doc="ID of request")
1683
1684    def _get_destination(self):
1685        '''Gets the URI of the destination of the request.
1686       
1687        @return the URI of the destination of the request
1688        '''
1689        return self.__destination
1690   
1691    def _set_destination(self, value):
1692        '''Sets the URI of the destination of the request.
1693       
1694        @param newDestination the URI of the destination of the request'''
1695        if not isinstance(value, basestring):
1696            raise TypeError('Expecting basestring derived type for '
1697                            '"destination", got %r' % type(value))
1698        self.__destination = value
1699       
1700    destination = property(fget=_get_destination, 
1701                           fset=_set_destination,
1702                           doc="Destination of request")
1703     
1704    def _get_consent(self):
1705        '''Gets the consent obtained from the principal for sending this
1706        request.
1707       
1708        @return: the consent obtained from the principal for sending this
1709        request
1710        '''
1711        return self.__consent
1712       
1713    def _set_consent(self, value):
1714        '''Sets the consent obtained from the principal for sending this
1715        request.
1716       
1717        @param value: the new consent obtained from the principal for
1718        sending this request
1719        ''' 
1720        if not isinstance(value, basestring):
1721            raise TypeError('Expecting basestring derived type for "consent", '
1722                            'got %r' % type(value))
1723        self.__consent = value
1724             
1725    consent = property(fget=_get_consent, 
1726                       fset=_set_consent,
1727                       doc="Consent for request")
1728   
1729    def _set_issuer(self, issuer):
1730        """Set issuer of request"""
1731        if not isinstance(issuer, Issuer):
1732            raise TypeError('"issuer" must be a %r, got %r' % (Issuer, 
1733                                                               type(issuer)))
1734       
1735        self.__issuer = issuer
1736   
1737    def _get_issuer(self):
1738        """Get the issuer name """
1739        return self.__issuer
1740
1741    issuer = property(fget=_get_issuer, 
1742                      fset=_set_issuer,
1743                      doc="Issuer of request")
1744 
1745    def _get_extensions(self):
1746        '''Gets the Extensions of this request.
1747       
1748        @return: the Status of this request
1749        '''
1750        return self.__extensions
1751     
1752    def _set_extensions(self, value):
1753        '''Sets the Extensions of this request.
1754       
1755        @param value: the Extensions of this request
1756        '''
1757        self.__extensions = value
1758       
1759    extensions = property(fget=_get_extensions, 
1760                          fset=_set_extensions,
1761                          doc="Request extensions")
1762
1763
1764class SubjectQuery(RequestAbstractType):
1765    """SAML 2.0 Core Subject Query type"""
1766   
1767    def __init__(self):
1768        self.__subject = None
1769       
1770    def _getSubject(self):
1771        '''Gets the Subject of this request.
1772       
1773        @return the Subject of this request'''   
1774        return self.__subject
1775   
1776    def _setSubject(self, value):
1777        '''Sets the Subject of this request.
1778       
1779        @param newSubject the Subject of this request'''
1780        if not isinstance(value, Subject):
1781            raise TypeError('Setting "subject", got %r, expecting %r' %
1782                            (Subject, type(value)))
1783           
1784        self.__subject = value
1785       
1786    subject = property(fget=_getSubject, fset=_setSubject, doc="Query subject")
1787   
1788   
1789class AttributeQuery(SubjectQuery):
1790    '''SAML 2.0 AttributeQuery'''
1791   
1792    # Element local name.
1793    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeQuery"
1794
1795    # Default element name.
1796    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
1797                                 DEFAULT_ELEMENT_LOCAL_NAME,
1798                                 SAMLConstants.SAML20P_PREFIX)
1799
1800    # Local name of the XSI type.
1801    TYPE_LOCAL_NAME = "AttributeQueryType"
1802
1803    # QName of the XSI type.
1804    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1805                      TYPE_LOCAL_NAME,
1806                      SAMLConstants.SAML20P_PREFIX)
1807
1808    def __init__(self):
1809        self.__attributes = TypedList(Attribute)
1810 
1811    def _getAttributes(self):
1812        '''Gets the Attributes of this query.
1813       
1814        @return the list of Attributes of this query'''
1815        return self.__attributes
1816
1817    def _setAttributes(self, value):
1818        self.__attributes = value
1819
1820    attributes = property(fget=_getAttributes, 
1821                          fset=_setAttributes, 
1822                          doc="Attributes")
1823
1824
1825class StatusResponseType(SAMLObject):
1826    '''SAML 2.0 Core Status Response Type
1827    '''
1828
1829    # Local name of the XSI type.
1830    TYPE_LOCAL_NAME = "StatusResponseType"
1831
1832    # QName of the XSI type.
1833    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
1834                      TYPE_LOCAL_NAME,
1835                      SAMLConstants.SAML20P_PREFIX)
1836
1837    # ID attribute name
1838    ID_ATTRIB_NAME = "ID"
1839
1840    # InResponseTo attribute name
1841    IN_RESPONSE_TO_ATTRIB_NAME = "InResponseTo"
1842
1843    # Version attribute name
1844    VERSION_ATTRIB_NAME = "Version"
1845
1846    # IssueInstant attribute name
1847    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
1848
1849    # Destination attribute name
1850    DESTINATION_ATTRIB_NAME = "Destination"
1851
1852    # Consent attribute name.
1853    CONSENT_ATTRIB_NAME = "Consent"
1854
1855    # Unspecified consent URI
1856    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
1857
1858    # Obtained consent URI
1859    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
1860
1861    # Prior consent URI
1862    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
1863
1864    # Implicit consent URI
1865    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
1866
1867    # Explicit consent URI
1868    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
1869
1870    # Unavailable consent URI
1871    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
1872
1873    # Inapplicable consent URI
1874    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
1875
1876    def __init__(self):
1877        self.__qname = None
1878       
1879        self.__version = SAMLVersion(SAMLVersion.VERSION_20)
1880        self.__id = None
1881        self.__inResponseTo = None
1882        self.__issueInstant = None
1883        self.__destination = None
1884        self.__consent = None
1885        self.__issuer = None
1886        self.__status = None
1887        self.__extensions = None
1888       
1889    def _getQName(self):
1890        return self.__qname
1891       
1892    def _setQName(self, value):
1893        if not isinstance(value, QName):
1894            raise TypeError("\"qname\" must be a %r derived type, "
1895                            "got %r" % (QName, type(value)))
1896           
1897        self.__qname = value
1898
1899    qname = property(fget=_getQName, fset=_setQName, doc="qualified name")
1900
1901    def _get_version(self):
1902        '''@return the SAML Version of this response.
1903        '''
1904        return self.__version
1905   
1906    def _set_version(self, version):
1907        '''@param version the SAML Version of this response
1908        '''
1909        if not isinstance(version, SAMLVersion):
1910            raise TypeError("Expecting SAMLVersion type got: %r" % 
1911                            version.__class__)
1912       
1913        self.__version = version
1914       
1915    version = property(fget=_get_version,
1916                       fset=_set_version,
1917                       doc="SAML Version of the response")
1918
1919    def _get_id(self):
1920        '''Sets the ID of this response.
1921       
1922        @return the ID of this response
1923        '''
1924        return self.__id
1925   
1926    def _set_id(self, value):
1927        '''Sets the ID of this response.
1928       
1929        @param value: the ID of this response
1930        '''
1931        if not isinstance(value, basestring):
1932            raise TypeError('Expecting basestring derived type for "id", got '
1933                            '%r' % type(value))
1934        self.__id = value
1935       
1936    id = property(fget=_get_id, fset=_set_id, doc="ID of response")
1937
1938    def _getInResponseTo(self):
1939        '''Get the unique request identifier for which this is a response
1940       
1941        @return value: the unique identifier of the originating
1942        request
1943        '''
1944        return self.__inResponseTo
1945   
1946    def _setInResponseTo(self, value):
1947        '''Set the unique request identifier for which this is a response
1948       
1949        @param value: the unique identifier of the originating
1950        request
1951        '''
1952        if not isinstance(value, basestring):
1953            raise TypeError('Expecting basestring derived type for '
1954                            '"inResponseTo", got %r' % type(value))
1955        self.__inResponseTo = value
1956       
1957    inResponseTo = property(fget=_getInResponseTo, 
1958                            fset=_setInResponseTo,
1959                            doc="unique request identifier for which this is "
1960                                "a response")
1961
1962    def _get_issueInstant(self):
1963        '''Gets the issue instance of this response.
1964       
1965        @return the issue instance of this response'''
1966        return self.__issueInstant
1967   
1968    def _set_issueInstant(self, issueInstant):
1969        '''Sets the issue instance of this response.
1970       
1971        @param newIssueInstance the issue instance of this response
1972        '''
1973        if not isinstance(issueInstant, datetime):
1974            raise TypeError('Expecting "datetime" type for "issueInstant", '
1975                            'got %r' % issueInstant.__class__)
1976           
1977        self.__issueInstant = issueInstant
1978       
1979    issueInstant = property(fget=_get_issueInstant, 
1980                            fset=_set_issueInstant,
1981                            doc="Issue instant of the response")
1982
1983    def _get_destination(self):
1984        '''Gets the URI of the destination of the response.
1985       
1986        @return the URI of the destination of the response
1987        '''
1988        return self.__destination
1989   
1990    def _set_destination(self, value):
1991        '''Sets the URI of the destination of the response.
1992       
1993        @param value: the URI of the destination of the response'''
1994        if not isinstance(value, basestring):
1995            raise TypeError('Expecting basestring derived type for '
1996                            '"destination", got %r' % type(value))
1997        self.__destination = value
1998       
1999    destination = property(fget=_get_destination, 
2000                           fset=_set_destination,
2001                           doc="Destination of response")
2002     
2003    def _get_consent(self):
2004        '''Gets the consent obtained from the principal for sending this
2005        response.
2006       
2007        @return: the consent obtained from the principal for sending this
2008        response
2009        '''
2010        return self.__consent
2011       
2012    def _set_consent(self, value):
2013        '''Sets the consent obtained from the principal for sending this
2014        response.
2015       
2016        @param value: the new consent obtained from the principal for
2017        sending this response
2018        ''' 
2019        if not isinstance(value, basestring):
2020            raise TypeError('Expecting basestring derived type for "consent", '
2021                            'got %r' % type(value))
2022        self.__consent = value
2023             
2024    consent = property(fget=_get_consent, 
2025                       fset=_set_consent,
2026                       doc="Consent for response")
2027   
2028    def _set_issuer(self, issuer):
2029        """Set issuer of response"""
2030        if not isinstance(issuer, Issuer):
2031            raise TypeError('"issuer" must be a %r, got %r' % (Issuer,
2032                                                               type(issuer)))
2033        self.__issuer = issuer
2034   
2035    def _get_issuer(self):
2036        """Get the issuer name """
2037        return self.__issuer
2038
2039    issuer = property(fget=_get_issuer, 
2040                      fset=_set_issuer,
2041                      doc="Issuer of response")
2042   
2043    def _getStatus(self):
2044        '''Gets the Status of this response.
2045       
2046        @return the Status of this response
2047        '''
2048        return self.__status
2049
2050    def _setStatus(self, value):
2051        '''Sets the Status of this response.
2052       
2053        @param newStatus the Status of this response
2054        '''
2055        if not isinstance(value, Status):
2056            raise TypeError('"status" must be a %r, got %r' % (Status,
2057                                                               type(value)))
2058        self.__status = value
2059       
2060    status = property(fget=_getStatus, fset=_setStatus, doc="Response status")   
2061       
2062    def _get_extensions(self):
2063        '''Gets the Extensions of this response.
2064       
2065        @return: the Status of this response
2066        '''
2067        return self.__extensions
2068     
2069    def _set_extensions(self, value):
2070        '''Sets the Extensions of this response.
2071       
2072        @param value: the Extensions of this response
2073        '''
2074        if not isinstance(value, (list, tuple)):
2075            raise TypeError('Expecting list or tuple for "extensions", got %r'
2076                            % type(value))
2077        self.__extensions = value
2078       
2079    extensions = property(fget=_get_extensions, 
2080                          fset=_set_extensions,
2081                          doc="Response extensions")   
2082
2083
2084class Response(StatusResponseType):
2085    '''SAML2 Core Response'''
2086   
2087    # Element local name.
2088    DEFAULT_ELEMENT_LOCAL_NAME = "Response"
2089   
2090    # Default element name.
2091    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2092                                 DEFAULT_ELEMENT_LOCAL_NAME, 
2093                                 SAMLConstants.SAML20P_PREFIX)
2094   
2095    # Local name of the XSI type.
2096    TYPE_LOCAL_NAME = "ResponseType"
2097       
2098    # QName of the XSI type.
2099    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2100                      TYPE_LOCAL_NAME, 
2101                      SAMLConstants.SAML20P_PREFIX)
2102   
2103    def __init__(self):
2104        '''''' 
2105        super(Response, self).__init__()
2106       
2107        # Assertion child elements
2108        self.__indexedChildren = []
2109   
2110    def _getAssertions(self): 
2111        return self.__indexedChildren
2112   
2113    assertions = property(fget=_getAssertions,
2114                          doc="Assertions contained in this response")
Note: See TracBrowser for help on using the repository browser.