Beispiel #1
0
class Session(object):
    """
    セッション管理をするクラス
    cachelibの機能を使ってファイルによってセッションを管理する
    セッション自体は1つの辞書っぽいもので,一番上のキーが各セッションのIDになるえ
    Flask Sessionの実装を参考に作成した
    https://github.com/fengsp/flask-session/blob/a88f07e7260ae582b0744de42e77c4625e6884ea/flask_session/sessions.py

    TODO: セッション情報を削除する機能を追加
    """
    def __init__(self, config: Config):
        self.cache = FileSystemCache(config.session_cache_dir)
        self.session_lifetime = config.session_lifetime

    def get(self, session_id: str) -> Dict[str, Hashable]:
        """
        与えられたセッションIDのセッション情報を取得する
        :param session_id: セッションID
        :return:
        """
        if not session_id:
            return {}
        return self._load_session_from_file(session_id)

    def set(self, key: str, value: Hashable, session_id: str = None) -> str:
        """
        セッションを追加する
        :param session_id: セッションId
        :param key: 追加するセッション情報のキー
        :param value: 追加するセッション情報の値
        """
        if not session_id:
            # セッションを新規作成
            session_id = self._generate_session_id()
        session_obj = self._load_session_from_file(session_id) or {}
        session_obj.update({key: value})
        self._save_session(session_id, session_obj)
        return session_id

    def destroy(self, session_id):
        """
        セッションを削除する
        :param session_id: 削除するセッションのID
        :return: None
        """
        self.cache.delete(session_id)

    def _load_session_from_file(self, session_id) -> Dict[str, Hashable]:
        """
        与えられたセッションIDの情報を取得する
        :param session_id: セッションID
        :return dict: セッション情報
        """
        return self.cache.get(session_id)

    def _save_session(self, session_id: str, obj: Hashable) -> None:
        self.cache.set(session_id, obj, timeout=self.session_lifetime)

    def _generate_session_id(self) -> str:
        return uuid4().hex
Beispiel #2
0
class FileSystemSessionInterface(SessionInterface):
    """Uses the :class:`werkzeug.contrib.cache.FileSystemCache` as a session
    backend.

    .. versionadded:: 0.2
        The `use_signer` parameter was added.

    :param cache_dir: the directory where session files are stored.
    :param threshold: the maximum number of items the session stores before it
                      starts deleting some.
    :param mode: the file mode wanted for the session files, default 0600
    :param key_prefix: A prefix that is added to FileSystemCache store keys.
    :param use_signer: Whether to sign the session id cookie or not.
    :param permanent: Whether to use permanent session or not.
    """

    session_class = FileSystemSession

    def __init__(self,
                 cache_dir,
                 threshold,
                 mode,
                 key_prefix,
                 use_signer=False,
                 permanent=True):
        from cachelib.file import FileSystemCache
        self.cache = FileSystemCache(cache_dir, threshold=threshold, mode=mode)
        self.key_prefix = key_prefix
        self.use_signer = use_signer
        self.permanent = permanent

    def open_session(self, app, request):
        sid = request.cookies.get(app.session_cookie_name)
        if not sid:
            sid = self._generate_sid()
            return self.session_class(sid=sid, permanent=self.permanent)
        if self.use_signer:
            signer = self._get_signer(app)
            if signer is None:
                return None
            try:
                sid_as_bytes = signer.unsign(sid)
                sid = sid_as_bytes.decode()
            except BadSignature:
                sid = self._generate_sid()
                return self.session_class(sid=sid, permanent=self.permanent)

        data = self.cache.get(self.key_prefix + sid)
        if data is not None:
            return self.session_class(data, sid=sid)
        return self.session_class(sid=sid, permanent=self.permanent)

    def save_session(self, app, session, response):
        domain = self.get_cookie_domain(app)
        path = self.get_cookie_path(app)
        if not session:
            if session.modified:
                self.cache.delete(self.key_prefix + session.sid)
                response.delete_cookie(app.session_cookie_name,
                                       domain=domain,
                                       path=path)
            return

        httponly = self.get_cookie_httponly(app)
        secure = self.get_cookie_secure(app)
        expires = self.get_expiration_time(app, session)
        data = dict(session)
        self.cache.set(self.key_prefix + session.sid, data,
                       total_seconds(app.permanent_session_lifetime))
        if self.use_signer:
            session_id = self._get_signer(app).sign(want_bytes(session.sid))
        else:
            session_id = session.sid
        response.set_cookie(app.session_cookie_name,
                            session_id,
                            expires=expires,
                            httponly=httponly,
                            domain=domain,
                            path=path,
                            secure=secure,
                            samesite='None')
Beispiel #3
0
def set_cache(key, value, timeout=15, cache_dir=None):
    global cache
    if cache is None:
        cache = FileSystemCache(cache_dir or get_cache_dir())
    cache.set(str(key), value, timeout=timeout)