changeset 4193:1e954e802ed2

Start to make auth work again with the new session layer
author Florian Krupicka <florian.krupicka@googlemail.com>
date Fri, 27 Jun 2008 18:38:29 +0200
parents 105c5469ac05
children 9c80451df643
files MoinMoin/action/newaccount.py MoinMoin/auth/__init__.py MoinMoin/web/contexts.py MoinMoin/web/session.py MoinMoin/web/utils.py MoinMoin/wsgiapp.py
diffstat 6 files changed, 118 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/newaccount.py	Wed Jun 25 01:04:42 2008 +0200
+++ b/MoinMoin/action/newaccount.py	Fri Jun 27 18:38:29 2008 +0200
@@ -29,7 +29,7 @@
 
     # Require non-empty name
     try:
-        theuser.name = form['name'][0]
+        theuser.name = form['name']
     except KeyError:
         return _("Empty user name. Please enter a user name.")
 
@@ -44,8 +44,8 @@
         return _("This user name already belongs to somebody else.")
 
     # try to get the password and pw repeat
-    password = form.get('password1', [''])[0]
-    password2 = form.get('password2', [''])[0]
+    password = form.get('password1', '')
+    password2 = form.get('password2', '')
 
     # Check if password is given and matches with password repeat
     if password != password2:
@@ -68,7 +68,7 @@
             return "Can't encode password: %s" % str(err)
 
     # try to get the email, for new users it is required
-    email = wikiutil.clean_input(form.get('email', [''])[0])
+    email = wikiutil.clean_input(form.get('email', ''))
     theuser.email = email.strip()
     if not theuser.email and 'email' not in request.cfg.user_form_remove:
         return _("Please provide your email address. If you lose your"
@@ -82,7 +82,7 @@
     # save data
     theuser.save()
 
-    if form.has_key('create_and_mail'):
+    if 'create_and_mail' in form:
         theuser.mailAccountData()
 
     result = _("User account created! You can use this account to login now...")
@@ -161,7 +161,7 @@
     _ = request.getText
     form = request.form
 
-    submitted = form.has_key('create_only') or form.has_key('create_and_mail')
+    submitted = 'create_only' in form or 'create_and_mail' in form:
 
     if submitted: # user pressed create button
         request.theme.add_msg(_create_user(request), "dialog")
--- a/MoinMoin/auth/__init__.py	Wed Jun 25 01:04:42 2008 +0200
+++ b/MoinMoin/auth/__init__.py	Fri Jun 27 18:38:29 2008 +0200
@@ -251,3 +251,53 @@
                'userprefslink': userprefslink,
                'sendmypasswordlink': sendmypasswordlink}
 
+def handle_login(request, userobj=None, username=None, password=None,
+                 attended=True, openid_identifier=None, stage=None):
+    params = {
+        'username': username,
+        'password': password,
+        'attended': attended,
+        'openid_identifier': openid_identifier,
+        'multistage': (stage and True) or None
+    }
+    for authmethod in request.cfg.auth:
+        if stage and authmethod.name != stage:
+            continue
+        ret = authmethod.login(request, userobj, **params)
+
+        userobj = ret.user_obj
+        cont = ret.continue_flag
+        if stage:
+            stage = None
+            del params['multistage']
+
+        if ret.multistage:
+            request._login_multistage = ret.multistage
+            request._login_multistage_name = authmethod.name
+            return userobj
+
+        if ret.redirect_to:
+            nextstage = auth.get_multistage_continuation_url(request, authmethod.name)
+            url = ret.redirect_to
+            url = url.replace('%return_form', quote_plus(nextstage))
+            url = url.replace('%return', quote(nextstage))
+            abort(redirect(url))
+        msg = ret.message
+        if msg and not msg in request._login_messages:
+            request._login_messages.append(msg)
+
+    return userobj
+
+def handle_logout(request, userobj):
+    for authmethod in request.cfg.auth:
+        userobj, cont = authmethod.logout(request, userobj, cookie=request.cookies)
+        if not cont:
+            break
+    return userobj
+
+def handle_request(request, userobj):
+    for authmethod in request.cfg.auth:
+        userobj, cont = authmethod.request(request, userobj, cookie=request.cookies)
+        if not cont:
+            break
+    return userobj
--- a/MoinMoin/web/contexts.py	Wed Jun 25 01:04:42 2008 +0200
+++ b/MoinMoin/web/contexts.py	Fri Jun 27 18:38:29 2008 +0200
@@ -271,7 +271,12 @@
     parsePageLinks_running = EnvironProxy('parsePageLinks_running', lambda o: {})
     mode_getpagelinks = EnvironProxy('mode_getpagelinks', 0)
     clock = EnvironProxy('clock', lambda o: Clock())
-    pragma = EnvironProxy('pragma', lambda o: dict())
+    pragma = EnvironProxy('pragma', lambda o: {})
+    _login_messages = EnvironProxy('_login_messages', lambda o: [])
+    _login_multistage = EnvironProxy('_login_multistage', None)
+
+
+    _setuid_real_user = EnvironProxy('_setuid_real_user', None)
 
     def uid_generator(self):
         pagename = None
--- a/MoinMoin/web/session.py	Wed Jun 25 01:04:42 2008 +0200
+++ b/MoinMoin/web/session.py	Fri Jun 27 18:38:29 2008 +0200
@@ -15,6 +15,9 @@
 from MoinMoin.web.api import ISessionService
 from MoinMoin import caching
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 class MoinSession(Session):
     """ Compatibility interface to Werkzeug-sessions for old Moin-code. """
     is_new = property(lambda s: s.new)
@@ -42,6 +45,18 @@
         return session
 
     def finalize(self, request, session):
+        userobj = request.user
+        if userobj and userobj.valid:
+            if 'user.id' in session and session['user.id'] != userobj.id:
+                request.cfg.session_service.delete(session)
+            session['user.id'] = userobj.id
+            session['user.auth_method'] = userobj.auth_method
+            session['user.auth_attribs'] = userobj.auth_attribs
+            logging.debug("after auth: storing valid user into session: %r" % userobj.name)
+        else:
+            if 'user.id' in session:
+                request.cfg.session_service.delete(session)                
+
         if session.should_save:
             self.store.save(session)
             cookie_lifetime = request.cfg.cookie_lifetime * 3600
--- a/MoinMoin/web/utils.py	Wed Jun 25 01:04:42 2008 +0200
+++ b/MoinMoin/web/utils.py	Fri Jun 27 18:38:29 2008 +0200
@@ -29,21 +29,23 @@
         is_spider = cfg.cache.ua_spiders.search(useragent.browser) is not None
     return is_spider
 
-def check_setuid(request):
-    """ Check for setuid conditions and set user accordingly
+def check_setuid(request, userobj):
+    """ Check for setuid conditions.
+    Returns a tuple of either new user and old user
+    or just user and None.
     
     @param request: a moin request object
+    @param userobj: a moin user object
     @rtype: boolean
-    @return: Wether a UID change took place
+    @return: (new_user, user) or (user, None)
     """
-    if 'setuid' in request.session and request.user.isSuperUser():
-        request._setuid_real_user = request.user
+    old_user = None
+    if 'setuid' in request.session and userobj.isSuperUser():
+        old_user = userobj
         uid = request.session['setuid']
-        request.user = user.User(request, uid, auth_method='setuid')
-        request.user.valid = True
-        return True
-    else:
-        return False
+        userobj = user.User(request, uid, auth_method='setuid')
+        userobj.valid = True
+    return (userobj, old_user)
 
 def check_forbidden(request):
     """ Simple action and host access checks
@@ -153,70 +155,6 @@
     else:
         return False
 
-def handle_auth(user_obj, request, attended=False, username=None,
-                password=None, openid_identifier=None, login=None,
-                logout=None, stage=None):
-    extra = { 'cookie': request.cookies }
-    if login:
-        extra['attended'] = attended
-        extra['username'] = username
-        extra['password'] = password
-        extra['openid_identifier'] = openid_identifier
-        if stage:
-            extra['multistage'] = True
-    login_msgs = []
-    request._login_multistage = None
-
-    if logout and 'setuid' in request.session:
-        del request.session['setuid']
-        return user_obj
-
-    for authmethod in request.cfg.auth:
-        if logout:
-            user_obj, cont = authmethod.logout(request, user_obj, **extra)
-        elif login:
-            if stage and authmethod.name != stage:
-                continue
-            ret = authmethod.login(request, user_obj, **extra)
-            user_obj = ret.user_obj
-            cont = ret.continue_flag
-            if stage:
-                stage = None
-                del extra['multistage']
-            if ret.multistage:
-                request._login_multistage = ret.multistage
-                request._login_multistage_name = authmethod.name
-                return user_obj
-            if ret.redirect_to:
-                nextstage = auth.get_multistage_continuation_url(request, authmethod.name)
-                url = ret.redirect_to
-                url = url.replace('%return_form', quote_plus(nextstage))
-                url = url.replace('%return', quote(nextstage))
-                abort(redirect(url))
-            msg = ret.message
-            if msg and not msg in login_msgs:
-                login_msgs.append(msg)
-        else:
-            user_obj, cont = authmethod.request(request, user_obj, **extra)
-        if not cont:
-            break
-
-    request._login_messages = login_msgs
-    return user_obj
-
-def handle_auth_form(user_obj, request):
-    form = request.form
-    params = {
-        'username': form.get('name'),
-        'password': form.get('password'),
-        'openid_identifier': form.get('openid_identifier'),
-        'login': 'login' in form,
-        'logout': 'logout' in form,
-        'stage': form.get('stage'),
-        'attended': True
-    }
-    return handle_auth(user_obj, request, **params)
-
 def redirect_last_visited(request):
     pagetrail = request.user.getTrail()
     if pagetrail:
--- a/MoinMoin/wsgiapp.py	Wed Jun 25 01:04:42 2008 +0200
+++ b/MoinMoin/wsgiapp.py	Fri Jun 27 18:38:29 2008 +0200
@@ -13,7 +13,7 @@
 from MoinMoin.web.contexts import HTTPContext, RenderContext, AllContext
 from MoinMoin.web.request import Request
 from MoinMoin.web.utils import check_spider, check_forbidden, check_setuid
-from MoinMoin.web.utils import check_surge_protect, handle_auth_form
+from MoinMoin.web.utils import check_surge_protect
 from MoinMoin.web.apps import HTTPExceptionsMiddleware
 
 from MoinMoin.Page import Page
@@ -35,7 +35,34 @@
 
     request.session = request.cfg.session_service.get_session(request)
 
-    check_setuid(request)
+    # auth & user handling
+    userobj = None
+    form = request.form
+
+    if 'login' in form:
+        params = {
+            'username': form.get('name'),
+            'password': form.get('password'),
+            'attended': True,
+            'openid_identifier': form.get('openid_identifier'),
+            'stage': form.get('stage')
+        }
+        userobj = auth.handle_login(request, userobj, **params)
+    elif 'logout' in form:
+        userobj = auth.handle_logout(request, userobj)
+    else:
+        userobj = auth.handle_request(request, userobj)
+
+    userobj, olduser = check_setuid(request, userobj)
+
+    if not userobj:
+        userobj = user.User(request, auth_method='request:invalid')
+
+    request.user = userobj
+    request._setuid_real_user = olduser
+
+    # preliminary access control
+    # check against spiders, blacklists and request-spam
     check_forbidden(request)
     check_surge_protect(request)