summaryrefslogtreecommitdiffstats
path: root/ipalib/session.py
diff options
context:
space:
mode:
Diffstat (limited to 'ipalib/session.py')
-rw-r--r--ipalib/session.py126
1 files changed, 121 insertions, 5 deletions
diff --git a/ipalib/session.py b/ipalib/session.py
index a58643983..1f5ee379d 100644
--- a/ipalib/session.py
+++ b/ipalib/session.py
@@ -25,6 +25,8 @@ import re
import time
from text import _
from ipapython.ipa_log_manager import *
+from ipalib import api, errors
+from ipalib import Command
from ipalib.krb_utils import *
__doc__ = '''
@@ -632,6 +634,82 @@ def fmt_time(timestamp):
#-------------------------------------------------------------------------------
+class AuthManager(object):
+ '''
+ This class is an abstract base class and is meant to be subclassed
+ to provide actual functionality. The purpose is to encapsulate all
+ the callbacks one might need to manage authenticaion. Different
+ authentication mechanisms will instantiate a subclass of this and
+ register it with the SessionAuthManger. When an authentication
+ event occurs the matching method will be called for each
+ registered class. This allows the SessionAuthManager to notify
+ interested parties.
+ '''
+
+ def __init__(self, name):
+ log_mgr.get_logger(self, True)
+ self.name = name
+
+
+ def logout(self, session_data):
+ '''
+ Called when a user requests to be logged out of their session.
+
+ :parameters:
+ session_data
+ The current session data
+ :returns:
+ None
+ '''
+ self.debug('AuthManager.logout.%s:', self.name)
+
+class SessionAuthManager(object):
+ '''
+ '''
+
+ def __init__(self):
+ '''
+ '''
+ log_mgr.get_logger(self, True)
+ self.auth_managers = {}
+
+ def register(self, name, auth_mgr):
+ self.debug('SessionAuthManager.register: name=%s', name)
+
+ existing_mgr = self.auth_managers.get(name)
+ if existing_mgr is not None:
+ raise KeyError('cannot register auth manager named "%s" one already exists, name="%s" object=%s',
+ name, existing_mgr.name, repr(existing_mgr))
+
+ if not isinstance(auth_mgr, AuthManager):
+ raise TypeError('auth_mgr must be an instance of AuthManager, not %s',
+ auth_mgr.__class__.__name__)
+
+ self.auth_managers[name] = auth_mgr
+
+
+ def unregister(self, name):
+ self.debug('SessionAuthManager.unregister: name=%s', name)
+
+ if not self.auth_managers.has_key(name):
+ raise KeyError('cannot unregister auth manager named "%s", does not exist',
+ name)
+ del self.auth_managers[name]
+
+
+ def logout(self, session_data):
+ '''
+ '''
+ self.debug('SessionAuthManager.logout:')
+
+ for auth_mgr in self.auth_managers.values():
+ try:
+ auth_mgr.logout(session_data)
+ except Exception, e:
+ self.error('%s auth_mgr logout failed: %s', auth_mgr.name, e)
+
+#-------------------------------------------------------------------------------
+
class SessionManager(object):
'''
@@ -649,8 +727,9 @@ class SessionManager(object):
log_mgr.get_logger(self, True)
self.generated_session_ids = set()
+ self.auth_mgr = SessionAuthManager()
- def generate_session_id(self, n_bits=48):
+ def generate_session_id(self, n_bits=128):
'''
Return a random string to be used as a session id.
@@ -790,8 +869,7 @@ class MemcacheSessionManager(SessionManager):
n_retries = 0
while n_retries < max_retries:
session_id = super(MemcacheSessionManager, self).new_session_id(max_retries)
- session_key = self.session_key(session_id)
- session_data = self.mc.get(session_key)
+ session_data = self.get_session_data(session_id)
if session_data is None:
break
n_retries += 1
@@ -843,6 +921,21 @@ class MemcacheSessionManager(SessionManager):
'''
return 'ipa.session.%s' % (session_id)
+ def get_session_data(self, session_id):
+ '''
+ Given a session id retrieve the session data associated with it.
+ If no session data exists for the session id return None.
+
+ :parameters:
+ session_id
+ The session id whose session data is desired.
+ :returns:
+ Session data if found, None otherwise.
+ '''
+ session_key = self.session_key(session_id)
+ session_data = self.mc.get(session_key)
+ return session_data
+
def get_session_id_from_http_cookie(self, cookie_header):
'''
Parse an HTTP cookie header and search for our session
@@ -904,8 +997,7 @@ class MemcacheSessionManager(SessionManager):
self.store_session_data(session_data)
return session_data
else:
- session_key = self.session_key(session_id)
- session_data = self.mc.get(session_key)
+ session_data = self.get_session_data(session_id)
if session_data is None:
self.debug('no session data in cache with id=%s, generating empty session data', session_id)
session_data = self.new_session_data(session_id)
@@ -1094,5 +1186,29 @@ def delete_krbccache_file(krbccache_pathname=None):
#-------------------------------------------------------------------------------
+from ipalib.request import context
+
+class session_logout(Command):
+ '''
+ RPC command used to log the current user out of their session.
+ '''
+
+ def execute(self, *args, **options):
+ session_data = getattr(context, 'session_data', None)
+ if session_data is None:
+ self.debug('session logout command: no session_data found')
+ else:
+ session_id = session_data.get('session_id')
+ self.debug('session logout command: session_id=%s', session_id)
+
+ # Notifiy registered listeners
+ session_mgr.auth_mgr.logout(session_data)
+
+ return dict(result=None)
+
+api.register(session_logout)
+
+#-------------------------------------------------------------------------------
+
session_mgr = MemcacheSessionManager()