mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-02 23:47:42 -04:00
Replace cookie implementation with flask builtin secure cookie.
However, by default, session cookies don't expire (only cleared out by the end user's browser). 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. 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 🙄 http://flask.pocoo.org/docs/0.12/api/#flask.session https://stackoverflow.com/questions/34118093/flask-permanent-session-where-to-define-them
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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'))
|
||||
Reference in New Issue
Block a user