Source code for flask_mongoengine.sessions

import logging
import uuid
from datetime import datetime, timedelta

from bson.tz_util import utc
from flask.sessions import SessionInterface, SessionMixin
from werkzeug.datastructures import CallbackDict

logger = logging.getLogger("flask_mongoengine")

__all__ = ("MongoEngineSession", "MongoEngineSessionInterface")


[docs] class MongoEngineSession(CallbackDict, SessionMixin): def __init__(self, initial=None, sid=None): def on_update(self): self.modified = True CallbackDict.__init__(self, initial, on_update) self.sid = sid self.modified = False
[docs] class MongoEngineSessionInterface(SessionInterface): """SessionInterface for mongoengine""" def __init__(self, db, collection="session"): """ The MongoSessionInterface :param db: The app's db eg: MongoEngine() :param collection: The session collection name defaults to "session" """ logger.warning( "Session management by flask-mongoengine soon to be deprecat." "We recommended to migrate to flask-session." "for migration guid follow this instruction: " "https://flask-mongoengine-3.readthedocs.io/en/latest/session_interface.html" ) if not isinstance(collection, str): raise ValueError("Collection argument should be string") class DBSession(db.Document): sid = db.StringField(primary_key=True) data = db.DictField() expiration = db.DateTimeField() meta = { "allow_inheritance": False, "collection": collection, "indexes": [ { "fields": ["expiration"], "expireAfterSeconds": 60 * 60 * 24 * 7 * 31, } ], } self.cls = DBSession
[docs] def get_expiration_time(self, app, session) -> timedelta: if session.permanent: return app.permanent_session_lifetime # Fallback to 1 day session ttl, if SESSION_TTL not set. return timedelta(**app.config.get("SESSION_TTL", {"days": 1}))
[docs] def open_session(self, app, request): sid = request.cookies.get(app.config["SESSION_COOKIE_NAME"]) if sid: stored_session = self.cls.objects(sid=sid).first() if stored_session: expiration = stored_session.expiration if not expiration.tzinfo: expiration = expiration.replace(tzinfo=utc) if expiration > datetime.utcnow().replace(tzinfo=utc): return MongoEngineSession( initial=stored_session.data, sid=stored_session.sid ) return MongoEngineSession(sid=str(uuid.uuid4()))
[docs] def save_session(self, app, session, response): domain = self.get_cookie_domain(app) httponly = self.get_cookie_httponly(app) # If the session is modified to be empty, remove the cookie. # If the session is empty, return without setting the cookie. if not session: if session.modified: response.delete_cookie(app.config["SESSION_COOKIE_NAME"], domain=domain) return expiration = datetime.utcnow().replace(tzinfo=utc) + self.get_expiration_time( app, session ) if session.modified: self.cls(sid=session.sid, data=session, expiration=expiration).save() response.set_cookie( app.config["SESSION_COOKIE_NAME"], session.sid, expires=expiration, httponly=httponly, domain=domain, )