Fix logout one more time

- larpe/sessions.py:
   when expiring a session, remove all data indexed by the providerId
 - larpe/site_authentication.py:
   allows to give directly the list of cookies to local_logout(), bypass
   the fact that cookies are stored in Federation object that are by
   identity and by session objects (but cookies are by session). The
   result is that if the user clean its cookies, re-login on the same
   larpe SP, at next logout, the first session will not be logged out,
   but larpe could perfectly terminate it if the cookies had been kept
   somewhere.
 - larpe/saml2.ptl:
   do not kill session during logout, you never know if they are not
   shared with another service provider (they are used by all site
   behind larpe ;( ). instead clean up data indexed by provider Id, and
   ask for local_logout() and expire_session() to run.

git-svn-id: svn+ssh://labs.libre-entreprise.org/svnroot/larpe@481 3ed937ae-f919-0410-9a43-8e6f19e4ba6e
This commit is contained in:
bdauvergne 2009-09-29 09:25:06 +00:00
parent 584d05cc70
commit dddf6c4132
3 changed files with 46 additions and 23 deletions

View File

@ -279,10 +279,10 @@ class Saml2(Saml2Directory):
get_logger().warn('Request Denied')
elif error[0] == lasso.LOGOUT_ERROR_UNKNOWN_PRINCIPAL:
get_logger().warn('Unknown principal on logout, probably session stopped already on IdP')
# XXX: wouldn't work when logged on two IdP
del session.lasso_session_dumps[logout.server.providerId]
else:
raise
get_logger().error('Unknown Lasso exception on logout return: ' + repr(error))
except Exception, exception:
get_logger().error('Unknown exception on logout return: ' + repr(exception))
get_session_manager().expire_session(logout.server.providerId)
@ -314,7 +314,8 @@ class Saml2(Saml2Directory):
request_name_identifier = logout.nameIdentifier.content
request_session_index = logout.request.sessionIndex
if request_name_identifier == name_identifier and \
(not session_index or request_session_index == session_index):
(not session_index or request_session_index == session_index) \
and session.lasso_session_dump.get(providerId):
get_logger().info('SLO/SOAP from %s' % logout.remoteProviderId)
break
else:
@ -345,7 +346,8 @@ class Saml2(Saml2Directory):
request_name_identifier = logout.nameIdentifier.content
request_session_index = logout.request.sessionIndex
if request_name_identifier == name_identifier and \
(not session_index or request_session_index == session_index):
(not session_index or request_session_index == session_index) \
and session.lasso_session_dump.get(providerId):
get_logger().info('SLO/SOAP from %s' % logout.remoteProviderId)
break
else:
@ -384,25 +386,42 @@ class Saml2(Saml2Directory):
pass
elif error[0] == lasso.PROFILE_ERROR_MISSING_ASSERTION:
pass
elif error[0] == lasso.SERVER_ERROR_PROVIDER_NOT_FOUND:
pass
elif error[0] == lasso.NAME_IDENTIFIER_NOT_FOUND:
pass
else:
raise
else:
try:
providerId = logout.server.providerId
session_index = logout.request.sessionIndex
name_identifier = logout.nameIdentifier.content
# Remove reference to local authentication on this SP in the session
# if a user is present, try a local logout
for session2 in get_session_manager().values():
if session2.lasso_session_name_identifiers.get(providerId) == name_identifier \
and ( not session_index
or session2.lasso_session_indexes.get(providerId) == session_index):
if session2.users.has_key(provider_id):
# try a local logout
try:
site_authentication.get_site_authentication(Host.get_host_from_url()).local_logout(user=session2.users[provider_id], cookies=getattr(session2,'cookies'))
except:
pass
del session2.users[provider_id]
if session2.lasso_session_dumps.has_key(provider_id):
del session2.lasso_session_dumps[provider_id]
if session2.lasso_session_indexes.has_key(provider_id):
del session2.lasso_session_indexes[provider_id]
if session2.lasso_session_name_identifiers.has_key(provider_id):
del session2.lasso_session_name_identifiers[provider_id]
session2.store()
except:
# killing all session failed, ignoring silently
pass
get_session_manager().expire_session(logout.server.providerId)
try:
providerId = logout.server.providerId
session_index = logout.request.sessionIndex
name_identifier = logout.nameIdentifier.content
# Remove all session for this name_identifier and if present for this session index
for session2 in get_session_manager().values():
if session2.lasso_session_name_identifiers.get(providerId) == name_identifier \
and ( not session_index
or session2.lasso_session_indexes.get(providerId) == session_index):
del get_session_manager()[session2.id]
except:
# killing all session failed, ignoring silently
pass
logout.buildResponseMsg()
if logout.msgBody: # soap answer
return logout.msgBody

View File

@ -81,6 +81,10 @@ class StorageSessionManager(SessionManager):
del session.users[provider_id]
if session.lasso_session_dumps.has_key(provider_id):
del session.lasso_session_dumps[provider_id]
if session.lasso_session_indexes.has_key(provider_id):
del session.lasso_session_indexes[provider_id]
if session.lasso_session_name_identifiers.has_key(provider_id):
del session.lasso_session_name_identifiers[provider_id]
session.store()
if not session.users:
SessionManager.expire_session(self)

View File

@ -290,15 +290,15 @@ class SiteAuthentication:
return success, return_content
def local_logout(self, federation=None, user=None):
if federation is None and user is not None:
def local_logout(self, federation=None, user=None, cookies=None):
if cookies is None and federation is None and user is not None:
federations = Federation.select(lambda x: user.name_identifiers[0] in x.name_identifiers)
if federations:
federation = federations[0]
cookies = federations[0].cookies
# Logout request to the site
url = self.host.logout_url
if url is not None and federation is not None and federation.cookies is not None:
if url is not None and cookies is not None:
try:
http_get_page(url, {'Cookie': federation.cookies})
except: