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

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

Incomplete - task 2: XACML-Security Integration

  • Porting SAML SAOP binding code from ndg.security to ndg.saml - working SOAP package unit tests
  • Property svn:keywords set to Id
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: name
154        @type name: basestring
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 nameFormat: name format
177        @type nameFormat: 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 friendlyName: friendly name
200        @type friendlyName: 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 attributeValues: attribute values
223        @type attributeValues: list/tuple
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 value: 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 value: ?
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 value: 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 value: ?
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        @rtype: ?
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 value: ?
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 decision: decision type
611        @type decision: 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: 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 value: 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 value: base identifier
1075        @type value: 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 value: name identifier
1097        @type value: 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 value: encrypted identifier
1120        @type value: 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 value: name value
1302        @type value: 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 value: name qualifier
1323        @type value: 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 value: SP name qualifier
1341        @type value: 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 format: name format
1359        @type format: 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 value: SP provided identifier
1380        @type value: 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 value: 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 value: 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: 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: value
2089        @type value: 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 isinstance(value, TypedList) and not issubclass(value.elementType, 
3393                                                           Attribute):
3394            raise TypeError('Expecting %r derived type for "attributes" '
3395                            'elements; got %r' % (Attribute, value.elementType))
3396        else:
3397            self.__attributes = TypedList(Attribute)
3398            for i in value:
3399                self.__attributes.append(i)
3400           
3401    attributes = property(fget=_getAttributes, 
3402                          fset=_setAttributes, 
3403                          doc="Attributes")
3404
3405
3406class Evidentiary(SAMLObject):
3407    """Base class for types set in an evidence object"""
3408    __slots__ = ()
3409
3410
3411class AssertionURIRef(Evidentiary):
3412    '''SAML 2.0 Core AssertionURIRef
3413   
3414    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name
3415    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3416    @cvar DEFAULT_ELEMENT_NAME: Default element name
3417    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3418
3419    @ivar __assertionURI: URI for this assertion reference
3420    @type __assertionURI: basestring
3421    '''
3422    __slots__ = ('__assertionURI',)
3423   
3424    # Element local name
3425    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionURIRef"
3426
3427    # Default element name
3428    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3429                                 DEFAULT_ELEMENT_LOCAL_NAME,
3430                                 SAMLConstants.SAML20_PREFIX)
3431   
3432    def __init__(self, **kw):
3433        '''Create assertion URI reference
3434       
3435        @param kw: keywords to initialise superclasses
3436        @type kw: dict
3437        '''
3438        super(AssertionURIRef, self).__init__(**kw)
3439       
3440        # URI of the Assertion
3441        self.__assertionURI = None   
3442
3443    def __getstate__(self):
3444        '''Enable pickling
3445       
3446        @return: object's attribute dictionary
3447        @rtype: dict
3448        '''
3449        _dict = super(AssertionURIRef, self).__getstate__()
3450        for attrName in AssertionURIRef.__slots__:
3451            # Ugly hack to allow for derived classes setting private member
3452            # variables
3453            if attrName.startswith('__'):
3454                attrName = "_AssertionURIRef" + attrName
3455               
3456            _dict[attrName] = getattr(self, attrName)
3457           
3458        return _dict
3459   
3460    def _getAssertionURI(self):
3461        '''Get assertion URI
3462       
3463        @return: assertion URI
3464        @rtype: basestring
3465        '''
3466        return self.__assertionURI
3467
3468    def _setAssertionURI(self, value):
3469        '''Set assertion URI
3470       
3471        @param value: assertion URI
3472        @type value: basestring
3473        @raise TypeError: incorrect input value type
3474        '''
3475        if not isinstance(value, basestring):
3476            raise TypeError('Expecting string type for "assertionID" '
3477                            'attribute; got %r' % type(value))
3478        self.__assertionURI = value
3479
3480    def getOrderedChildren(self):
3481        """Return list of all attributes - not implemented for this class
3482        """
3483
3484    assertionURI = property(_getAssertionURI, _setAssertionURI, 
3485                            doc="Assertion URI")
3486   
3487   
3488class AssertionIDRef(Evidentiary):
3489    '''SAML 2.0 Core AssertionIDRef.
3490   
3491    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3492    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3493    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3494    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3495
3496    @ivar __assertionID: assertion identifier
3497    @type __assertionID: basestring
3498    '''
3499
3500    # Element local name.
3501    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionIDRef"
3502
3503    # Default element name.
3504    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3505                                 DEFAULT_ELEMENT_LOCAL_NAME,
3506                                 SAMLConstants.SAML20_PREFIX)
3507   
3508    __slots__ = ("__assertionID",)
3509   
3510    def __init__(self, **kw):
3511        '''
3512        @param kw: keywords for superclass initialisation
3513        @type kw: dict
3514        '''
3515        super(AssertionIDRef, self).__init__(**kw)
3516        self.__assertionID = None
3517
3518    def __getstate__(self):
3519        '''Enable pickling
3520       
3521        @return: object's attribute dictionary
3522        @rtype: dict
3523        '''
3524
3525        _dict = super(AssertionIDRef, self).__getstate__()
3526        for attrName in AssertionIDRef.__slots__:
3527            # Ugly hack to allow for derived classes setting private member
3528            # variables
3529            if attrName.startswith('__'):
3530                attrName = "_AssertionIDRef" + attrName
3531               
3532            _dict[attrName] = getattr(self, attrName)
3533           
3534        return _dict
3535       
3536    def _getAssertionID(self):
3537        '''Get the ID of the assertion this references
3538       
3539        @return: the ID of the assertion this references
3540        @rtype: basestring
3541        '''
3542        return self.__assertionID
3543       
3544    def _setAssertionID(self, value):
3545        '''Sets the ID of the assertion this references.
3546       
3547        @param value: the ID of the assertion this references
3548        @type value: basestring
3549        @raise TypeError: incorrect type for input value
3550        '''
3551        if not isinstance(value, basestring):
3552            raise TypeError('Expecting string type for "assertionID" '
3553                            'attribute; got %r' % type(value))
3554        self.__assertionID = value
3555
3556    def getOrderedChildren(self):
3557        '''Get attributes for this element as a list - not implemented for this
3558        class'''
3559
3560    assertionID = property(_getAssertionID, _setAssertionID, 
3561                           doc="Assertion ID")
3562       
3563   
3564class EncryptedElementType(SAMLObject):
3565    '''SAML 2.0 Core EncryptedElementType
3566   
3567    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3568    @type TYPE_LOCAL_NAME: string
3569    @cvar TYPE_NAME: QName of the XSI type.
3570    @type TYPE_NAME: string
3571
3572    '''
3573   
3574    # Local name of the XSI type.
3575    TYPE_LOCAL_NAME = "EncryptedElementType"
3576       
3577    # QName of the XSI type.
3578    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
3579                      TYPE_LOCAL_NAME, 
3580                      SAMLConstants.SAML20_PREFIX)
3581   
3582    __slots__ = ()
3583   
3584    def _getEncryptedData(self):
3585        '''Get the EncryptedData child element.  Not currently implemented
3586       
3587        @return: the EncryptedData child element'''
3588        raise NotImplementedError()
3589   
3590    def _setEncryptedData(self, value):
3591        '''Set the EncryptedData child element.  Not currently implemented
3592       
3593        @param value: the new EncryptedData child element'''
3594        raise NotImplementedError()
3595   
3596    def _getEncryptedKeys(self):
3597        '''A list of EncryptedKey child elements.  Not currently implemented
3598       
3599        @return: a list of EncryptedKey child elements'''
3600        raise NotImplementedError()
3601   
3602   
3603class EncryptedAssertion(EncryptedElementType, Evidentiary):
3604    '''SAML 2.0 Core EncryptedAssertion
3605   
3606    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3607    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3608    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3609    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3610    '''
3611   
3612    # Element local name.
3613    DEFAULT_ELEMENT_LOCAL_NAME = "EncryptedAssertion"
3614
3615    # Default element name.
3616    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3617                                 DEFAULT_ELEMENT_LOCAL_NAME,
3618                                 SAMLConstants.SAML20_PREFIX) 
3619    __slots__ = ()
3620     
3621   
3622class Evidence(SAMLObject):
3623    '''SAML 2.0 Core Evidence
3624   
3625    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3626    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3627    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3628    @type DEFAULT_ELEMENT_NAME: ndg.saml.common.xml.QName
3629    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3630    @type TYPE_LOCAL_NAME: string
3631    @cvar TYPE_NAME: QName of the XSI type.
3632    @type TYPE_NAME: ndg.saml.common.xml.QName
3633   
3634    @ivar __values: list of evidence values
3635    @type __values: ndg.saml.utils.TypedList
3636    '''
3637   
3638    # Element local name.
3639    DEFAULT_ELEMENT_LOCAL_NAME = "Evidence"
3640   
3641    # Default element name.
3642    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS, 
3643                                 DEFAULT_ELEMENT_LOCAL_NAME, 
3644                                 SAMLConstants.SAML20_PREFIX)
3645   
3646    # Local name of the XSI type.
3647    TYPE_LOCAL_NAME = "EvidenceType" 
3648       
3649    # QName of the XSI type.
3650    TYPE_NAME = QName(SAMLConstants.SAML20_NS, 
3651                      TYPE_LOCAL_NAME, 
3652                      SAMLConstants.SAML20_PREFIX)
3653
3654    __slots__ = ('__values',)
3655   
3656    def __init__(self, **kw):
3657        '''Create an authorization evidence type
3658       
3659        @param kw: keyword to initialise superclasses
3660        @type kw: dict
3661        '''
3662        super(Evidence, self).__init__(**kw)
3663
3664        # Assertion of the Evidence.
3665        self.__values = TypedList(Evidentiary) 
3666
3667    def __getstate__(self):
3668        '''Enable pickling
3669       
3670        @return: object's attribute dictionary
3671        @rtype: dict
3672        '''
3673
3674        _dict = super(Evidence, self).__getstate__()
3675        for attrName in Evidence.__slots__:
3676            # Ugly hack to allow for derived classes setting private member
3677            # variables
3678            if attrName.startswith('__'):
3679                attrName = "_Evidence" + attrName
3680               
3681            _dict[attrName] = getattr(self, attrName)
3682           
3683        return _dict   
3684         
3685    @property
3686    def assertionIDReferences(self):
3687        '''Get the list of Assertion ID references used as evidence
3688   
3689        @return: the list of AssertionID references used as evidence
3690        @rtype: list
3691        '''
3692        return [i for i in self.__values
3693                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3694                    AssertionIDRef.DEFAULT_ELEMENT_NAME)]
3695   
3696    @property
3697    def assertionURIReferences(self):
3698        '''Get the list of Assertion URI references used as evidence
3699       
3700        @return: the list of AssertionURI references used as evidence
3701        @rtype: list'''
3702        return [i for i in self.__values
3703                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3704                    AssertionURIRef.DEFAULT_ELEMENT_NAME)]
3705   
3706    @property
3707    def assertions(self):
3708        '''Get the list of Assertions used as evidence
3709       
3710        @return: the list of Assertions used as evidence
3711        @rtype: list
3712        '''
3713        return [i for i in self.__values
3714                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3715                    Assertion.DEFAULT_ELEMENT_NAME)]
3716   
3717    @property
3718    def encryptedAssertions(self):
3719        '''Gets the list of EncryptedAssertions used as evidence.
3720       
3721        @return: the list of EncryptedAssertions used as evidence
3722        @rtype: list
3723        '''
3724        return [i for i in self.__values
3725                if (getattr(i, "DEFAULT_ELEMENT_NAME") == 
3726                    EncryptedAssertion.DEFAULT_ELEMENT_NAME)]   
3727
3728    @property
3729    def values(self):
3730        '''Get the list of all elements used as evidence.
3731       
3732        @return: the list of Evidentiary objects used as evidence
3733        @rtype: ndg.saml.utils.TypedList
3734        '''
3735        return self.__values
3736   
3737    def getOrderedChildren(self):
3738        '''Return list of evidence objects
3739        '''
3740        children = []
3741
3742        if len(self.__values) == 0:
3743            return None
3744
3745        children.extend(self.__values)
3746
3747        return tuple(children)
3748   
3749
3750class AuthzDecisionQuery(SubjectQuery):
3751    '''SAML 2.0 AuthzDecisionQuery
3752   
3753    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
3754    @type DEFAULT_ELEMENT_LOCAL_NAME: string
3755    @cvar DEFAULT_ELEMENT_NAME: Default element name.
3756    @type DEFAULT_ELEMENT_NAME: string
3757    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
3758    @type TYPE_LOCAL_NAME: string
3759    @cvar TYPE_NAME: QName of the XSI type.
3760    @type TYPE_NAME: string
3761    @cvar RESOURCE_ATTRIB_NAME: Resource attribute name.
3762    @type RESOURCE_ATTRIB_NAME: string
3763   
3764    @ivar resource: Resource attribute value.
3765    @type resource: string
3766    @ivar evidence: Evidence child element.
3767    @type evidence: string
3768    @ivar actions: Action child elements.
3769    @type actions: string
3770    @ivar normalizeResource: Set to Truefor normalization of resource URIs in
3771    property set method
3772    @type normalizeResource: bool
3773    @ivar safeNormalizationChars: safe character settings for normalisation
3774    @type safeNormalizationChars: string
3775    '''
3776
3777    # Element local name.
3778    DEFAULT_ELEMENT_LOCAL_NAME = "AuthzDecisionQuery"
3779
3780    # Default element name.
3781    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
3782                                 DEFAULT_ELEMENT_LOCAL_NAME,
3783                                 SAMLConstants.SAML20P_PREFIX)
3784
3785    # Local name of the XSI type.
3786    TYPE_LOCAL_NAME = "AuthzDecisionQueryType"
3787
3788    # QName of the XSI type.
3789    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
3790                      TYPE_LOCAL_NAME,
3791                      SAMLConstants.SAML20P_PREFIX)
3792
3793    # Resource attribute name.
3794    RESOURCE_ATTRIB_NAME = "Resource"
3795   
3796    __slots__ = (
3797       '__resource',
3798       '__evidence',
3799       '__actions',
3800       '__normalizeResource',
3801       '__safeNormalizationChars'
3802    )
3803   
3804    def __init__(self, normalizeResource=True, safeNormalizationChars='/%'):
3805        '''Create new authorisation decision query
3806        '''
3807        super(AuthzDecisionQuery, self).__init__()
3808
3809        # Resource attribute value.
3810        self.__resource = None
3811   
3812        # Evidence child element.
3813        self.__evidence = None
3814   
3815        # Action child elements.
3816        self.__actions = TypedList(Action)   
3817       
3818        # Tuning for normalization of resource URIs in property set method
3819        self.normalizeResource = normalizeResource
3820        self.safeNormalizationChars = safeNormalizationChars
3821
3822    def __getstate__(self):
3823        '''Enable pickling
3824       
3825        @return: object's attribute dictionary
3826        @rtype: dict
3827        '''
3828
3829        _dict = super(AuthzDecisionQuery, self).__getstate__()
3830        for attrName in AuthzDecisionQuery.__slots__:
3831            # Ugly hack to allow for derived classes setting private member
3832            # variables
3833            if attrName.startswith('__'):
3834                attrName = "_AuthzDecisionQuery" + attrName
3835               
3836            _dict[attrName] = getattr(self, attrName)
3837           
3838        return _dict
3839   
3840    def _getNormalizeResource(self):
3841        '''
3842        @return: flag to set whether to apply normalisation of resource URI or
3843        not
3844        @rtype: bool
3845        '''
3846        return self.__normalizeResource
3847
3848    def _setNormalizeResource(self, value):
3849        '''
3850        @param value: flag to set whether to apply normalisation of resource URI
3851        or not
3852        @type value: bool
3853        @raise TypeError: incorrect type for input value
3854        '''
3855        if not isinstance(value, bool):
3856            raise TypeError('Expecting bool type for "normalizeResource" '
3857                            'attribute; got %r instead' % type(value))
3858           
3859        self.__normalizeResource = value
3860
3861    normalizeResource = property(_getNormalizeResource, 
3862                                 _setNormalizeResource, 
3863                                 doc="Flag to normalize new resource value "
3864                                     "assigned to the \"resource\" property.  "
3865                                     "The setting only applies for URIs "
3866                                     'beginning with "http://" or "https://"')
3867
3868    def _getSafeNormalizationChars(self):
3869        '''
3870        @return: safe normalisation characters for input into normalisation
3871        of resource URI.
3872        @rtype: string
3873        '''
3874        return self.__safeNormalizationChars
3875
3876    def _setSafeNormalizationChars(self, value):
3877        '''
3878        @param value: safe normalisation characters for input into normalisation
3879        of resource URI.  It only applies if normalizeResource is set to True
3880        @type value: string
3881        @raise TypeError: incorrect type for input value
3882        '''
3883        if not isinstance(value, basestring):
3884            raise TypeError('Expecting string type for "normalizeResource" '
3885                            'attribute; got %r instead' % type(value))
3886           
3887        self.__safeNormalizationChars = value
3888
3889    safeNormalizationChars = property(_getSafeNormalizationChars, 
3890                                      _setSafeNormalizationChars, 
3891                                      doc="String containing a list of "
3892                                          "characters that should not be "
3893                                          "converted when Normalizing the "
3894                                          "resource URI.  These are passed to "
3895                                          "urllib.quote when the resource "
3896                                          "property is set.  The default "
3897                                          "characters are '/%'")
3898
3899    def _getResource(self):
3900        '''Get the Resource attrib value of this query
3901
3902        @return: the Resource attrib value of this query
3903        @rtype: basestring
3904        '''
3905        return self.__resource
3906   
3907    def _setResource(self, value):
3908        '''Sets the Resource attrib value of this query.
3909       
3910        If normalizeResource attribute is True, the path is normalized
3911        removing spurious port numbers (80 for HTTP and 443 for HTTPS) and
3912        converting the host component to lower case.
3913       
3914        @param value: the new Resource attrib value of this query
3915        @type value: basestring
3916        @raise TypeError: if incorrect input type
3917        '''
3918        if not isinstance(value, basestring):
3919            raise TypeError('Expecting string type for "resource" attribute; '
3920                            'got %r instead' % type(value))
3921       
3922        if (self.normalizeResource and 
3923            value.startswith('http://') or value.startswith('https://')):
3924            # Normalise the path, set the host name to lower case and remove
3925            # port redundant numbers 80 and 443
3926            splitResult = urlsplit(value)
3927            uriComponents = list(splitResult)
3928           
3929            # hostname attribute is lowercase
3930            uriComponents[1] = splitResult.hostname
3931           
3932            if splitResult.port is not None:
3933                isHttpWithStdPort = (splitResult.port == 80 and 
3934                                     splitResult.scheme == 'http')
3935               
3936                isHttpsWithStdPort = (splitResult.port == 443 and
3937                                      splitResult.scheme == 'https')
3938               
3939                if not isHttpWithStdPort and not isHttpsWithStdPort:
3940                    uriComponents[1] += ":%d" % splitResult.port
3941           
3942            uriComponents[2] = urllib.quote(splitResult.path, 
3943                                            self.safeNormalizationChars)
3944           
3945            self.__resource = urlunsplit(uriComponents)
3946        else:
3947            self.__resource = value
3948   
3949    resource = property(fget=_getResource, fset=_setResource,
3950                        doc="Resource for which authorisation is requested")
3951   
3952    @property
3953    def actions(self):
3954        '''The actions for which authorisation is requested
3955       
3956        @return: the Actions of this query
3957        @rtype: ndg.saml.utils.TypedList
3958        '''
3959        return self.__actions
3960   
3961    def _getEvidence(self):
3962        '''Get the Evidence of this query
3963
3964        @return: the Evidence of this query
3965        @rtype: ndg.saml.saml2.core.Evidence or NoneType
3966        '''
3967        return self.__evidence
3968
3969    def _setEvidence(self, value):
3970        '''Set the Evidence of this query
3971       
3972        @param value: the new Evidence of this query
3973        @type value: ndg.saml.saml2.core.Evidence
3974        @raise TypeError: incorrect input type
3975        ''' 
3976        if not isinstance(value, Evidence):
3977            raise TypeError('Expecting Evidence type for "evidence" '
3978                            'attribute; got %r' % type(value))
3979
3980        self.__evidence = value 
3981
3982    evidence = property(fget=_getEvidence, fset=_setEvidence, 
3983                        doc="A set of assertions which the Authority may use "
3984                            "to base its authorisation decision on")
3985   
3986    def getOrderedChildren(self):
3987        '''Return attributes for this element as a tuple
3988       
3989        @return: attributes for this element
3990        @rtype: tuple
3991        '''
3992        children = []
3993
3994        superChildren = super(AuthzDecisionQuery, self).getOrderedChildren()
3995        if superChildren:
3996            children.extend(superChildren)
3997
3998        children.extend(self.__actions)
3999       
4000        if self.__evidence is not None:
4001            children.extend(self.__evidence)
4002
4003        if len(children) == 0:
4004            return None
4005
4006        return tuple(children)
4007
4008
4009class StatusResponseType(SAMLObject):
4010    '''SAML 2.0 Core Status Response Type
4011
4012    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
4013    @type TYPE_LOCAL_NAME: string
4014    @cvar TYPE_NAME: QName of the XSI type.
4015    @type TYPE_NAME: ndg.saml.common.xml.QName
4016    @cvar ID_ATTRIB_NAME: ID attribute name
4017    @type ID_ATTRIB_NAME: string
4018    @cvar IN_RESPONSE_TO_ATTRIB_NAME: InResponseTo attribute name
4019    @type IN_RESPONSE_TO_ATTRIB_NAME: string
4020    @cvar VERSION_ATTRIB_NAME: Version attribute name
4021    @type VERSION_ATTRIB_NAME: string
4022    @cvar ISSUE_INSTANT_ATTRIB_NAME: IssueInstant attribute name
4023    @type ISSUE_INSTANT_ATTRIB_NAME: string
4024    @cvar DESTINATION_ATTRIB_NAME: Destination attribute name
4025    @type DESTINATION_ATTRIB_NAME: string
4026    @cvar CONSENT_ATTRIB_NAME: Consent attribute name.
4027    @type CONSENT_ATTRIB_NAME: string
4028    @cvar UNSPECIFIED_CONSENT: Unspecified consent URI
4029    @type UNSPECIFIED_CONSENT: string
4030    @cvar OBTAINED_CONSENT: Obtained consent URI
4031    @type OBTAINED_CONSENT: string
4032    @cvar PRIOR_CONSENT: Prior consent URI
4033    @type PRIOR_CONSENT: string
4034    @cvar IMPLICIT_CONSENT: Implicit consent URI
4035    @type IMPLICIT_CONSENT: string
4036    @cvar EXPLICIT_CONSENT: Explicit consent URI
4037    @type EXPLICIT_CONSENT: string
4038    @cvar UNAVAILABLE_CONSENT: Unavailable consent URI
4039    @type UNAVAILABLE_CONSENT: string
4040    @cvar INAPPLICABLE_CONSENT: Inapplicable consent URI
4041    @type INAPPLICABLE_CONSENT: string
4042
4043    @ivar __version: SAML version
4044    @type __version: string
4045    @ivar __id: response identifier
4046    @type __id: string
4047    @ivar __inResponseTo: identifier corresponding to the query this response is
4048    responding to
4049    @type __inResponseTo: string
4050    @ivar __issueInstant: issue instant for the response
4051    @type __issueInstant: datetime.datetime
4052    @ivar __destination: destination for the response
4053    @type __destination: string
4054    @ivar __consent: consent information
4055    @type __consent: string
4056    @ivar __issuer: issuer identifier
4057    @type __issuer: ndg.saml.saml2.core.Issuer
4058    @ivar __status: status of the response
4059    @type __status: ndg.saml.saml2.core.Status
4060    @ivar __extensions: response extensions
4061    @type __extensions: list or tuple
4062    '''
4063
4064    # Local name of the XSI type.
4065    TYPE_LOCAL_NAME = "StatusResponseType"
4066
4067    # QName of the XSI type.
4068    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
4069                      TYPE_LOCAL_NAME,
4070                      SAMLConstants.SAML20P_PREFIX)
4071
4072    # ID attribute name
4073    ID_ATTRIB_NAME = "ID"
4074
4075    # InResponseTo attribute name
4076    IN_RESPONSE_TO_ATTRIB_NAME = "InResponseTo"
4077
4078    # Version attribute name
4079    VERSION_ATTRIB_NAME = "Version"
4080
4081    # IssueInstant attribute name
4082    ISSUE_INSTANT_ATTRIB_NAME = "IssueInstant"
4083
4084    # Destination attribute name
4085    DESTINATION_ATTRIB_NAME = "Destination"
4086
4087    # Consent attribute name.
4088    CONSENT_ATTRIB_NAME = "Consent"
4089
4090    # Unspecified consent URI
4091    UNSPECIFIED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
4092
4093    # Obtained consent URI
4094    OBTAINED_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:obtained"
4095
4096    # Prior consent URI
4097    PRIOR_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:prior"
4098
4099    # Implicit consent URI
4100    IMPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:implicit"
4101
4102    # Explicit consent URI
4103    EXPLICIT_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:explicit"
4104
4105    # Unavailable consent URI
4106    UNAVAILABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:unavailable"
4107
4108    # Inapplicable consent URI
4109    INAPPLICABLE_CONSENT = "urn:oasis:names:tc:SAML:2.0:consent:inapplicable"
4110
4111    __slots__ = (   
4112        '__version',
4113        '__id',
4114        '__inResponseTo',
4115        '__issueInstant',
4116        '__destination',
4117        '__consent',
4118        '__issuer',
4119        '__status',
4120        '__extensions'               
4121    )
4122   
4123    def __init__(self, **kw):
4124        '''
4125        @param kw: keywords for initialisation of superclass
4126        @type kw: dict
4127        '''
4128        super(StatusResponseType, self).__init__(**kw)
4129       
4130        self.__version = SAMLVersion(SAMLVersion.VERSION_20)
4131        self.__id = None
4132        self.__inResponseTo = None
4133        self.__issueInstant = None
4134        self.__destination = None
4135        self.__consent = None
4136        self.__issuer = None
4137        self.__status = None
4138        self.__extensions = None
4139
4140    def __getstate__(self):
4141        '''Enable pickling
4142       
4143        @return: object's attribute dictionary
4144        @rtype: dict
4145        '''
4146
4147        _dict = super(StatusResponseType, self).__getstate__()
4148        for attrName in StatusResponseType.__slots__:
4149            # Ugly hack to allow for derived classes setting private member
4150            # variables
4151            if attrName.startswith('__'):
4152                attrName = "_StatusResponseType" + attrName
4153               
4154            _dict[attrName] = getattr(self, attrName)
4155           
4156        return _dict
4157   
4158    def _get_version(self):
4159        '''@return: the SAML Version of this response
4160        @rtype: string
4161        '''
4162        return self.__version
4163   
4164    def _set_version(self, version):
4165        '''@param version: the SAML Version of this response
4166        @type version: basestring
4167        @raise TypeError: incorrect type for input version
4168        '''
4169        if not isinstance(version, SAMLVersion):
4170            raise TypeError("Expecting SAMLVersion type got: %r" % 
4171                            version.__class__)
4172       
4173        self.__version = version
4174       
4175    version = property(fget=_get_version,
4176                       fset=_set_version,
4177                       doc="SAML Version of the response")
4178
4179    def _get_id(self):
4180        '''Sets the ID of this response.
4181       
4182        @return: the ID of this response
4183        @rtype: basestring
4184        '''
4185        return self.__id
4186   
4187    def _set_id(self, value):
4188        '''Sets the ID of this response.
4189       
4190        @param value: the ID of this response
4191        @type value: basestring
4192        @raise TypeError: incorrect type for input value
4193        '''
4194        if not isinstance(value, basestring):
4195            raise TypeError('Expecting basestring derived type for "id", got '
4196                            '%r' % type(value))
4197        self.__id = value
4198       
4199    id = property(fget=_get_id, fset=_set_id, doc="ID of response")
4200
4201    def _getInResponseTo(self):
4202        '''Get the unique request identifier for which this is a response
4203       
4204        @return: the unique identifier of the originating
4205        request
4206        @rtype: basestring
4207        '''
4208        return self.__inResponseTo
4209   
4210    def _setInResponseTo(self, value):
4211        '''Set the unique request identifier for which this is a response
4212       
4213        @param value: the unique identifier of the originating
4214        request
4215        @type value: basestring
4216        @raise TypeError: incorrect type for input value
4217        '''
4218        if not isinstance(value, basestring):
4219            raise TypeError('Expecting basestring derived type for '
4220                            '"inResponseTo", got %r' % type(value))
4221        self.__inResponseTo = value
4222       
4223    inResponseTo = property(fget=_getInResponseTo, 
4224                            fset=_setInResponseTo,
4225                            doc="unique request identifier for which this is "
4226                                "a response")
4227
4228    def _get_issueInstant(self):
4229        '''Gets the issue instant of this response.
4230       
4231        @return: the issue instant of this response
4232        @rtype: datetime.datetime'''
4233        return self.__issueInstant
4234   
4235    def _set_issueInstant(self, issueInstant):
4236        '''Set the issue instant of this response
4237       
4238        @param issueInstant: the issue instance of this response
4239        @type issueInstant: datetime.datetime
4240        @raise TypeError: incorrect type for input value
4241        '''
4242        if not isinstance(issueInstant, datetime):
4243            raise TypeError('Expecting "datetime" type for "issueInstant", '
4244                            'got %r' % issueInstant.__class__)
4245           
4246        self.__issueInstant = issueInstant
4247       
4248    issueInstant = property(fget=_get_issueInstant, 
4249                            fset=_set_issueInstant,
4250                            doc="Issue instant of the response")
4251
4252    def _get_destination(self):
4253        '''Gets the URI of the destination of the response.
4254       
4255        @return: the URI of the destination of the response
4256        @rtype: basestring
4257        '''
4258        return self.__destination
4259   
4260    def _set_destination(self, value):
4261        '''Sets the URI of the destination of the response.
4262       
4263        @param value: the URI of the destination of the response
4264        @type value: basestring
4265        @raise TypeError: incorrect type for input value
4266        '''
4267        if not isinstance(value, basestring):
4268            raise TypeError('Expecting basestring derived type for '
4269                            '"destination", got %r' % type(value))
4270        self.__destination = value
4271       
4272    destination = property(fget=_get_destination, 
4273                           fset=_set_destination,
4274                           doc="Destination of response")
4275     
4276    def _get_consent(self):
4277        '''Get the consent obtained from the principal for sending this
4278        response
4279       
4280        @return: the consent obtained from the principal for sending this
4281        response
4282        @rtype: basestring
4283        '''
4284        return self.__consent
4285       
4286    def _set_consent(self, value):
4287        '''Sets the consent obtained from the principal for sending this
4288        response.
4289       
4290        @param value: the new consent obtained from the principal for
4291        sending this response
4292        @type value: basestring
4293        @raise TypeError: incorrect type for input value
4294        ''' 
4295        if not isinstance(value, basestring):
4296            raise TypeError('Expecting basestring derived type for "consent", '
4297                            'got %r' % type(value))
4298        self.__consent = value
4299             
4300    consent = property(fget=_get_consent, 
4301                       fset=_set_consent,
4302                       doc="Consent for response")
4303   
4304    def _set_issuer(self, issuer):
4305        """Set issuer of response
4306       
4307        @param issuer: issuer of this response
4308        sending this response
4309        @type issuer: ndg.saml.saml2.core.Issuer
4310        @raise TypeError: incorrect type for input value
4311        """
4312        if not isinstance(issuer, Issuer):
4313            raise TypeError('"issuer" must be a %r, got %r' % (Issuer,
4314                                                               type(issuer)))
4315        self.__issuer = issuer
4316   
4317    def _get_issuer(self):
4318        """Get the issuer name
4319       
4320        @return: issuer of this response
4321        sending this response
4322        @rtype: ndg.saml.saml2.core.Issuer
4323        """
4324        return self.__issuer
4325
4326    issuer = property(fget=_get_issuer, 
4327                      fset=_set_issuer,
4328                      doc="Issuer of response")
4329   
4330    def _getStatus(self):
4331        '''Gets the Status of this response.
4332       
4333        @return: the Status of this response
4334        @rtype: ndg.saml.saml2.core.Status
4335        '''
4336        return self.__status
4337
4338    def _setStatus(self, value):
4339        '''Sets the Status of this response.
4340       
4341        @param value: the Status of this response
4342        @type value: ndg.saml.saml2.core.Status
4343        @raise TypeError: incorrect type for input value
4344        '''
4345        if not isinstance(value, Status):
4346            raise TypeError('"status" must be a %r, got %r' % (Status,
4347                                                               type(value)))
4348        self.__status = value
4349       
4350    status = property(fget=_getStatus, fset=_setStatus, doc="Response status")   
4351       
4352    def _get_extensions(self):
4353        '''Gets the Extensions of this response.
4354       
4355        @return: the Status of this response
4356        @rtype: tuple/list/NoneType
4357        '''
4358        return self.__extensions
4359     
4360    def _set_extensions(self, value):
4361        '''Sets the Extensions of this response.
4362       
4363        @param value: the Extensions of this response
4364        @type value: tuple or list
4365        @raise TypeError: incorrect type for input value       
4366        '''
4367        if not isinstance(value, (list, tuple)):
4368            raise TypeError('Expecting list or tuple for "extensions", got %r'
4369                            % type(value))
4370        self.__extensions = value
4371       
4372    extensions = property(fget=_get_extensions, 
4373                          fset=_set_extensions,
4374                          doc="Response extensions")   
4375
4376
4377class Response(StatusResponseType):
4378    '''SAML2 Core Response
4379   
4380    @cvar DEFAULT_ELEMENT_LOCAL_NAME: Element local name.
4381    @type DEFAULT_ELEMENT_LOCAL_NAME: ndg.saml.common.xml.QName
4382    @cvar DEFAULT_ELEMENT_NAME: Default element name.
4383    @type DEFAULT_ELEMENT_NAME: string
4384    @cvar TYPE_LOCAL_NAME: Local name of the XSI type.
4385    @type TYPE_LOCAL_NAME: string
4386    @cvar TYPE_NAME: QName of the XSI type.
4387    @type TYPE_NAME: ndg.saml.common.xml.QName
4388   
4389    @ivar __indexedChildren: response elements
4390    @type __indexedChildren: list
4391    '''
4392   
4393    # Element local name.
4394    DEFAULT_ELEMENT_LOCAL_NAME = "Response"
4395   
4396    # Default element name.
4397    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS, 
4398                                 DEFAULT_ELEMENT_LOCAL_NAME, 
4399                                 SAMLConstants.SAML20P_PREFIX)
4400   
4401    # Local name of the XSI type.
4402    TYPE_LOCAL_NAME = "ResponseType"
4403       
4404    # QName of the XSI type.
4405    TYPE_NAME = QName(SAMLConstants.SAML20P_NS, 
4406                      TYPE_LOCAL_NAME, 
4407                      SAMLConstants.SAML20P_PREFIX)
4408   
4409    __slots__ = ('__indexedChildren',)
4410   
4411    def __init__(self, **kw):
4412        '''
4413        @param kw: keywords to initialise superclass instance
4414        @type kw: dict
4415        ''' 
4416        super(Response, self).__init__(**kw)
4417       
4418        # Assertion child elements
4419        self.__indexedChildren = []
4420
4421    def __getstate__(self):
4422        '''Enable pickling
4423       
4424        @return: object's attribute dictionary
4425        @rtype: dict
4426        '''
4427
4428        _dict = super(Response, self).__getstate__()
4429        for attrName in Response.__slots__:
4430            # Ugly hack to allow for derived classes setting private member
4431            # variables
4432            if attrName.startswith('__'):
4433                attrName = "_Response" + attrName
4434               
4435            _dict[attrName] = getattr(self, attrName)
4436           
4437        return _dict
4438       
4439    @property
4440    def assertions(self): 
4441        """Assertions contained in this response
4442       
4443        @return: list of assertion for this response
4444        @rtype: list
4445        """
4446        return self.__indexedChildren
Note: See TracBrowser for help on using the repository browser.