source: TI12-security/trunk/python/ndg.security.saml/saml/saml2/core.py @ 5620

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

Assertion parsing near complete but fixes needed to XSGroupRoleElementTree

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