session: moved pyramid_beaker internally to apply some patches required for better session handling
This commit is contained in:
parent
7d97198330
commit
89d320077e
5 changed files with 202 additions and 19 deletions
|
|
@ -1395,21 +1395,6 @@ self: super: {
|
|||
license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
|
||||
};
|
||||
};
|
||||
"pyramid-beaker" = super.buildPythonPackage {
|
||||
name = "pyramid-beaker-0.8";
|
||||
doCheck = false;
|
||||
propagatedBuildInputs = [
|
||||
self."pyramid"
|
||||
self."beaker"
|
||||
];
|
||||
src = fetchurl {
|
||||
url = "https://files.pythonhosted.org/packages/d9/6e/b85426e00fd3d57f4545f74e1c3828552d8700f13ededeef9233f7bca8be/pyramid_beaker-0.8.tar.gz";
|
||||
sha256 = "0hflx3qkcdml1mwpq53sz46s7jickpfn0zy0ns2c7j445j66bp3p";
|
||||
};
|
||||
meta = {
|
||||
license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
|
||||
};
|
||||
};
|
||||
"pyramid-debugtoolbar" = super.buildPythonPackage {
|
||||
name = "pyramid-debugtoolbar-4.5";
|
||||
doCheck = false;
|
||||
|
|
@ -1793,7 +1778,6 @@ self: super: {
|
|||
self."pycrypto"
|
||||
self."pygments"
|
||||
self."pyparsing"
|
||||
self."pyramid-beaker"
|
||||
self."pyramid-debugtoolbar"
|
||||
self."pyramid-mako"
|
||||
self."pyramid"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ pycurl==7.43.0.2
|
|||
pycrypto==2.6.1
|
||||
pygments==2.4.2
|
||||
pyparsing==2.3.0
|
||||
pyramid-beaker==0.8
|
||||
pyramid-debugtoolbar==4.5.0
|
||||
pyramid-mako==1.0.2
|
||||
pyramid==1.10.4
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ def includeme(config):
|
|||
|
||||
# Includes which are required. The application would fail without them.
|
||||
config.include('pyramid_mako')
|
||||
config.include('pyramid_beaker')
|
||||
config.include('rhodecode.lib.rc_beaker')
|
||||
config.include('rhodecode.lib.rc_cache')
|
||||
|
||||
config.include('rhodecode.apps._base.navigation')
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ def bootstrap_config(request):
|
|||
|
||||
# allow pyramid lookup in testing
|
||||
config.include('pyramid_mako')
|
||||
config.include('pyramid_beaker')
|
||||
config.include('rhodecode.lib.rc_beaker')
|
||||
config.include('rhodecode.lib.rc_cache')
|
||||
|
||||
add_events_routes(config)
|
||||
|
|
|
|||
200
rhodecode/lib/rc_beaker.py
Normal file
200
rhodecode/lib/rc_beaker.py
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
# 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
|
||||
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
|
||||
|
||||
|
||||
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)
|
||||
|
||||
def __init__(self, request):
|
||||
SessionObject.__init__(self, request.environ, **self._options)
|
||||
|
||||
def session_callback(request, response):
|
||||
exception = getattr(request, 'exception', None)
|
||||
if (exception is None or self._cookie_on_exception) and self.accessed():
|
||||
self.persist()
|
||||
headers = self.__dict__['_headers']
|
||||
if headers['set_cookie'] and headers['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_' + queue, [])
|
||||
if allow_duplicate or (msg not in storage):
|
||||
storage.append(msg)
|
||||
|
||||
def pop_flash(self, queue=''):
|
||||
storage = self.pop('_f_' + queue, [])
|
||||
return storage
|
||||
|
||||
def peek_flash(self, queue=''):
|
||||
storage = self.get('_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 = {}
|
||||
|
||||
# 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)
|
||||
options[option_name] = v
|
||||
|
||||
options = coerce_session_params(options)
|
||||
return BeakerSessionFactoryConfig(**options)
|
||||
|
||||
|
||||
def set_cache_regions_from_settings(settings):
|
||||
""" Add cache support to the Pylons application.
|
||||
|
||||
The ``settings`` passed to the configurator are used to setup
|
||||
the cache options. Cache options in the settings should start
|
||||
with either 'beaker.cache.' or 'cache.'.
|
||||
|
||||
"""
|
||||
cache_settings = {'regions': []}
|
||||
for key in settings.keys():
|
||||
for prefix in ['beaker.cache.', 'cache.']:
|
||||
if key.startswith(prefix):
|
||||
name = key.split(prefix)[1].strip()
|
||||
cache_settings[name] = settings[key].strip()
|
||||
|
||||
if ('expire' in cache_settings
|
||||
and isinstance(cache_settings['expire'], basestring)
|
||||
and cache_settings['expire'].lower() in ['none', 'no']):
|
||||
cache_settings['expire'] = None
|
||||
|
||||
coerce_cache_params(cache_settings)
|
||||
|
||||
if 'enabled' not in cache_settings:
|
||||
cache_settings['enabled'] = True
|
||||
|
||||
regions = cache_settings['regions']
|
||||
if regions:
|
||||
for region in regions:
|
||||
if not region:
|
||||
continue
|
||||
|
||||
region_settings = {
|
||||
'data_dir': cache_settings.get('data_dir'),
|
||||
'lock_dir': cache_settings.get('lock_dir'),
|
||||
'expire': cache_settings.get('expire', 60),
|
||||
'enabled': cache_settings['enabled'],
|
||||
'key_length': cache_settings.get('key_length', 250),
|
||||
'type': cache_settings.get('type'),
|
||||
'url': cache_settings.get('url'),
|
||||
}
|
||||
region_prefix = '%s.' % region
|
||||
region_len = len(region_prefix)
|
||||
for key in list(cache_settings.keys()):
|
||||
if key.startswith(region_prefix):
|
||||
region_settings[key[region_len:]] = cache_settings.pop(key)
|
||||
|
||||
if (isinstance(region_settings['expire'], basestring)
|
||||
and region_settings['expire'].lower() in ['none', 'no']):
|
||||
region_settings['expire'] = None
|
||||
coerce_cache_params(region_settings)
|
||||
cache.cache_regions[region] = region_settings
|
||||
|
||||
|
||||
def includeme(config):
|
||||
session_factory = session_factory_from_settings(config.registry.settings)
|
||||
config.set_session_factory(session_factory)
|
||||
set_cache_regions_from_settings(config.registry.settings)
|
||||
Loading…
Add table
Add a link
Reference in a new issue