source: TI12-security/trunk/ndg_saml/ndg/saml/utils/__init__.py @ 7634

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

0.5.1 Release - fixes:

  • Property svn:keywords set to Id
Line 
1"""Utilities module for NDG Security SAML implementation
2
3NERC DataGrid Project
4
5This implementation is adapted from the Java OpenSAML implementation.  The
6copyright and licence information are included here:
7
8Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
9
10Licensed under the Apache License, Version 2.0 (the "License");
11you may not use this file except in compliance with the License.
12You may obtain a copy of the License at
13
14http://www.apache.org/licenses/LICENSE-2.0
15
16Unless required by applicable law or agreed to in writing, software
17distributed under the License is distributed on an "AS IS" BASIS,
18WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19See the License for the specific language governing permissions and
20limitations under the License.
21"""
22__author__ = "P J Kershaw"
23__date__ = "10/08/09"
24__copyright__ = "(C) 2009 Science and Technology Facilities Council"
25__license__ = "http://www.apache.org/licenses/LICENSE-2.0"
26__contact__ = "Philip.Kershaw@stfc.ac.uk"
27__revision__ = '$Id$'
28try:
29    from datetime import strptime
30except ImportError:
31    # Allow for Python < 2.5
32    from time import strptime as _strptime
33    strptime = lambda datetimeStr, format: datetime(*(_strptime(datetimeStr, 
34                                                                format)[0:6]))
35from datetime import datetime, timedelta
36
37       
38# Interpret a string as a boolean
39str2Bool = lambda str: str.lower() in ("yes", "true", "t", "1")
40
41     
42class SAMLDateTime(object):
43    """Generic datetime formatting utility for SAML timestamps - XMLSchema
44    Datetime format
45   
46    @cvar DATETIME_FORMAT: date/time format string for SAML timestamps
47    @type DATETIME_FORMAT: string
48    """
49    DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
50   
51    @classmethod
52    def toString(cls, dtValue):
53        """Convert issue instant datetime to correct string type for output
54       
55        @type dtValue: datetime.datetime
56        @param dtValue: issue instance as a datetime
57        @rtype: basestring
58        @return: issue instance as a string
59        """
60        if not isinstance(dtValue, datetime):
61            raise TypeError("Expecting datetime type for string conversion, "
62                            "got %r" % dtValue)
63           
64        # isoformat provides the correct formatting
65#        return dtIssueInstant.strftime(cls.DATETIME_FORMAT)
66        return datetime.isoformat(dtValue)+'Z'
67
68    @classmethod
69    def fromString(cls, strDateTime):
70        """Convert issue instant string to datetime type
71       
72        @type strDateTime: basestring
73        @param strDateTime: issue instance as a string
74        @rtype: datetime.datetime
75        @return: issue instance as a datetime
76        """
77        if not isinstance(strDateTime, basestring):
78            raise TypeError("Expecting basestring derived type for string "
79                            "conversion, got %r" % strDateTime)
80       
81        # Workaround for seconds fraction as strptime doesn't seem able to deal
82        # with this
83        dateTimeTuple = strDateTime.split('.')
84       
85        # Seconds fraction may not be present - see
86        # http://www.w3.org/TR/xmlschema-2/#dateTime - explicitly test for ...
87        if len(dateTimeTuple) == 2:
88            strDateTimeFraction, strSecondsFraction = dateTimeTuple
89            secondsFraction = float("0." + strSecondsFraction.replace('Z', ''))
90        else:
91            strDateTimeFraction = dateTimeTuple[0].replace('Z', '')
92            secondsFraction = 0.
93           
94        dtValue = datetime.strptime(strDateTimeFraction, cls.DATETIME_FORMAT)
95        dtValue += timedelta(seconds=secondsFraction)
96       
97        return dtValue
98
99
100class TypedList(list):
101    """Extend list type to enabled only items of a given type.  Supports
102    any type where the array type in the Standard Library is restricted to
103    only limited set of primitive types
104    """
105   
106    def __init__(self, elementType, *arg, **kw):
107        """
108        @type elementType: type/tuple
109        @param elementType: object type or types which the list is allowed to
110        contain.  If more than one type, pass as a tuple
111        """
112        self.__elementType = elementType
113        super(TypedList, self).__init__(*arg, **kw)
114   
115    def _getElementType(self):
116        """@return: element type for this list
117        @rtype: type
118        """
119        return self.__elementType
120   
121    elementType = property(fget=_getElementType, 
122                           doc="The allowed type or types for list elements")
123     
124    def extend(self, iter):
125        """Extend an existing list with the input iterable
126        @param iter: iterable to extend list with
127        @type iter: iterable
128        """
129        for i in iter:
130            if not isinstance(i, self.__elementType):
131                raise TypeError("List items must be of type %s" % 
132                                (self.__elementType,))
133               
134        return super(TypedList, self).extend(iter)
135       
136    def __iadd__(self, iter):
137        """Extend an existing list with the input iterable with += operator
138       
139        @param iter: iterable to extend list with
140        @type iter: iterable
141        """
142        for i in iter:
143            if not isinstance(i, self.__elementType):
144                raise TypeError("List items must be of type %s" % 
145                                (self.__elementType,))
146                   
147        return super(TypedList, self).__iadd__(iter)
148         
149    def append(self, item):
150        """Append a list with the given item
151       
152        @param item: item to extend list
153        @type item: must agree witj "elementType" attribute of this list
154        """
155        if not isinstance(item, self.__elementType):
156                raise TypeError("List items must be of type %s" % 
157                                (self.__elementType,))
158   
159        return super(TypedList, self).append(item)
Note: See TracBrowser for help on using the repository browser.