[PATCH] middleware: use secure cookies over secure connections
Andrew Shadura
andrew at shadura.me
Wed Mar 4 17:58:19 EST 2015
# HG changeset patch
# User Andrew Shadura <andrew at shadura.me>
# Date 1425509877 -3600
# Wed Mar 04 23:57:57 2015 +0100
# Node ID 6e0cecf00cdad2d108caca97c4cd9dece0333d73
# Parent 599fba9967a4981e8c401c39521a52635dd93380
middleware: use secure cookies over secure connections
Use our own wrapper around Beaker's SessionMiddleware class to
give secure cookies over HTTPS connections.
diff --git a/kallithea/config/middleware.py b/kallithea/config/middleware.py
--- a/kallithea/config/middleware.py
+++ b/kallithea/config/middleware.py
@@ -15,7 +15,6 @@
Pylons middleware initialization
"""
-from beaker.middleware import SessionMiddleware
from routes.middleware import RoutesMiddleware
from paste.cascade import Cascade
from paste.registry import RegistryManager
@@ -29,6 +28,7 @@ from pylons.wsgiapp import PylonsApp
from kallithea.lib.middleware.simplehg import SimpleHg
from kallithea.lib.middleware.simplegit import SimpleGit
from kallithea.lib.middleware.https_fixup import HttpsFixup
+from kallithea.lib.middleware.sessionmiddleware import SessionMiddleware
from kallithea.config.environment import load_environment
from kallithea.lib.middleware.wrapper import RequestWrapper
diff --git a/kallithea/lib/middleware/sessionmiddleware.py b/kallithea/lib/middleware/sessionmiddleware.py
new file mode 100644
--- /dev/null
+++ b/kallithea/lib/middleware/sessionmiddleware.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+kallithea.lib.middleware.sessionmiddleware
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+session management middleware
+
+This file overrides Beaker's built-in SessionMiddleware
+class to automagically use secure cookies over HTTPS.
+
+Original Beaker SessionMiddleware class written by Ben Bangert
+
+:created_on: March 04, 2015
+:author: andrewsh
+:copyright: (c) 2015 Andrew Shadura
+:license: GPLv3, see LICENSE.md for more details.
+"""
+
+from beaker.session import SessionObject
+from beaker.middleware import SessionMiddleware as BeakerSessionMiddleware
+
+class SessionMiddleware(BeakerSessionMiddleware):
+ def __init__(self, wrap_app, config=None, environ_key='beaker.session',
+ **kwargs):
+ """
+ Initialise the session middleware
+
+ Call Beaker's original constructor to set the options, then
+ unset secure option as we're handling that on our own and don't
+ want Beaker to interfere.
+ """
+ super(SessionMiddleware, self).__init__(wrap_app, config,
+ environ_key, **kwargs)
+ self.options["secure"] = False
+ # self.options["httponly"] = True
+
+ def __call__(self, environ, start_response):
+ """
+ This function's implementation is taken directly from Beaker,
+ with HTTPS detection added. When accessed over HTTPS, force
+ setting cookie's secure flag.
+ """
+ session = SessionObject(environ, **self.options)
+ if environ.get('paste.registry'):
+ if environ['paste.registry'].reglist:
+ environ['paste.registry'].register(self.session, session)
+ environ[self.environ_key] = session
+ environ['beaker.get_session'] = self._get_session
+
+ if 'paste.testing_variables' in environ and 'webtest_varname' in self.options:
+ environ['paste.testing_variables'][self.options['webtest_varname']] = session
+
+ is_ssl = environ['wsgi.url_scheme'] == 'https'
+
+ def session_start_response(status, headers, exc_info=None):
+ if session.accessed():
+ session.persist()
+ if session.__dict__['_headers']['set_cookie']:
+ cookie = session.__dict__['_headers']['cookie_out']
+
+ if is_ssl:
+ cookie += "; secure"
+ if cookie:
+ headers.append(('Set-cookie', cookie))
+ return start_response(status, headers, exc_info)
+ return self.wrap_app(environ, session_start_response)
More information about the kallithea-general
mailing list