mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-24 08:16:51 -04:00
Merge pull request #1753 from alphagov/session-cookie
Replace cookie implementation with flask builtin secure cookie.
This commit is contained in:
@@ -38,7 +38,6 @@ from werkzeug.local import LocalProxy
|
|||||||
from app import proxy_fix
|
from app import proxy_fix
|
||||||
from app.config import configs
|
from app.config import configs
|
||||||
from app.asset_fingerprinter import AssetFingerprinter
|
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.service_api_client import ServiceAPIClient
|
||||||
from app.notify_client.api_key_api_client import ApiKeyApiClient
|
from app.notify_client.api_key_api_client import ApiKeyApiClient
|
||||||
from app.notify_client.invite_api_client import InviteApiClient
|
from app.notify_client.invite_api_client import InviteApiClient
|
||||||
@@ -124,8 +123,6 @@ def create_app(application):
|
|||||||
|
|
||||||
proxy_fix.init_app(application)
|
proxy_fix.init_app(application)
|
||||||
|
|
||||||
application.session_interface = ItsdangerousSessionInterface()
|
|
||||||
|
|
||||||
add_template_filters(application)
|
add_template_filters(application)
|
||||||
|
|
||||||
register_errorhandlers(application)
|
register_errorhandlers(application)
|
||||||
@@ -139,6 +136,16 @@ def init_app(application):
|
|||||||
application.before_request(load_service_before_request)
|
application.before_request(load_service_before_request)
|
||||||
application.before_request(request_helper.check_proxy_header_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
|
@application.context_processor
|
||||||
def _attach_current_service():
|
def _attach_current_service():
|
||||||
return {'current_service': 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