diff options
author | Emmanuel Raviart <eraviart@entrouvert.com> | 2004-08-09 18:00:27 +0000 |
---|---|---|
committer | Emmanuel Raviart <eraviart@entrouvert.com> | 2004-08-09 18:00:27 +0000 |
commit | eb450efe8c113e44e002524428d5957d2bc58cf5 (patch) | |
tree | 2cd5c3ba9889db3ec3307764f8648eafb8dfdb8f /python/tests | |
parent | e851b95362633806e5ec851ff04d458b732d3ccd (diff) | |
download | lasso-eb450efe8c113e44e002524428d5957d2bc58cf5.tar.gz lasso-eb450efe8c113e44e002524428d5957d2bc58cf5.tar.xz lasso-eb450efe8c113e44e002524428d5957d2bc58cf5.zip |
LECP now nearly works. Still a segmentation fault at the end, but Valos is
aware of it.
Diffstat (limited to 'python/tests')
-rw-r--r-- | python/tests/LibertyEnabledClient.py | 22 | ||||
-rw-r--r-- | python/tests/abstractweb.py | 13 | ||||
-rw-r--r-- | python/tests/http.py | 100 | ||||
-rw-r--r-- | python/tests/login_tests.py | 16 | ||||
-rw-r--r-- | python/tests/websimulator.py | 6 |
5 files changed, 92 insertions, 65 deletions
diff --git a/python/tests/LibertyEnabledClient.py b/python/tests/LibertyEnabledClient.py index 9a02872b..f25f9c59 100644 --- a/python/tests/LibertyEnabledClient.py +++ b/python/tests/LibertyEnabledClient.py @@ -73,6 +73,7 @@ class LibertyEnabledClient(WebClient): # without metadata, instead of using 'singleSignOnServiceUrl'. idpSingleSignOnServiceUrl = None lassoServerDump = None + principal = None def __init__(self, internet): WebClient.__init__(self, internet) @@ -80,7 +81,15 @@ class LibertyEnabledClient(WebClient): def getLassoServer(self): return lasso.Server.new_from_dump(self.lassoServerDump) + def getSessionTokens(self): + # LECP is a proxy, not au principal, so it doesn't have its own sessionTokens. + if self.principal is None: + return {} + return self.principal.sessionTokens + def login(self, principal, site, path): + self.principal = principal + httpResponse = self.sendHttpRequestToSite(site, 'GET', path) failUnlessEqual( httpResponse.headers['Content-Type'], 'application/vnd.liberty-request+xml') @@ -102,7 +111,20 @@ class LibertyEnabledClient(WebClient): lecp.build_authn_response_msg() failUnless(lecp.msg_url) failUnless(lecp.msg_body) + + del self.principal + # FIXME: Should we use 'multipart/form-data' for forms? return self.sendHttpRequest( 'POST', lecp.msg_url, headers = {'Content-Type': 'multipart/form-data'}, form = {'LARES': lecp.msg_body}) + + def setKeyring(self, keyring): + # LECP is a proxy, not au principal, so it doesn't have its own keyring. + pass + + def setSessionTokens(self, sessionTokens): + # LECP is a proxy, not au principal, so it doesn't have its own sessionTokens. + pass + + sessionTokens = property(getSessionTokens, setSessionTokens) diff --git a/python/tests/abstractweb.py b/python/tests/abstractweb.py index 6c80ff7a..cdfc1445 100644 --- a/python/tests/abstractweb.py +++ b/python/tests/abstractweb.py @@ -143,19 +143,16 @@ class HttpRequestHandlerMixin: site = None # The virtual host def respond(self, statusCode = 200, statusMessage = None, headers = None, body = None): - # Session must be saved before responding. Otherwise, when the server is multitasked or - # multithreaded, it may receive a new HTTP request before the session is saved. - if self.session is not None and self.session.isDirty: - self.session.save() - self.httpResponse = self.HttpResponse( self, statusCode, statusMessage = statusMessage, headers = headers, body = body) - # Session must be saved before responding. Otherwise, when the server is multitasked or - # multithreaded, it may receive a new HTTP request before the session is saved. - # FIXME: For some status codes, session must not be saved. See outputXXX methods in http. + # Session and user must be saved before responding. Otherwise, when the server is + # multitasked or multithreaded, it may receive a new HTTP request before the session is + # saved. if self.session is not None and self.session.isDirty: self.session.save() + if self.user is not None and self.user.isDirty: + self.user.save() return self.httpResponse.send(self) diff --git a/python/tests/http.py b/python/tests/http.py index 301f0393..46347fa3 100644 --- a/python/tests/http.py +++ b/python/tests/http.py @@ -335,9 +335,6 @@ class HttpRequestHandlerMixin(abstractweb.HttpRequestHandlerMixin): if session is None: sessionToken = None del user.sessionToken - # Don't call user.getDocument().save() now, because the session - # will be retrieved (from cookie or sessionToken query field) - # or created. So user/@sessionToken will be updated. else: # For security reasons, we want to minimize the publication of # session token (it is better not to store it in a cookie or in @@ -372,7 +369,7 @@ class HttpRequestHandlerMixin(abstractweb.HttpRequestHandlerMixin): except: login = loginAndPassword password = '' - logs.debug('Basic authentication: login = "%s" / password = "%s"' % ( + logger.debug('Basic authentication: login = "%s" / password = "%s"' % ( login, password)) if password: user = self.site.authenticateLoginPasswordUser(login, password) @@ -382,47 +379,41 @@ class HttpRequestHandlerMixin(abstractweb.HttpRequestHandlerMixin): return self.outputErrorUnauthorized(httpPath) else: sessionToken = user.sessionToken - if sessionToken: - session = sessions.retrieveSession(sessionToken) - if session is None: - sessionToken = None - user.deleteSessionToken() - # Don't call user.getDocument().save() now, because the session - # will be retrieved (from cookie or sessionToken query field) - # or created. So user/@sessionToken will be updated. - else: - # For security reasons, we want to minimize the publication of - # session token (it is better not to store it in a cookie or in - # URLs). - if session.publishToken: - del session.publishToken + if sessionToken: + session = self.site.getSessionFromToken(sessionToken) + if session is None: + sessionToken = None + del user.sessionToken + else: + # For security reasons, we want to minimize the publication of + # session token (it is better not to store it in a cookie or in + # URLs). The client need to send the certificate each time, for the + # session to continue. + if session.publishToken: + del session.publishToken elif login: # No password was given. Assume login contains a session token. # TODO: sanity chek on login - session = sessions.retrieveSession(login) + session = self.site.getSessionFromToken(sessionToken) if session is not None: - account = session.getAccount() - if account is not None: - user = account.getUser() - if user is not None \ - and user.getSessionToken() != session.getToken(): - # Sanity check. - user.setSessionToken(session.getToken()) - user.getDocument().save() + user = session.user + if user is not None and user.sessionToken != session.token: + # Sanity check. + user.sessionToken = session.token else: - logs.info('Unknown authentication scheme = %s' % authenticationScheme) + logger.info('Unknown authentication scheme = %s' % authenticationScheme) return self.outputErrorUnauthorized(httpPath) # Handle use of cookies, session and user. cookie = None cookieContent = {} if self.httpRequest.headers.has_key('Cookie'): - logs.debug('Cookie received:') + logger.debug('Cookie received:') cookie = Cookie.SimpleCookie( self.httpRequest.headers['Cookie']) for k, v in cookie.items(): cookieContent[k] = v.value - logs.debug(' %s = %s' % (k, cookieContent[k])) + logger.debug(' %s = %s' % (k, cookieContent[k])) self.cookie = cookie sessionToken = None @@ -443,50 +434,44 @@ class HttpRequestHandlerMixin(abstractweb.HttpRequestHandlerMixin): sessionTokenInCookie = True canUseCookie = True if session is None and sessionToken is not None: - session = sessions.retrieveSession(sessionToken) + session = self.site.getSessionFromToken(sessionToken) if session is None: sessionToken = None sessionTokenInCookie = False else: if user is None: - # import expression.modules.passwordaccounts as passwordaccounts - account = session.getAccount(acceptOnlyAccount = False) - if account is not None: - user = account.getUser() - if user is not None and user.getSessionToken() != sessionToken: - # Sanity check. - user.setSessionToken(session.getToken()) - user.getDocument().save() + user = session.user + if user is not None and user.sessionToken != sessionToken: + # Sanity check. + user.sessionToken = sessionToken else: - # The user has been authenticated (using HTTP authentication), but the + # The user has been authenticated (using HTTP or X.509 authentication), but the # associated session didn't exist (or was too old, or...). So, update # its sessionToken. - user.setSessionToken(session.getToken()) - user.getDocument().save() + user.sessionToken = sessionToken # For security reasons, we want to minimize the publication of session # token (it is better not to store it in a cookie or in URLs). if session.publishToken: del session.publishToken if session is None and user is not None: - # The user has been authenticated (using HTTP authentication), but the session + # The user has been authenticated (using HTTP or X.509 authentication), but the session # doesn't exist yet (or was too old, or...). Create a new session. session = sessions.getOrCreateSession() # For security reasons, we want to minimize the publication of session # token (it is better not to store it in a cookie or in URLs). # session.publishToken = False # False is the default value. session.setAccountAbsolutePath(account.getAbsolutePath()) - user.setSessionToken(session.getToken()) - user.getDocument().save() + user.sessionToken = session.token self.user = user if user is not None: - logs.debug('User: %s' % user.simpleLabel) + logger.debug('User: %s' % user.simpleLabel) self.session = session if session is not None: if not sessionTokenInCookie: # The sessionToken is valid but is not stored in the cookie. So, don't try to # use cookie. canUseCookie = False - logs.debug('Session: %s' % session.token) + logger.debug('Session: %s' % session.simpleLabel) self.canUseCookie = canUseCookie ############### @@ -530,10 +515,13 @@ class HttpRequestHandlerMixin(abstractweb.HttpRequestHandlerMixin): ## def outputData(self, data, contentLocation = None, headers = None, mimeType = None, ## modificationTime = None, successCode = 200): -## # Session must be saved before responding. Otherwise, when the server is multitasked or -## # multithreaded, it may receive a new HTTP request before the session is saved. +## # Session and user must be saved before responding. Otherwise, when the server is +## # multitasked or multithreaded, it may receive a new HTTP request before the session is +## # saved. ## if self.session is not None and self.session.isDirty: ## self.session.save() +## if self.user is not None and self.user.isDirty: +## self.user.save() ## if isinstance(data, basestring): ## dataFile = None @@ -738,10 +726,13 @@ An exception "%(exception)s" of class "%(exceptionType)s" occurred. return self.outputErrorInternalServer() def respondRedirectTemporarily(self, url): - # Session must be saved before responding. Otherwise, when the server is multitasked or - # multithreaded, it may receive a new HTTP request before the session is saved. + # Session and user must be saved before responding. Otherwise, when the server is + # multitasked or multithreaded, it may receive a new HTTP request before the session is + # saved. if self.session is not None and self.session.isDirty: self.session.save() + if self.user is not None and self.user.isDirty: + self.user.save() message = 'Moved Temporarily to "%s".' % url logger.debug(message) @@ -760,10 +751,13 @@ An exception "%(exception)s" of class "%(exceptionType)s" occurred. self.wfile.write(data) def send_error(self, code, message = None, data = None, headers = None, setCookie = False): - # Session must be saved before responding. Otherwise, when the server is multitasked or - # multithreaded, it may receive a new HTTP request before the session is saved. + # Session and user must be saved before responding. Otherwise, when the server is + # multitasked or multithreaded, it may receive a new HTTP request before the session is + # saved. if self.session is not None and self.session.isDirty: self.session.save() + if self.user is not None and self.user.isDirty: + self.user.save() shortMessage, longMessage = self.responses.get(code, ('???', '???')) if message is None: diff --git a/python/tests/login_tests.py b/python/tests/login_tests.py index 88034c3c..54827aee 100644 --- a/python/tests/login_tests.py +++ b/python/tests/login_tests.py @@ -251,13 +251,23 @@ class LoginTestCase(unittest.TestCase): idpSite = self.generateIdpSite(internet) spSite = self.generateSpSite(internet) spSite.idpSite = idpSite - lec = self.generateLibertyEnabledClient(internet) - lec.idpSite = idpSite principal = Principal(internet, 'Romain Chantereau') principal.keyring[idpSite.url] = 'Chantereau' principal.keyring[spSite.url] = 'Romain' + lec = self.generateLibertyEnabledClient(internet) + lec.idpSite = idpSite + + # Try LECP, but the principal is not authenticated on identity-provider. So, LECP must + # fail. httpResponse = lec.login(principal, spSite, '/login') - raise str((httpResponse.statusCode, httpResponse.statusMessage, httpResponse.headers['Content-Type'], httpResponse.body)) + failUnlessEqual(httpResponse.statusCode, 401) + + # Now we authenticate principal, before testing LECP. So, LECP must succeed. + httpResponse = principal.sendHttpRequestToSite(spSite, 'GET', '/login') + failUnlessEqual(httpResponse.statusCode, 200) + idpSite.createSession(lec) + httpResponse = lec.login(principal, spSite, '/login') + failUnlessEqual(httpResponse.statusCode, 200) suite1 = unittest.makeSuite(LoginTestCase, 'test') diff --git a/python/tests/websimulator.py b/python/tests/websimulator.py index 411a1268..360fcd06 100644 --- a/python/tests/websimulator.py +++ b/python/tests/websimulator.py @@ -182,8 +182,8 @@ class WebSession(abstractweb.WebSessionMixin, object): expirationTime = None # A sample session variable isDirty = True - loginDump = None # Used only by some identity providers lassoSessionDump = None + loginDump = None # Used only by some identity providers userId = None # ID of logged user. def __init__(self, token): @@ -288,9 +288,13 @@ class WebSite(abstractweb.WebSiteMixin, WebClient): class WebUser(abstractweb.WebUserMixin, object): """Simulation of user of a web site""" + isDirty = True lassoIdentityDump = None language = 'fr' # A sample user variable uniqueId = None # The user name is used as an ID in this simulation. def __init__(self, uniqueId): self.uniqueId = uniqueId + + def save(self): + pass |