##// END OF EJS Templates
fix(caching): fixed problems with Cache query for users....
fix(caching): fixed problems with Cache query for users. The old way of querying caused the user get query to be always cached, and returning old results even in 2fa forms. The new limited query doesn't cache the user object resolving issues

File last commit:

r5148:5ce7d4ae default
r5365:ae8a165b default
Show More
rc_beaker.py
171 lines | 5.6 KiB | text/x-python | PythonLexer
# Copyright (c) 2010 Agendaless Consulting and Contributors.
# (http://www.agendaless.com), All Rights Reserved
# License: BSD-derived (http://www.repoze.org/LICENSE.txt)
# With Patches from RhodeCode GmBH
import os
from beaker import cache
from beaker.session import SessionObject, Session
from beaker.util import coerce_cache_params
from beaker.util import coerce_session_params
from pyramid.interfaces import ISession
from pyramid.settings import asbool
from zope.interface import implementer
from binascii import hexlify
class CustomSession(Session):
pass
def BeakerSessionFactoryConfig(**options):
""" Return a Pyramid session factory using Beaker session settings
supplied directly as ``**options``"""
class PyramidBeakerSessionObject(SessionObject):
_options = options
_cookie_on_exception = _options.pop('cookie_on_exception', True)
_constant_csrf_token = _options.pop('constant_csrf_token', False)
_sa_opts = _options.pop('sa_opts', {})
def __init__(self, request):
self._options['session_class'] = CustomSession
self._options['sa_opts'] = self._sa_opts
SessionObject.__init__(self, request.environ, **self._options)
def session_callback(_request, _response):
exception = getattr(_request, 'exception', None)
file_response = getattr(_request, '_file_response', None)
api_call = getattr(_request, 'rpc_method', None)
if file_response is not None:
return
if api_call is not None:
return
if exception is not None and not self._cookie_on_exception:
return
if self.accessed():
self.persist()
headers = self.__dict__['_headers']
if headers.get('set_cookie') and headers.get('cookie_out'):
_response.headerlist.append(('Set-Cookie', headers['cookie_out']))
request.add_response_callback(session_callback)
# ISession API
@property
def id(self):
# this is as inspected in SessionObject.__init__
if self.__dict__['_params'].get('type') != 'cookie':
return self._session().id
return None
@property
def new(self):
return self.last_accessed is None
changed = SessionObject.save
# modifying dictionary methods
@call_save
def clear(self):
return self._session().clear()
@call_save
def update(self, d, **kw):
return self._session().update(d, **kw)
@call_save
def setdefault(self, k, d=None):
return self._session().setdefault(k, d)
@call_save
def pop(self, k, d=None):
return self._session().pop(k, d)
@call_save
def popitem(self):
return self._session().popitem()
__setitem__ = call_save(SessionObject.__setitem__)
__delitem__ = call_save(SessionObject.__delitem__)
# Flash API methods
def flash(self, msg, queue='', allow_duplicate=True):
storage = self.setdefault(f'_f_{queue}', [])
if allow_duplicate or (msg not in storage):
storage.append(msg)
def pop_flash(self, queue=''):
storage = self.pop(f'_f_{queue}', [])
return storage
def peek_flash(self, queue=''):
storage = self.get(f'_f_{queue}', [])
return storage
# CSRF API methods
def new_csrf_token(self):
token = (self._constant_csrf_token
or hexlify(os.urandom(20)).decode('ascii'))
self['_csrft_'] = token
return token
def get_csrf_token(self):
token = self.get('_csrft_', None)
if token is None:
token = self.new_csrf_token()
return token
return implementer(ISession)(PyramidBeakerSessionObject)
def call_save(wrapped):
""" By default, in non-auto-mode beaker badly wants people to
call save even though it should know something has changed when
a mutating method is called. This hack should be removed if
Beaker ever starts to do this by default. """
def save(session, *arg, **kw):
value = wrapped(session, *arg, **kw)
session.save()
return value
save.__doc__ = wrapped.__doc__
return save
def session_factory_from_settings(settings):
""" Return a Pyramid session factory using Beaker session settings
supplied from a Paste configuration file"""
prefixes = ('session.', 'beaker.session.')
options = {}
# custom gather of our specific sqlalchemy session db configuration we need to translate this into a single entry
# dict because this is how beaker expects that.
sa_opts = {}
# Pull out any config args meant for beaker session. if there are any
for k, v in settings.items():
for prefix in prefixes:
if k.startswith(prefix):
option_name = k[len(prefix):]
if option_name == 'cookie_on_exception':
v = asbool(v)
if option_name.startswith('sa.'):
sa_opts[option_name] = v
options[option_name] = v
options = coerce_session_params(options)
options['sa_opts'] = sa_opts
return BeakerSessionFactoryConfig(**options)
def includeme(config):
session_factory = session_factory_from_settings(config.registry.settings)
config.set_session_factory(session_factory)