--- saml.py	2013-01-11 16:21:41.894383660 +0100
+++ saml.py	2013-01-14 15:09:17.430496216 +0100
@@ -27,13 +27,18 @@
 from MoinMoin.auth import MultistageRedirectLogin
 from MoinMoin.auth import get_multistage_continuation_url
 
-from werkzeug import redirect, abort
+try:
+    from werkzeug import redirect, abort
+except ImportError:
+    redirect = None
+    abort = None
 
 from saml2 import BINDING_HTTP_REDIRECT
 from saml2.cache import Cache
 from saml2.client import Saml2Client
 from saml2.config import SPConfig
 
+from MoinSupport import get_form
 
 def get_saml_sp_conf(config_dict):
     conf = SPConfig()
@@ -132,6 +137,7 @@
         except KeyError:
             logging.debug('SAML: The attribute %s was not found in the assertion'
                           % attribute)
+            logging.debug('SAML attributes: %r' % saml_attributes)
             return CancelLogin(_('The assetion is missing required attributes'))
 
         # check if the user is valid
@@ -148,12 +154,13 @@
         _ = request.getText
 
         logging.debug('SAML: assertion consumer service')
-        saml_response = request.values.get('SAMLResponse')
+        form = get_form(request)
+        saml_response = form.get('SAMLResponse')
         if saml_response is None:
             logging.debug('SAML: missing SAMLResponse POST key')
             return CancelLogin(_('SAML error: missing SAMLResponse POST key'))
 
-        post = {'SAMLResponse': saml_response}
+        post = {'SAMLResponse': saml_response[0]}
         conf = get_saml_sp_conf(request.cfg.saml_config)
         client = Saml2Client(conf, logger=logging,
                              identity_cache=IdentityCache(request.session))
@@ -184,7 +191,12 @@
         _ = request.getText
 
         # session can't be stored
-        if not request.cfg.cookie_lifetime[0]:
+        lifetime = request.cfg.cookie_lifetime
+        try:
+            lifetime = lifetime[0]
+        except TypeError:
+            pass
+        if not lifetime:
             msg = _('Anonymous sessions need to be enabled for SAML login.')
             return ContinueLogin(user_obj, msg)
 
@@ -214,8 +226,10 @@
                              state_cache=state,
                              identity_cache=IdentityCache(request.session))
 
-        if 'SAMLResponse' in request.values:  # we started the logout
-            saml_response = request.values.get('SAMLResponse')
+        form = get_form(request)
+
+        if form.has_key('SAMLResponse'):  # we started the logout
+            saml_response = form['SAMLResponse'][0]
             response = client.logout_response(saml_response,
                                               binding=BINDING_HTTP_REDIRECT)
             state.sync()
@@ -227,9 +241,10 @@
             else:
                 return CancelLogin(_('Error during logout'))
 
-        elif 'SAMLRequest' in request.values:  # logout started by the IdP
+        elif form.has_key('SAMLRequest'):  # logout started by the IdP
             subject_id = request.session['saml_subject_id']
-            response, success = client.logout_request(request.values,
+            fields = dict([(k, v[0]) for (k, v) in form.items()])
+            response, success = client.logout_request(fields,
                                                       subject_id)
             state.sync()
             if success:
@@ -247,11 +262,11 @@
             return CancelLogin(_('No SAMLResponse or SAMLRequest parameter found'))
 
     def logout(self, request, user_obj, **kw):
-        form = request.values
+        form = get_form(request)
 
         stage = form.get('stage')
 
-        if stage == 'saml':
+        if stage and stage[0] == 'saml':
             return self._logout_service(request, user_obj)
 
         if not (self.name and user_obj
@@ -269,11 +284,21 @@
         session_id, code, head, body = client.global_logout(subject_id)
         headers = dict(head)
         state.sync()
-        # we need to manually save the session because the abort
-        # function raises and exception and the standard code path
-        # for saving the seession is not reached
-        # In other words: MoinMoin does not support multistage logout
-        # process and this is a workaround.
-        request.cfg.session_service.finalize(request, request.session)
 
-        abort(redirect(headers['Location']))
+        if hasattr(request.cfg, 'session_service'):
+            # we need to manually save the session because the abort
+            # function raises and exception and the standard code path
+            # for saving the seession is not reached
+            # In other words: MoinMoin does not support multistage logout
+            # process and this is a workaround.
+            request.cfg.session_service.finalize(request, request.session)
+        else:
+            user_obj.valid = False
+
+        if headers.has_key('Location'):
+            if abort:
+                abort(redirect(headers['Location']))
+            else:
+                request.http_redirect(headers['Location'])
+
+        return user_obj, False
