Changeset 5774 for TI12-security
- Timestamp:
- 28/09/09 17:15:41 (10 years ago)
- Location:
- TI12-security/trunk/python
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/__init__.py
r5770 r5774 27 27 USERNAME_ENVIRON_KEYNAME = 'REMOTE_USER' 28 28 USERDATA_ENVIRON_KEYNAME = 'REMOTE_USER_DATA' 29 USERNAME_SESSION_KEYNAME = 'username' 29 30 30 31 propertyDefaults = { -
TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/authn.py
r5770 r5774 27 27 28 28 29 class AuthenticationMiddlewareBase(NDGSecurityMiddlewareBase):29 class SessionMiddlewareBase(NDGSecurityMiddlewareBase): 30 30 """Base class for Authentication redirect middleware and Session Handler 31 31 middleware … … 37 37 'sessionKey': 'beaker.session.ndg.security' 38 38 } 39 USERNAME_SESSION_KEYNAME = 'username' 40 39 41 40 _isAuthenticated = lambda self: \ 42 AuthenticationMiddlewareBase.USERNAME_SESSION_KEYNAME in \41 SessionMiddlewareBase.USERNAME_SESSION_KEYNAME in \ 43 42 self.environ.get(self.sessionKey, ()) 44 43 … … 47 46 48 47 49 class AuthnRedirectMiddleware( AuthenticationMiddlewareBase):48 class AuthnRedirectMiddleware(SessionMiddlewareBase): 50 49 """Base class for Authentication HTTP redirect initiator and redirect 51 50 response WSGI middleware … … 229 228 230 229 231 class SessionHandlerMiddleware( AuthenticationMiddlewareBase):232 '''Middleware to handle:230 class SessionHandlerMiddleware(SessionMiddlewareBase): 231 '''Middleware to: 233 232 - establish user session details following redirect from OpenID Relying 234 233 Party sign-in or SSL Client authentication … … 243 242 244 243 SESSION_KEYNAMES = ( 245 AuthenticationMiddlewareBase.USERNAME_SESSION_KEYNAME,244 SessionMiddlewareBase.USERNAME_SESSION_KEYNAME, 246 245 SM_URI_SESSION_KEYNAME, 247 246 ID_SESSION_KEYNAME, -
TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/authz.py
r5766 r5774 13 13 from time import time 14 14 from urlparse import urlunsplit 15 from httplib import UNAUTHORIZED, FORBIDDEN 15 16 16 17 from ndg.security.common.utils.classfactory import importClass … … 21 22 from ndg.security.server.wsgi import NDGSecurityMiddlewareBase, \ 22 23 NDGSecurityMiddlewareConfigError 24 from ndg.security.server.wsgi.authn import SessionMiddlewareBase 23 25 24 26 from ndg.security.common.authz.msi import Policy, PIP, PDP, Request, \ 25 27 Response, Resource, Subject 26 28 27 class PEPResultHandlerMiddleware( NDGSecurityMiddlewareBase):29 class PEPResultHandlerMiddleware(SessionMiddlewareBase): 28 30 """This middleware is invoked if access is denied to a given resource. It 29 31 is incorporated into the call stack by passing it in to a MultiHandler … … 36 38 denied response e.g. include an interface to enable users to register for 37 39 the dataset from which they have been denied access. See 38 AuthorizationMiddleware pepResultHandler keyword 40 AuthorizationMiddleware pepResultHandler keyword. 41 42 SessionMiddlewareBase base class defines user session key and 43 isAuthenticated property 39 44 """ 40 propertyDefaults = { 41 'sessionKey': 'beaker.session.ndg.security' 42 } 43 44 _isAuthenticated = lambda self: \ 45 'username' in self.environ.get(self.sessionKey,()) 46 isAuthenticated = property(fget=_isAuthenticated, 47 doc='boolean to indicate is user logged in') 48 45 49 46 def __init__(self, app, global_conf, prefix='', **app_conf): 50 47 ''' … … 75 72 log.warning("PEPResultHandlerMiddleware: user is not " 76 73 "authenticated - setting HTTP 401 response") 77 return self._setErrorResponse(code= 401)74 return self._setErrorResponse(code=UNAUTHORIZED) 78 75 else: 79 76 # Get response message from PDP recorded by PEP … … 82 79 msg = getattr(pdpResponse, 'message', '') 83 80 84 response = \ 85 """Access is forbidden for this resource: 86 %s 87 Please check with your site administrator that you have the required access privileges. 88 """ % msg.join('\n'*2) 89 90 return self._setErrorResponse(code=403, msg=response) 81 response = ("Access is forbidden for this resource:%s" 82 "Please check with your site administrator that you " 83 "have the required access privileges." % 84 msg.join('\n\n'*2)) 85 86 return self._setErrorResponse(code=FORBIDDEN, msg=response) 91 87 92 88 … … 97 93 """Configuration related error for PEPFilter""" 98 94 99 class PEPFilter( NDGSecurityMiddlewareBase):95 class PEPFilter(SessionMiddlewareBase): 100 96 """PEP (Policy Enforcement Point) WSGI Middleware. The PEP enforces 101 97 access control decisions made by the PDP (Policy Decision Point). In … … 104 100 access denied decision is made, the PEP enforces this by returning a 105 101 403 Forbidden HTTP response without the application middleware executing 102 103 SessionMiddlewareBase base class defines user session key and 104 isAuthenticated property 106 105 """ 107 TRIGGER_HTTP_STATUS_CODE = '403'106 TRIGGER_HTTP_STATUS_CODE = str(FORBIDDEN) 108 107 MIDDLEWARE_ID = 'PEPFilter' 109 110 propertyDefaults = { 111 'sessionKey': 'beaker.session.ndg.security' 112 } 113 114 _isAuthenticated = lambda self: \ 115 'username' in self.environ.get(self.sessionKey,()) 116 isAuthenticated = property(fget=_isAuthenticated, 117 doc='boolean to indicate is user logged in') 118 108 POLICY_PARAM_PREFIX = 'policy.' 109 SESSION_KEYNAME = 'sessionKey' 110 POLICY_FILEPATH_PARAMNAME = 'filePath' 111 119 112 def __init__(self, app, global_conf, prefix='', **local_conf): 120 113 """Initialise the PIP (Policy Information Point) and PDP (Policy … … 135 128 """ 136 129 # Initialise the PDP reading in the policy 137 policyCfg = PEPFilter._filterKeywords(local_conf, 'policy.') 138 self.policyFilePath = policyCfg['filePath'] 139 policy = Policy.Parse(policyCfg['filePath']) 130 policyCfg = PEPFilter._filterKeywords(local_conf, 131 PEPFilter.POLICY_PARAM_PREFIX) 132 self.policyFilePath = policyCfg[PEPFilter.POLICY_FILEPATH_PARAMNAME] 133 policy = Policy.Parse(policyCfg[PEPFilter.POLICY_FILEPATH_PARAMNAME]) 140 134 141 135 # Initialise the Policy Information Point to None. This object is … … 143 137 self.pdp = PDP(policy, None) 144 138 145 self.sessionKey = local_conf.get('sessionKey', 146 PEPFilter.propertyDefaults['sessionKey']) 139 self.sessionKey = local_conf.get(PEPFilter.SESSION_KEYNAME, 140 PEPFilter.propertyDefaults[ 141 PEPFilter.SESSION_KEYNAME]) 147 142 148 143 super(PEPFilter, self).__init__(app, … … 151 146 **local_conf) 152 147 153 154 148 @NDGSecurityMiddlewareBase.initCall 155 149 def __call__(self, environ, start_response): … … 162 156 @return: response 163 157 """ 164 165 log.debug("PEPFilter.__call__ ...")166 167 158 session = environ.get(self.sessionKey) 168 159 if session is None: … … 177 168 targetMatch = len(matchingTargets) > 0 178 169 if not targetMatch: 179 log. info("PEPFilter.__call__: granting access - no matching URI "180 "path target was found in the policy for URI path [%s]",181 resourceURI)170 log.debug("PEPFilter.__call__: granting access - no matching URI " 171 "path target was found in the policy for URI path [%s]", 172 resourceURI) 182 173 return self._app(environ, start_response) 183 174 184 log. info("PEPFilter.__call__: found matching target(s):\n\n %s\n"185 "\nfrom policy file [%s] for URI Path=[%s]\n",186 '\n'.join(["RegEx=%s" % t for t in matchingTargets]),187 self.policyFilePath,188 resourceURI)175 log.debug("PEPFilter.__call__: found matching target(s):\n\n %s\n" 176 "\nfrom policy file [%s] for URI Path=[%s]\n", 177 '\n'.join(["RegEx=%s" % t for t in matchingTargets]), 178 self.policyFilePath, 179 resourceURI) 189 180 190 181 if not self.isAuthenticated: … … 193 184 194 185 # Set a 401 response for an authentication handler to capture 195 return self._setErrorResponse(code= 401)186 return self._setErrorResponse(code=UNAUTHORIZED) 196 187 197 188 log.debug("PEPFilter.__call__: creating request to call PDP to check " … … 224 215 225 216 if response.status == Response.DECISION_PERMIT: 226 log.debug("PEPFilter: PDP granted access for URI path [%s] " 227 "using policy [%s]", resourceURI, self.policyFilePath) 217 log.info("PEPFilter.__call__: PDP granted access for URI path " 218 "[%s] using policy [%s]", 219 resourceURI, 220 self.policyFilePath) 228 221 229 222 return self._app(environ, start_response) 230 223 else: 231 log.info("PEPFilter : PDP returned a status of [%s] "224 log.info("PEPFilter.__call__: PDP returned a status of [%s] " 232 225 "denying access for URI path [%s] using policy [%s]", 233 226 response.decisionValue2String[response.status], … … 236 229 237 230 # Trigger AuthZResultHandlerMiddleware by setting a response 238 # with HTTP status code equal to the TRIGGER_HTTP_STATUS_CODE class attribute 239 # value 240 return self._setErrorResponse(code=int(PEPFilter.TRIGGER_HTTP_STATUS_CODE)) 231 # with HTTP status code equal to the TRIGGER_HTTP_STATUS_CODE class 232 # attribute value 233 triggerStatusCode = int(PEPFilter.TRIGGER_HTTP_STATUS_CODE) 234 return self._setErrorResponse(code=triggerStatusCode) 241 235 242 236 def _getMatchingTargets(self, resourceURI): … … 277 271 278 272 if status.startswith(PEPFilter.TRIGGER_HTTP_STATUS_CODE): 279 log. info("PEPFilter: found [%s] status for URI path [%s]: "280 "invoking access denied response",281 PEPFilter.TRIGGER_HTTP_STATUS_CODE,282 environ['PATH_INFO'])273 log.debug("PEPFilter: found [%s] status for URI path [%s]: " 274 "invoking access denied response", 275 PEPFilter.TRIGGER_HTTP_STATUS_CODE, 276 environ['PATH_INFO']) 283 277 return True 284 278 else: … … 479 473 ndg.security.server.wsgi.authn.AuthenticationMiddleware 480 474 ''' 475 PEP_PARAM_PREFIX = 'pep.filter.' 476 PIP_PARAM_PREFIX = 'pip.' 477 PEP_RESULT_HANDLER_PARAMNAME = "pepResultHandler" 481 478 482 479 def __init__(self, app, global_conf, prefix='', **app_conf): … … 496 493 dictionary 497 494 """ 498 495 authzPrefix = prefix + AuthorizationMiddleware.PEP_PARAM_PREFIX 499 496 pepFilter = PEPFilter(app, 500 497 global_conf, 501 prefix= prefix+'pep.filter.',498 prefix=authzPrefix, 502 499 **app_conf) 503 500 pepInterceptFunc = pepFilter.multiHandlerInterceptFactory() … … 506 503 # so that it can take a copy of the beaker session object from environ 507 504 # ahead of the PDP's request to it for an Attribute Certificate 505 pipPrefix = AuthorizationMiddleware.PIP_PARAM_PREFIX 508 506 pipFilter = PIPMiddleware(pepFilter, 509 507 global_conf, 510 prefix= 'pip.',508 prefix=pipPrefix, 511 509 **app_conf) 512 510 pepFilter.pdp.pip = pipFilter … … 514 512 app = MultiHandler(pipFilter) 515 513 516 pepResultHandlerClassName = app_conf.pop(prefix+"pepResultHandler", 517 None) 514 pepResultHandlerClassName = app_conf.pop( 515 prefix+AuthorizationMiddleware.PEP_RESULT_HANDLER_PARAMNAME, 516 None) 518 517 if pepResultHandlerClassName is None: 519 518 pepResultHandler = PEPResultHandlerMiddleware -
TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/ssl.py
r5771 r5774 271 271 msg='No client SSL Certificate set') 272 272 273 if self.isValidClientCert(): 273 if self.isValidClientCert(): 274 self._setUser() 274 275 return self._setResponse() 275 276 else: … … 343 344 344 345 if len(self.clientCertDNMatchList) > 0: 345 if self.__clientCert.dn not in self.clientCertDNMatchList: 346 return False 346 dn = self.__clientCert.dn 347 for expectedDN in self.clientCertDNMatchList: 348 if dn == expectedDN: 349 return True 350 351 return False 347 352 348 353 return True 349 354 355 def _setUser(self): 356 """Interface hook for a derived class to set user ID from certificate 357 set or other context info. 358 """ 359 350 360 351 361 class AuthKitSSLAuthnMiddleware(ApacheSSLAuthnMiddleware): … … 353 363 flag logged in status to other middleware 354 364 """ 365 SET_USER_ENVIRON_KEYNAME = 'paste.auth_tkt.set_user' 366 355 367 @NDGSecurityMiddlewareBase.initCall 356 368 def __call__(self, environ, start_response): … … 384 396 385 397 elif self.isValidClientCert(): 386 # Update environ so that downstream AuthenticationMiddleware can 387 # set the session cookie 388 environ['REMOTE_USER'] = self.clientCert.dn['CN'] 389 environ['paste.auth_tkt.set_user'](environ['REMOTE_USER']) 390 391 # Set-up redirect back to original request URI 392 else: 393 # IsValidCert will log warnings/errors no need to flag this 394 # condition 395 pass 398 # Update session cookie with user ID 399 self._setUser() 400 401 # ... isValidCert will log warnings/errors no need to flag the False 402 # condition 396 403 397 404 # Pass request to next middleware in the chain without setting an 398 405 # error response - see method doc string for explanation. 399 406 return self._setResponse() 407 408 def _setUser(self): 409 """Set user ID in AuthKit cookie from client certificate submitted 410 """ 411 userId = self.clientCert.dn['CN'] 412 413 self.environ[AuthKitSSLAuthnMiddleware.USERNAME_ENVIRON_KEYNAME]=userId 414 self.environ[AuthKitSSLAuthnMiddleware.SET_USER_ENVIRON_KEYNAME](userId) -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/integration/authz_lite/securityservices.ini
r5771 r5774 104 104 prefix = ssl. 105 105 ssl.caCertFilePathList = %(testConfigDir)s/ca/ndg-test-ca.crt 106 107 # HTTP_ prefix is set when passed through a proxy 106 #ssl.clientCertDNMatchList = /O=NDG/OU=BADC/CN=mytest /O=gabriel/OU=BADC/CN=test /O=NDG/OU=BADC/CN=test 107 108 # 'HTTP_' prefix is set when passed through a proxy 108 109 ssl.sslKeyName = HTTP_HTTPS 109 110 ssl.sslClientCertKeyName = HTTP_SSL_CLIENT_CERT -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/integration/authz_lite/securityservicesapp.py
r5739 r5774 13 13 from os.path import dirname, abspath, join 14 14 15 15 from ndg.security.test.unit.wsgi import PasteDeployAppServer 16 16 17 # To start run 17 18 # $ paster serve services.ini or run this file as a script … … 19 20 if __name__ == '__main__': 20 21 import sys 21 import logging22 logging.basicConfig(level=logging.DEBUG)23 24 22 if len(sys.argv) > 1: 25 23 port = int(sys.argv[1]) … … 27 25 port = 7443 28 26 29 cfgFilePath = os.path.join(dirname(abspath(__file__)), 30 'securityservices.ini') 31 32 from paste.httpserver import serve 33 from paste.deploy import loadapp 34 from paste.script.util.logging_config import fileConfig 35 36 fileConfig(cfgFilePath) 37 app = loadapp('config:%s' % cfgFilePath) 38 serve(app, host='0.0.0.0', port=port) 27 cfgFileName='securityservices.ini' 28 cfgFilePath = os.path.join(dirname(abspath(__file__)), cfgFileName) 29 server = PasteDeployAppServer(cfgFilePath, port=port) 30 server.start() -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/__init__.py
r5499 r5774 12 12 import unittest 13 13 import logging 14 import socket 14 15 logging.basicConfig() 15 16 … … 19 20 TEST_CONFIG_DIR = join(abspath(dirname(dirname(__file__))), 'config') 20 21 22 mkDataDirPath = lambda file:join(TEST_CONFIG_DIR, file) 23 24 from ndg.security.test.unit.wsgi import PasteDeployAppServer 25 21 26 class BaseTestCase(unittest.TestCase): 22 27 '''Convenience base class from which other unit tests can extend. Its 23 28 sets the generic data directory path''' 24 29 configDirEnvVarName = 'NDGSEC_TEST_CONFIG_DIR' 30 31 mkDataDirPath = staticmethod(mkDataDirPath) 25 32 26 33 def __init__(self, *arg, **kw): … … 29 36 30 37 unittest.TestCase.__init__(self, *arg, **kw) 38 self.services = [] 39 40 def addService(self, cfgFilePath, port): 41 """Utility for setting up threads to run Paste HTTP based services with 42 unit tests 43 44 @param cfgFilePath: ini file containing configuration for the service 45 @type cfgFilePath: basestring 46 @param port: port number to run the service from 47 @type port: int 48 """ 49 try: 50 self.services.append(PasteDeployAppServer(cfgFilePath, port=port)) 51 self.services[-1].startThread() 52 53 except socket.error: 54 pass 31 55 32 mkDataDirPath = lambda file:join(TEST_CONFIG_DIR, file) 56 def startAttributeAuthorities(self): 57 """Serve test Attribute Authorities to test against""" 58 siteACfgFilePath = mkDataDirPath(join('attributeauthority', 59 'sitea', 60 'site-a.ini')) 61 self.addService(siteACfgFilePath, 5000) 62 63 siteBCfgFilePath = mkDataDirPath(join('attributeauthority', 64 'siteb', 65 'site-b.ini')) 66 self.addService(siteBCfgFilePath, 5100) 67 33 68 69 def __del__(self): 70 """Stop any services started with the addService method""" 71 if hasattr(self, 'services'): 72 for service in self.services: 73 service.terminateThread() 74 34 75 def _getParentDir(depth=0, path=dirname(__file__)): 35 76 """ -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/attributeauthorityclient/test_attributeauthorityclient.py
r5741 r5774 24 24 from xml.etree import ElementTree 25 25 26 from ndg.security.test.unit import BaseTestCase 26 from ndg.security.test.unit import BaseTestCase, mkDataDirPath 27 27 28 28 from ndg.security.common.utils.etree import prettyPrint … … 44 44 from ndg.security.common.saml.bindings import SOAPBinding as SamlSoapBinding 45 45 46 46 47 class AttributeAuthorityClientBaseTestCase(BaseTestCase): 47 48 def __init__(self, *arg, **kw): … … 66 67 except KeyError: 67 68 self.sslCACertList = [] 68 69 70 self.startAttributeAuthorities() 71 69 72 70 73 class AttributeAuthorityClientTestCase(AttributeAuthorityClientBaseTestCase): -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/credentialwallet/test_credentialwallet.py
r5648 r5774 36 36 class. 37 37 """ 38 def __init__(self, *arg, **kw): 39 super(CredentialWalletTestCase, self).__init__(*arg, **kw) 40 self.startAttributeAuthorities() 38 41 39 42 def setUp(self): -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/nosetests.ini
r5712 r5774 14 14 [nosetests] 15 15 verbosity: 3 16 tests: ndg.security.test.unit.x509.test_x509, 17 ndg.security.test.unit.soap.test_soap, 18 ndg.security.test.unit.configfileparsers.test_configfileparsers, 16 tests: 17 #tests: ndg.security.test.unit.x509.test_x509, 18 # ndg.security.test.unit.soap.test_soap, 19 # ndg.security.test.unit.configfileparsers.test_configfileparsers, 19 20 ndg.security.test.unit.credentialwallet.test_credentialwallet, 20 ndg.security.test.unit.xacml.test_xacml,21 ndg.security.test.unit.attributeauthorityclient.test_attributeauthorityclient,22 ndg.security.test.unit.sessionmanager.test_sessionmanager,23 ndg.security.test.unit.authz.pdp.test_proftp_pdp,24 # ./sslclientauthnmiddleware/test_sslclientauthn.py,25 ndg.security.test.unit.openid.relyingparty.validation.test_validation,26 ndg.security.test.unit.xmlsec.etree.test_etree,27 # ./wsgi/authn/test_authn.py,28 # ./wsgi/ssl/test_ssl.py,29 ndg.security.test.unit.wsgi.authz.test_authz,30 ndg.security.test.unit.sessionmanagerclient.test_sessionmanagerclient,31 ndg.security.test.unit.attributeauthority.test_attributeauthority,32 ndg.security.test.unit.saml.test_samlinterface,33 ndg.security.test.unit.wssecurity.foursuite.client.test_echoclient.py,34 ndg.security.test.unit.wssecurity.dom.client.test_echoclient.py21 # ndg.security.test.unit.xacml.test_xacml, 22 ./attributeauthorityclient.test_attributeauthorityclient.py 23 # ndg.security.test.unit.sessionmanager.test_sessionmanager, 24 # ndg.security.test.unit.authz.pdp.test_proftp_pdp, 25 ## ./sslclientauthnmiddleware/test_sslclientauthn.py, 26 # ndg.security.test.unit.openid.relyingparty.validation.test_validation, 27 # ndg.security.test.unit.xmlsec.etree.test_etree, 28 ## ./wsgi/authn/test_authn.py, 29 ## ./wsgi/ssl/test_ssl.py, 30 # ndg.security.test.unit.wsgi.authz.test_authz, 31 # ndg.security.test.unit.sessionmanagerclient.test_sessionmanagerclient, 32 # ndg.security.test.unit.attributeauthority.test_attributeauthority, 33 # ndg.security.test.unit.saml.test_samlinterface, 34 # ndg.security.test.unit.wssecurity.foursuite.client.test_echoclient.py, 35 # ndg.security.test.unit.wssecurity.dom.client.test_echoclient.py 35 36 -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/nosetests.py
r5292 r5774 3 3 Suite to wrap all granulator test cases 4 4 5 NERC Data 5 NERC DataGrid Project 6 6 7 7 """ -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/__init__.py
r5015 r5774 9 9 __contact__ = "Philip.Kershaw@stfc.ac.uk" 10 10 __revision__ = '$Id$' 11 12 import paste.httpserver 13 from threading import Thread 14 from paste.deploy import loadapp 15 from paste.script.util.logging_config import fileConfig 16 17 import logging 18 logging.basicConfig(level=logging.DEBUG) 19 20 class PasteDeployAppServer(object): 21 """Wrapper to paste.httpserver to enable background threading""" 22 23 def __init__(self, cfgFilePath, port=7443, host='0.0.0.0'): 24 """Load an application configuration from cfgFilePath ini file and 25 instantiate Paste server object 26 """ 27 self.__thread = None 28 fileConfig(cfgFilePath) 29 app = loadapp('config:%s' % cfgFilePath) 30 self.__pasteServer = paste.httpserver.serve(app, host=host, port=port, 31 start_loop=False) 32 33 def _getPasteServer(self): 34 return self.__pasteServer 35 36 pasteServer = property(fget=_getPasteServer) 37 38 def _getThread(self): 39 return self.__thread 40 41 thread = property(fget=_getThread) 42 43 def start(self): 44 """Start server""" 45 self.pasteServer.serve_forever() 46 47 def startThread(self): 48 """Start server in a separate thread""" 49 self.__thread = Thread(target=PasteDeployAppServer.start, args=(self,)) 50 self.thread.start() 51 52 def terminateThread(self): 53 self.pasteServer.server_close() 54 -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/authn/ssl-test.ini
r5770 r5774 5 5 # 6 6 [DEFAULT] 7 testConfigDir = ../../../config7 testConfigDir = %(here)s/../../../config 8 8 beakerSessionKeyName = beaker.session.ndg.security 9 9 -
TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/ssl/test.ini
r5757 r5774 5 5 # 6 6 [DEFAULT] 7 testConfigDir = ../../../config7 testConfigDir = %(here)s/../../../config 8 8 9 9 [server:main]
Note: See TracChangeset
for help on using the changeset viewer.