source: TI12-security/trunk/ndg_saml/ndg/saml/saml2/core.py @ 6911

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

Incomplete - task 6: Put NDG SAML package on PyPI

  • updating epydoc for 'core' module
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__ = "http://www.apache.org/licenses/LICENSE-2.0"
29__contact__ = "Philip.Kershaw@stfc.ac.uk"
30__revision__ = "$Id$"
31from datetime import datetime
32from urlparse import urlsplit, urlunsplit
33import urllib
34
35from ndg.saml.common import SAMLObject, SAMLVersion
36from ndg.saml.common.xml import SAMLConstants, QName
37from ndg.saml.utils import TypedList
38
39
40class Attribute(SAMLObject):
41    '''SAML 2.0 Core Attribute
42   
43    @cvar DEFAULT_ELEMENT_LOCAL_NAME:  Local name of the Attribute element.
44    @type DEFAULT_ELEMENT_LOCAL_NAME: string
45    @cvar DEFAULT_ELEMENT_NAME:  Default element name.
46    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
47    @cvar TYPE_LOCAL_NAME:  Local name of the XSI type.
48    @type TYPE_LOCAL_NAME: string
49    @cvar TYPE_NAME:  QName of the XSI type.
50    @type TYPE_NAME: ndg.saml.common.xml.QName
51    @cvar NAME_ATTRIB_NAME:  Name of the Name attribute.
52    @type NAME_ATTRIB_NAME: string
53    @cvar NAME_FORMAT_ATTRIB_NAME:  Name for the NameFormat attribute.
54    @type NAME_FORMAT_ATTRIB_NAME: string
55    @cvar FRIENDLY_NAME_ATTRIB_NAME:  Name of the FriendlyName attribute.
56    @type FRIENDLY_NAME_ATTRIB_NAME: string
57    @cvar UNSPECIFIED:  Unspecified attribute format ID.
58    @type UNSPECIFIED: string
59    @cvar URI_REFERENCE:  URI reference attribute format ID.
60    @type URI_REFERENCE: string
61    @cvar BASIC:  Basic attribute format ID.
62    @type BASIC: string
63   
64    @ivar __name: attribute name
65    @type __name: NoneType / basestring
66    @ivar __nameFormat: name format
67    @type __nameFormat: NoneType / basestring
68    @ivar __friendlyName: friendly name for attribute
69    @type __friendlyName: NoneType / basestring
70    @ivar __attributeValues: list of values
71    @type __attributeValues: list / tuple
72    '''
73   
74    # Local name of the Attribute element.
75    DEFAULT_ELEMENT_LOCAL_NAME = "Attribute"
76
77    # Default element name.
78    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
79                                 DEFAULT_ELEMENT_LOCAL_NAME,
80                                 SAMLConstants.SAML20_PREFIX)
81
82    # Local name of the XSI type.
83    TYPE_LOCAL_NAME = "AttributeType"
84
85    # QName of the XSI type.
86    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
87                      TYPE_LOCAL_NAME,
88                      SAMLConstants.SAML20_PREFIX)
89
90    # Name of the Name attribute.
91    NAME_ATTRIB_NAME = "Name"
92
93    # Name for the NameFormat attribute.
94    NAME_FORMAT_ATTRIB_NAME = "NameFormat"
95
96    # Name of the FriendlyName attribute.
97    FRIENDLY_NAME_ATTRIB_NAME = "FriendlyName"
98
99    # Unspecified attribute format ID.
100    UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
101
102    # URI reference attribute format ID.
103    URI_REFERENCE = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
104
105    # Basic attribute format ID.
106    BASIC = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
107
108    __slots__ = (
109        '__name',
110        '__nameFormat',
111        '__friendlyName',
112        '__attributeValues'
113    )
114   
115    def __init__(self, **kw):
116        """Initialise Attribute Class attributes
117        @param **kw: keywords SAMLObject parent instantiation
118        @type **kw: dict
119        """
120        super(Attribute, self).__init__(**kw)
121       
122        self.__name = None
123        self.__nameFormat = None
124        self.__friendlyName = None
125        self.__attributeValues = []
126
127    def __getstate__(self):
128        '''Enable pickling
129       
130        @return: object's attribute dictionary
131        @rtype: dict
132        '''
133        _dict = super(Attribute, self).__getstate__()
134        for attrName in Attribute.__slots__:
135            # Ugly hack to allow for derived classes setting private member
136            # variables
137            if attrName.startswith('__'):
138                attrName = "_Attribute" + attrName
139               
140            _dict[attrName] = getattr(self, attrName)
141           
142        return _dict
143   
144    def _get_name(self):
145        """Get name
146        @return: name
147        @rtype: string
148        """
149        return self.__name
150   
151    def _set_name(self, name):
152        """Set name
153        @param: name
154        @type: name
155        @raise TypeError: invalid input value type
156        """
157        if not isinstance(name, basestring):
158            raise TypeError("Expecting basestring type for name, got %r"% 
159                            type(name))
160       
161        self.__name = name
162       
163    name = property(fget=_get_name,
164                    fset=_set_name,
165                    doc="name of this attribute")
166   
167    def _get_nameFormat(self):
168        """Get name format
169        @return: name format
170        @rtype: string
171        """
172        return self.__nameFormat
173   
174    def _set_nameFormat(self, nameFormat):
175        """Set name format
176        @param: name format
177        @type: string
178        @raise TypeError: invalid input value type
179        """
180        if not isinstance(nameFormat, basestring):
181            raise TypeError("Expecting basestring type for nameFormat, got %r"
182                            % type(nameFormat))
183           
184        self.__nameFormat = nameFormat
185       
186    nameFormat = property(fget=_get_nameFormat,
187                          fset=_set_nameFormat,
188                          doc="Get the name format of this attribute.")
189   
190    def _get_friendlyName(self):
191        """Get friendly name
192        @return: friendly name
193        @rtype: string
194        """
195        return self.__friendlyName
196   
197    def _set_friendlyName(self, friendlyName):
198        """Set friendly name
199        @param: friendly name
200        @type: string
201        @raise TypeError: invalid input value type
202        """
203        if not isinstance(friendlyName, basestring):
204            raise TypeError("Expecting basestring type for friendlyName, got "
205                            "%r" % type(friendlyName))
206           
207        self.__friendlyName = friendlyName
208       
209    friendlyName = property(fget=_get_friendlyName,
210                            fset=_set_friendlyName,
211                            doc="the friendly name of this attribute.")
212   
213    def _get_attributeValues(self):
214        """Get attribute values
215        @return: attribute values
216        @rtype: string
217        """
218        return self.__attributeValues
219   
220    def _set_attributeValues(self, attributeValues):
221        """Set attribute values
222        @param: attribute values
223        @type: string
224        @raise TypeError: invalid input value type
225        """
226        if not isinstance(attributeValues, (list, tuple)):
227            raise TypeError("Expecting list/tuple type for attributeValues, "
228                            "got %r" % type(attributeValues))
229           
230        self.__attributeValues = attributeValues
231       
232    attributeValues = property(fget=_get_attributeValues,
233                               fset=_set_attributeValues,
234                               doc="the list of attribute values for this "
235                               "attribute.")
236
237
238class Statement(SAMLObject):
239    '''SAML 2.0 Core Statement.  Abstract base class which all statement
240    types must implement.
241   
242    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name
243    @type DEFAULT_ELEMENT_LOCAL_NAME: string
244    @cvar DEFAULT_ELEMENT_NAME: Default element name
245    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
246    @cvar TYPE_LOCAL_NAME: Local name of the XSI type
247    @type TYPE_LOCAL_NAME: string
248    @cvar TYPE_NAME: QName of the XSI type
249    @type TYPE_NAME: ndg.saml.common.xml.QName
250    '''
251    __slots__ = ()
252   
253    # Element local name
254    DEFAULT_ELEMENT_LOCAL_NAME = "Statement"
255
256    # Default element name
257    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
258                                 DEFAULT_ELEMENT_LOCAL_NAME,
259                                 SAMLConstants.SAML20_PREFIX)
260
261    # Local name of the XSI type
262    TYPE_LOCAL_NAME = "StatementAbstractType"
263
264    # QName of the XSI type
265    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
266                      TYPE_LOCAL_NAME,
267                      SAMLConstants.SAML20_PREFIX)
268   
269           
270class AttributeStatement(Statement):
271    '''SAML 2.0 Core AttributeStatement
272   
273    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name
274    @type DEFAULT_ELEMENT_LOCAL_NAME: string
275    @cvar DEFAULT_ELEMENT_NAME: Default element name.
276    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
277    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
278    @type TYPE_LOCAL_NAME: string
279    @cvar TYPE_NAME: QName of the XSI type.
280    @type TYPE_NAME: ndg.saml.common.xml.QName
281   
282    @ivar __attributes: list of ndg.saml.saml2.core.Attribute type attributes
283    @type __attributes: ndg.saml.utils.TypedList
284    @ivar __encryptedAttributes: list of encrypted attributes of type
285    ndg.saml.saml2.core.Attribute
286    @type __encryptedAttributes: ndg.saml.utils.TypedList
287    '''
288   
289    # Element local name
290    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeStatement"
291   
292    # Default element name.
293    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
294                                 DEFAULT_ELEMENT_LOCAL_NAME, 
295                                 SAMLConstants.SAML20_PREFIX)
296   
297    # Local name of the XSI type.
298    TYPE_LOCAL_NAME = "AttributeStatementType" 
299       
300    # QName of the XSI type.
301    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
302                      TYPE_LOCAL_NAME, 
303                      SAMLConstants.SAML20_PREFIX)
304   
305    __slots__ = ('__attributes', '__encryptedAttributes')
306   
307    def __init__(self, **kw):
308        """
309        @param **kw: keywords Statement parent class instantiation
310        @type **kw: dict
311        """
312        super(AttributeStatement, self).__init__(**kw)
313       
314        self.__attributes = TypedList(Attribute)
315        self.__encryptedAttributes = TypedList(Attribute)
316
317    def __getstate__(self):
318        '''Enable pickling
319       
320        @return: object's attribute dictionary
321        @rtype: dict
322        '''
323
324        _dict = super(AttributeStatement, self).__getstate__()
325        for attrName in AttributeStatement.__slots__:
326            # Ugly hack to allow for derived classes setting private member
327            # variables
328            if attrName.startswith('__'):
329                attrName = "_AttributeStatement" + attrName
330               
331            _dict[attrName] = getattr(self, attrName)
332           
333        return _dict
334
335    def _get_attributes(self):
336        '''@return: the attributes expressed in this statement
337        @rtype: ndg.saml.utils.TypedList
338        '''
339        return self.__attributes
340
341    attributes = property(fget=_get_attributes)
342   
343    def _get_encryptedAttributes(self):
344       '''@return: the encrypted attribtues expressed in this statement
345       @rtype: ndg.saml.utils.TypedList
346       '''
347       return self.__encryptedAttributes
348   
349    encryptedAttributes = property(fget=_get_encryptedAttributes)
350
351
352class AuthnStatement(Statement):
353    '''SAML 2.0 Core AuthnStatement.  Currently implemented in abstract form
354    only
355   
356    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name
357    @type DEFAULT_ELEMENT_LOCAL_NAME: string
358    @cvar DEFAULT_ELEMENT_NAME: Default element name
359    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
360    @cvar TYPE_LOCAL_NAME: Local name of the XSI type
361    @type TYPE_LOCAL_NAME: string
362    @cvar TYPE_NAME: QName of the XSI type
363    @type TYPE_NAME: ndg.saml.common.xml.QName
364    @cvar AUTHN_INSTANT_ATTRIB_NAME: AuthnInstant attribute name
365    @type AUTHN_INSTANT_ATTRIB_NAME: string
366    @cvar SESSION_INDEX_ATTRIB_NAME: SessionIndex attribute name
367    @type SESSION_INDEX_ATTRIB_NAME: string
368    @cvar SESSION_NOT_ON_OR_AFTER_ATTRIB_NAME: SessionNoOnOrAfter attribute name
369    @type SESSION_NOT_ON_OR_AFTER_ATTRIB_NAME: string
370    '''
371
372    # Element local name
373    DEFAULT_ELEMENT_LOCAL_NAME = "AuthnStatement"
374
375    # Default element name
376    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
377                                 DEFAULT_ELEMENT_LOCAL_NAME,
378                                 SAMLConstants.SAML20_PREFIX)
379
380    # Local name of the XSI type
381    TYPE_LOCAL_NAME = "AuthnStatementType"
382
383    # QName of the XSI type
384    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
385                      TYPE_LOCAL_NAME,
386                      SAMLConstants.SAML20_PREFIX)
387
388    # AuthnInstant attribute name
389    AUTHN_INSTANT_ATTRIB_NAME = "AuthnInstant"
390
391    # SessionIndex attribute name
392    SESSION_INDEX_ATTRIB_NAME = "SessionIndex"
393
394    # SessionNoOnOrAfter attribute name
395    SESSION_NOT_ON_OR_AFTER_ATTRIB_NAME = "SessionNotOnOrAfter"
396   
397    __slots__ = ()
398   
399    def _getAuthnInstant(self):
400        '''Abstract method.  Gets the time when the authentication took place.
401       
402        @return: the time when the authentication took place
403        @rtype: datetime.datetime
404        @raise NotImplementedError: abstract method
405        '''
406        raise NotImplementedError()
407
408    def _setAuthnInstant(self, value):
409        '''Sets the time when the authentication took place.
410       
411        @param value: the time when the authentication took place
412        @type: datetime.datetime
413        @raise NotImplementedError: abstract method
414        '''
415        raise NotImplementedError()
416
417    def _getSessionIndex(self):
418        '''Get the session index between the principal and the authenticating
419        authority.
420       
421        @return: the session index between the principal and the authenticating
422        authority
423        @rtype: ?
424        @raise NotImplementedError: abstract method
425        '''
426        raise NotImplementedError()
427
428    def _setSessionIndex(self, value):
429        '''Sets the session index between the principal and the authenticating
430        authority.
431       
432        @param value: the session index between the principal and the
433        authenticating authority
434        @type: ?
435        @raise NotImplementedError: abstract method
436        '''
437        raise NotImplementedError()
438
439    def _getSessionNotOnOrAfter(self):
440        '''Get the time when the session between the principal and the SAML
441        authority ends.
442       
443        @return: the time when the session between the principal and the SAML
444        authority ends
445        @rtype: datetime.datetime
446        @raise NotImplementedError: abstract method
447        '''
448        raise NotImplementedError()
449
450    def _setSessionNotOnOrAfter(self, value):
451        '''Set the time when the session between the principal and the SAML
452        authority ends.
453       
454        @param value: the time when the session between the
455        principal and the SAML authority ends
456        @type: datetime.datetime
457        @raise NotImplementedError: abstract method
458        '''
459        raise NotImplementedError()
460
461    def _getSubjectLocality(self):
462        '''Get the DNS domain and IP address of the system where the principal
463        was authenticated.
464       
465        @return: the DNS domain and IP address of the system where the principal
466        was authenticated
467        @rtype: ?
468        @raise NotImplementedError: abstract method
469        '''
470        raise NotImplementedError()
471
472    def _setSubjectLocality(self, value):
473        '''Set the DNS domain and IP address of the system where the principal
474        was authenticated.
475       
476        @param value: the DNS domain and IP address of the system where
477        the principal was authenticated
478        @type: ?
479        @raise NotImplementedError: abstract method
480        '''
481        raise NotImplementedError()
482
483    def _getAuthnContext(self):
484        '''Gets the context used to authenticate the subject.
485       
486        @return: the context used to authenticate the subject
487        @type: ?
488        @raise NotImplementedError: abstract method
489        '''
490        raise NotImplementedError()
491
492    def _setAuthnContext(self, value):
493        '''Sets the context used to authenticate the subject.
494       
495        @param value: the context used to authenticate the subject
496        @type: ?
497        @raise NotImplementedError: abstract method
498        '''
499        raise NotImplementedError()
500
501
502class DecisionType(object):
503    """Define decision types for the authorisation decisions
504       
505    @cvar PERMIT_STR: "Permit" decision type
506    @type PERMIT_STR: string
507    @cvar DENY_STR: "Deny" decision type
508    @type DENY_STR: string
509    @cvar INDETERMINATE_STR: "Indeterminate" decision type
510    @type INDETERMINATE_STR: string
511    @cvar TYPES: Permissable type strings
512    @type TYPES: string
513
514    @cvar PERMIT: permit as a decision type subclass
515    @type PERMIT: ndg.saml.saml2.core.PermitDecisionType
516    @cvar DENY: deny as a decision type subclass
517    @type DENY: ndg.saml.saml2.core.DenyDecisionType
518    @cvar INDETERMINATE: indeterminate as a decision type subclass
519    @type INDETERMINATE: ndg.saml.saml2.core.IndeterminateDecisionType
520   
521    @ivar __value: decision value
522    @type __value: string
523    """
524   
525    # "Permit" decision type
526    PERMIT_STR = "Permit"
527   
528    # "Deny" decision type
529    DENY_STR = "Deny"
530   
531    # "Indeterminate" decision type
532    INDETERMINATE_STR = "Indeterminate"
533   
534    # Permissable type strings
535    TYPES = (PERMIT_STR, DENY_STR, INDETERMINATE_STR)
536   
537    __slots__ = ('__value',)
538   
539    def __init__(self, decisionType):
540        '''@param decisionType: decision value
541        @type decisionType: string/ndg.saml.saml2.core.DecisionType
542        '''
543        self.__value = None
544        self.value = decisionType
545
546    def __getstate__(self):
547        '''Enable pickling
548       
549        @return: object's attribute dictionary
550        @rtype: dict
551        '''
552
553        _dict = {}
554        for attrName in DecisionType.__slots__:
555            # Ugly hack to allow for derived classes setting private member
556            # variables
557            if attrName.startswith('__'):
558                attrName = "_DecisionType" + attrName
559               
560            _dict[attrName] = getattr(self, attrName)
561           
562        return _dict
563 
564    def __setstate__(self, attrDict):
565        '''Enable pickling
566       
567        @param attrDict: object's attribute dictionary
568        @type attrDict: dict
569        '''
570        for attrName, val in attrDict.items():
571            setattr(self, attrName, val)
572           
573    def _setValue(self, value):
574        '''Set decision type
575        @param value: decision value
576        @type value: string/ndg.saml.saml2.core.DecisionType
577        '''
578        if isinstance(value, DecisionType):
579            # Cast to string
580            value = str(value)
581           
582        elif not isinstance(value, basestring):
583            raise TypeError('Expecting string or DecisionType instance for '
584                            '"value" attribute; got %r instead' % type(value))
585           
586        if value not in self.__class__.TYPES:
587            raise AttributeError('Permissable decision types are %r; got '
588                                 '%r instead' % (DecisionType.TYPES, value))
589        self.__value = value
590       
591    def _getValue(self):
592        '''Get decision type
593        @return: decision value
594        @rtype: string/ndg.saml.saml2.core.DecisionType
595        '''
596        return self.__value
597   
598    value = property(fget=_getValue, fset=_setValue, doc="Decision value")
599   
600    def __str__(self):
601        '''Representation of decision type as a string
602        @return: decision value
603        @rtype: string
604        '''
605        return self.__value
606
607    def __eq__(self, decision):
608        """Test for equality against an input decision type
609       
610        @param version: decision type
611        @type version: ndg.saml.saml2.core.DecisionType or basestring
612        @return: True if input and this object match
613        @rtype: bool
614        @raise TypeError: unexpected type for decision type input
615        """
616        if isinstance(decision, DecisionType):
617            # Cast to string
618            value = decision.value
619           
620        elif isinstance(decision, basestring):
621            value = decision
622           
623        else:
624            raise TypeError('Expecting string or DecisionType instance for '
625                            'input decision value; got %r instead' % 
626                            type(value))
627           
628        if value not in self.__class__.TYPES:
629            raise AttributeError('Permissable decision types are %r; got '
630                                 '%r instead' % (DecisionType.TYPES, value))
631           
632        return self.__value == value
633
634
635class PermitDecisionType(DecisionType):
636    """Permit authorisation Decision"""
637    __slots__ = ()
638
639    def __init__(self):
640        """Initialise with permit decision setting"""
641        super(PermitDecisionType, self).__init__(DecisionType.PERMIT_STR)
642       
643    def _setValue(self):
644        """
645        @raise AttributeError: instances have read only decision type
646        """ 
647        raise AttributeError("can't set attribute")
648
649
650class DenyDecisionType(DecisionType):
651    """Deny authorisation Decision"""
652    __slots__ = ()
653   
654    def __init__(self):
655        """Initialise with deny decision setting"""
656        super(DenyDecisionType, self).__init__(DecisionType.DENY_STR)
657       
658    def _setValue(self, value): 
659        """
660        @raise AttributeError: instances have read only decision type
661        """ 
662        raise AttributeError("can't set attribute")
663
664
665class IndeterminateDecisionType(DecisionType):
666    """Indeterminate authorisation Decision"""
667    __slots__ = ()
668   
669    def __init__(self):
670        """Initialise with indeterminate decision setting"""
671        super(IndeterminateDecisionType, self).__init__(
672                                            DecisionType.INDETERMINATE_STR)
673       
674    def _setValue(self, value): 
675        """
676        @raise AttributeError: instances have read only decision type
677        """ 
678        raise AttributeError("can't set attribute")
679
680# Add instances of each for convenience
681DecisionType.PERMIT = PermitDecisionType()
682DecisionType.DENY = DenyDecisionType()
683DecisionType.INDETERMINATE = IndeterminateDecisionType()
684
685
686class AuthzDecisionStatement(Statement):
687    '''SAML 2.0 Core AuthzDecisionStatement.  Currently implemented in abstract
688    form only
689
690    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name
691    @type DEFAULT_ELEMENT_LOCAL_NAME: string
692    @cvar DEFAULT_ELEMENT_NAME: Default element name
693    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
694    @cvar TYPE_LOCAL_NAME: Local name of the XSI type
695    @type TYPE_LOCAL_NAME: string
696    @cvar TYPE_NAME: QName of the XSI type
697    @type TYPE_NAME: ndg.saml.common.xml.QName
698    @cvar RESOURCE_ATTRIB_NAME: Resource attribute name
699    @type RESOURCE_ATTRIB_NAME: string
700    @cvar DECISION_ATTRIB_NAME: Decision attribute name
701    @type DECISION_ATTRIB_NAME: string
702   
703    @ivar __resource: identifier for the resource which is the subject of the
704    authorisation statement
705    @type __resource: basestring
706    @ivar __decision: decision type for this authorisation statement
707    @type __decision: ndg.saml.saml2.core.DecisionType
708    @ivar __actions: list of ndg.saml.saml2.core.Action elements
709    @type __actions: ndg.saml.utils.TypedList
710    @ivar __evidence: evidence (not currently implemented)
711    @type __evidence: None
712    @ivar __normalizeResource: set to True to normalize the URI object attribute
713    in the set property method (functionality likely to be deprecated)
714    @type __normalizeResource: bool
715    @ivar __safeNormalizationChars: acceptable characters for normalizing URIs
716    (functionality likely to be deprecated)
717    @type __safeNormalizationChars: string
718    '''
719   
720    # Element local name
721    DEFAULT_ELEMENT_LOCAL_NAME = "AuthzDecisionStatement"
722
723    # Default element name
724    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
725                                 DEFAULT_ELEMENT_LOCAL_NAME,
726                                 SAMLConstants.SAML20_PREFIX)
727
728    # Local name of the XSI type
729    TYPE_LOCAL_NAME = "AuthzDecisionStatementType"
730
731    # QName of the XSI type
732    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
733                      TYPE_LOCAL_NAME,
734                      SAMLConstants.SAML20_PREFIX)
735
736    # Resource attribute name
737    RESOURCE_ATTRIB_NAME = "Resource"
738
739    # Decision attribute name
740    DECISION_ATTRIB_NAME = "Decision"
741   
742    __slots__ = (
743        '__resource', 
744        '__decision', 
745        '__actions', 
746        '__evidence',
747        '__normalizeResource',
748        '__safeNormalizationChars'
749    )
750   
751    def __init__(self, 
752                 normalizeResource=True, 
753                 safeNormalizationChars='/%',
754                 **kw):
755        '''Create new authorisation decision statement
756        @param normalizeResource: set to True to normalize the URI object
757        attribute in the set property method (functionality likely to be
758        deprecated)
759        @type normalizeResource: bool
760        @param safeNormalizationChars: acceptable characters for normalizing
761        URIs (functionality likely to be deprecated)
762        @type safeNormalizationChars: string
763        @param **kw: keywords for the initialisation of the parent classes'
764        attributes
765        @type **kw: dict
766        '''
767        super(AuthzDecisionStatement, self).__init__(**kw)
768
769        # Resource attribute value.
770        self.__resource = None 
771       
772        self.__decision = DecisionType.INDETERMINATE   
773        self.__actions = TypedList(Action)
774        self.__evidence = None
775       
776        # Tuning for normalization of resource URIs in property set method
777        self.normalizeResource = normalizeResource
778        self.safeNormalizationChars = safeNormalizationChars
779
780    def __getstate__(self):
781        '''Enable pickling
782       
783        @return: object's attribute dictionary
784        @rtype: dict
785        '''
786
787        _dict = super(AuthzDecisionStatement, self).__getstate__()
788        for attrName in AuthzDecisionStatement.__slots__:
789            # Ugly hack to allow for derived classes setting private member
790            # variables
791            if attrName.startswith('__'):
792                attrName = "_AuthzDecisionStatement" + attrName
793               
794            _dict[attrName] = getattr(self, attrName)
795           
796        return _dict
797   
798    def _getNormalizeResource(self):
799        '''Get normalise resource flag
800        @return: flag value
801        @rtype: bool       
802        '''
803        return self.__normalizeResource
804
805    def _setNormalizeResource(self, value):
806        '''Set normalise resource flag
807        @param value: flag value
808        @type value: bool
809        @raise TypeError: input value is incorrect type
810        '''
811        if not isinstance(value, bool):
812            raise TypeError('Expecting bool type for "normalizeResource" '
813                            'attribute; got %r instead' % type(value))
814           
815        self.__normalizeResource = value
816
817    normalizeResource = property(_getNormalizeResource, 
818                                 _setNormalizeResource, 
819                                 doc="Flag to normalize new resource value "
820                                     "assigned to the \"resource\" property.  "
821                                     "The setting only applies for URIs "
822                                     'beginning with "http://" or "https://"')
823
824    def _getSafeNormalizationChars(self):
825        '''Get normalisation safe chars
826        @return: normalisation safe chars
827        @rtype value: basetring
828        '''
829        return self.__safeNormalizationChars
830
831    def _setSafeNormalizationChars(self, value):
832        '''Set normalisation safe chars
833        @param value: normalisation safe chars
834        @type value: basetring
835        @raise TypeError: input value is incorrect type
836        '''
837        if not isinstance(value, basestring):
838            raise TypeError('Expecting string type for "normalizeResource" '
839                            'attribute; got %r instead' % type(value))
840           
841        self.__safeNormalizationChars = value
842
843    safeNormalizationChars = property(_getSafeNormalizationChars, 
844                                      _setSafeNormalizationChars, 
845                                      doc="String containing a list of "
846                                          "characters that should not be "
847                                          "converted when Normalizing the "
848                                          "resource URI.  These are passed to "
849                                          "urllib.quote when the resource "
850                                          "property is set.  The default "
851                                          "characters are '/%'")
852
853    def _getResource(self):
854        '''Gets the Resource attrib value of this statement.
855
856        @return: the Resource attrib value of this statement
857        @rtype: basestring
858        '''
859        return self.__resource
860   
861    def _setResource(self, value):
862        '''Sets the Resource attrib value of this statement normalizing the path
863        component, removing spurious port numbers (80 for HTTP and 443 for
864        HTTPS) and converting the host component to lower case.
865       
866        @param value: the new Resource attrib value of this statement
867        @type: basestring
868        @raise TypeError: input value is incorrect type
869        '''
870        if not isinstance(value, basestring):
871            raise TypeError('Expecting string type for "resource" attribute; '
872                            'got %r instead' % type(value))
873       
874        if (self.normalizeResource and 
875            value.startswith('http://') or value.startswith('https://')):
876            # Normalise the path, set the host name to lower case and remove
877            # port redundant numbers 80 and 443
878            splitResult = urlsplit(value)
879            uriComponents = list(splitResult)
880           
881            # hostname attribute is lowercase
882            uriComponents[1] = splitResult.hostname
883           
884            if splitResult.port is not None:
885                isHttpWithStdPort = (splitResult.port == 80 and 
886                                     splitResult.scheme == 'http')
887               
888                isHttpsWithStdPort = (splitResult.port == 443 and
889                                      splitResult.scheme == 'https')
890               
891                if not isHttpWithStdPort and not isHttpsWithStdPort:
892                    uriComponents[1] += ":%d" % splitResult.port
893           
894            uriComponents[2] = urllib.quote(splitResult.path, 
895                                            self.safeNormalizationChars)
896           
897            self.__resource = urlunsplit(uriComponents)
898        else:
899            self.__resource = value
900   
901    resource = property(fget=_getResource, fset=_setResource,
902                        doc="Resource for which authorisation was requested")
903
904    def _getDecision(self):
905        '''
906        Gets the decision of the authorization request.
907       
908        @return: the decision of the authorization request
909        '''
910        return self.__decision
911
912    def _setDecision(self, value):
913        '''
914        Sets the decision of the authorization request.
915       
916        @param value: the decision of the authorization request
917        @raise TypeError: input value is incorrect type
918        '''
919        if not isinstance(value, DecisionType):
920            raise TypeError('Expecting %r type for "decision" attribute; '
921                            'got %r instead' % (DecisionType, type(value)))
922        self.__decision = value
923
924    decision = property(_getDecision, _setDecision, 
925                        doc="Authorization decision as a DecisionType instance")
926   
927    @property
928    def actions(self):
929        '''The actions for which authorisation is requested
930       
931        @return: the Actions of this statement
932        @rtype: TypedList
933        '''
934        return self.__actions
935   
936    def _getEvidence(self):
937        '''Gets the Evidence of this statement.  Evidence attribute
938        functionality is not currently implemented in this class
939
940        @return: the Evidence of this statement
941        @rtype: None'''
942        return self.__evidence
943
944    def _setEvidence(self, value):
945        '''Sets the Evidence of this statement.  Evidence attribute
946        functionality is not currently implemented in this class
947       
948        @param value: the new Evidence of this statement
949        @type value: None
950        @raise TypeError: input value is incorrect type
951        '''
952        if not isinstance(value, Evidence):
953            raise TypeError('Expecting Evidence type for "evidence" '
954                            'attribute; got %r' % type(value))
955
956        self.__evidence = value 
957
958    evidence = property(fget=_getEvidence, fset=_setEvidence, 
959                        doc="A set of assertions which the Authority may use "
960                            "to base its authorisation decision on")
961   
962    def getOrderedChildren(self):
963        """Get ordered children
964        @return: list actions and evidence for this statement
965        @rtype: tuple
966        """
967        children = []
968
969        superChildren = super(AuthzDecisionStatement, self).getOrderedChildren()
970        if superChildren:
971            children.extend(superChildren)
972
973        children.extend(self.__actions)
974       
975        if self.__evidence is not None:
976            children.extend(self.__evidence)
977
978        if len(children) == 0:
979            return None
980
981        return tuple(children)
982       
983
984class Subject(SAMLObject):
985    '''Implementation of SAML 2.0 Subject
986   
987    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
988    @type DEFAULT_ELEMENT_LOCAL_NAME: string
989    @cvar DEFAULT_ELEMENT_NAME: Default element name.
990    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
991    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
992    @type TYPE_LOCAL_NAME: string
993    @cvar TYPE_NAME: QName of the XSI type.
994    @type TYPE_NAME: ndg.saml.common.xml.QName
995   
996    @ivar __baseID: base identifier
997    @type __baseID: basestring
998    @ivar __nameID: name identifier
999    @type __nameID: basestring
1000    @ivar __encryptedID: encrypted identifier
1001    @type __encryptedID: any - not implemented for type checking
1002    @ivar __subjectConfirmations: list of subject confirmations
1003    @type __subjectConfirmations: list
1004    '''
1005   
1006    # Element local name.
1007    DEFAULT_ELEMENT_LOCAL_NAME = "Subject"
1008
1009    # Default element name.
1010    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1011                                 DEFAULT_ELEMENT_LOCAL_NAME,
1012                                 SAMLConstants.SAML20_PREFIX)
1013
1014    # Local name of the XSI type.
1015    TYPE_LOCAL_NAME = "SubjectType"
1016
1017    # QName of the XSI type.
1018    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1019                      TYPE_LOCAL_NAME,
1020                      SAMLConstants.SAML20_PREFIX)
1021   
1022    __slots__ = (
1023        '__baseID',
1024        '__nameID',
1025        '__encryptedID',
1026        '__subjectConfirmations'
1027    )
1028   
1029    def __init__(self, **kw):
1030        '''
1031        @param **kw: keywords for initialisation of parent class attributes
1032        @type **kw: dict
1033        '''
1034        super(Subject, self).__init__(**kw)
1035       
1036        # BaseID child element.
1037        self.__baseID = None
1038   
1039        # NameID child element.
1040        self.__nameID = None
1041   
1042        # EncryptedID child element.
1043        self.__encryptedID = None
1044   
1045        # Subject Confirmations of the Subject.
1046        self.__subjectConfirmations = []
1047
1048    def __getstate__(self):
1049        '''Enable pickling
1050       
1051        @return: object's attribute dictionary
1052        @rtype: dict
1053        '''
1054        _dict = super(Subject, self).__getstate__()
1055        for attrName in Subject.__slots__:
1056            # Ugly hack to allow for derived classes setting private member
1057            # variables
1058            if attrName.startswith('__'):
1059                attrName = "_Subject" + attrName
1060               
1061            _dict[attrName] = getattr(self, attrName)
1062           
1063        return _dict
1064   
1065    def _getBaseID(self): 
1066        """Get base identifier
1067        @return: base identifier
1068        @rtype: basestring
1069        """ 
1070        return self.__baseID
1071
1072    def _setBaseID(self, value):
1073        """Set base identifier
1074        @param: base identifier
1075        @type: basestring
1076        @raise TypeError: invalid input value type
1077        """ 
1078        if not isinstance(value, basestring):
1079            raise TypeError("Expecting %r type for \"baseID\" got %r" %
1080                            (basestring, value.__class__))
1081        self.__baseID = value
1082
1083    baseID = property(fget=_getBaseID, 
1084                      fset=_setBaseID, 
1085                      doc="Base identifier")
1086     
1087    def _getNameID(self):
1088        """Get name identifier
1089        @return: name identifier
1090        @rtype: basestring
1091        """ 
1092        return self.__nameID
1093   
1094    def _setNameID(self, value):
1095        """Set name identifier
1096        @param: name identifier
1097        @type: basestring
1098        @raise TypeError: invalid input value type
1099        """ 
1100        if not isinstance(value, NameID):
1101            raise TypeError("Expecting %r type for \"nameID\" got %r" %
1102                            (NameID, type(value)))
1103        self.__nameID = value
1104
1105    nameID = property(fget=_getNameID, 
1106                      fset=_setNameID, 
1107                      doc="Name identifier")
1108   
1109    def _getEncryptedID(self):
1110        """Get encrypted identifier
1111        @return: encrypted identifier
1112        @rtype: basestring
1113        """ 
1114        return self.__encryptedID
1115   
1116    def _setEncryptedID(self, value): 
1117        """Set encrypted identifier
1118       
1119        @param: encrypted identifier
1120        @type: any type
1121        @raise TypeError: invalid input value type
1122        """ 
1123        self.__encryptedID = value
1124
1125    encryptedID = property(fget=_getEncryptedID, 
1126                           fset=_setEncryptedID, 
1127                           doc="EncryptedID's Docstring")
1128   
1129    def _getSubjectConfirmations(self): 
1130        """Get list of subject confirmations
1131        @return: list of subject confirmations
1132        @rtype: list
1133        """ 
1134        return self.__subjectConfirmations
1135
1136    subjectConfirmations = property(fget=_getSubjectConfirmations, 
1137                                    doc="Subject Confirmations")   
1138   
1139    def getOrderedChildren(self): 
1140        """Get list containing base, name and encrypted IDs and the subject
1141        confirmations
1142       
1143        @return: list of all child attributes
1144        @rtype: list
1145        """ 
1146        children = []
1147
1148        if self.baseID is not None:
1149            children.append(self.baseID)
1150       
1151        if self.nameID is not None: 
1152            children.append(self.nameID)
1153       
1154        if self.encryptedID is not None: 
1155            children.append(self.encryptedID)
1156       
1157        children += self.subjectConfirmations
1158
1159        return tuple(children)
1160
1161
1162class AbstractNameIDType(SAMLObject):
1163    '''Abstract implementation of NameIDType
1164   
1165    @cvar SP_NAME_QUALIFIER_ATTRIB_NAME: SPNameQualifier attribute name.
1166    @type SP_NAME_QUALIFIER_ATTRIB_NAME: string
1167    @cvar FORMAT_ATTRIB_NAME: Format attribute name.
1168    @type FORMAT_ATTRIB_NAME: string
1169    @cvar SPPROVIDED_ID_ATTRIB_NAME: SPProviderID attribute name.
1170    @type SPPROVIDED_ID_ATTRIB_NAME: string
1171    @cvar UNSPECIFIED: URI for unspecified name format.
1172    @type UNSPECIFIED: string
1173    @cvar EMAIL: URI for email name format.
1174    @type EMAIL: string
1175    @cvar X509_SUBJECT: URI for X509 subject name format.
1176    @type X509_SUBJECT: string
1177    @cvar WIN_DOMAIN_QUALIFIED: URI for windows domain qualified name name
1178    format.
1179    @type WIN_DOMAIN_QUALIFIED: string
1180    @cvar KERBEROS: URI for kerberos name format.
1181    @type KERBEROS: string
1182    @cvar ENTITY: URI for SAML entity name format.
1183    @type ENTITY: string
1184    @cvar PERSISTENT: URI for persistent name format.
1185    @type PERSISTENT: string
1186    @cvar TRANSIENT: URI for transient name format.
1187    @type TRANSIENT: string
1188    @cvar ENCRYPTED: Special URI used by NameIDPolicy to indicate a NameID
1189    should be encrypted
1190    @type ENCRYPTED: string
1191
1192    @ivar __name: Name of the Name ID.
1193    @type __name: string
1194    @ivar __nameQualifier: Name Qualifier of the Name ID.
1195    @type __nameQualifier: string
1196    @ivar __spNameQualifier: SP Name Qualifier of the Name ID.
1197    @type __spNameQualifier: string
1198    @ivar __format: Format of the Name ID.
1199    @type __format: string
1200    @ivar __spProvidedID: SP ProvidedID of the NameID.
1201    @type __spProvidedID: string
1202    '''
1203
1204    # SPNameQualifier attribute name.
1205    SP_NAME_QUALIFIER_ATTRIB_NAME = "SPNameQualifier"
1206
1207    # Format attribute name.
1208    FORMAT_ATTRIB_NAME = "Format"
1209
1210    # SPProviderID attribute name.
1211    SPPROVIDED_ID_ATTRIB_NAME = "SPProvidedID"
1212
1213    # URI for unspecified name format.
1214    UNSPECIFIED = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
1215
1216    # URI for email name format.
1217    EMAIL = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
1218
1219    # URI for X509 subject name format.
1220    X509_SUBJECT = "urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName"
1221
1222    # URI for windows domain qualified name name format.
1223    WIN_DOMAIN_QUALIFIED = \
1224        "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName"
1225
1226    # URI for kerberos name format.
1227    KERBEROS = "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos"
1228
1229    # URI for SAML entity name format.
1230    ENTITY = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
1231
1232    # URI for persistent name format.
1233    PERSISTENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
1234
1235    # URI for transient name format.
1236    TRANSIENT = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
1237
1238    # Special URI used by NameIDPolicy to indicate a NameID should be encrypted
1239    ENCRYPTED = "urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted"
1240   
1241    __slots__ = (
1242        '__name',
1243        '__nameQualifier',
1244        '__spNameQualifier',
1245        '__format',
1246        '__spProvidedID',
1247        '__value'
1248    )
1249   
1250    def __init__(self, **kw): 
1251        '''
1252        @param **kw: keywords to set attributes of parent class
1253        @type **kw: dict
1254        '''
1255        super(AbstractNameIDType, self).__init__(**kw)
1256   
1257        # Name of the Name ID.
1258        self.__name = None
1259       
1260        # Name Qualifier of the Name ID.
1261        self.__nameQualifier = None
1262   
1263        # SP Name Qualifier of the Name ID.
1264        self.__spNameQualifier = None
1265   
1266        # Format of the Name ID.
1267        self.__format = None
1268   
1269        # SP ProvidedID of the NameID.
1270        self.__spProvidedID = None
1271
1272        self.__value = None
1273
1274    def __getstate__(self):
1275        '''Enable pickling
1276       
1277        @return: object's attribute dictionary
1278        @rtype: dict
1279        '''
1280
1281        _dict = super(AbstractNameIDType, self).__getstate__()
1282        for attrName in AbstractNameIDType.__slots__:
1283            # Ugly hack to allow for derived classes setting private member
1284            # variables
1285            if attrName.startswith('__'):
1286                attrName = "_AbstractNameIDType" + attrName
1287               
1288            _dict[attrName] = getattr(self, attrName)
1289           
1290        return _dict
1291             
1292    def _getValue(self):
1293        """Get name value
1294        @return: name value
1295        @rtype: string
1296        """
1297        return self.__value
1298       
1299    def _setValue(self, value):
1300        """Set name value
1301        @param: name value
1302        @type: string
1303        @raise TypeError: invalid input value type
1304        """
1305        if not isinstance(value, basestring):
1306            raise TypeError("\"value\" must be a basestring derived type, "
1307                            "got %r" % value.__class__)
1308           
1309        self.__value = value
1310
1311    value = property(fget=_getValue, fset=_setValue, doc="string value") 
1312   
1313    def _getNameQualifier(self): 
1314        """Get name qualifier
1315        @return: name qualifier
1316        @rtype: string
1317        """
1318        return self.__nameQualifier
1319   
1320    def _setNameQualifier(self, value): 
1321        """Set name qualifier
1322        @param: name qualifier
1323        @type: string
1324        """
1325        self.__nameQualifier = value
1326
1327    nameQualifier = property(fget=_getNameQualifier, 
1328                             fset=_setNameQualifier, 
1329                             doc="Name qualifier")   
1330
1331    def _getSPNameQualifier(self): 
1332        """Get SP name qualifier
1333        @return: SP name qualifier
1334        @rtype: string
1335        """
1336        return self.__spNameQualifier
1337   
1338    def _setSPNameQualifier(self, value): 
1339        """Set SP name qualifier
1340        @param: SP name qualifier
1341        @type: string
1342        """
1343        self.__spNameQualifier = value
1344
1345    spNameQualifier = property(fget=_getSPNameQualifier, 
1346                               fset=_setSPNameQualifier, 
1347                               doc="SP Name qualifier")   
1348   
1349    def _getFormat(self):
1350        """Get name format
1351        @return: name format
1352        @rtype: string
1353        """
1354        return self.__format
1355       
1356    def _setFormat(self, format):
1357        """Set name format
1358        @param: name format
1359        @type: string
1360        @raise TypeError: invalid input value type
1361        """
1362        if not isinstance(format, basestring):
1363            raise TypeError("\"format\" must be a basestring derived type, "
1364                            "got %r" % format.__class__)
1365           
1366        self.__format = format
1367
1368    format = property(fget=_getFormat, fset=_setFormat, doc="Name format") 
1369   
1370    def _getSPProvidedID(self): 
1371        """Get SP provided identifier
1372        @return: SP provided identifier
1373        @rtype: string
1374        """
1375        return self.__spProvidedID
1376   
1377    def _setSPProvidedID(self, value): 
1378        """Set SP provided identifier
1379        @param: SP provided identifier
1380        @type: string
1381        """
1382        self.__spProvidedID = value
1383
1384    spProvidedID = property(fget=_getSPProvidedID, fset=_setSPProvidedID, 
1385                            doc="SP Provided Identifier") 
1386   
1387    def getOrderedChildren(self): 
1388        """Get attributes as a list - not currently implemented
1389        @return: list of object attribute values
1390        @rtype: tuple
1391        @raise NotImplementedError: not implemented in this version
1392        """
1393        raise NotImplementedError()
1394
1395   
1396class Issuer(AbstractNameIDType):
1397    """SAML 2.0 Core Issuer type
1398   
1399    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
1400    @type DEFAULT_ELEMENT_LOCAL_NAME: string
1401    @cvar DEFAULT_ELEMENT_NAME: Default element name.
1402    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
1403    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
1404    @type TYPE_LOCAL_NAME: string
1405    @cvar TYPE_NAME: Qualified Name of the XSI type.
1406    @type TYPE_NAME: ndg.saml.common.xml.QName
1407    """
1408   
1409    # Element local name.
1410    DEFAULT_ELEMENT_LOCAL_NAME = "Issuer"
1411
1412    # Default element name.
1413    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1414                                 DEFAULT_ELEMENT_LOCAL_NAME,
1415                                 SAMLConstants.SAML20_PREFIX)
1416
1417    # Local name of the XSI type.
1418    TYPE_LOCAL_NAME = "IssuerType"
1419
1420    # QName of the XSI type.
1421    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1422                      TYPE_LOCAL_NAME,
1423                      SAMLConstants.SAML20_PREFIX) 
1424   
1425    __slots__ = ()
1426
1427     
1428class NameID(AbstractNameIDType):
1429    '''SAML 2.0 Core NameID
1430    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
1431    @type DEFAULT_ELEMENT_LOCAL_NAME: string
1432    @cvar DEFAULT_ELEMENT_NAME: Default element name.
1433    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
1434    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
1435    @type TYPE_LOCAL_NAME: string
1436    @cvar TYPE_NAME: Qualified Name of the XSI type.
1437    @type TYPE_NAME: ndg.saml.common.xml.QName
1438    '''
1439   
1440    # Element local name.
1441    DEFAULT_ELEMENT_LOCAL_NAME = "NameID"
1442
1443    # Default element name.
1444    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1445                                 DEFAULT_ELEMENT_LOCAL_NAME,
1446                                 SAMLConstants.SAML20_PREFIX)
1447
1448    # Local name of the XSI type.
1449    TYPE_LOCAL_NAME = "NameIDType"
1450
1451    # QName of the XSI type.
1452    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1453                      TYPE_LOCAL_NAME,
1454                      SAMLConstants.SAML20_PREFIX)
1455   
1456    __slots__ = ()
1457   
1458
1459class Conditions(SAMLObject): 
1460    '''SAML 2.0 Core Conditions.
1461   
1462    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
1463    @type DEFAULT_ELEMENT_LOCAL_NAME: string
1464    @cvar DEFAULT_ELEMENT_NAME: Default element name.
1465    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
1466    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
1467    @type TYPE_LOCAL_NAME: string
1468    @cvar TYPE_NAME: Qualified Name of the XSI type.
1469    @type TYPE_NAME: ndg.saml.common.xml.QName
1470    @cvar NOT_BEFORE_ATTRIB_NAME: NotBefore attribute name.
1471    @type NOT_BEFORE_ATTRIB_NAME: string
1472    @cvar NOT_ON_OR_AFTER_ATTRIB_NAME: NotOnOrAfter attribute name.
1473    @type NOT_ON_OR_AFTER_ATTRIB_NAME: string
1474   
1475    @ivar self.__conditions: A list of Conditions.
1476    @type self.__conditions: list
1477    @ivar self.__notBefore: Not Before condition
1478    @type self.__notBefore: NoneType / datetime.datetime
1479    @ivar self.__notOnOrAfter: Not On Or After conditions.
1480    @type self.__notOnOrAfter: NoneType / datetime.datetime
1481    '''
1482   
1483    # Element local name.
1484    DEFAULT_ELEMENT_LOCAL_NAME = "Conditions"
1485
1486    # Default element name.
1487    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1488                                 DEFAULT_ELEMENT_LOCAL_NAME,
1489                                 SAMLConstants.SAML20_PREFIX)
1490
1491    # Local name of the XSI type.
1492    TYPE_LOCAL_NAME = "ConditionsType"
1493
1494    # QName of the XSI type.
1495    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1496                      TYPE_LOCAL_NAME,
1497                      SAMLConstants.SAML20_PREFIX)
1498
1499    # NotBefore attribute name.
1500    NOT_BEFORE_ATTRIB_NAME = "NotBefore"
1501
1502    # NotOnOrAfter attribute name.
1503    NOT_ON_OR_AFTER_ATTRIB_NAME = "NotOnOrAfter"
1504
1505    __slots__ = (
1506        '__conditions',
1507        '__notBefore',
1508        '__notOnOrAfter'
1509    )
1510   
1511    def __init__(self, **kw):
1512        super(Conditions, self).__init__(**kw)
1513       
1514        # A list of Conditions
1515        self.__conditions = []
1516   
1517        # Not Before time condition
1518        self.__notBefore = None
1519   
1520        # Not On Or After time conditions
1521        self.__notOnOrAfter = None
1522
1523    def __getstate__(self):
1524        '''Enable pickling
1525       
1526        @return: object's attribute dictionary
1527        @rtype: dict
1528        '''
1529        _dict = super(Conditions, self).__getstate__()
1530        for attrName in Conditions.__slots__:
1531            # Ugly hack to allow for derived classes setting private member
1532            # variables
1533            if attrName.startswith('__'):
1534                attrName = "_Conditions" + attrName
1535               
1536            _dict[attrName] = getattr(self, attrName)
1537           
1538        return _dict
1539   
1540    def _getNotBefore(self):
1541        '''Get the date/time before which the assertion is invalid.
1542       
1543        @return: the date/time before which the assertion is invalid
1544        @rtype: NoneType / datetime.datetime
1545        '''
1546        return self.__notBefore
1547   
1548    def _setNotBefore(self, value):
1549        '''Sets the date/time before which the assertion is invalid.
1550       
1551        @param value: the date/time before which the assertion is invalid
1552        @type: datetime.datetime
1553        '''
1554        if not isinstance(value, datetime):
1555            raise TypeError('Expecting "datetime" type for "notBefore", '
1556                            'got %r' % type(value))
1557        self.__notBefore = value
1558
1559    def _getNotOnOrAfter(self):
1560        '''Gets the date/time on, or after, which the assertion is invalid.
1561       
1562        @return: the date/time on, or after, which the assertion is invalid'
1563        @rtype: NoneType / datetime.datetime
1564        '''
1565        return self.__notOnOrAfter
1566   
1567    def _setNotOnOrAfter(self, value):
1568        '''Sets the date/time on, or after, which the assertion is invalid.
1569       
1570        @param value: the date/time on, or after, which the assertion
1571        is invalid
1572        @type: datetime.datetime
1573        '''
1574        if not isinstance(value, datetime):
1575            raise TypeError('Expecting "datetime" type for "notOnOrAfter", '
1576                            'got %r' % type(value))
1577        self.__notOnOrAfter = value 
1578
1579    notBefore = property(_getNotBefore, _setNotBefore, 
1580                         doc="Not before time restriction")
1581
1582    notOnOrAfter = property(_getNotOnOrAfter, _setNotOnOrAfter, 
1583                            doc="Not on or after time restriction")
1584
1585    @property
1586    def conditions(self):
1587        '''All the conditions on the assertion.
1588       
1589        @return: all the conditions on the assertion
1590        @rtype: list
1591        '''
1592        return self.__conditions
1593   
1594    def _getAudienceRestrictions(self):
1595        '''Get the audience restriction conditions for the assertion.
1596       
1597        @return: the audience restriction conditions for the assertion
1598        @rtype: list
1599        @raise NotImplementedError: not currently implemented
1600        '''
1601        raise NotImplementedError()
1602
1603    def _getOneTimeUse(self):
1604        '''Get the OneTimeUse condition for the assertion
1605       
1606        @return: the OneTimeUse condition for the assertion
1607        @rtype: ?
1608        @raise NotImplementedError: not currently implemented
1609        '''
1610        raise NotImplementedError()
1611
1612    def _getProxyRestriction(self):   
1613        '''Get the ProxyRestriction condition for the assertion
1614       
1615        @return: the ProxyRestriction condition for the assertion
1616        @rtype: ?
1617        @raise NotImplementedError: not currently implemented
1618        '''
1619        raise NotImplementedError()
1620   
1621   
1622class Advice(SAMLObject):
1623    '''SAML 2.0 Core Advice.  Only the skeleton of this class is implemented
1624   
1625    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
1626    @type DEFAULT_ELEMENT_LOCAL_NAME: string
1627    @cvar DEFAULT_ELEMENT_NAME: Default element name.
1628    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
1629    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
1630    @type TYPE_LOCAL_NAME: string
1631    '''
1632
1633    # Element local name
1634    DEFAULT_ELEMENT_LOCAL_NAME = "Advice"
1635
1636    # Default element name.
1637    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1638                                 DEFAULT_ELEMENT_LOCAL_NAME,
1639                                 SAMLConstants.SAML20_PREFIX)
1640
1641    # Local name of the XSI type
1642    TYPE_LOCAL_NAME = "AdviceType"
1643
1644    # QName of the XSI type
1645    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
1646                      TYPE_LOCAL_NAME,
1647                      SAMLConstants.SAML20_PREFIX)
1648
1649    __slots__ = ()
1650   
1651    def _getChildren(self, typeOrName=None):
1652        '''
1653        Gets the list of all child elements attached to this advice.
1654       
1655        @return: the list of all child elements attached to this advice
1656        @rtype: list
1657        @raise NotImplementedError: not currently implemented
1658        '''
1659        raise NotImplementedError()
1660
1661    def _getAssertionIDReferences(self):
1662        '''Gets the list of AssertionID references used as advice.
1663       
1664        @return: the list of AssertionID references used as advice
1665        @rtype: list
1666        @raise NotImplementedError: not currently implemented
1667        '''
1668        raise NotImplementedError()
1669
1670    def _getAssertionURIReferences(self):
1671        '''Gets the list of AssertionURI references used as advice.
1672       
1673        @return: the list of AssertionURI references used as advice
1674        @rtype: list
1675        @raise NotImplementedError: not currently implemented
1676        '''
1677        raise NotImplementedError()
1678   
1679    def _getAssertions(self):
1680        '''Gets the list of Assertions used as advice.
1681       
1682        @return: the list of Assertions used as advice
1683        @rtype: list
1684        @raise NotImplementedError: not currently implemented
1685        '''
1686        raise NotImplementedError()
1687   
1688    def _getEncryptedAssertions(self):
1689        '''Gets the list of EncryptedAssertions used as advice.
1690       
1691        @return: the list of EncryptedAssertions used as advice
1692        @rtype: list
1693        @raise NotImplementedError: not currently implemented
1694        '''
1695        raise NotImplementedError()
1696       
1697
1698class Assertion(SAMLObject):
1699    """SAML 2.0 Attribute Assertion for use with NERC DataGrid   
1700
1701    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
1702    @type DEFAULT_ELEMENT_LOCAL_NAME: string
1703    @cvar DEFAULT_ELEMENT_NAME: Default element name.
1704    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
1705    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
1706    @type TYPE_LOCAL_NAME: string
1707    @cvar TYPE_NAME: QName of the XSI type.
1708    @type TYPE_NAME: ndg.saml.common.xml.QName
1709    @cvar VERSION_ATTRIB_NAME: Version attribute name.
1710    @type VERSION_ATTRIB_NAME: string
1711    @cvar ISSUE_INSTANT_ATTRIB_NAME: IssueInstant attribute name.
1712    @type ISSUE_INSTANT_ATTRIB_NAME: string
1713    @cvar ID_ATTRIB_NAME: ID attribute name.
1714    @type ID_ATTRIB_NAME: string
1715   
1716    @ivar __version: SAML version used
1717    @type __version: ndg.saml.common.SAMLVersion
1718    @ivar __issueInstant: issue instant for assertion
1719    @type __issueInstant: datetime.datetime
1720    @ivar __id: assertion identifier
1721    @type __id: string
1722    @ivar __issuer: issuer of this assertion
1723    @type __issuer: ndg.saml.saml2.core.Issuer
1724    @ivar __subject: subject of this assertion
1725    @type __subject: ndg.saml.saml2.core.Subject
1726    @ivar __conditions: conditions for this assertion
1727    @type __conditions: ndg.saml.saml2.core.Conditions
1728    @ivar __advice: advice statement
1729    @type __advice: string
1730    @ivar __statements: asserted statements
1731    @type __statements: ndg.saml.utils.TypedList
1732    @ivar __authnStatements: asserted authentication statements
1733    @type __authnStatements: list
1734    @ivar __authzDecisionStatements: asserted authorization decision statements
1735    @type __authzDecisionStatements: ndg.saml.utils.TypedList
1736    @ivar __attributeStatements: asserted attribute statements
1737    @type __attributeStatements: ndg.saml.utils.TypedList
1738    """   
1739     
1740    # Element local name.
1741    DEFAULT_ELEMENT_LOCAL_NAME = "Assertion"
1742
1743    # Default element name.
1744    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
1745                                 DEFAULT_ELEMENT_LOCAL_NAME,
1746                                 SAMLConstants.SAML20_PREFIX)
1747
1748    # Local name of the XSI type.
1749    TYPE_LOCAL_NAME = "AssertionType"
1750
1751    # QName of the XSI type.
1752    TYPE_NAME = QName(SAMLConstants.SAML20_NS, TYPE_LOCAL_NAME,
1753                      SAMLConstants.SAML20_PREFIX)
1754
1755    # Version attribute name.
1756    VERSION_ATTRIB_NAME = "Version"
1757
1758    # IssueInstant attribute name.
1759    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
1760
1761    # ID attribute name.
1762    ID_ATTRIB_NAME = "ID"
1763
1764    __slots__ = (
1765        '__version',
1766        '__issueInstant',
1767        '__id',
1768        '__issuer',
1769        '__subject',
1770        '__conditions',
1771        '__advice',
1772        '__statements',
1773        '__authnStatements',
1774        '__authzDecisionStatements',
1775        '__attributeStatements'
1776    )
1777   
1778    def __init__(self):
1779        # Base class initialisation
1780        super(Assertion, self).__init__()
1781       
1782        self.__version = None
1783        self.__issueInstant = None
1784        self.__id = None
1785        self.__issuer = None
1786        self.__subject = None
1787       
1788        self.__conditions = None
1789        self.__advice = None
1790        self.__statements = TypedList(Statement)
1791       
1792        # TODO: Implement AuthnStatement class
1793        self.__authnStatements = []
1794        self.__authzDecisionStatements = TypedList(AuthzDecisionStatement)
1795        self.__attributeStatements = TypedList(AttributeStatement)
1796
1797    def __getstate__(self):
1798        '''Enable pickling
1799       
1800        @return: object's attribute dictionary
1801        @rtype: dict
1802        '''
1803        _dict = super(Assertion, self).__getstate__()
1804        for attrName in Assertion.__slots__:
1805            # Ugly hack to allow for derived classes setting private member
1806            # variables
1807            if attrName.startswith('__'):
1808                attrName = "_Assertion" + attrName
1809               
1810            _dict[attrName] = getattr(self, attrName)
1811           
1812        return _dict   
1813                 
1814    def _get_version(self):
1815        '''
1816        @return: the SAML Version of this assertion
1817        @rtype: ndg.saml.common.SAMLVersion/NoneType
1818        '''
1819        return self.__version
1820   
1821    def _set_version(self, version):
1822        '''
1823        @param version: the SAML Version of this assertion
1824        @type version: ndg.saml.common.SAMLVersion
1825        @raise TypeError: incorrect type for input value
1826        '''
1827        if not isinstance(version, SAMLVersion):
1828            raise TypeError("Expecting SAMLVersion type got: %r" % 
1829                            version.__class__)
1830       
1831        self.__version = version
1832       
1833    version = property(fget=_get_version,
1834                       fset=_set_version,
1835                       doc="SAML Version of the assertion")
1836
1837    def _get_issueInstant(self):
1838        '''Gets the issue instance of this assertion.
1839       
1840        @return: the issue instance of this assertion
1841        @rtype: datetime.datetime/NoneType
1842        '''
1843        return self.__issueInstant
1844   
1845    def _set_issueInstant(self, issueInstant):
1846        '''Sets the issue instance of this assertion.
1847       
1848        @param issueInstant: the issue instance of this assertion
1849        @type issueInstant: datetime.datetime/NoneType
1850        @raise TypeError: incorrect type for input value
1851        '''
1852        if not isinstance(issueInstant, datetime):
1853            raise TypeError('Expecting "datetime" type for "issueInstant", '
1854                            'got %r' % issueInstant.__class__)
1855           
1856        self.__issueInstant = issueInstant
1857       
1858    issueInstant = property(fget=_get_issueInstant, 
1859                            fset=_set_issueInstant,
1860                            doc="Issue instant of the assertion")
1861
1862    def _get_id(self):
1863        '''Get the ID of this assertion
1864       
1865        @return: the ID of this assertion
1866        @rtype: basestring/NoneType
1867        '''
1868        return self.__id
1869   
1870    def _set_id(self, _id):
1871        '''Set the ID of this assertion
1872       
1873        @param _id: the ID of this assertion
1874        @type _id: basestring
1875        @raise TypeError: incorrect type for input value
1876        '''
1877        if not isinstance(_id, basestring):
1878            raise TypeError('Expecting basestring derived type for "id", got '
1879                            '%r' % _id.__class__)
1880        self.__id = _id
1881       
1882    id = property(fget=_get_id, fset=_set_id, doc="ID of assertion")
1883   
1884    def _set_issuer(self, issuer):
1885        """Set issuer
1886        @param issuer: issuer of the assertion
1887        @type issuer: ndg.saml.saml2.core.Issuer
1888        @raise TypeError: incorrect type for input value
1889        """
1890        if not isinstance(issuer, Issuer):
1891            raise TypeError("issuer must be %r, got %r" % (Issuer, 
1892                                                           type(issuer)))
1893        self.__issuer = issuer
1894   
1895    def _get_issuer(self):
1896        """Get the issuer name
1897        @return: issuer name
1898        @rtype: ndg.saml.saml2.core.Issuer
1899        """
1900        return self.__issuer
1901
1902    issuer = property(fget=_get_issuer, 
1903                      fset=_set_issuer,
1904                      doc="Issuer of assertion")
1905   
1906    def _set_subject(self, subject):
1907        """Set subject string
1908        @param subject: subject of this assertion
1909        @type subject: ndg.saml.saml2.core.Subject
1910        @raise TypeError: incorrect type for input value"""
1911        if not isinstance(subject, Subject):
1912            raise TypeError("subject must be %r, got %r" % (Subject, 
1913                                                            type(subject)))
1914
1915        self.__subject = subject
1916   
1917    def _get_subject(self):
1918        """Get subject string
1919       
1920        @return: subject of this assertion
1921        @rtype subject: ndg.saml.saml2.core.Subject
1922        """
1923        return self.__subject
1924
1925    subject = property(fget=_get_subject,
1926                       fset=_set_subject, 
1927                       doc="Attribute Assertion subject")
1928   
1929    def _get_conditions(self):
1930        """Get conditions
1931        @return: conditions for this assertion
1932        @rtype: ndg.saml.saml2.core.Conditions
1933        """
1934        return self.__conditions
1935   
1936    def _set_conditions(self, value):
1937        """Set conditions
1938        @param value: conditions for this assertion
1939        @type value: ndg.saml.saml2.core.Conditions
1940        @raise TypeError: incorrect type for input value"""
1941        if not isinstance(value, Conditions):
1942            raise TypeError("Conditions must be %r, got %r" % (Conditions, 
1943                                                               type(value)))
1944
1945        self.__conditions = value
1946
1947    conditions = property(fget=_get_conditions,
1948                          fset=_set_conditions,
1949                          doc="Attribute Assertion conditions")
1950   
1951    def _set_advice(self, advice):
1952        """Set advice string
1953       
1954        @param advice: advice for this assertion
1955        @type advice: basestring
1956        @raise TypeError: incorrect type for input value"""
1957        if not isinstance(advice, basestring):
1958            raise TypeError("advice must be a string")
1959
1960        self.__advice = advice
1961   
1962    def _get_advice(self):
1963        """Get advice string
1964       
1965        @return: advice for this assertion
1966        @rtype: basestring
1967        """
1968        return self.__advice
1969
1970    advice = property(fget=_get_advice,
1971                      fset=_set_advice, 
1972                      doc="Attribute Assertion advice")
1973   
1974    @property
1975    def statements(self):
1976        """Assertion statements
1977       
1978        @return: list of assertion statements
1979        @rtype: ndg.saml.utils.TypedList
1980        """
1981        return self.__statements
1982   
1983    @property
1984    def authnStatements(self):
1985        """Attribute Assertion authentication
1986       
1987        @return: list of assertion statements
1988        @rtype: ndg.saml.utils.TypedList
1989        """
1990        return self.__authnStatements
1991   
1992    @property
1993    def authzDecisionStatements(self):
1994        """Attribute Assertion authorisation decision statements
1995       
1996        @return: list of assertion statements
1997        @rtype: ndg.saml.utils.TypedList
1998        """
1999        return self.__authzDecisionStatements
2000   
2001    @property
2002    def attributeStatements(self):
2003        """Attribute Assertion attribute statements
2004       
2005        @return: list of assertion statements
2006        @rtype: ndg.saml.utils.TypedList
2007        """
2008        return self.__attributeStatements
2009   
2010
2011class AttributeValue(SAMLObject):
2012    """Base class for Attribute Value type
2013   
2014    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element name, no namespace
2015    @type DEFAULT_ELEMENT_LOCAL_NAME: string
2016    @cvar DEFAULT_ELEMENT_NAME: Default element name
2017    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName   
2018    """
2019   
2020    # Element name, no namespace
2021    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeValue"
2022
2023    # Default element name
2024    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
2025                                 DEFAULT_ELEMENT_LOCAL_NAME,
2026                                 SAMLConstants.SAML20_PREFIX)
2027    __slots__ = ()
2028
2029
2030class XSStringAttributeValue(AttributeValue):
2031    """XML XS:String Attribute Value type
2032   
2033    @cvar TYPE_LOCAL_NAME: Local name of the XSI type
2034    @type TYPE_LOCAL_NAME: string
2035    @cvar TYPE_NAME: QName of the XSI type
2036    @type TYPE_NAME: ndg.saml.common.xml.QName
2037   
2038    @ivar __value: value of this attribute
2039    @type __value: basestring
2040    """
2041   
2042    # Local name of the XSI type
2043    TYPE_LOCAL_NAME = "string"
2044       
2045    # QName of the XSI type
2046    TYPE_NAME = QName(SAMLConstants.XSD_NS, 
2047                      TYPE_LOCAL_NAME, 
2048                      SAMLConstants.XSD_PREFIX)
2049   
2050    DEFAULT_FORMAT = "%s#%s" % (SAMLConstants.XSD_NS, TYPE_LOCAL_NAME)
2051 
2052    __slots__ = ('__value',)
2053   
2054    def __init__(self, **kw):
2055        """
2056        @param **kw: keywords for setting attributes of parent class
2057        @type **kw: dict
2058        """
2059        super(XSStringAttributeValue, self).__init__(**kw)
2060        self.__value = None
2061
2062    def __getstate__(self):
2063        '''Enable pickling
2064       
2065        @return: object's attribute dictionary
2066        @rtype: dict
2067        '''
2068        _dict = super(XSStringAttributeValue, self).__getstate__()
2069        for attrName in XSStringAttributeValue.__slots__:
2070            # Ugly hack to allow for derived classes setting private member
2071            # variables
2072            if attrName.startswith('__'):
2073                attrName = "_XSStringAttributeValue" + attrName
2074               
2075            _dict[attrName] = getattr(self, attrName)
2076           
2077        return _dict
2078           
2079    def _getValue(self):
2080        """Set value of XS string
2081        @return: value of string to assign
2082        @rtype: string
2083        """
2084        return self.__value
2085       
2086    def _setValue(self, value):
2087        """Set value of XS string
2088        @param: value
2089        @type: string
2090        @raise TypeError: invalid input value type
2091        """
2092        if not isinstance(value, basestring):
2093            raise TypeError("Input must be a basestring derived type, got %r" %
2094                            value.__class__)
2095           
2096        self.__value = value
2097
2098    value = property(fget=_getValue, fset=_setValue, doc="string value") 
2099
2100
2101class StatusDetail(SAMLObject):
2102    '''Implementation of SAML 2.0 StatusDetail
2103   
2104    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Local Name of StatusDetail.
2105    @type DEFAULT_ELEMENT_LOCAL_NAME: string
2106    @cvar DEFAULT_ELEMENT_NAME: Default element name.
2107    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
2108    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
2109    @type TYPE_LOCAL_NAME: string
2110    @cvar TYPE_NAME: QName of the XSI type.
2111    @type TYPE_NAME: ndg.saml.common.xml.QName
2112   
2113    @ivar __unknownChildren: unknown child elements
2114    @type __unknownChildren: ndg.saml.common.SAMLObject
2115   
2116    '''
2117   
2118    # Local Name of StatusDetail.
2119    DEFAULT_ELEMENT_LOCAL_NAME = "StatusDetail"
2120
2121    # Default element name.
2122    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2123                                 DEFAULT_ELEMENT_LOCAL_NAME,
2124                                 SAMLConstants.SAML20P_PREFIX)
2125
2126    # Local name of the XSI type.
2127    TYPE_LOCAL_NAME = "StatusDetailType"
2128
2129    # QName of the XSI type.
2130    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2131                      TYPE_LOCAL_NAME,
2132                      SAMLConstants.SAML20P_PREFIX)
2133   
2134    __slots__ = ('__unknownChildren', )
2135   
2136    def __init__(self, **kw):
2137        """
2138        @param **kw: keywords for setting attributes of parent class
2139        @type **kw: dict
2140        """
2141        super(StatusDetail, self).__init__(**kw)
2142       
2143        # child "any" elements.
2144        self.__unknownChildren = TypedList(SAMLObject)         
2145
2146    def __getstate__(self):
2147        '''Enable pickling
2148       
2149        @return: object's attribute dictionary
2150        @rtype: dict
2151        '''
2152
2153        _dict = super(StatusDetail, self).__getstate__()
2154        for attrName in StatusDetail.__slots__:
2155            # Ugly hack to allow for derived classes setting private member
2156            # variables
2157            if attrName.startswith('__'):
2158                attrName = "_StatusDetail" + attrName
2159               
2160            _dict[attrName] = getattr(self, attrName)
2161           
2162        return _dict
2163   
2164    def getUnknownXMLTypes(self, qname=None):
2165        """Retrieve unknown child attributes
2166       
2167        This is untested
2168        @param qname: qualified name for matching types to be retrieved
2169        @type qname: ndg.saml.common.xml.QName
2170        @raise TypeError: incorrect type for qname keyword
2171        """ 
2172        if qname is not None:
2173            if not isinstance(qname, QName):
2174                raise TypeError("\"qname\" must be a %r derived type, "
2175                                "got %r" % (QName, type(qname)))
2176               
2177            children = []
2178            for child in self.__unknownChildren:
2179                childQName = getattr(child, "qname", None)
2180                if childQName is not None:
2181                    if childQName.namespaceURI == qname.namespaceURI or \
2182                       childQName.localPart == qname.localPart:
2183                        children.append(child)
2184                       
2185            return children
2186        else:
2187            return self.__unknownChildren
2188   
2189    unknownChildren = property(fget=getUnknownXMLTypes,
2190                               doc="Child objects of Status Detail - may be "
2191                                   "any type")
2192   
2193
2194class StatusMessage(SAMLObject):
2195    '''Implementation of SAML 2.0 Status Message
2196   
2197    @cvar DEFAULT_ELEMENT_LOCAL_NAME:  Local name of the Status message element
2198    @type DEFAULT_ELEMENT_LOCAL_NAME: string
2199    @cvar DEFAULT_ELEMENT_NAME:  Default element name
2200    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
2201   
2202    @ivar __value: message text
2203    @type __value: basestring
2204    '''
2205
2206    DEFAULT_ELEMENT_LOCAL_NAME = "StatusMessage"
2207    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2208                                 DEFAULT_ELEMENT_LOCAL_NAME,
2209                                 SAMLConstants.SAML20P_PREFIX)
2210   
2211    __slots__ = ('__value', )
2212   
2213    def __init__(self, **kw):
2214        super(StatusMessage, self).__init__(**kw)
2215       
2216        # message text
2217        self.__value = None       
2218
2219    def __getstate__(self):
2220        '''Enable pickling
2221       
2222        @return: object's attribute dictionary
2223        @rtype: dict
2224        '''
2225        _dict = super(StatusMessage, self).__getstate__()
2226        for attrName in StatusMessage.__slots__:
2227            # Ugly hack to allow for derived classes setting private member
2228            # variables
2229            if attrName.startswith('__'):
2230                attrName = "_StatusMessage" + attrName
2231               
2232            _dict[attrName] = getattr(self, attrName)
2233           
2234        return _dict
2235   
2236    def _getValue(self):
2237        '''
2238        @return: message text
2239        @rtype: basestring
2240        '''
2241        return self.__value
2242       
2243    def _setValue(self, value):
2244        '''
2245        @param __value: message text
2246        @type __value: basestring
2247        @raise TypeError: incorrect type for input value
2248        '''
2249        if not isinstance(value, basestring):
2250            raise TypeError("\"value\" must be a basestring derived type, "
2251                            "got %r" % type(value))
2252           
2253        self.__value = value
2254
2255    value = property(fget=_getValue, fset=_setValue, doc="Status message value")
2256
2257
2258class StatusCode(SAMLObject):
2259    '''Implementation of SAML 2.0 StatusCode.
2260   
2261    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Local Name of StatusCode.                                                                       
2262    @type DEFAULT_ELEMENT_LOCAL_NAME: string                                                                                           
2263    @cvar DEFAULT_ELEMENT_NAME: Default element name.                                                                                 
2264    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName                                                                                                 
2265    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.                                                                                 
2266    @type TYPE_LOCAL_NAME: string                                                                                                     
2267    @cvar TYPE_NAME: QName of the XSI type.                                                                                           
2268    @type TYPE_NAME: ndg.saml.common.xml.QName                                                                                                           
2269    @cvar VALUE_ATTRIB_NAME: Local Name of the Value attribute.                                                                       
2270    @type VALUE_ATTRIB_NAME: string                                                                                                   
2271    @cvar SUCCESS_URI: URI for Success status code.                                                                                   
2272    @type SUCCESS_URI: string                                                                                                         
2273    @cvar REQUESTER_URI: URI for Requester status code.                                                                               
2274    @type REQUESTER_URI: string                                                                                                       
2275    @cvar RESPONDER_URI: URI for Responder status code.
2276    @type RESPONDER_URI: string
2277    @cvar VERSION_MISMATCH_URI: URI for VersionMismatch status code.
2278    @type VERSION_MISMATCH_URI: string
2279    @cvar AUTHN_FAILED_URI: URI for AuthnFailed status code.
2280    @type AUTHN_FAILED_URI: string
2281    @cvar INVALID_ATTR_NAME_VALUE_URI: URI for InvalidAttrNameOrValue status code.
2282    @type INVALID_ATTR_NAME_VALUE_URI: string
2283    @cvar INVALID_NAMEID_POLICY_URI: URI for InvalidNameIDPolicy status code.
2284    @type INVALID_NAMEID_POLICY_URI: string
2285    @cvar NO_AUTHN_CONTEXT_URI: URI for NoAuthnContext status code.
2286    @type NO_AUTHN_CONTEXT_URI: string
2287    @cvar NO_AVAILABLE_IDP_URI: URI for NoAvailableIDP status code.
2288    @type NO_AVAILABLE_IDP_URI: string
2289    @cvar NO_PASSIVE_URI: URI for NoPassive status code.
2290    @type NO_PASSIVE_URI: string
2291    @cvar NO_SUPPORTED_IDP_URI: URI for NoSupportedIDP status code.
2292    @type NO_SUPPORTED_IDP_URI: string
2293    @cvar PARTIAL_LOGOUT_URI: URI for PartialLogout status code.
2294    @type PARTIAL_LOGOUT_URI: string
2295    @cvar PROXY_COUNT_EXCEEDED_URI: URI for ProxyCountExceeded status code.
2296    @type PROXY_COUNT_EXCEEDED_URI: string
2297    @cvar REQUEST_DENIED_URI: URI for RequestDenied status code.
2298    @type REQUEST_DENIED_URI: string
2299    @cvar REQUEST_UNSUPPORTED_URI: URI for RequestUnsupported status code.
2300    @type REQUEST_UNSUPPORTED_URI: string
2301    @cvar REQUEST_VERSION_DEPRECATED_URI: URI for RequestVersionDeprecated status code.
2302    @type REQUEST_VERSION_DEPRECATED_URI: string
2303    @cvar REQUEST_VERSION_TOO_HIGH_URI: URI for RequestVersionTooHigh status code.
2304    @type REQUEST_VERSION_TOO_HIGH_URI: string
2305    @cvar REQUEST_VERSION_TOO_LOW_URI: URI for RequestVersionTooLow status code.
2306    @type REQUEST_VERSION_TOO_LOW_URI: string
2307    @cvar RESOURCE_NOT_RECOGNIZED_URI: URI for ResourceNotRecognized status code.
2308    @type RESOURCE_NOT_RECOGNIZED_URI: string
2309    @cvar TOO_MANY_RESPONSES: URI for TooManyResponses status code.
2310    @type TOO_MANY_RESPONSES: string
2311    @cvar UNKNOWN_ATTR_PROFILE_URI: URI for UnknownAttrProfile status code.
2312    @type UNKNOWN_ATTR_PROFILE_URI: string
2313    @cvar UNKNOWN_PRINCIPAL_URI: URI for UnknownPrincipal status code.
2314    @type UNKNOWN_PRINCIPAL_URI: string
2315    @cvar UNSUPPORTED_BINDING_URI: URI for UnsupportedBinding status code.
2316    @type UNSUPPORTED_BINDING_URI: string
2317   
2318    @ivar __value: status code value
2319    @type __value:
2320    @ivar __childStatusCode: child element status code value
2321    @type __childStatusCode:
2322    '''
2323   
2324    # Local Name of StatusCode.
2325    DEFAULT_ELEMENT_LOCAL_NAME = "StatusCode"
2326
2327    # Default element name.
2328    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2329                                 DEFAULT_ELEMENT_LOCAL_NAME,
2330                                 SAMLConstants.SAML20P_PREFIX)
2331
2332    # Local name of the XSI type.
2333    TYPE_LOCAL_NAME = "StatusCodeType"
2334
2335    # QName of the XSI type.
2336    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2337                      TYPE_LOCAL_NAME,
2338                      SAMLConstants.SAML20P_PREFIX)
2339
2340    # Local Name of the Value attribute.
2341    VALUE_ATTRIB_NAME = "Value"
2342
2343    # URI for Success status code.
2344    SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success"
2345
2346    # URI for Requester status code.
2347    REQUESTER_URI = "urn:oasis:names:tc:SAML:2.0:status:Requester"
2348
2349    # URI for Responder status code.
2350    RESPONDER_URI = "urn:oasis:names:tc:SAML:2.0:status:Responder"
2351
2352    # URI for VersionMismatch status code.
2353    VERSION_MISMATCH_URI = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
2354
2355    # URI for AuthnFailed status code.
2356    AUTHN_FAILED_URI = "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
2357
2358    # URI for InvalidAttrNameOrValue status code.
2359    INVALID_ATTR_NAME_VALUE_URI = \
2360                "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue"
2361
2362    # URI for InvalidNameIDPolicy status code.
2363    INVALID_NAMEID_POLICY_URI = \
2364                "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"
2365
2366    # URI for NoAuthnContext status code.
2367    NO_AUTHN_CONTEXT_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"
2368
2369    # URI for NoAvailableIDP status code.
2370    NO_AVAILABLE_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"
2371
2372    # URI for NoPassive status code.
2373    NO_PASSIVE_URI = "urn:oasis:names:tc:SAML:2.0:status:NoPassive"
2374
2375    # URI for NoSupportedIDP status code.
2376    NO_SUPPORTED_IDP_URI = "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"
2377
2378    # URI for PartialLogout status code.
2379    PARTIAL_LOGOUT_URI = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
2380
2381    # URI for ProxyCountExceeded status code.
2382    PROXY_COUNT_EXCEEDED_URI = \
2383                "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"
2384
2385    # URI for RequestDenied status code.
2386    REQUEST_DENIED_URI = "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"
2387
2388    # URI for RequestUnsupported status code.
2389    REQUEST_UNSUPPORTED_URI = \
2390                "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
2391
2392    # URI for RequestVersionDeprecated status code.
2393    REQUEST_VERSION_DEPRECATED_URI = \
2394                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
2395
2396    # URI for RequestVersionTooHigh status code.
2397    REQUEST_VERSION_TOO_HIGH_URI = \
2398                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
2399   
2400    # URI for RequestVersionTooLow status code.
2401    REQUEST_VERSION_TOO_LOW_URI = \
2402                "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"
2403
2404    # URI for ResourceNotRecognized status code.
2405    RESOURCE_NOT_RECOGNIZED_URI = \
2406                "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"
2407
2408    # URI for TooManyResponses status code.
2409    TOO_MANY_RESPONSES = "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"
2410
2411    # URI for UnknownAttrProfile status code.
2412    UNKNOWN_ATTR_PROFILE_URI = \
2413                "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile"
2414
2415    # URI for UnknownPrincipal status code.
2416    UNKNOWN_PRINCIPAL_URI = \
2417                "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"
2418
2419    # URI for UnsupportedBinding status code.
2420    UNSUPPORTED_BINDING_URI = \
2421                "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"
2422
2423    __slots__ = ('__value', '__childStatusCode',)
2424   
2425    def __init__(self, **kw):
2426        """
2427        @param **kw: keywords to initialise superclass attributes
2428        @type **kw: dict
2429        """
2430        super(StatusCode, self).__init__(**kw)
2431       
2432        # Value attribute URI.
2433        self.__value = None
2434   
2435        # Nested secondary StatusCode child element.
2436        self.__childStatusCode = None
2437
2438    def __getstate__(self):
2439        '''Enable pickling
2440       
2441        @return: object's attribute dictionary
2442        @rtype: dict
2443        '''
2444
2445        _dict = super(StatusCode, self).__getstate__()
2446        for attrName in StatusCode.__slots__:
2447            # Ugly hack to allow for derived classes setting private member
2448            # variables
2449            if attrName.startswith('__'):
2450                attrName = "_StatusCode" + attrName
2451               
2452            _dict[attrName] = getattr(self, attrName)
2453           
2454        return _dict
2455   
2456    def _getStatusCode(self): 
2457        """Get child status code
2458        @return: status code value
2459        @rtype: ndg.saml.saml2.core.StatusCode
2460        """
2461        return self.__childStatusCode
2462   
2463    def _setStatusCode(self, value):
2464        """Set child status code
2465        @param __value: status code value
2466        @type __value: ndg.saml.saml2.core.StatusCode
2467        """
2468        if not isinstance(value, StatusCode):
2469            raise TypeError('Child "statusCode" must be a %r derived type, '
2470                            "got %r" % (StatusCode, type(value)))
2471           
2472        self.__childStatusCode = value
2473
2474    value = property(fget=_getStatusCode, 
2475                     fset=_setStatusCode, 
2476                     doc="Child Status code")
2477             
2478    def _getValue(self):
2479        """Get status message
2480        @return: message text
2481        @rtype: basestring
2482        """ 
2483        return self.__value
2484       
2485    def _setValue(self, value):
2486        """Set status message
2487        @param value: message text
2488        @type value: basestring
2489        """ 
2490        if not isinstance(value, basestring):
2491            raise TypeError("\"value\" must be a basestring derived type, "
2492                            "got %r" % value.__class__)
2493           
2494        self.__value = value
2495
2496    value = property(fget=_getValue, fset=_setValue, doc="Status code value")
2497       
2498
2499class Status(SAMLObject): 
2500    '''SAML 2.0 Core Status
2501   
2502    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Local Name of Status.
2503    @type DEFAULT_ELEMENT_LOCAL_NAME: string
2504    @cvar DEFAULT_ELEMENT_NAME: Default element name.
2505    @type DEFAULT_ELEMENT_NAME: ndg.common.xml.QName
2506    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
2507    @type TYPE_LOCAL_NAME: string
2508    @cvar TYPE_NAME: QName of the XSI type.
2509    @type TYPE_NAME: ndg.common.xml.QName
2510   
2511    @ivar __statusCode: status code
2512    @type __statusCode: ndg.saml.saml2.core.StatusCode
2513    @ivar __statusMessage: status message
2514    @type __statusMessage: ndg.saml.saml2.core.StatusMessage
2515    @ivar __statusDetail: status detail
2516    @type __statusDetail: ndg.saml.saml2.core.StatusDetail
2517    '''
2518   
2519    # Local Name of Status.
2520    DEFAULT_ELEMENT_LOCAL_NAME = "Status"
2521
2522    # Default element name.
2523    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
2524                                 DEFAULT_ELEMENT_LOCAL_NAME,
2525                                 SAMLConstants.SAML20P_PREFIX)
2526
2527    # Local name of the XSI type.
2528    TYPE_LOCAL_NAME = "StatusType"
2529
2530    # QName of the XSI type.
2531    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2532                      TYPE_LOCAL_NAME,
2533                      SAMLConstants.SAML20P_PREFIX)
2534
2535    __slots__ = (
2536        '__statusCode', 
2537        '__statusMessage', 
2538        '__statusDetail', 
2539    )
2540   
2541    def __init__(self, **kw):
2542        super(Status, self).__init__(**kw)
2543       
2544        # StatusCode element.
2545        self.__statusCode = None
2546   
2547        # StatusMessage element.
2548        self.__statusMessage = None
2549   
2550        # StatusDetail element.
2551        self.__statusDetail = None
2552       
2553    def __getstate__(self):
2554        '''Enable pickling
2555       
2556        @return: object's attribute dictionary
2557        @rtype: dict
2558        '''
2559        _dict = super(Status, self).__getstate__()
2560        for attrName in Status.__slots__:
2561            # Ugly hack to allow for derived classes setting private member
2562            # variables
2563            if attrName.startswith('__'):
2564                attrName = "_Status" + attrName
2565               
2566            _dict[attrName] = getattr(self, attrName)
2567           
2568        return _dict
2569   
2570    def _getStatusCode(self):
2571        '''Get the Code of this Status
2572       
2573        @return: Status object's StatusCode
2574        @rtype: ndg.saml.saml2.core.StatusCode
2575        '''
2576        return self.__statusCode
2577
2578    def _setStatusCode(self, value):
2579        '''Set the Code of this Status
2580       
2581        @param value: the Code of this Status object
2582        @type value: ndg.saml.saml2.core.StatusCode
2583        @raise TypeError: incorrect type for input code value
2584        '''
2585        if not isinstance(value, StatusCode):
2586            raise TypeError('"statusCode" must be a %r derived type, '
2587                            "got %r" % (StatusCode, type(value)))
2588           
2589        self.__statusCode = value
2590       
2591    statusCode = property(fget=_getStatusCode,
2592                          fset=_setStatusCode,
2593                          doc="status code object")
2594   
2595    def _getStatusMessage(self):
2596        '''Get the Message of this Status.
2597       
2598        @return: Status message
2599        @rtype: ndg.saml.saml2.core.StatusMessage
2600        '''
2601        return self.__statusMessage
2602
2603    def _setStatusMessage(self, value):
2604        '''Set the Message of this Status
2605       
2606        @param value: the Message associated with this Status
2607        @type value: ndg.saml.saml2.core.StatusMessage
2608        @raise TypeError: incorrect input value type
2609        '''
2610        if not isinstance(value, StatusMessage):
2611            raise TypeError('"statusMessage" must be a %r derived type, '
2612                            "got %r" % (StatusMessage, type(value)))
2613           
2614        self.__statusMessage = value
2615       
2616    statusMessage = property(fget=_getStatusMessage,
2617                             fset=_setStatusMessage,
2618                             doc="status message")
2619
2620    def _getStatusDetail(self):
2621        '''Get the Detail of this Status
2622       
2623        @return: Status object's StatusDetail
2624        @rtype: ndg.saml.saml2.core.StatusDetail
2625        '''
2626        return self.__statusDetail
2627   
2628    def _setStatusDetail(self, value):
2629        '''
2630        Sets the Detail of this Status.
2631       
2632        @param value: the Detail of this Status
2633        @type value: ndg.saml.saml2.core.StatusDetail;
2634        @raise TypeError: incorrect input value type
2635        '''
2636        if not isinstance(value, StatusDetail):
2637            raise TypeError('"statusDetail" must be a %r derived type, '
2638                            "got %r" % (StatusDetail, type(value)))
2639        self.__statusDetail = value
2640       
2641    statusDetail = property(fget=_getStatusDetail,
2642                            fset=_setStatusDetail,
2643                            doc="status detail")
2644
2645
2646class Action(SAMLObject): 
2647    '''SAML 2.0 Core Action
2648    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.                                 
2649    @type DEFAULT_ELEMENT_LOCAL_NAME: string                                               
2650    @cvar DEFAULT_ELEMENT_NAME: Default element name.                                     
2651    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName                                                     
2652    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.                                     
2653    @type TYPE_LOCAL_NAME: string                                                         
2654    @cvar TYPE_NAME: QName of the XSI type                                                 
2655    @type TYPE_NAME: ndg.saml.common.xml.QName                                                               
2656    @cvar NAMESPACE_ATTRIB_NAME: Name of the Namespace attribute.
2657    @type NAMESPACE_ATTRIB_NAME: string
2658    @cvar RWEDC_NS_URI: Read/Write/Execute/Delete/Control action namespace.
2659    @type RWEDC_NS_URI: string
2660    @cvar RWEDC_NEGATION_NS_URI: Read/Write/Execute/Delete/Control negation
2661    action namespace.
2662    @type RWEDC_NEGATION_NS_URI: string
2663    @cvar GHPP_NS_URI: Get/Head/Put/Post action namespace.
2664    @type GHPP_NS_URI: string
2665    @cvar UNIX_NS_URI: UNIX file permission action namespace.
2666    @type UNIX_NS_URI: string
2667    @cvar ACTION_NS_IDENTIFIERS: Action namespace identifiers
2668    @type ACTION_NS_IDENTIFIERS: tuple
2669    @cvar READ_ACTION: Read action.
2670    @type READ_ACTION: string
2671    @cvar WRITE_ACTION: Write action.
2672    @type WRITE_ACTION: string
2673    @cvar EXECUTE_ACTION: Execute action.
2674    @type EXECUTE_ACTION: string
2675    @cvar DELETE_ACTION: Delete action.
2676    @type DELETE_ACTION: string
2677    @cvar CONTROL_ACTION: Control action.
2678    @type CONTROL_ACTION: string
2679    @cvar NEG_READ_ACTION: Negated Read action.
2680    @type NEG_READ_ACTION: string
2681    @cvar NEG_WRITE_ACTION: Negated Write action.
2682    @type NEG_WRITE_ACTION: string
2683    @cvar NEG_EXECUTE_ACTION: Negated Execute action.
2684    @type NEG_EXECUTE_ACTION: string
2685    @cvar NEG_DELETE_ACTION: Negated Delete action.
2686    @type NEG_DELETE_ACTION: string
2687    @cvar NEG_CONTROL_ACTION: Negated Control action.
2688    @type NEG_CONTROL_ACTION: string
2689    @cvar HTTP_GET_ACTION: HTTP GET action.
2690    @type HTTP_GET_ACTION: string
2691    @cvar HTTP_HEAD_ACTION: HTTP HEAD action.
2692    @type HTTP_HEAD_ACTION: string
2693    @cvar HTTP_PUT_ACTION: HTTP PUT action.
2694    @type HTTP_PUT_ACTION: string
2695    @cvar HTTP_POST_ACTION: HTTP POST action.
2696    @type HTTP_POST_ACTION: string
2697    @cvar ACTION_TYPES: Recognised action URI to action types mapping
2698    @type ACTION_TYPES: dict
2699       
2700    @ivar __namespace: action namespace
2701    @type __namespace: string
2702    @ivar __value: action type value
2703    @type __value: string
2704    @ivar __actionTypes: valid action types for each of a given set of action
2705    namespaces
2706    @type __actionTypes: dict
2707    '''
2708   
2709    # Element local name.
2710    DEFAULT_ELEMENT_LOCAL_NAME = "Action"
2711
2712    # Default element name.
2713    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
2714                                 DEFAULT_ELEMENT_LOCAL_NAME,
2715                                 SAMLConstants.SAML20_PREFIX)
2716
2717    # Local name of the XSI type.
2718    TYPE_LOCAL_NAME = "ActionType"
2719
2720    # QName of the XSI type
2721    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
2722                      TYPE_LOCAL_NAME,
2723                      SAMLConstants.SAML20_PREFIX)
2724
2725    # Name of the Namespace attribute.
2726    NAMESPACE_ATTRIB_NAME = "Namespace"
2727
2728    # Read/Write/Execute/Delete/Control action namespace.
2729    RWEDC_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:rwedc"
2730
2731    # Read/Write/Execute/Delete/Control negation action namespace.
2732    RWEDC_NEGATION_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:rwedc-negation"
2733
2734    # Get/Head/Put/Post action namespace.
2735    GHPP_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:ghpp"
2736
2737    # UNIX file permission action namespace.
2738    UNIX_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:unix"
2739
2740    # Action namespace identifiers
2741    ACTION_NS_IDENTIFIERS = (
2742        RWEDC_NS_URI,
2743        RWEDC_NEGATION_NS_URI,   
2744        GHPP_NS_URI,
2745        UNIX_NS_URI       
2746    )
2747   
2748    # Read action.
2749    READ_ACTION = "Read"
2750
2751    # Write action.
2752    WRITE_ACTION = "Write"
2753
2754    # Execute action.
2755    EXECUTE_ACTION = "Execute"
2756
2757    # Delete action.
2758    DELETE_ACTION = "Delete"
2759
2760    # Control action.
2761    CONTROL_ACTION = "Control"
2762
2763    # Negated Read action.
2764    NEG_READ_ACTION = "~Read"
2765
2766    # Negated Write action.
2767    NEG_WRITE_ACTION = "~Write"
2768
2769    # Negated Execute action.
2770    NEG_EXECUTE_ACTION = "~Execute"
2771
2772    # Negated Delete action.
2773    NEG_DELETE_ACTION = "~Delete"
2774
2775    # Negated Control action.
2776    NEG_CONTROL_ACTION = "~Control"
2777
2778    # HTTP GET action.
2779    HTTP_GET_ACTION = "GET"
2780
2781    # HTTP HEAD action.
2782    HTTP_HEAD_ACTION = "HEAD"
2783
2784    # HTTP PUT action.
2785    HTTP_PUT_ACTION = "PUT"
2786
2787    # HTTP POST action.
2788    HTTP_POST_ACTION = "POST"
2789   
2790    # Recognised action URI to action types mapping
2791    ACTION_TYPES = {
2792        RWEDC_NS_URI: (READ_ACTION, WRITE_ACTION, EXECUTE_ACTION, DELETE_ACTION,
2793                       CONTROL_ACTION),
2794        RWEDC_NEGATION_NS_URI: (READ_ACTION, WRITE_ACTION, EXECUTE_ACTION, 
2795                                DELETE_ACTION, CONTROL_ACTION, NEG_READ_ACTION, 
2796                                NEG_WRITE_ACTION, NEG_EXECUTE_ACTION, 
2797                                NEG_CONTROL_ACTION),   
2798        GHPP_NS_URI: (HTTP_GET_ACTION, HTTP_HEAD_ACTION, HTTP_PUT_ACTION,
2799                      HTTP_POST_ACTION),
2800                     
2801        # This namespace uses octal bitmask for file permissions
2802        UNIX_NS_URI: ()   
2803    }
2804   
2805    __slots__ = (
2806        '__namespace', 
2807        '__value', 
2808        '__actionTypes'
2809    )
2810   
2811    def __init__(self, **kw):
2812        '''Create an authorization action type
2813        '''
2814        super(Action, self).__init__(**kw)
2815
2816        # URI of the Namespace of this action.  Default to read/write/negation
2817        # type - 2.7.4.2 SAML 2 Core Spec. 15 March 2005
2818        self.__namespace = Action.RWEDC_NEGATION_NS_URI
2819
2820        # Action value
2821        self.__value = None       
2822   
2823        self.__actionTypes = Action.ACTION_TYPES
2824       
2825    def __getstate__(self):
2826        '''Enable pickling
2827       
2828        @return: object's attribute dictionary
2829        @rtype: dict
2830        '''
2831        _dict = super(Action, self).__getstate__()
2832        for attrName in Action.__slots__:
2833            # Ugly hack to allow for derived classes setting private member
2834            # variables
2835            if attrName.startswith('__'):
2836                attrName = "_Action" + attrName
2837               
2838            _dict[attrName] = getattr(self, attrName)
2839           
2840        return _dict
2841   
2842    def _getActionTypes(self):
2843        """Get action namespace to action types map
2844        @return: action types map
2845        @rtype: dict
2846        """ 
2847        return self.__actionTypes
2848
2849    def _setActionTypes(self, value):
2850        """Set action namespace to action types map
2851        @param value: action types map
2852        @type value: dict
2853        @raise TypeError: incorrect type for input value
2854        """ 
2855        if not isinstance(value, dict):
2856            raise TypeError('Expecting list or tuple type for "actionTypes" '
2857                            'attribute; got %r' % type(value))
2858           
2859        for k, v in value.items():
2860            if not isinstance(v, (tuple, type(None))):
2861                raise TypeError('Expecting None or tuple type for '
2862                                '"actionTypes" dictionary values; got %r for '
2863                                '%r key' % (type(value), k))
2864        self.__actionTypes = value
2865
2866    actionTypes = property(_getActionTypes, 
2867                           _setActionTypes, 
2868                           doc="Restrict vocabulary of action types")
2869       
2870    def _getNamespace(self):
2871        '''Get the namespace of the action
2872       
2873        @return: the namespace of the action
2874        @rtype: basestring
2875        '''
2876        return self.__namespace
2877
2878    def _setNamespace(self, value):
2879        '''Set the namespace of the action
2880       
2881        @param value: the namespace of the action
2882        @type value: basestring
2883        '''
2884        if not isinstance(value, basestring):
2885            raise TypeError('Expecting string type for "namespace" '
2886                            'attribute; got %r' % type(value))
2887           
2888        if value not in self.__actionTypes.keys():
2889            raise AttributeError('"namespace" action type %r not recognised. '
2890                                 'It must be one of these action types: %r' % 
2891                                 self.__actionTypes.keys())
2892           
2893        self.__namespace = value
2894
2895    namespace = property(_getNamespace, _setNamespace, doc="Action Namespace")
2896
2897    def _getValue(self):
2898        '''Get the URI of the action to be performed.
2899       
2900        @return: the URI of the action to be performed
2901        @rtype: basestring or int
2902        '''
2903        return self.__value
2904
2905    def _setValue(self, value):
2906        '''Set the URI of the action to be performed.
2907       
2908        @param value: the URI of the value to be performed
2909        @type value: basestring or int
2910        @raise TypeError: incorrect type for input value
2911        '''
2912        # int and oct allow for UNIX file permissions action type
2913        if not isinstance(value, (basestring, int)):
2914            raise TypeError('Expecting string or int type for "action" '
2915                            'attribute; got %r' % type(value))
2916           
2917        # Default to read/write/negation type - 2.7.4.2 SAML 2 Core Spec.
2918        # 15 March 2005
2919        allowedActions = self.__actionTypes.get(self.__namespace,
2920                                                Action.RWEDC_NEGATION_NS_URI)
2921       
2922        # Only apply restriction for action type that has a restricted
2923        # vocabulary - UNIX type is missed out of this because its an octal
2924        # mask
2925        if len(allowedActions) > 0 and value not in allowedActions:
2926            raise AttributeError('%r action not recognised; known actions for '
2927                                 'the %r namespace identifier are: %r.  ' 
2928                                 'If this is not as expected make sure to set '
2929                                 'the "namespace" attribute to an alternative '
2930                                 'value first or override completely by '
2931                                 'explicitly setting the "allowTypes" '
2932                                 'attribute' % 
2933                                 (value, self.__namespace, allowedActions))
2934        self.__value = value
2935
2936    value = property(_getValue, _setValue, doc="Action string")
2937       
2938
2939class RequestAbstractType(SAMLObject): 
2940    '''SAML 2.0 Core RequestAbstractType
2941   
2942    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
2943    @type TYPE_LOCAL_NAME: string
2944    @cvar TYPE_NAME: QName of the XSI type.
2945    @type TYPE_NAME: ndg.saml.common.xml.QName
2946    @cvar ID_ATTRIB_NAME: ID attribute name.
2947    @type ID_ATTRIB_NAME: string
2948    @cvar VERSION_ATTRIB_NAME: Version attribute name.
2949    @type VERSION_ATTRIB_NAME: string
2950    @cvar ISSUE_INSTANT_ATTRIB_NAME: IssueInstant attribute name.
2951    @type ISSUE_INSTANT_ATTRIB_NAME: string
2952    @cvar DESTINATION_ATTRIB_NAME: Destination attribute name.
2953    @type DESTINATION_ATTRIB_NAME: string
2954    @cvar CONSENT_ATTRIB_NAME: Consent attribute name.
2955    @type CONSENT_ATTRIB_NAME: string
2956    @cvar UNSPECIFIED_CONSENT: Unspecified consent URI.
2957    @type UNSPECIFIED_CONSENT: string
2958    @cvar OBTAINED_CONSENT: Obtained consent URI.
2959    @type OBTAINED_CONSENT: string
2960    @cvar PRIOR_CONSENT: Prior consent URI.
2961    @type PRIOR_CONSENT: string
2962    @cvar IMPLICIT_CONSENT: Implicit consent URI.
2963    @type IMPLICIT_CONSENT: string
2964    @cvar EXPLICIT_CONSENT: Explicit consent URI.
2965    @type EXPLICIT_CONSENT: string
2966    @cvar UNAVAILABLE_CONSENT: Unavailable consent URI.
2967    @type UNAVAILABLE_CONSENT: string
2968    @cvar INAPPLICABLE_CONSENT: Inapplicable consent URI.
2969    @type INAPPLICABLE_CONSENT: string
2970   
2971    @ivar __version: SAML version
2972    @type __version: string
2973    @ivar __id: request identifier
2974    @type __id: string
2975    @ivar __issueInstant: issue instant
2976    @type __issueInstant: string
2977    @ivar __destination: destination for request
2978    @type __destination: string
2979    @ivar __consent: consent information
2980    @type __consent: string
2981    @ivar __issuer: request issuer identifier
2982    @type __issuer: string
2983    @ivar __extensions: request extensions
2984    @type __extensions: string
2985    '''
2986   
2987    # Local name of the XSI type.
2988    TYPE_LOCAL_NAME = "RequestAbstractType"
2989
2990    # QName of the XSI type.
2991    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
2992                      TYPE_LOCAL_NAME,
2993                      SAMLConstants.SAML20P_PREFIX)
2994
2995    # ID attribute name.
2996    ID_ATTRIB_NAME = "ID"
2997
2998    # Version attribute name.
2999    VERSION_ATTRIB_NAME = "Version"
3000
3001    # IssueInstant attribute name.
3002    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
3003
3004    # Destination attribute name.
3005    DESTINATION_ATTRIB_NAME = "Destination"
3006
3007    # Consent attribute name.
3008    CONSENT_ATTRIB_NAME = "Consent"
3009
3010    # Unspecified consent URI.
3011    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
3012
3013    # Obtained consent URI.
3014    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
3015
3016    # Prior consent URI.
3017    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
3018
3019    # Implicit consent URI.
3020    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
3021
3022    # Explicit consent URI.
3023    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
3024
3025    # Unavailable consent URI.
3026    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
3027
3028    # Inapplicable consent URI.
3029    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
3030     
3031    __slots__ = (
3032        '__version',
3033        '__id',
3034        '__issueInstant',
3035        '__destination',
3036        '__consent',
3037        '__issuer',
3038        '__extensions'
3039    )
3040   
3041    def __init__(self, **kw):
3042        '''Request abstract type
3043        @type kw: dict
3044        @param kw: see SAMLObject.__init__
3045        '''
3046        super(RequestAbstractType, self).__init__(**kw)
3047       
3048        # SAML Version of the request.
3049        self.__version = None
3050   
3051        # Unique identifier of the request.
3052        self.__id = None
3053   
3054        # Date/time request was issued.
3055        self.__issueInstant = None
3056   
3057        # URI of the request destination.
3058        self.__destination = None
3059   
3060        # URI of the SAML user consent type.
3061        self.__consent = None
3062   
3063        # URI of the SAML user consent type.
3064        self.__issuer = None
3065   
3066        # Extensions child element.
3067        self.__extensions = None
3068
3069    def __getstate__(self):
3070        '''Enable pickling
3071       
3072        @return: object's attribute dictionary
3073        @rtype: dict
3074        '''
3075
3076        _dict = super(RequestAbstractType, self).__getstate__()
3077        for attrName in RequestAbstractType.__slots__:
3078            # Ugly hack to allow for derived classes setting private member
3079            # variables
3080            if attrName.startswith('__'):
3081                attrName = "_RequestAbstractType" + attrName
3082               
3083            _dict[attrName] = getattr(self, attrName)
3084           
3085        return _dict
3086   
3087    def _get_version(self):
3088        '''
3089        @return: the SAML Version of this assertion
3090        @rtype: ndg.saml.common.SAMLVersion
3091        '''
3092        return self.__version
3093   
3094    def _set_version(self, version):
3095        '''
3096        @param version: the SAML Version of this assertion
3097        @type version: ndg.saml.common.SAMLVersion
3098        @raise TypeError: incorrect input version value type
3099        '''
3100        if not isinstance(version, SAMLVersion):
3101            raise TypeError("Expecting SAMLVersion type got: %r" % 
3102                            version.__class__)
3103       
3104        self.__version = version
3105       
3106    version = property(fget=_get_version,
3107                       fset=_set_version,
3108                       doc="SAML Version of the assertion")
3109
3110    def _get_issueInstant(self):
3111        '''Get the date/time the request was issued
3112       
3113        @return: the issue instance of this request
3114        @rtype: datetime.datetime
3115        '''
3116        return self.__issueInstant
3117   
3118    def _set_issueInstant(self, value):
3119        '''Sets the date/time the request was issued
3120       
3121        @param value: the issue instance of this request
3122        @type value: datetime.datetime
3123        '''
3124        if not isinstance(value, datetime):
3125            raise TypeError('Expecting "datetime" type for "issueInstant", '
3126                            'got %r' % type(value))
3127           
3128        self.__issueInstant = value
3129       
3130    issueInstant = property(fget=_get_issueInstant, 
3131                            fset=_set_issueInstant,
3132                            doc="Issue instant of the request") 
3133
3134    def _get_id(self):
3135        '''Get the unique identifier for this request
3136       
3137        @return: the ID of this request
3138        @rtype: basestring
3139        '''
3140        return self.__id
3141   
3142    def _set_id(self, value):
3143        '''Set the unique identifier for this request
3144       
3145        @param value: the ID of this assertion
3146        @type value: basestring
3147        @raise TypeError: incorrect input type
3148        '''
3149        if not isinstance(value, basestring):
3150            raise TypeError('Expecting basestring derived type for "id", got '
3151                            '%r' % type(value))
3152        self.__id = value
3153       
3154    id = property(fget=_get_id, fset=_set_id, doc="ID of request")
3155
3156    def _get_destination(self):
3157        '''Get the URI of the destination of the request
3158       
3159        @return: the URI of the destination of the request
3160        @rtype: basestring
3161        '''
3162        return self.__destination
3163   
3164    def _set_destination(self, value):
3165        '''Set the URI of the destination of the request
3166       
3167        @param value: the URI of the destination of the request
3168        @type value: basestring
3169        @raise TypeError: incorrect input value type
3170        '''
3171        if not isinstance(value, basestring):
3172            raise TypeError('Expecting basestring derived type for '
3173                            '"destination", got %r' % type(value))
3174        self.__destination = value
3175       
3176    destination = property(fget=_get_destination, 
3177                           fset=_set_destination,
3178                           doc="Destination of request")
3179     
3180    def _get_consent(self):
3181        '''Get the consent obtained from the principal for sending this
3182        request
3183       
3184        @return: the consent obtained from the principal for sending this
3185        request
3186        @rtype: basestring
3187        '''
3188        return self.__consent
3189       
3190    def _set_consent(self, value):
3191        '''Set the consent obtained from the principal for sending this
3192        request
3193       
3194        @param value: the new consent obtained from the principal for
3195        sending this request
3196        @type value: basestring
3197        @raise TypeError: incorrect input type
3198        ''' 
3199        if not isinstance(value, basestring):
3200            raise TypeError('Expecting basestring derived type for "consent", '
3201                            'got %r' % type(value))
3202        self.__consent = value
3203             
3204    consent = property(fget=_get_consent, 
3205                       fset=_set_consent,
3206                       doc="Consent for request")
3207   
3208    def _set_issuer(self, issuer):
3209        """Set issuer of request
3210       
3211        @param issuer: issuer of the request
3212        @type issuer: ndg.saml.saml2.coreIssuer
3213        @raise TypeError: incorrect input type
3214        """
3215        if not isinstance(issuer, Issuer):
3216            raise TypeError('"issuer" must be a %r, got %r' % (Issuer, 
3217                                                               type(issuer)))
3218       
3219        self.__issuer = issuer
3220   
3221    def _get_issuer(self):
3222        """Get the issuer name
3223               
3224        @return: issuer of the request
3225        @rtype: ndg.saml.saml2.coreIssuer
3226        """
3227        return self.__issuer
3228
3229    issuer = property(fget=_get_issuer, 
3230                      fset=_set_issuer,
3231                      doc="Issuer of request")
3232 
3233    def _get_extensions(self):
3234        '''Get the Extensions of this request
3235       
3236        @return: the Status of this request
3237        @rtype: iterable
3238        '''
3239        return self.__extensions
3240     
3241    def _set_extensions(self, value):
3242        '''Sets the Extensions of this request.
3243       
3244        @param value: the Extensions of this request
3245        @type value: iterable
3246        '''
3247        self.__extensions = value
3248       
3249    extensions = property(fget=_get_extensions, 
3250                          fset=_set_extensions,
3251                          doc="Request extensions")
3252
3253
3254class SubjectQuery(RequestAbstractType):
3255    """SAML 2.0 Core Subject Query type
3256   
3257    @cvar DEFAULT_ELEMENT_LOCAL_NAME: XML element name for Subject Query
3258    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3259   
3260    @ivar __subject: subject for this query
3261    @type __subject: ndg.saml.saml2.core.Subject
3262    """
3263   
3264    DEFAULT_ELEMENT_LOCAL_NAME = 'SubjectQuery'
3265   
3266    __slots__ = ('__subject', )
3267   
3268    def __init__(self, **kw):
3269        '''Subject Query initialisation
3270        @type kw: dict
3271        @param kw: keywords to set attributes of superclasses
3272        '''
3273        super(SubjectQuery, self).__init__(**kw)
3274        self.__subject = None
3275
3276    def __getstate__(self):
3277        '''Enable pickling
3278       
3279        @return: object's attribute dictionary
3280        @rtype: dict
3281        '''
3282
3283        _dict = super(SubjectQuery, self).__getstate__()
3284        for attrName in SubjectQuery.__slots__:
3285            # Ugly hack to allow for derived classes setting private member
3286            # variables
3287            if attrName.startswith('__'):
3288                attrName = "_SubjectQuery" + attrName
3289               
3290            _dict[attrName] = getattr(self, attrName)
3291           
3292        return _dict
3293           
3294    def _getSubject(self):
3295        '''Gets the Subject of this request.
3296       
3297        @return: the Subject of this request
3298        @rtype: ndg.saml.saml2.core.Subject
3299        '''   
3300        return self.__subject
3301   
3302    def _setSubject(self, value):
3303        '''Sets the Subject of this request.
3304       
3305        @param value: the Subject of this request
3306        @type value: ndg.saml.saml2.core.Subject
3307        @raise TypeError: incorrect input type
3308        '''
3309        if not isinstance(value, Subject):
3310            raise TypeError('Setting "subject", got %r, expecting %r' %
3311                            (Subject, type(value)))
3312           
3313        self.__subject = value
3314       
3315    subject = property(fget=_getSubject, fset=_setSubject, doc="Query subject")
3316   
3317   
3318class AttributeQuery(SubjectQuery):
3319    '''SAML 2.0 AttributeQuery
3320   
3321    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3322    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3323    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3324    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3325    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3326    @type TYPE_LOCAL_NAME: string
3327    @cvar TYPE_NAME: QName of the XSI type.
3328    @type TYPE_NAME: ndg.saml.common.xml.QName
3329
3330    @ivar __attributes: list of attributes for this query
3331    @type __attributes: TypedList
3332    '''
3333   
3334    # Element local name.
3335    DEFAULT_ELEMENT_LOCAL_NAME = "AttributeQuery"
3336
3337    # Default element name.
3338    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
3339                                 DEFAULT_ELEMENT_LOCAL_NAME,
3340                                 SAMLConstants.SAML20P_PREFIX)
3341
3342    # Local name of the XSI type.
3343    TYPE_LOCAL_NAME = "AttributeQueryType"
3344
3345    # QName of the XSI type.
3346    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
3347                      TYPE_LOCAL_NAME,
3348                      SAMLConstants.SAML20P_PREFIX)
3349
3350    __slots__ = ('__attributes',)
3351   
3352    def __init__(self, **kw):
3353        '''Attribute Query initialisation
3354        @type kw: dict
3355        @param kw: keywords to set attributes of superclasses
3356        '''
3357        super(AttributeQuery, self).__init__(**kw)
3358        self.__attributes = TypedList(Attribute)
3359
3360    def __getstate__(self):
3361        '''Enable pickling
3362       
3363        @return: object's attribute dictionary
3364        @rtype: dict
3365        '''
3366
3367        _dict = super(AttributeQuery, self).__getstate__()
3368        for attrName in AttributeQuery.__slots__:
3369            # Ugly hack to allow for derived classes setting private member
3370            # variables
3371            if attrName.startswith('__'):
3372                attrName = "_AttributeQuery" + attrName
3373               
3374            _dict[attrName] = getattr(self, attrName)
3375           
3376        return _dict
3377 
3378    def _getAttributes(self):
3379        '''Get the Attributes of this query
3380       
3381        @return: the list of Attributes of this query
3382        @rtype: ndg.saml.utils.TypedList'''
3383        return self.__attributes
3384
3385    def _setAttributes(self, value):
3386        '''Set the attributes for this query
3387       
3388        @param value: new attributes for this query
3389        @type value: TypedList
3390        @raise TypeError: incorrect type for attributes list
3391        '''
3392        if not isinstance(value, TypedList):
3393            raise TypeError('Expecting %r type for "attributes"; got %r' %
3394                            (TypedList, (type)))
3395       
3396        if not issubclass(value.elementType, Attribute):
3397            raise TypeError('Expecting %r derived type for "attributes" '
3398                            'elements; got %r' % (Attribute, value.elementType))
3399           
3400        self.__attributes = value
3401
3402    attributes = property(fget=_getAttributes, 
3403                          fset=_setAttributes, 
3404                          doc="Attributes")
3405
3406
3407class Evidentiary(SAMLObject):
3408    """Base class for types set in an evidence object"""
3409    __slots__ = ()
3410
3411
3412class AssertionURIRef(Evidentiary):
3413    '''SAML 2.0 Core AssertionURIRef
3414   
3415    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name
3416    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3417    @cvar DEFAULT_ELEMENT_NAME: Default element name
3418    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3419
3420    @ivar __assertionURI: URI for this assertion reference
3421    @type __assertionURI: basestring
3422    '''
3423    __slots__ = ('__assertionURI',)
3424   
3425    # Element local name
3426    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionURIRef"
3427
3428    # Default element name
3429    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3430                                 DEFAULT_ELEMENT_LOCAL_NAME,
3431                                 SAMLConstants.SAML20_PREFIX)
3432   
3433    def __init__(self, **kw):
3434        '''Create assertion URI reference
3435       
3436        @param **kw: keywords to initialise superclasses
3437        @type **kw: dict
3438        '''
3439        super(AssertionURIRef, self).__init__(**kw)
3440       
3441        # URI of the Assertion
3442        self.__assertionURI = None   
3443
3444    def __getstate__(self):
3445        '''Enable pickling
3446       
3447        @return: object's attribute dictionary
3448        @rtype: dict
3449        '''
3450        _dict = super(AssertionURIRef, self).__getstate__()
3451        for attrName in AssertionURIRef.__slots__:
3452            # Ugly hack to allow for derived classes setting private member
3453            # variables
3454            if attrName.startswith('__'):
3455                attrName = "_AssertionURIRef" + attrName
3456               
3457            _dict[attrName] = getattr(self, attrName)
3458           
3459        return _dict
3460   
3461    def _getAssertionURI(self):
3462        '''Get assertion URI
3463       
3464        @return assertionURI: assertion URI
3465        @rtype assertionURI: basestring
3466        '''
3467        return self.__assertionURI
3468
3469    def _setAssertionURI(self, value):
3470        '''Set assertion URI
3471       
3472        @param assertionURI: assertion URI
3473        @type assertionURI: basestring
3474        @raise TypeError: incorrect input value type
3475        '''
3476        if not isinstance(value, basestring):
3477            raise TypeError('Expecting string type for "assertionID" '
3478                            'attribute; got %r' % type(value))
3479        self.__assertionURI = value
3480
3481    def getOrderedChildren(self):
3482        """Return list of all attributes - not implemented for this class
3483        """
3484
3485    assertionURI = property(_getAssertionURI, _setAssertionURI, 
3486                            doc="Assertion URI")
3487   
3488   
3489class AssertionIDRef(Evidentiary):
3490    '''SAML 2.0 Core AssertionIDRef.
3491   
3492    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3493    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3494    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3495    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3496
3497    @ivar __assertionID: assertion identifier
3498    @type __assertionID: basestring
3499    '''
3500
3501    # Element local name.
3502    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionIDRef"
3503
3504    # Default element name.
3505    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3506                                 DEFAULT_ELEMENT_LOCAL_NAME,
3507                                 SAMLConstants.SAML20_PREFIX)
3508   
3509    __slots__ = ("__assertionID",)
3510   
3511    def __init__(self, **kw):
3512        '''
3513        @param **kw: keywords for superclass initialisation
3514        @type **kw: dict
3515        '''
3516        super(AssertionIDRef, self).__init__(**kw)
3517        self.__assertionID = None
3518
3519    def __getstate__(self):
3520        '''Enable pickling
3521       
3522        @return: object's attribute dictionary
3523        @rtype: dict
3524        '''
3525
3526        _dict = super(AssertionIDRef, self).__getstate__()
3527        for attrName in AssertionIDRef.__slots__:
3528            # Ugly hack to allow for derived classes setting private member
3529            # variables
3530            if attrName.startswith('__'):
3531                attrName = "_AssertionIDRef" + attrName
3532               
3533            _dict[attrName] = getattr(self, attrName)
3534           
3535        return _dict
3536       
3537    def _getAssertionID(self):
3538        '''Get the ID of the assertion this references
3539       
3540        @return: the ID of the assertion this references
3541        @rtype: basestring
3542        '''
3543        return self.__assertionID
3544       
3545    def _setAssertionID(self, value):
3546        '''Sets the ID of the assertion this references.
3547       
3548        @param value: the ID of the assertion this references
3549        @type value: basestring
3550        @raise TypeError: incorrect type for input value
3551        '''
3552        if not isinstance(value, basestring):
3553            raise TypeError('Expecting string type for "assertionID" '
3554                            'attribute; got %r' % type(value))
3555        self.__assertionID = value
3556
3557    def getOrderedChildren(self):
3558        '''Get attributes for this element as a list - not implemented for this
3559        class'''
3560
3561    assertionID = property(_getAssertionID, _setAssertionID, 
3562                           doc="Assertion ID")
3563       
3564   
3565class EncryptedElementType(SAMLObject):
3566    '''SAML 2.0 Core EncryptedElementType
3567   
3568    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3569    @type TYPE_LOCAL_NAME: string
3570    @cvar TYPE_NAME: QName of the XSI type.
3571    @type TYPE_NAME: string
3572
3573    '''
3574   
3575    # Local name of the XSI type.
3576    TYPE_LOCAL_NAME = "EncryptedElementType"
3577       
3578    # QName of the XSI type.
3579    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
3580                      TYPE_LOCAL_NAME, 
3581                      SAMLConstants.SAML20_PREFIX)
3582   
3583    __slots__ = ()
3584   
3585    def _getEncryptedData(self):
3586        '''Get the EncryptedData child element.  Not currently implemented
3587       
3588        @return: the EncryptedData child element'''
3589        raise NotImplementedError()
3590   
3591    def _setEncryptedData(self, value):
3592        '''Set the EncryptedData child element.  Not currently implemented
3593       
3594        @param value: the new EncryptedData child element'''
3595        raise NotImplementedError()
3596   
3597    def _getEncryptedKeys(self):
3598        '''A list of EncryptedKey child elements.  Not currently implemented
3599       
3600        @return: a list of EncryptedKey child elements'''
3601        raise NotImplementedError()
3602   
3603   
3604class EncryptedAssertion(EncryptedElementType, Evidentiary):
3605    '''SAML 2.0 Core EncryptedAssertion
3606   
3607    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3608    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3609    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3610    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3611    '''
3612   
3613    # Element local name.
3614    DEFAULT_ELEMENT_LOCAL_NAME = "EncryptedAssertion"
3615
3616    # Default element name.
3617    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3618                                 DEFAULT_ELEMENT_LOCAL_NAME,
3619                                 SAMLConstants.SAML20_PREFIX) 
3620    __slots__ = ()
3621     
3622   
3623class Evidence(SAMLObject):
3624    '''SAML 2.0 Core Evidence
3625   
3626    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3627    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3628    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3629    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3630    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3631    @type TYPE_LOCAL_NAME: string
3632    @cvar TYPE_NAME: QName of the XSI type.
3633    @type TYPE_NAME: ndg.saml.common.xml.QName
3634   
3635    @ivar __values: list of evidence values
3636    @type __values: ndg.saml.utils.TypedList
3637    '''
3638   
3639    # Element local name.
3640    DEFAULT_ELEMENT_LOCAL_NAME = "Evidence"
3641   
3642    # Default element name.
3643    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3644                                 DEFAULT_ELEMENT_LOCAL_NAME, 
3645                                 SAMLConstants.SAML20_PREFIX)
3646   
3647    # Local name of the XSI type.
3648    TYPE_LOCAL_NAME = "EvidenceType" 
3649       
3650    # QName of the XSI type.
3651    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
3652                      TYPE_LOCAL_NAME, 
3653                      SAMLConstants.SAML20_PREFIX)
3654
3655    __slots__ = ('__values',)
3656   
3657    def __init__(self, **kw):
3658        '''Create an authorization evidence type
3659       
3660        @param **kw: keyword to initialise superclasses
3661        @type **kw: dict
3662        '''
3663        super(Evidence, self).__init__(**kw)
3664
3665        # Assertion of the Evidence.
3666        self.__values = TypedList(Evidentiary) 
3667
3668    def __getstate__(self):
3669        '''Enable pickling
3670       
3671        @return: object's attribute dictionary
3672        @rtype: dict
3673        '''
3674
3675        _dict = super(Evidence, self).__getstate__()
3676        for attrName in Evidence.__slots__:
3677            # Ugly hack to allow for derived classes setting private member
3678            # variables
3679            if attrName.startswith('__'):
3680                attrName = "_Evidence" + attrName
3681               
3682            _dict[attrName] = getattr(self, attrName)
3683           
3684        return _dict   
3685         
3686    @property
3687    def assertionIDReferences(self):
3688        '''Get the list of Assertion ID references used as evidence
3689   
3690        @return: the list of AssertionID references used as evidence
3691        @rtype: list
3692        '''
3693        return [i for i in self.__values
3694                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3695                    AssertionIDRef.DEFAULT_ELEMENT_NAME)]
3696   
3697    @property
3698    def assertionURIReferences(self):
3699        '''Get the list of Assertion URI references used as evidence
3700       
3701        @return: the list of AssertionURI references used as evidence
3702        @rtype: list'''
3703        return [i for i in self.__values
3704                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3705                    AssertionURIRef.DEFAULT_ELEMENT_NAME)]
3706   
3707    @property
3708    def assertions(self):
3709        '''Get the list of Assertions used as evidence
3710       
3711        @return: the list of Assertions used as evidence
3712        @rtype: list
3713        '''
3714        return [i for i in self.__values
3715                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3716                    Assertion.DEFAULT_ELEMENT_NAME)]
3717   
3718    @property
3719    def encryptedAssertions(self):
3720        '''Gets the list of EncryptedAssertions used as evidence.
3721       
3722        @return: the list of EncryptedAssertions used as evidence
3723        @rtype: list
3724        '''
3725        return [i for i in self.__values
3726                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3727                    EncryptedAssertion.DEFAULT_ELEMENT_NAME)]   
3728
3729    @property
3730    def values(self):
3731        '''Get the list of all elements used as evidence.
3732       
3733        @return: the list of Evidentiary objects used as evidence
3734        @rtype: ndg.saml.utils.TypedList
3735        '''
3736        return self.__values
3737   
3738    def getOrderedChildren(self):
3739        '''Return list of evidence objects
3740        '''
3741        children = []
3742
3743        if len(self.__values) == 0:
3744            return None
3745
3746        children.extend(self.__values)
3747
3748        return tuple(children)
3749   
3750
3751class AuthzDecisionQuery(SubjectQuery):
3752    '''SAML 2.0 AuthzDecisionQuery
3753   
3754    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3755    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3756    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3757    @type DEFAULT_ELEMENT_NAME: string
3758    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3759    @type TYPE_LOCAL_NAME: string
3760    @cvar TYPE_NAME: QName of the XSI type.
3761    @type TYPE_NAME: string
3762    @cvar RESOURCE_ATTRIB_NAME: Resource attribute name.
3763    @type RESOURCE_ATTRIB_NAME: string
3764   
3765    @ivar resource: Resource attribute value.
3766    @type resource: string
3767    @ivar evidence: Evidence child element.
3768    @type evidence: string
3769    @ivar actions: Action child elements.
3770    @type actions: string
3771    @ivar normalizeResource: Set to Truefor normalization of resource URIs in
3772    property set method
3773    @type normalizeResource: bool
3774    @ivar safeNormalizationChars: safe character settings for normalisation
3775    @type safeNormalizationChars: string
3776    '''
3777
3778    # Element local name.
3779    DEFAULT_ELEMENT_LOCAL_NAME = "AuthzDecisionQuery"
3780
3781    # Default element name.
3782    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
3783                                 DEFAULT_ELEMENT_LOCAL_NAME,
3784                                 SAMLConstants.SAML20P_PREFIX)
3785
3786    # Local name of the XSI type.
3787    TYPE_LOCAL_NAME = "AuthzDecisionQueryType"
3788
3789    # QName of the XSI type.
3790    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
3791                      TYPE_LOCAL_NAME,
3792                      SAMLConstants.SAML20P_PREFIX)
3793
3794    # Resource attribute name.
3795    RESOURCE_ATTRIB_NAME = "Resource"
3796   
3797    __slots__ = (
3798       '__resource',
3799       '__evidence',
3800       '__actions',
3801       '__normalizeResource',
3802       '__safeNormalizationChars'
3803    )
3804   
3805    def __init__(self, normalizeResource=True, safeNormalizationChars='/%'):
3806        '''Create new authorisation decision query
3807        '''
3808        super(AuthzDecisionQuery, self).__init__()
3809
3810        # Resource attribute value.
3811        self.__resource = None
3812   
3813        # Evidence child element.
3814        self.__evidence = None
3815   
3816        # Action child elements.
3817        self.__actions = TypedList(Action)   
3818       
3819        # Tuning for normalization of resource URIs in property set method
3820        self.normalizeResource = normalizeResource
3821        self.safeNormalizationChars = safeNormalizationChars
3822
3823    def __getstate__(self):
3824        '''Enable pickling
3825       
3826        @return: object's attribute dictionary
3827        @rtype: dict
3828        '''
3829
3830        _dict = super(AuthzDecisionQuery, self).__getstate__()
3831        for attrName in AuthzDecisionQuery.__slots__:
3832            # Ugly hack to allow for derived classes setting private member
3833            # variables
3834            if attrName.startswith('__'):
3835                attrName = "_AuthzDecisionQuery" + attrName
3836               
3837            _dict[attrName] = getattr(self, attrName)
3838           
3839        return _dict
3840   
3841    def _getNormalizeResource(self):
3842        '''
3843        @return: flag to set whether to apply normalisation of resource URI or
3844        not
3845        @rtype: bool
3846        '''
3847        return self.__normalizeResource
3848
3849    def _setNormalizeResource(self, value):
3850        '''
3851        @param value: flag to set whether to apply normalisation of resource URI
3852        or not
3853        @type value: bool
3854        @raise TypeError: incorrect type for input value
3855        '''
3856        if not isinstance(value, bool):
3857            raise TypeError('Expecting bool type for "normalizeResource" '
3858                            'attribute; got %r instead' % type(value))
3859           
3860        self.__normalizeResource = value
3861
3862    normalizeResource = property(_getNormalizeResource, 
3863                                 _setNormalizeResource, 
3864                                 doc="Flag to normalize new resource value "
3865                                     "assigned to the \"resource\" property.  "
3866                                     "The setting only applies for URIs "
3867                                     'beginning with "http://" or "https://"')
3868
3869    def _getSafeNormalizationChars(self):
3870        '''
3871        @param value: safe normalisation characters for input into normalisation
3872        of resource URI.
3873        @type value: string
3874        @raise TypeError: incorrect type for input value
3875        '''
3876        return self.__safeNormalizationChars
3877
3878    def _setSafeNormalizationChars(self, value):
3879        '''
3880        @param value: safe normalisation characters for input into normalisation
3881        of resource URI.  It only applies if normalizeResource is set to True
3882        @type value: string
3883        @raise TypeError: incorrect type for input value
3884        '''
3885        if not isinstance(value, basestring):
3886            raise TypeError('Expecting string type for "normalizeResource" '
3887                            'attribute; got %r instead' % type(value))
3888           
3889        self.__safeNormalizationChars = value
3890
3891    safeNormalizationChars = property(_getSafeNormalizationChars, 
3892                                      _setSafeNormalizationChars, 
3893                                      doc="String containing a list of "
3894                                          "characters that should not be "
3895                                          "converted when Normalizing the "
3896                                          "resource URI.  These are passed to "
3897                                          "urllib.quote when the resource "
3898                                          "property is set.  The default "
3899                                          "characters are '/%'")
3900
3901    def _getResource(self):
3902        '''Get the Resource attrib value of this query
3903
3904        @return: the Resource attrib value of this query
3905        @rtype: basestring
3906        '''
3907        return self.__resource
3908   
3909    def _setResource(self, value):
3910        '''Sets the Resource attrib value of this query.
3911       
3912        If normalizeResource attribute is True, the path is normalized
3913        removing spurious port numbers (80 for HTTP and 443 for HTTPS) and
3914        converting the host component to lower case.
3915       
3916        @param value: the new Resource attrib value of this query
3917        @type value: basestring
3918        @raise TypeError: if incorrect input type
3919        '''
3920        if not isinstance(value, basestring):
3921            raise TypeError('Expecting string type for "resource" attribute; '
3922                            'got %r instead' % type(value))
3923       
3924        if (self.normalizeResource and 
3925            value.startswith('http://') or value.startswith('https://')):
3926            # Normalise the path, set the host name to lower case and remove
3927            # port redundant numbers 80 and 443
3928            splitResult = urlsplit(value)
3929            uriComponents = list(splitResult)
3930           
3931            # hostname attribute is lowercase
3932            uriComponents[1] = splitResult.hostname
3933           
3934            if splitResult.port is not None:
3935                isHttpWithStdPort = (splitResult.port == 80 and 
3936                                     splitResult.scheme == 'http')
3937               
3938                isHttpsWithStdPort = (splitResult.port == 443 and
3939                                      splitResult.scheme == 'https')
3940               
3941                if not isHttpWithStdPort and not isHttpsWithStdPort:
3942                    uriComponents[1] += ":%d" % splitResult.port
3943           
3944            uriComponents[2] = urllib.quote(splitResult.path, 
3945                                            self.safeNormalizationChars)
3946           
3947            self.__resource = urlunsplit(uriComponents)
3948        else:
3949            self.__resource = value
3950   
3951    resource = property(fget=_getResource, fset=_setResource,
3952                        doc="Resource for which authorisation is requested")
3953   
3954    @property
3955    def actions(self):
3956        '''The actions for which authorisation is requested
3957       
3958        @return: the Actions of this query
3959        @rtype: ndg.saml.utils.TypedList
3960        '''
3961        return self.__actions
3962   
3963    def _getEvidence(self):
3964        '''Get the Evidence of this query
3965
3966        @return: the Evidence of this query
3967        @rtype: ndg.saml.saml2.core.Evidence or NoneType
3968        '''
3969        return self.__evidence
3970
3971    def _setEvidence(self, value):
3972        '''Set the Evidence of this query
3973       
3974        @param value: the new Evidence of this query
3975        @type value: ndg.saml.saml2.core.Evidence
3976        @raise TypeError: incorrect input type
3977        ''' 
3978        if not isinstance(value, Evidence):
3979            raise TypeError('Expecting Evidence type for "evidence" '
3980                            'attribute; got %r' % type(value))
3981
3982        self.__evidence = value 
3983
3984    evidence = property(fget=_getEvidence, fset=_setEvidence, 
3985                        doc="A set of assertions which the Authority may use "
3986                            "to base its authorisation decision on")
3987   
3988    def getOrderedChildren(self):
3989        '''Return attributes for this element as a tuple
3990       
3991        @return: attributes for this element
3992        @rtype: tuple
3993        '''
3994        children = []
3995
3996        superChildren = super(AuthzDecisionQuery, self).getOrderedChildren()
3997        if superChildren:
3998            children.extend(superChildren)
3999
4000        children.extend(self.__actions)
4001       
4002        if self.__evidence is not None:
4003            children.extend(self.__evidence)
4004
4005        if len(children) == 0:
4006            return None
4007
4008        return tuple(children)
4009
4010
4011class StatusResponseType(SAMLObject):
4012    '''SAML 2.0 Core Status Response Type
4013
4014    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
4015    @type TYPE_LOCAL_NAME: string
4016    @cvar TYPE_NAME: QName of the XSI type.
4017    @type TYPE_NAME: string
4018    @cvar ID_ATTRIB_NAME: ID attribute name
4019    @type ID_ATTRIB_NAME: string
4020    @cvar IN_RESPONSE_TO_ATTRIB_NAME: InResponseTo attribute name
4021    @type IN_RESPONSE_TO_ATTRIB_NAME: string
4022    @cvar VERSION_ATTRIB_NAME: Version attribute name
4023    @type VERSION_ATTRIB_NAME: string
4024    @cvar ISSUE_INSTANT_ATTRIB_NAME: IssueInstant attribute name
4025    @type ISSUE_INSTANT_ATTRIB_NAME: string
4026    @cvar DESTINATION_ATTRIB_NAME: Destination attribute name
4027    @type DESTINATION_ATTRIB_NAME: string
4028    @cvar CONSENT_ATTRIB_NAME: Consent attribute name.
4029    @type CONSENT_ATTRIB_NAME: string
4030    @cvar UNSPECIFIED_CONSENT: Unspecified consent URI
4031    @type UNSPECIFIED_CONSENT: string
4032    @cvar OBTAINED_CONSENT: Obtained consent URI
4033    @type OBTAINED_CONSENT: string
4034    @cvar PRIOR_CONSENT: Prior consent URI
4035    @type PRIOR_CONSENT: string
4036    @cvar IMPLICIT_CONSENT: Implicit consent URI
4037    @type IMPLICIT_CONSENT: string
4038    @cvar EXPLICIT_CONSENT: Explicit consent URI
4039    @type EXPLICIT_CONSENT: string
4040    @cvar UNAVAILABLE_CONSENT: Unavailable consent URI
4041    @type UNAVAILABLE_CONSENT: string
4042    @cvar INAPPLICABLE_CONSENT: Inapplicable consent URI
4043    @type INAPPLICABLE_CONSENT: string
4044
4045    '''
4046
4047    # Local name of the XSI type.
4048    TYPE_LOCAL_NAME = "StatusResponseType"
4049
4050    # QName of the XSI type.
4051    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
4052                      TYPE_LOCAL_NAME,
4053                      SAMLConstants.SAML20P_PREFIX)
4054
4055    # ID attribute name
4056    ID_ATTRIB_NAME = "ID"
4057
4058    # InResponseTo attribute name
4059    IN_RESPONSE_TO_ATTRIB_NAME = "InResponseTo"
4060
4061    # Version attribute name
4062    VERSION_ATTRIB_NAME = "Version"
4063
4064    # IssueInstant attribute name
4065    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
4066
4067    # Destination attribute name
4068    DESTINATION_ATTRIB_NAME = "Destination"
4069
4070    # Consent attribute name.
4071    CONSENT_ATTRIB_NAME = "Consent"
4072
4073    # Unspecified consent URI
4074    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
4075
4076    # Obtained consent URI
4077    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
4078
4079    # Prior consent URI
4080    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
4081
4082    # Implicit consent URI
4083    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
4084
4085    # Explicit consent URI
4086    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
4087
4088    # Unavailable consent URI
4089    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
4090
4091    # Inapplicable consent URI
4092    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
4093
4094    __slots__ = (   
4095        '__version',
4096        '__id',
4097        '__inResponseTo',
4098        '__issueInstant',
4099        '__destination',
4100        '__consent',
4101        '__issuer',
4102        '__status',
4103        '__extensions'               
4104    )
4105   
4106    def __init__(self, **kw):
4107        super(StatusResponseType, self).__init__(**kw)
4108       
4109        self.__version = SAMLVersion(SAMLVersion.VERSION_20)
4110        self.__id = None
4111        self.__inResponseTo = None
4112        self.__issueInstant = None
4113        self.__destination = None
4114        self.__consent = None
4115        self.__issuer = None
4116        self.__status = None
4117        self.__extensions = None
4118
4119    def __getstate__(self):
4120        '''Enable pickling
4121       
4122        @return: object's attribute dictionary
4123        @rtype: dict
4124        '''
4125
4126        _dict = super(StatusResponseType, self).__getstate__()
4127        for attrName in StatusResponseType.__slots__:
4128            # Ugly hack to allow for derived classes setting private member
4129            # variables
4130            if attrName.startswith('__'):
4131                attrName = "_StatusResponseType" + attrName
4132               
4133            _dict[attrName] = getattr(self, attrName)
4134           
4135        return _dict
4136   
4137    def _get_version(self):
4138        '''@return: the SAML Version of this response.
4139        '''
4140        return self.__version
4141   
4142    def _set_version(self, version):
4143        '''@param version: the SAML Version of this response
4144        '''
4145        if not isinstance(version, SAMLVersion):
4146            raise TypeError("Expecting SAMLVersion type got: %r" % 
4147                            version.__class__)
4148       
4149        self.__version = version
4150       
4151    version = property(fget=_get_version,
4152                       fset=_set_version,
4153                       doc="SAML Version of the response")
4154
4155    def _get_id(self):
4156        '''Sets the ID of this response.
4157       
4158        @return: the ID of this response
4159        '''
4160        return self.__id
4161   
4162    def _set_id(self, value):
4163        '''Sets the ID of this response.
4164       
4165        @param value: the ID of this response
4166        '''
4167        if not isinstance(value, basestring):
4168            raise TypeError('Expecting basestring derived type for "id", got '
4169                            '%r' % type(value))
4170        self.__id = value
4171       
4172    id = property(fget=_get_id, fset=_set_id, doc="ID of response")
4173
4174    def _getInResponseTo(self):
4175        '''Get the unique request identifier for which this is a response
4176       
4177        @return: the unique identifier of the originating
4178        request
4179        '''
4180        return self.__inResponseTo
4181   
4182    def _setInResponseTo(self, value):
4183        '''Set the unique request identifier for which this is a response
4184       
4185        @param value: the unique identifier of the originating
4186        request
4187        '''
4188        if not isinstance(value, basestring):
4189            raise TypeError('Expecting basestring derived type for '
4190                            '"inResponseTo", got %r' % type(value))
4191        self.__inResponseTo = value
4192       
4193    inResponseTo = property(fget=_getInResponseTo, 
4194                            fset=_setInResponseTo,
4195                            doc="unique request identifier for which this is "
4196                                "a response")
4197
4198    def _get_issueInstant(self):
4199        '''Gets the issue instance of this response.
4200       
4201        @return: the issue instance of this response'''
4202        return self.__issueInstant
4203   
4204    def _set_issueInstant(self, issueInstant):
4205        '''Sets the issue instance of this response.
4206       
4207        @param newIssueInstance: the issue instance of this response
4208        '''
4209        if not isinstance(issueInstant, datetime):
4210            raise TypeError('Expecting "datetime" type for "issueInstant", '
4211                            'got %r' % issueInstant.__class__)
4212           
4213        self.__issueInstant = issueInstant
4214       
4215    issueInstant = property(fget=_get_issueInstant, 
4216                            fset=_set_issueInstant,
4217                            doc="Issue instant of the response")
4218
4219    def _get_destination(self):
4220        '''Gets the URI of the destination of the response.
4221       
4222        @return: the URI of the destination of the response
4223        '''
4224        return self.__destination
4225   
4226    def _set_destination(self, value):
4227        '''Sets the URI of the destination of the response.
4228       
4229        @param value: the URI of the destination of the response'''
4230        if not isinstance(value, basestring):
4231            raise TypeError('Expecting basestring derived type for '
4232                            '"destination", got %r' % type(value))
4233        self.__destination = value
4234       
4235    destination = property(fget=_get_destination, 
4236                           fset=_set_destination,
4237                           doc="Destination of response")
4238     
4239    def _get_consent(self):
4240        '''Gets the consent obtained from the principal for sending this
4241        response.
4242       
4243        @return: the consent obtained from the principal for sending this
4244        response
4245        '''
4246        return self.__consent
4247       
4248    def _set_consent(self, value):
4249        '''Sets the consent obtained from the principal for sending this
4250        response.
4251       
4252        @param value: the new consent obtained from the principal for
4253        sending this response
4254        ''' 
4255        if not isinstance(value, basestring):
4256            raise TypeError('Expecting basestring derived type for "consent", '
4257                            'got %r' % type(value))
4258        self.__consent = value
4259             
4260    consent = property(fget=_get_consent, 
4261                       fset=_set_consent,
4262                       doc="Consent for response")
4263   
4264    def _set_issuer(self, issuer):
4265        """Set issuer of response"""
4266        if not isinstance(issuer, Issuer):
4267            raise TypeError('"issuer" must be a %r, got %r' % (Issuer,
4268                                                               type(issuer)))
4269        self.__issuer = issuer
4270   
4271    def _get_issuer(self):
4272        """Get the issuer name """
4273        return self.__issuer
4274
4275    issuer = property(fget=_get_issuer, 
4276                      fset=_set_issuer,
4277                      doc="Issuer of response")
4278   
4279    def _getStatus(self):
4280        '''Gets the Status of this response.
4281       
4282        @return: the Status of this response
4283        '''
4284        return self.__status
4285
4286    def _setStatus(self, value):
4287        '''Sets the Status of this response.
4288       
4289        @param newStatus: the Status of this response
4290        '''
4291        if not isinstance(value, Status):
4292            raise TypeError('"status" must be a %r, got %r' % (Status,
4293                                                               type(value)))
4294        self.__status = value
4295       
4296    status = property(fget=_getStatus, fset=_setStatus, doc="Response status")   
4297       
4298    def _get_extensions(self):
4299        '''Gets the Extensions of this response.
4300       
4301        @return: the Status of this response
4302        '''
4303        return self.__extensions
4304     
4305    def _set_extensions(self, value):
4306        '''Sets the Extensions of this response.
4307       
4308        @param value: the Extensions of this response
4309        '''
4310        if not isinstance(value, (list, tuple)):
4311            raise TypeError('Expecting list or tuple for "extensions", got %r'
4312                            % type(value))
4313        self.__extensions = value
4314       
4315    extensions = property(fget=_get_extensions, 
4316                          fset=_set_extensions,
4317                          doc="Response extensions")   
4318
4319
4320class Response(StatusResponseType):
4321    '''SAML2 Core Response'''
4322   
4323    # Element local name.
4324    DEFAULT_ELEMENT_LOCAL_NAME = "Response"
4325   
4326    # Default element name.
4327    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
4328                                 DEFAULT_ELEMENT_LOCAL_NAME, 
4329                                 SAMLConstants.SAML20P_PREFIX)
4330   
4331    # Local name of the XSI type.
4332    TYPE_LOCAL_NAME = "ResponseType"
4333       
4334    # QName of the XSI type.
4335    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
4336                      TYPE_LOCAL_NAME, 
4337                      SAMLConstants.SAML20P_PREFIX)
4338   
4339    __slots__ = ('__indexedChildren',)
4340   
4341    def __init__(self, **kw):
4342        '''''' 
4343        super(Response, self).__init__(**kw)
4344       
4345        # Assertion child elements
4346        self.__indexedChildren = []
4347
4348    def __getstate__(self):
4349        '''Enable pickling
4350       
4351        @return: object's attribute dictionary
4352        @rtype: dict
4353        '''
4354
4355        _dict = super(Response, self).__getstate__()
4356        for attrName in Response.__slots__:
4357            # Ugly hack to allow for derived classes setting private member
4358            # variables
4359            if attrName.startswith('__'):
4360                attrName = "_Response" + attrName
4361               
4362            _dict[attrName] = getattr(self, attrName)
4363           
4364        return _dict
4365       
4366    @property
4367    def assertions(self): 
4368        "Assertions contained in this response"
4369        return self.__indexedChildren
Note: See TracBrowser for help on using the repository browser.