diff --git a/app/__init__.py b/app/__init__.py index 7669fbc73..48a664431 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -38,7 +38,6 @@ from werkzeug.local import LocalProxy from app import proxy_fix from app.config import configs from app.asset_fingerprinter import AssetFingerprinter -from app.its_dangerous_session import ItsdangerousSessionInterface from app.notify_client.service_api_client import ServiceAPIClient from app.notify_client.api_key_api_client import ApiKeyApiClient from app.notify_client.invite_api_client import InviteApiClient @@ -124,8 +123,6 @@ def create_app(application): proxy_fix.init_app(application) - application.session_interface = ItsdangerousSessionInterface() - add_template_filters(application) register_errorhandlers(application) @@ -139,6 +136,16 @@ def init_app(application): application.before_request(load_service_before_request) application.before_request(request_helper.check_proxy_header_before_request) + @application.before_request + def make_session_permanent(): + # this is dumb. You'd think, given that there's `config['PERMANENT_SESSION_LIFETIME']`, that you'd enable + # permanent sessions in the config too - but no, you have to declare it for each request. + # https://stackoverflow.com/questions/34118093/flask-permanent-session-where-to-define-them + # session.permanent is also, helpfully, a way of saying that the session isn't permanent - in that, it will + # expire on its own, as opposed to being controlled by the browser's session. Because session is a proxy, it's + # only accessible from within a request context, so we need to set this before every request :rolls_eyes: + session.permanent = True + @application.context_processor def _attach_current_service(): return {'current_service': current_service} diff --git a/app/its_dangerous_session.py b/app/its_dangerous_session.py deleted file mode 100644 index e16cecc55..000000000 --- a/app/its_dangerous_session.py +++ /dev/null @@ -1,53 +0,0 @@ -from datetime import timedelta, datetime - -from werkzeug.datastructures import CallbackDict -from flask.sessions import SessionInterface, SessionMixin -from itsdangerous import URLSafeTimedSerializer, BadSignature - - -class ItsdangerousSession(CallbackDict, SessionMixin): - def __init__(self, initial=None): - def on_update(self): - self.modified = True - - CallbackDict.__init__(self, initial, on_update) - self.modified = False - - -class ItsdangerousSessionInterface(SessionInterface): - session_class = ItsdangerousSession - - def get_serializer(self, app): - salt = app.config.get('DANGEROUS_SALT') - if not app.secret_key: - return None - return URLSafeTimedSerializer(app.secret_key, - salt=salt) - - def open_session(self, app, request): - s = self.get_serializer(app) - if s is None: - return None - val = request.cookies.get(app.session_cookie_name) - if not val: - return self.session_class() - max_age = app.permanent_session_lifetime.total_seconds() - try: - data = s.loads(val, max_age=max_age) - return self.session_class(data) - except BadSignature: - return self.session_class() - - def save_session(self, app, session, response): - domain = self.get_cookie_domain(app) - if not session: - if session.modified: - response.delete_cookie(app.session_cookie_name, - domain=domain) - return - session.permanent = True - expires = datetime.utcnow() + timedelta(seconds=app.config.get('PERMANENT_SESSION_LIFETIME')) - val = self.get_serializer(app).dumps(dict(session)) - response.set_cookie(app.session_cookie_name, val, - expires=expires, httponly=True, - domain=domain, secure=app.config.get('SESSION_COOKIE_SECURE'))