Changeset 4573


Ignore:
Timestamp:
09/12/08 13:26:58 (11 years ago)
Author:
pjkersha
Message:
  • updated configfileparsers imports for new module name.
  • improved error reporting and logging in soap and wssecurity WSGIs
  • fixed settings in attributeauthorityclient unit test site-a and site-b PAste ini files
  • updated Attribute Authority Client unit test names
Location:
TI12-security/trunk/python
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/credentialwallet.py

    r4480 r4573  
    6363 
    6464# generic parser to read INI/XML properties file 
    65 from ndg.security.common.utils.ConfigFileParsers import \ 
     65from ndg.security.common.utils.configfileparsers import \ 
    6666                                                INIPropertyFileWithValidation 
    6767 
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/utils/configfileparsers.py

    r4569 r4573  
    332332    turn.  Convert to a list if validKeys dict item indicates so 
    333333     
    334     @type cfg: ndg.security.common.utils.ConfigFileParsers.CaseSensitiveConfigParser 
     334    @type cfg: ndg.security.common.utils.configfileparsers.CaseSensitiveConfigParser 
    335335    @param cfg: config file object 
    336336    @type section: basestring 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/attributeauthority.py

    r4569 r4573  
    4040from ndg.security.common.AttCert import * 
    4141 
    42 from ndg.security.common.utils.ConfigFileParsers import \ 
     42from ndg.security.common.utils.configfileparsers import \ 
    4343    readAndValidateProperties 
    4444from ndg.security.common.utils.classfactory import instantiateClass 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/sessionmanager.py

    r4569 r4573  
    5050 
    5151# generic parser to read INI/XML properties file 
    52 from ndg.security.common.utils.ConfigFileParsers import \ 
     52from ndg.security.common.utils.configfileparsers import \ 
    5353                                                INIPropertyFileWithValidation 
    5454 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/soap.py

    r4569 r4573  
    2626    """Base error handling exception class for the SOAP WSGI middleware module 
    2727    """ 
     28    _log = log 
     29    def __init__(self, *arg, **kw): 
     30        '''Extend to enable logging of errors''' 
     31        if len(arg) > 0: 
     32            self.__class__._log.error(arg[0]) 
     33        Exception.__init__(self, *arg, **kw) 
    2834     
    2935class SOAPMiddlewareReadError(SOAPMiddlewareError): 
     
    5965        # This flag if set to True causes this handler to call the  
    6066        # start_response method and output the SOAP response 
    61         self.writeResponseSet = bool(self.app_conf.get('writeResponse', False)) 
     67        self.writeResponseSet = self.app_conf.get('writeResponse',  
     68                                                  'false').lower() == 'true' 
    6269 
    6370        # Check for a list of other filters to be referenced by this one 
     
    208215                errorCode = "200 OK" 
    209216                 
     217        log.debug("SOAP Response for handler %r" % self.__class__) 
     218        log.debug("_"*80) 
     219        log.debug(soapOut) 
     220        log.debug("_"*80) 
    210221        start_response(errorCode, 
    211222                       [('content-type', 'text/xml'+charset), 
     
    330341        soapOut = str(sw) 
    331342        charset = self.app_conf['charset'] 
    332                  
    333         log.debug("SOAP Response") 
    334         log.debug("_"*80) 
    335         log.debug(soapOut) 
    336         log.debug("_"*80) 
    337343 
    338344        return self.writeResponse(environ, start_response) 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/wssecurity.py

    r4527 r4573  
    2020from ZSI.writer import SoapWriter 
    2121from ndg.security.common.wssecurity.dom import SignatureHandler 
    22 from ndg.security.server.wsgi.soap import SOAPMiddleware 
     22from ndg.security.server.wsgi.soap import SOAPMiddleware, SOAPMiddlewareError 
    2323 
    24 class WSSecurityFilterError(Exception): 
     24class WSSecurityFilterError(SOAPMiddlewareError): 
    2525    """Base exception class for WS-Security WSGI Filter""" 
     26    _log = log 
    2627     
    2728class WSSecurityFilterConfigError(WSSecurityFilterError): 
     
    110111 
    111112             
    112         try:     
     113        try: 
    113114            self.signatureHandler.sign(sw) 
    114115        except Exception, e: 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/zsi/attributeauthority/__init__.py

    r4521 r4573  
    4949                                        'wsseSignatureVerificationFilterID',  
    5050                                        None) 
    51           
     51        if self.wsseSignatureVerificationFilterID is None: 
     52            log.warning('No "wsseSignatureVerificationFilterID" option was ' 
     53                        'set in the input config') 
     54      
    5255        # Initialise Attribute Authority class - property file will be 
    5356        # picked up from default location under $NDG_DIR directory 
     
    7881            # Get certificate corresponding to private key that signed the 
    7982            # message - i.e. the user's proxy 
     83            log.debug("Reading holder certificate from WS-Security signature " 
     84                      "header") 
    8085            holderX509Cert = signatureFilter.signatureHandler.verifyingCert 
    8186        else: 
    8287            # No signature from client - they must instead provide the 
    8388            # designated holder cert via the UserX509Cert input 
     89            log.debug('Reading holder certificate from SOAP request ' 
     90                      '"userX509Cert" parameter') 
    8491            holderX509Cert = request.UserX509Cert 
    8592 
     
    209216         
    210217        return response 
    211  
    212  
    213     def soap_getX509Cert(self, ps, **kw): 
    214         '''Retrieve Attribute Authority's X.509 certificate 
    215          
    216         @type ps: ZSI ParsedSoap 
    217         @param ps: client SOAP message 
    218         @rtype: tuple 
    219         @return: response object''' 
    220         if self.__debug: 
    221             import pdb 
    222             pdb.set_trace() 
    223              
    224         response = _AttributeAuthorityService.soap_getX509Cert(self, ps) 
    225          
    226         x509Cert = X509CertRead(self.aa['signingCertFilePath']) 
    227         response.X509Cert = base64.encodestring(x509Cert.asDER()) 
    228         return response 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/zsi/sessionmanager/__init__.py

    r4521 r4573  
    4848        self.attributeAuthorityFilterID = kw.pop('attributeAuthorityFilterID',  
    4949                                                 None) 
     50        if self.attributeAuthorityFilterID is None: 
     51            log.warning('No "attributeAuthorityFilterID" option was ' 
     52                        'set in the input config: link to a local Attibute ' 
     53                        'Authority instance is disabled') 
    5054         
    5155        # ... and WS-Security signature verification filter 
     
    5357                                        'wsseSignatureVerificationFilterID',  
    5458                                        None) 
     59        if self.wsseSignatureVerificationFilterID is None: 
     60            log.warning('No "wsseSignatureVerificationFilterID" option was ' 
     61                        'set in the input config') 
    5562         
    5663        # Initialise Attribute Authority class - property file will be 
     
    111118            # Get certificate corresponding to private key that signed the 
    112119            # message - i.e. the user's certificate 
     120            log.debug("Reading holder certificate from WS-Security " 
     121                      "signature header") 
    113122            userX509Cert = signatureFilter.signatureHandler.verifyingCert 
    114123        else: 
    115124            # No signature from client - they must instead provide the 
    116125            # designated holder cert via the UserX509Cert input 
     126            log.debug('Reading holder certificate from SOAP "userX509Cert" ' 
     127                      'parameter') 
    117128            userX509Cert = request.UserX509Cert 
    118129             
     
    167178            # Get certificate corresponding to private key that signed the 
    168179            # message - i.e. the user's proxy 
     180            log.debug("Reading holder certificate from WS-Security " 
     181                      "signature header") 
    169182            userX509Cert = signatureFilter.signatureHandler.verifyingCert 
    170183        else: 
    171184            # No signature from client - they must instead provide the 
    172185            # designated holder cert via the UserX509Cert input 
     186            log.debug('Reading holder certificate from SOAP "userX509Cert" ' 
     187                      'parameter') 
    173188            userX509Cert = request.UserX509Cert 
    174189 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/attributeauthorityclient/attAuthorityClientTest.cfg

    r4318 r4573  
    1111# ! SiteBMapConfig.xml trusted site A aaURI setting must agree with this  
    1212# setting for test6GetMappedAttCert 
    13 uri = http://localhost:5000/AttributeAuthority 
     13 
     14# With TCP Mon: 
     15uri = http://localhost:4999/AttributeAuthority 
     16#uri = http://localhost:5000/AttributeAuthority 
    1417 
    1518# For https connections only.  !Omit ssl* settings if using http! 
     
    1922sslCACertFilePathList = $NDGSEC_AACLNT_UNITTEST_DIR/ca/ndg-test-ca.crt 
    2023 
    21 [test3GetTrustedHostInfo] 
     24[test02GetTrustedHostInfo] 
    2225role = postgrad 
    2326 
    24 [test3aGetTrustedHostInfoWithNoMatchingRoleFound] 
     27[test03GetTrustedHostInfoWithNoMatchingRoleFound] 
    2528# Set an alternative role to test no matching role found exception 
    2629role = blah 
    2730  
    28 [test5GetAttCert] 
     31[test06GetAttCert] 
    2932# If clntcertfilepath is a proxy set this cert as the one that issued the  
    3033# proxy.  Comment out if clntcertfilepath is a standard X.509 cert. 
     
    3437#issuingclntcertfilepath = $NDGSEC_AACLNT_UNITTEST_DIR/proxy-cert.pem 
    3538 
    36 # Setup for use by test7GetMappedAttCert test 
     39# Setup for use by test08GetMappedAttCert test 
    3740attCertFilePath = $NDGSEC_AACLNT_UNITTEST_DIR/ac-clnt.xml 
    3841 
    39 [test6GetAttCertWithUserIdSet] 
     42[test07GetAttCertWithUserIdSet] 
    4043userId = system 
    4144attCertFilePath = $NDGSEC_AACLNT_UNITTEST_DIR/ac-clnt-test6.xml 
    4245 
    43 [test7GetMappedAttCert] 
     46[test08GetMappedAttCert] 
    4447uri = http://localhost:5100/AttributeAuthority 
    4548userAttCertFilePath = $NDGSEC_AACLNT_UNITTEST_DIR/ac-clnt.xml 
    4649mappedAttCertFilePath = $NDGSEC_AACLNT_UNITTEST_DIR/mapped-ac.xml 
    4750 
    48 [test8GetMappedAttCertStressTest] 
     51[test09GetMappedAttCertStressTest] 
    4952uri = http://localhost:5100/AttributeAuthority 
    5053userAttCertFilePathList = $NDGSEC_AACLNT_UNITTEST_DIR/ac-clnt.xml 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/attributeauthorityclient/siteA/site-a.ini

    r4462 r4573  
    6262# Chain of SOAP Middleware filters 
    6363[pipeline:main] 
    64 pipeline = wsseSignatureVerificationFilter AttributeAuthorityFilter wsseSignatureFilter mainApp 
     64pipeline = wsseSignatureVerificationFilter  
     65                   AttributeAuthorityFilter  
     66                   wsseSignatureFilter  
     67                   mainApp 
    6568 
    6669 
     
    7174AttributeAuthority.propPrefix = attributeAuthority 
    7275AttributeAuthority.propFilePath = $NDGSEC_AACLNT_UNITTEST_DIR/siteA/site-a.ini 
     76AttributeAuthority.wsseSignatureVerificationFilterID = wsseSignatureVerificationFilter01 
    7377referencedFilters = wsseSignatureVerificationFilter01 
    7478path = /AttributeAuthority 
     
    8690# confirmation 
    8791referencedFilters = wsseSignatureVerificationFilter01 
     92wsseSignatureVerificationFilterID = wsseSignatureVerificationFilter01 
    8893 
    8994# Last filter in chain SOAP handlers writes the response 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/attributeauthorityclient/siteB/site-b.ini

    r4462 r4573  
    7171AttributeAuthority.propPrefix = attributeAuthority 
    7272AttributeAuthority.propFilePath = $NDGSEC_AACLNT_UNITTEST_DIR/siteB/site-b.ini 
     73AttributeAuthority.wsseSignatureVerificationFilterID = wsseSignatureVerificationFilter01 
    7374referencedFilters = wsseSignatureVerificationFilter01 
    7475path = /AttributeAuthority 
     
    8283[filter:wsseSignatureFilter] 
    8384paste.filter_app_factory = ndg.security.server.wsgi.wssecurity:ApplySignatureFilter 
     85 
     86# Reference the verification filter in order to be able to apply signature 
     87# confirmation - not needed if applySignatureConfirmation is set to False - see 
     88# WS-Security section below... 
     89#referencedFilters = wsseSignatureVerificationFilter01 
     90#wsseSignatureVerificationFilterID = wsseSignatureVerificationFilter01 
     91 
    8492# Last filter in chain SOAP handlers writes the response 
    8593writeResponse = True 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/attributeauthorityclient/test_attributeauthorityclient.py

    r4513 r4573  
    2222from ndg.security.common.AttCert import AttCertRead 
    2323from ndg.security.common.X509 import X509CertParse, X509CertRead 
    24 from ndg.security.common.utils.ConfigFileParsers import \ 
     24from ndg.security.common.utils.configfileparsers import \ 
    2525    CaseSensitiveConfigParser 
    2626     
     
    8383                        cfgFileSection='wsse', 
    8484                        cfg=self.cfgParser)             
    85      
    86     def test1GetX509Cert(self): 
    87         '''test1GetX509Cert: retrieve Attribute Authority's X.509 cert.''' 
    88         resp = self.siteAClnt.getX509Cert() 
    89         print "Attribute Authority X.509 cert.:\n" + resp 
    90  
    91     def test2GetHostInfo(self): 
    92         """test2GetHostInfo: retrieve info for AA host""" 
     85 
     86    def test01GetHostInfo(self): 
     87        """test01GetHostInfo: retrieve info for AA host""" 
    9388        hostInfo = self.siteAClnt.getHostInfo() 
    9489        print "Host Info:\n %s" % hostInfo         
    9590 
    96     def test3GetTrustedHostInfo(self): 
    97         """test3GetTrustedHostInfo: retrieve trusted host info matching a 
     91    def test02GetTrustedHostInfo(self): 
     92        """test02GetTrustedHostInfo: retrieve trusted host info matching a 
    9893        given role""" 
    9994        trustedHostInfo = self.siteAClnt.getTrustedHostInfo(\ 
    100                                  self.cfg['test3GetTrustedHostInfo']['role']) 
     95                                 self.cfg['test02GetTrustedHostInfo']['role']) 
    10196        for hostname, hostInfo in trustedHostInfo.items(): 
    10297            assert hostname, "Hostname not set" 
     
    106101        print "Trusted Host Info:\n %s" % trustedHostInfo 
    107102 
    108     def test3aGetTrustedHostInfoWithNoMatchingRoleFound(self): 
    109         """test3aGetTrustedHostInfoWithNoMatchingRoleFound: test the case  
     103    def test03GetTrustedHostInfoWithNoMatchingRoleFound(self): 
     104        """test03GetTrustedHostInfoWithNoMatchingRoleFound: test the case  
    110105        where the input role doesn't match any roles in the target AA's map  
    111106        config file""" 
    112         _cfg = self.cfg['test3aGetTrustedHostInfoWithNoMatchingRoleFound'] 
     107        _cfg = self.cfg['test03GetTrustedHostInfoWithNoMatchingRoleFound'] 
    113108        try: 
    114109            trustedHostInfo = self.siteAClnt.getTrustedHostInfo(_cfg['role']) 
     
    120115 
    121116 
    122     def test4GetTrustedHostInfoWithNoRole(self): 
    123         """test4GetTrustedHostInfoWithNoRole: retrieve trusted host info  
     117    def test04GetTrustedHostInfoWithNoRole(self): 
     118        """test04GetTrustedHostInfoWithNoRole: retrieve trusted host info  
    124119        irrespective of role""" 
    125120        trustedHostInfo = self.siteAClnt.getTrustedHostInfo() 
     
    133128         
    134129 
    135     def test4aGetAllHostsInfo(self): 
    136         """test4aGetAllHostsInfo: retrieve info for all hosts""" 
     130    def test05GetAllHostsInfo(self): 
     131        """test05GetAllHostsInfo: retrieve info for all hosts""" 
    137132        allHostInfo = self.siteAClnt.getAllHostsInfo() 
    138133        for hostname, hostInfo in allHostInfo.items(): 
     
    144139 
    145140 
    146     def test5GetAttCert(self):         
    147         """test5GetAttCert: Request attribute certificate from NDG Attribute  
     141    def test06GetAttCert(self):         
     142        """test06GetAttCert: Request attribute certificate from NDG Attribute  
    148143        Authority Web Service.""" 
    149         _cfg = self.cfg['test5GetAttCert'] 
     144        _cfg = self.cfg['test06GetAttCert'] 
    150145         
    151146        # Read user Certificate into a string ready for passing via WS 
     
    171166         
    172167         
    173     def test6GetAttCertWithUserIdSet(self):         
    174         """test6GetAttCertWithUserIdSet: Request attribute certificate from  
     168    def test07GetAttCertWithUserIdSet(self):         
     169        """test07GetAttCertWithUserIdSet: Request attribute certificate from  
    175170        NDG Attribute Authority Web Service setting a specific user Id  
    176171        independent of the signer of the SOAP request.""" 
    177         _cfg = self.cfg['test6GetAttCertWithUserIdSet'] 
     172        _cfg = self.cfg['test07GetAttCertWithUserIdSet'] 
    178173         
    179174        # Read user Certificate into a string ready for passing via WS 
     
    201196 
    202197 
    203     def test7GetMappedAttCert(self):         
    204         """test7GetMappedAttCert: Request mapped attribute certificate from  
     198    def test08GetMappedAttCert(self):         
     199        """test08GetMappedAttCert: Request mapped attribute certificate from  
    205200        NDG Attribute Authority Web Service.""" 
    206         _cfg = self.cfg['test7GetMappedAttCert'] 
     201        _cfg = self.cfg['test08GetMappedAttCert'] 
    207202         
    208203        # Read user Certificate into a string ready for passing via WS 
     
    241236         
    242237         
    243     def test8GetMappedAttCertStressTest(self):         
    244         """test8GetMappedAttCertStressTest: Request mapped attribute  
     238    def test09GetMappedAttCertStressTest(self):         
     239        """test09GetMappedAttCertStressTest: Request mapped attribute  
    245240        certificate from NDG Attribute Authority Web Service.""" 
    246         _cfg = self.cfg['test8GetMappedAttCertStressTest'] 
     241        _cfg = self.cfg['test09GetMappedAttCertStressTest'] 
    247242         
    248243        # Read user Certificate into a string ready for passing via WS 
     
    280275                                               userAttCert=userAttCert) 
    281276            except Exception, e: 
    282                 outFilePfx = 'test8GetMappedAttCertStressTest-%s' % \ 
     277                outFilePfx = 'test09GetMappedAttCertStressTest-%s' % \ 
    283278                        os.path.basename(acFilePath)     
    284279                msgFile = open(outFilePfx+".msg", 'w') 
     
    286281              
    287282              
    288 #_____________________________________________________________________________        
    289283class AttributeAuthorityClientTestSuite(unittest.TestSuite): 
    290284    def __init__(self): 
    291285        map = map(AttributeAuthorityClientTestCase, 
    292286                  ( 
    293                     "test1GetX509Cert", 
    294                     "test2GetHostInfo", 
    295                     "test3GetTrustedHostInfo", 
    296                     "test4GetTrustedHostInfoWithNoRole", 
    297                     "test5GetAttCert", 
    298                     "test6GetAttCertWithUserIdSet", 
    299                     "test7GetMappedAttCert", 
    300                     "test8GetMappedAttCertStressTest", 
     287                    "test01GetHostInfo", 
     288                    "test02GetTrustedHostInfo", 
     289                    "test03GetTrustedHostInfoWithNoMatchingRoleFound", 
     290                    "test04GetTrustedHostInfoWithNoRole", 
     291                    "test05GetAllHostsInfo", 
     292                    "test06GetAttCert", 
     293                    "test07GetAttCertWithUserIdSet", 
     294                    "test08GetMappedAttCert", 
     295                    "test09GetMappedAttCertStressTest", 
    301296                  )) 
    302297        unittest.TestSuite.__init__(self, map) 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/combinedservices/services.ini

    r4565 r4573  
    181181AttributeAuthority.propPrefix = attributeAuthority 
    182182AttributeAuthority.propFilePath = $NDGSEC_COMBINED_SRVS_UNITTEST_DIR/services.ini 
     183AttributeAuthority.wsseSignatureVerificationFilterID = ndg.security.server.wsgi.wsseSignatureVerificationFilter01 
    183184 
    184185# Provide an identifier for this filter so that main WSGI app  
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/combinedservices/test_combinedservices.py

    r4545 r4573  
    3636from ndg.security.common.X509 import X509CertParse, X509CertRead 
    3737from ndg.security.common.wssecurity.dom import SignatureHandler as SigHdlr 
    38 from ndg.security.common.utils.ConfigFileParsers import \ 
     38from ndg.security.common.utils.configfileparsers import \ 
    3939    CaseSensitiveConfigParser 
    4040 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/configfileparsers/test.cfg

    r4319 r4573  
    1 # Test Configuration file for ConfigFileParsers unit tests 
     1# Test Configuration file for configfileparsers unit tests 
    22#  
    33# NERC Data Grid Project 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/configfileparsers/test_configfileparsers.py

    r4404 r4573  
    1717import traceback 
    1818 
    19 from ndg.security.common.utils.ConfigFileParsers import \ 
     19from ndg.security.common.utils.configfileparsers import \ 
    2020    CaseSensitiveConfigParser, INIPropertyFile, readAndValidateProperties 
    2121from ConfigParser import SafeConfigParser 
     
    3131 
    3232class ConfigFileParsersTestCase(unittest.TestCase): 
    33     """Unit test case for ndg.security.common.utils.ConfigFileParsers 
     33    """Unit test case for ndg.security.common.utils.configfileparsers 
    3434    module. 
    3535    """ 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/credentialwallet/test_credentialwallet.py

    r4513 r4573  
    1717import traceback 
    1818 
    19 from ndg.security.common.utils.ConfigFileParsers import \ 
     19from ndg.security.common.utils.configfileparsers import \ 
    2020                                                    CaseSensitiveConfigParser 
    2121from ndg.security.common.X509 import X509CertParse 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/sessionmanager/test_sessionmanager.py

    r4516 r4573  
    2020import traceback 
    2121 
    22 from ndg.security.common.utils.ConfigFileParsers import \ 
     22from ndg.security.common.utils.configfileparsers import \ 
    2323                                                    CaseSensitiveConfigParser 
    2424from ndg.security.common.X509 import X509CertParse 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/sessionmanagerclient/test_sessionmanagerclient.py

    r4513 r4573  
    3131from ndg.security.common.X509 import X509CertParse, X509CertRead 
    3232from ndg.security.common.wssecurity.dom import SignatureHandler as SigHdlr 
    33 from ndg.security.common.utils.ConfigFileParsers import \ 
     33from ndg.security.common.utils.configfileparsers import \ 
    3434    CaseSensitiveConfigParser 
    3535 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/utils/testConfigFileParsers.py

    r4384 r4573  
    66''' 
    77import unittest, os 
    8 from ndg.security.common.utils.ConfigFileParsers import readProperties, readAndValidateProperties 
     8from ndg.security.common.utils.configfileparsers import readProperties, readAndValidateProperties 
    99from ndg.security.server.attributeauthority import AttributeAuthority 
    1010from ndg.security.server.sessionmanager import SessionManager 
Note: See TracChangeset for help on using the changeset viewer.