1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# Copyright 2012, 2013 Marco Ceppi, Canonical Ltd. This software is
# licensed under the GNU Affero General Public License version 3 (see
# the file LICENSE).
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.config import Configurator
from pyramid.security import Allow
from pyramid.security import Everyone
from pyramid.view import view_config
from pyramid_beaker import session_factory_from_settings
import venusian
from charmworld.forms import setup_custom_deform
from charmworld.lib.auth import RequestWithUserAttribute
from charmworld.models import acquire_session_secret
from charmworld.models import getconnection
from charmworld.models import getdb
from charmworld.models import UserMgr
from charmworld.routes import build_routes
from charmworld.globals import default_globals_factory
from charmworld.utils import (
get_session_url,
record_server_start_time,
)
class cached_view_config(view_config):
""" A replacement for the built in view_config to set HTTP_CACHE
Add a new param
:param http_cache_modifier: a multiple to use against the current cache
value.
Reads the http_cache time from the settings dict and appends that to all
views.
This is a copied view_config from the Pyramid version and updated to
specifically handle the http_cache setting.
"""
venusian = venusian # for testing injection
def __init__(self, **settings):
# Catch and work in the new http_cache_modifier setting.
if 'http_cache_modifier' in settings:
self.http_cache_modifier = settings['http_cache_modifier']
del settings['http_cache_modifier']
super(cached_view_config, self).__init__(**settings)
def __call__(self, wrapped):
settings = self.__dict__.copy()
depth = settings.pop('_depth', 0)
def callback(context, name, ob):
config = context.config.with_package(info.module)
app_settings = context.config.registry.settings
if 'http_cache' not in settings:
http_cache = app_settings.get('http_cache')
if http_cache is not None:
http_cache = int(http_cache)
settings['http_cache'] = http_cache
if 'http_cache_modifier' in settings:
mod = settings['http_cache_modifier']
if settings['http_cache'] is not None:
settings['http_cache'] = int(settings['http_cache'] * mod)
# We can't let the new setting to get add_view or it blows up
# with an unexpected kwarg.
del settings['http_cache_modifier']
config.add_view(view=ob, **settings)
info = self.venusian.attach(wrapped, callback, category='pyramid',
depth=depth + 1)
if info.scope == 'class':
# if the decorator was attached to a method in a class, or
# otherwise executed at class scope, we need to set an
# 'attr' into the settings if one isn't already in there
if settings.get('attr') is None:
settings['attr'] = wrapped.__name__
settings['_info'] = info.codeinfo # fbo "action_method"
return wrapped
class RootFactory(object):
"""This is a simple factory to allow all logged in users all acl access.
We'll not be needing full acl so we just allow everything for now. We'll
manually investigate the request.user as required for actual access.
"""
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, 'group charmers', 'edit'),
(Allow, 'group juju-jitsu', 'edit'),
]
def __init__(self, request):
pass
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
# Setup the data store connections based on the ini settings.
setup_custom_deform()
# Set the mongodb connection into the settings to cache it for the request
# factory to use as request.db.
settings['connection'] = getconnection(settings)
# Load up the beaker sessions into the same mongodb used for the
# application.
settings['session.url'] = get_session_url(settings)
database = getdb(settings['connection'], settings['mongo.database'])
authn_policy = AuthTktAuthenticationPolicy(
acquire_session_secret(database),
callback=UserMgr.auth_principalfinder,
hashalg='sha512',
)
# Turn the string ini config to a list.
openid_teams = settings.get('openid_teams', '')
settings['openid_teams'] = openid_teams.split(',')
authz_policy = ACLAuthorizationPolicy()
session_factory = session_factory_from_settings(settings)
config = Configurator(
authentication_policy=authn_policy,
authorization_policy=authz_policy,
request_factory=RequestWithUserAttribute,
root_factory='charmworld.RootFactory',
session_factory=session_factory,
settings=settings,
)
# Template globals
config.set_renderer_globals_factory(default_globals_factory)
config.add_static_view('static', 'charmworld:static', cache_max_age=3600)
config = build_routes(config)
config.scan("charmworld.views")
record_server_start_time(database)
return config.make_wsgi_app()
|