Show More
@@ -0,0 +1,200 b'' | |||||
|
1 | # Copyright (c) 2010 Agendaless Consulting and Contributors. | |||
|
2 | # (http://www.agendaless.com), All Rights Reserved | |||
|
3 | # License: BSD-derived (http://www.repoze.org/LICENSE.txt) | |||
|
4 | # With Patches from RhodeCode GmBH | |||
|
5 | ||||
|
6 | ||||
|
7 | import os | |||
|
8 | ||||
|
9 | from beaker import cache | |||
|
10 | from beaker.session import SessionObject | |||
|
11 | from beaker.util import coerce_cache_params | |||
|
12 | from beaker.util import coerce_session_params | |||
|
13 | ||||
|
14 | from pyramid.interfaces import ISession | |||
|
15 | from pyramid.settings import asbool | |||
|
16 | from zope.interface import implementer | |||
|
17 | ||||
|
18 | from binascii import hexlify | |||
|
19 | ||||
|
20 | ||||
|
21 | def BeakerSessionFactoryConfig(**options): | |||
|
22 | """ Return a Pyramid session factory using Beaker session settings | |||
|
23 | supplied directly as ``**options``""" | |||
|
24 | ||||
|
25 | class PyramidBeakerSessionObject(SessionObject): | |||
|
26 | _options = options | |||
|
27 | _cookie_on_exception = _options.pop('cookie_on_exception', True) | |||
|
28 | _constant_csrf_token = _options.pop('constant_csrf_token', False) | |||
|
29 | ||||
|
30 | def __init__(self, request): | |||
|
31 | SessionObject.__init__(self, request.environ, **self._options) | |||
|
32 | ||||
|
33 | def session_callback(request, response): | |||
|
34 | exception = getattr(request, 'exception', None) | |||
|
35 | if (exception is None or self._cookie_on_exception) and self.accessed(): | |||
|
36 | self.persist() | |||
|
37 | headers = self.__dict__['_headers'] | |||
|
38 | if headers['set_cookie'] and headers['cookie_out']: | |||
|
39 | response.headerlist.append(('Set-Cookie', headers['cookie_out'])) | |||
|
40 | request.add_response_callback(session_callback) | |||
|
41 | ||||
|
42 | # ISession API | |||
|
43 | ||||
|
44 | @property | |||
|
45 | def id(self): | |||
|
46 | # this is as inspected in SessionObject.__init__ | |||
|
47 | if self.__dict__['_params'].get('type') != 'cookie': | |||
|
48 | return self._session().id | |||
|
49 | return None | |||
|
50 | ||||
|
51 | @property | |||
|
52 | def new(self): | |||
|
53 | return self.last_accessed is None | |||
|
54 | ||||
|
55 | changed = SessionObject.save | |||
|
56 | ||||
|
57 | # modifying dictionary methods | |||
|
58 | ||||
|
59 | @call_save | |||
|
60 | def clear(self): | |||
|
61 | return self._session().clear() | |||
|
62 | ||||
|
63 | @call_save | |||
|
64 | def update(self, d, **kw): | |||
|
65 | return self._session().update(d, **kw) | |||
|
66 | ||||
|
67 | @call_save | |||
|
68 | def setdefault(self, k, d=None): | |||
|
69 | return self._session().setdefault(k, d) | |||
|
70 | ||||
|
71 | @call_save | |||
|
72 | def pop(self, k, d=None): | |||
|
73 | return self._session().pop(k, d) | |||
|
74 | ||||
|
75 | @call_save | |||
|
76 | def popitem(self): | |||
|
77 | return self._session().popitem() | |||
|
78 | ||||
|
79 | __setitem__ = call_save(SessionObject.__setitem__) | |||
|
80 | __delitem__ = call_save(SessionObject.__delitem__) | |||
|
81 | ||||
|
82 | # Flash API methods | |||
|
83 | def flash(self, msg, queue='', allow_duplicate=True): | |||
|
84 | storage = self.setdefault('_f_' + queue, []) | |||
|
85 | if allow_duplicate or (msg not in storage): | |||
|
86 | storage.append(msg) | |||
|
87 | ||||
|
88 | def pop_flash(self, queue=''): | |||
|
89 | storage = self.pop('_f_' + queue, []) | |||
|
90 | return storage | |||
|
91 | ||||
|
92 | def peek_flash(self, queue=''): | |||
|
93 | storage = self.get('_f_' + queue, []) | |||
|
94 | return storage | |||
|
95 | ||||
|
96 | # CSRF API methods | |||
|
97 | def new_csrf_token(self): | |||
|
98 | token = (self._constant_csrf_token | |||
|
99 | or hexlify(os.urandom(20)).decode('ascii')) | |||
|
100 | self['_csrft_'] = token | |||
|
101 | return token | |||
|
102 | ||||
|
103 | def get_csrf_token(self): | |||
|
104 | token = self.get('_csrft_', None) | |||
|
105 | if token is None: | |||
|
106 | token = self.new_csrf_token() | |||
|
107 | return token | |||
|
108 | ||||
|
109 | return implementer(ISession)(PyramidBeakerSessionObject) | |||
|
110 | ||||
|
111 | ||||
|
112 | def call_save(wrapped): | |||
|
113 | """ By default, in non-auto-mode beaker badly wants people to | |||
|
114 | call save even though it should know something has changed when | |||
|
115 | a mutating method is called. This hack should be removed if | |||
|
116 | Beaker ever starts to do this by default. """ | |||
|
117 | def save(session, *arg, **kw): | |||
|
118 | value = wrapped(session, *arg, **kw) | |||
|
119 | session.save() | |||
|
120 | return value | |||
|
121 | save.__doc__ = wrapped.__doc__ | |||
|
122 | return save | |||
|
123 | ||||
|
124 | ||||
|
125 | def session_factory_from_settings(settings): | |||
|
126 | """ Return a Pyramid session factory using Beaker session settings | |||
|
127 | supplied from a Paste configuration file""" | |||
|
128 | prefixes = ('session.', 'beaker.session.') | |||
|
129 | options = {} | |||
|
130 | ||||
|
131 | # Pull out any config args meant for beaker session. if there are any | |||
|
132 | for k, v in settings.items(): | |||
|
133 | for prefix in prefixes: | |||
|
134 | if k.startswith(prefix): | |||
|
135 | option_name = k[len(prefix):] | |||
|
136 | if option_name == 'cookie_on_exception': | |||
|
137 | v = asbool(v) | |||
|
138 | options[option_name] = v | |||
|
139 | ||||
|
140 | options = coerce_session_params(options) | |||
|
141 | return BeakerSessionFactoryConfig(**options) | |||
|
142 | ||||
|
143 | ||||
|
144 | def set_cache_regions_from_settings(settings): | |||
|
145 | """ Add cache support to the Pylons application. | |||
|
146 | ||||
|
147 | The ``settings`` passed to the configurator are used to setup | |||
|
148 | the cache options. Cache options in the settings should start | |||
|
149 | with either 'beaker.cache.' or 'cache.'. | |||
|
150 | ||||
|
151 | """ | |||
|
152 | cache_settings = {'regions': []} | |||
|
153 | for key in settings.keys(): | |||
|
154 | for prefix in ['beaker.cache.', 'cache.']: | |||
|
155 | if key.startswith(prefix): | |||
|
156 | name = key.split(prefix)[1].strip() | |||
|
157 | cache_settings[name] = settings[key].strip() | |||
|
158 | ||||
|
159 | if ('expire' in cache_settings | |||
|
160 | and isinstance(cache_settings['expire'], basestring) | |||
|
161 | and cache_settings['expire'].lower() in ['none', 'no']): | |||
|
162 | cache_settings['expire'] = None | |||
|
163 | ||||
|
164 | coerce_cache_params(cache_settings) | |||
|
165 | ||||
|
166 | if 'enabled' not in cache_settings: | |||
|
167 | cache_settings['enabled'] = True | |||
|
168 | ||||
|
169 | regions = cache_settings['regions'] | |||
|
170 | if regions: | |||
|
171 | for region in regions: | |||
|
172 | if not region: | |||
|
173 | continue | |||
|
174 | ||||
|
175 | region_settings = { | |||
|
176 | 'data_dir': cache_settings.get('data_dir'), | |||
|
177 | 'lock_dir': cache_settings.get('lock_dir'), | |||
|
178 | 'expire': cache_settings.get('expire', 60), | |||
|
179 | 'enabled': cache_settings['enabled'], | |||
|
180 | 'key_length': cache_settings.get('key_length', 250), | |||
|
181 | 'type': cache_settings.get('type'), | |||
|
182 | 'url': cache_settings.get('url'), | |||
|
183 | } | |||
|
184 | region_prefix = '%s.' % region | |||
|
185 | region_len = len(region_prefix) | |||
|
186 | for key in list(cache_settings.keys()): | |||
|
187 | if key.startswith(region_prefix): | |||
|
188 | region_settings[key[region_len:]] = cache_settings.pop(key) | |||
|
189 | ||||
|
190 | if (isinstance(region_settings['expire'], basestring) | |||
|
191 | and region_settings['expire'].lower() in ['none', 'no']): | |||
|
192 | region_settings['expire'] = None | |||
|
193 | coerce_cache_params(region_settings) | |||
|
194 | cache.cache_regions[region] = region_settings | |||
|
195 | ||||
|
196 | ||||
|
197 | def includeme(config): | |||
|
198 | session_factory = session_factory_from_settings(config.registry.settings) | |||
|
199 | config.set_session_factory(session_factory) | |||
|
200 | set_cache_regions_from_settings(config.registry.settings) |
@@ -1395,21 +1395,6 b' self: super: {' | |||||
1395 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1395 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
1396 | }; |
|
1396 | }; | |
1397 | }; |
|
1397 | }; | |
1398 | "pyramid-beaker" = super.buildPythonPackage { |
|
|||
1399 | name = "pyramid-beaker-0.8"; |
|
|||
1400 | doCheck = false; |
|
|||
1401 | propagatedBuildInputs = [ |
|
|||
1402 | self."pyramid" |
|
|||
1403 | self."beaker" |
|
|||
1404 | ]; |
|
|||
1405 | src = fetchurl { |
|
|||
1406 | url = "https://files.pythonhosted.org/packages/d9/6e/b85426e00fd3d57f4545f74e1c3828552d8700f13ededeef9233f7bca8be/pyramid_beaker-0.8.tar.gz"; |
|
|||
1407 | sha256 = "0hflx3qkcdml1mwpq53sz46s7jickpfn0zy0ns2c7j445j66bp3p"; |
|
|||
1408 | }; |
|
|||
1409 | meta = { |
|
|||
1410 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
|||
1411 | }; |
|
|||
1412 | }; |
|
|||
1413 | "pyramid-debugtoolbar" = super.buildPythonPackage { |
|
1398 | "pyramid-debugtoolbar" = super.buildPythonPackage { | |
1414 | name = "pyramid-debugtoolbar-4.5"; |
|
1399 | name = "pyramid-debugtoolbar-4.5"; | |
1415 | doCheck = false; |
|
1400 | doCheck = false; | |
@@ -1793,7 +1778,6 b' self: super: {' | |||||
1793 | self."pycrypto" |
|
1778 | self."pycrypto" | |
1794 | self."pygments" |
|
1779 | self."pygments" | |
1795 | self."pyparsing" |
|
1780 | self."pyparsing" | |
1796 | self."pyramid-beaker" |
|
|||
1797 | self."pyramid-debugtoolbar" |
|
1781 | self."pyramid-debugtoolbar" | |
1798 | self."pyramid-mako" |
|
1782 | self."pyramid-mako" | |
1799 | self."pyramid" |
|
1783 | self."pyramid" |
@@ -44,7 +44,6 b' pycurl==7.43.0.2' | |||||
44 | pycrypto==2.6.1 |
|
44 | pycrypto==2.6.1 | |
45 | pygments==2.4.2 |
|
45 | pygments==2.4.2 | |
46 | pyparsing==2.3.0 |
|
46 | pyparsing==2.3.0 | |
47 | pyramid-beaker==0.8 |
|
|||
48 | pyramid-debugtoolbar==4.5.0 |
|
47 | pyramid-debugtoolbar==4.5.0 | |
49 | pyramid-mako==1.0.2 |
|
48 | pyramid-mako==1.0.2 | |
50 | pyramid==1.10.4 |
|
49 | pyramid==1.10.4 |
@@ -250,7 +250,7 b' def includeme(config):' | |||||
250 |
|
250 | |||
251 | # Includes which are required. The application would fail without them. |
|
251 | # Includes which are required. The application would fail without them. | |
252 | config.include('pyramid_mako') |
|
252 | config.include('pyramid_mako') | |
253 |
config.include(' |
|
253 | config.include('rhodecode.lib.rc_beaker') | |
254 | config.include('rhodecode.lib.rc_cache') |
|
254 | config.include('rhodecode.lib.rc_cache') | |
255 |
|
255 | |||
256 | config.include('rhodecode.apps._base.navigation') |
|
256 | config.include('rhodecode.apps._base.navigation') |
@@ -536,7 +536,7 b' def bootstrap_config(request):' | |||||
536 |
|
536 | |||
537 | # allow pyramid lookup in testing |
|
537 | # allow pyramid lookup in testing | |
538 | config.include('pyramid_mako') |
|
538 | config.include('pyramid_mako') | |
539 |
config.include(' |
|
539 | config.include('rhodecode.lib.rc_beaker') | |
540 | config.include('rhodecode.lib.rc_cache') |
|
540 | config.include('rhodecode.lib.rc_cache') | |
541 |
|
541 | |||
542 | add_events_routes(config) |
|
542 | add_events_routes(config) |
General Comments 0
You need to be logged in to leave comments.
Login now