##// END OF EJS Templates
mailer: change pyramid_mailer initialization
ergo -
Show More
@@ -1,224 +1,225 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
4 4 #
5 5 # Licensed under the Apache License, Version 2.0 (the "License");
6 6 # you may not use this file except in compliance with the License.
7 7 # You may obtain a copy of the License at
8 8 #
9 9 # http://www.apache.org/licenses/LICENSE-2.0
10 10 #
11 11 # Unless required by applicable law or agreed to in writing, software
12 12 # distributed under the License is distributed on an "AS IS" BASIS,
13 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 14 # See the License for the specific language governing permissions and
15 15 # limitations under the License.
16 16
17 17 import datetime
18 18 import logging
19 19 import pyelasticsearch
20 20 import redis
21 21 import os
22 22 import pkg_resources
23 23 from pkg_resources import iter_entry_points
24 24
25 25 import appenlight.lib.jinja2_filters as jinja2_filters
26 26 import appenlight.lib.encryption as encryption
27 27
28 28 from pyramid.config import PHASE3_CONFIG
29 29 from pyramid.authentication import AuthTktAuthenticationPolicy
30 30 from pyramid.authorization import ACLAuthorizationPolicy
31 from pyramid_mailer.mailer import Mailer
31 from pyramid_mailer.interfaces import IMailer
32 32 from pyramid.renderers import JSON
33 33 from pyramid_redis_sessions import session_factory_from_settings
34 34 from pyramid.settings import asbool, aslist
35 35 from pyramid.security import AllPermissionsList
36 36 from pyramid_authstack import AuthenticationStackPolicy
37 37 from redlock import Redlock
38 38 from sqlalchemy import engine_from_config
39 39
40 40 from appenlight.celery import configure_celery
41 41 from appenlight.lib.configurator import (CythonCompatConfigurator,
42 42 register_appenlight_plugin)
43 43 from appenlight.lib import cache_regions
44 44 from appenlight.lib.ext_json import json
45 45 from appenlight.security import groupfinder, AuthTokenAuthenticationPolicy
46 46
47 47 __license__ = 'Apache 2.0'
48 48 __author__ = 'RhodeCode GmbH'
49 49 __url__ = 'http://rhodecode.com'
50 50 __version__ = pkg_resources.get_distribution("appenlight").parsed_version
51 51
52 52 json_renderer = JSON(serializer=json.dumps, indent=4)
53 53
54 54 log = logging.getLogger(__name__)
55 55
56 56
57 57 def datetime_adapter(obj, request):
58 58 return obj.isoformat()
59 59
60 60
61 61 def all_permissions_adapter(obj, request):
62 62 return '__all_permissions__'
63 63
64 64
65 65 json_renderer.add_adapter(datetime.datetime, datetime_adapter)
66 66 json_renderer.add_adapter(AllPermissionsList, all_permissions_adapter)
67 67
68 68
69 69 def main(global_config, **settings):
70 70 """ This function returns a Pyramid WSGI application.
71 71 """
72 72 auth_tkt_policy = AuthTktAuthenticationPolicy(
73 73 settings['authtkt.secret'],
74 74 hashalg='sha512',
75 75 callback=groupfinder,
76 76 max_age=2592000,
77 77 secure=asbool(settings.get('authtkt.secure', 'false')))
78 78 auth_token_policy = AuthTokenAuthenticationPolicy(
79 79 callback=groupfinder
80 80 )
81 81 authorization_policy = ACLAuthorizationPolicy()
82 82 authentication_policy = AuthenticationStackPolicy()
83 83 authentication_policy.add_policy('auth_tkt', auth_tkt_policy)
84 84 authentication_policy.add_policy('auth_token', auth_token_policy)
85 85 # set crypto key
86 86 encryption.ENCRYPTION_SECRET = settings.get('encryption_secret')
87 87 # import this later so encyption key can be monkeypatched
88 88 from appenlight.models import DBSession, register_datastores
89 89
90 90 # registration
91 91 settings['appenlight.disable_registration'] = asbool(
92 92 settings.get('appenlight.disable_registration'))
93 93
94 94 # update config with cometd info
95 95 settings['cometd_servers'] = {'server': settings['cometd.server'],
96 96 'secret': settings['cometd.secret']}
97 97
98 98 # Create the Pyramid Configurator.
99 99 settings['_mail_url'] = settings['mailing.app_url']
100 100 config = CythonCompatConfigurator(
101 101 settings=settings,
102 102 authentication_policy=authentication_policy,
103 103 authorization_policy=authorization_policy,
104 104 root_factory='appenlight.security.RootFactory',
105 105 default_permission='view')
106 106 # custom registry variables
107 107
108 108 # resource type information
109 109 config.registry.resource_types = ['resource', 'application']
110 110 # plugin information
111 111 config.registry.appenlight_plugins = {}
112 112
113 113 config.set_default_csrf_options(require_csrf=True, header='X-XSRF-TOKEN')
114 114 config.add_view_deriver('appenlight.predicates.csrf_view',
115 115 name='csrf_view')
116 116
117 117 # later, when config is available
118 118 dogpile_config = {'url': settings['redis.url'],
119 119 "redis_expiration_time": 86400,
120 120 "redis_distributed_lock": True}
121 121 cache_regions.regions = cache_regions.CacheRegions(dogpile_config)
122 122 config.registry.cache_regions = cache_regions.regions
123 123 engine = engine_from_config(settings, 'sqlalchemy.',
124 124 json_serializer=json.dumps)
125 125 DBSession.configure(bind=engine)
126 126
127 127 # json rederer that serializes datetime
128 128 config.add_renderer('json', json_renderer)
129 129 config.set_request_property('appenlight.lib.request.es_conn', 'es_conn')
130 130 config.set_request_property('appenlight.lib.request.get_user', 'user',
131 131 reify=True)
132 132 config.set_request_property('appenlight.lib.request.get_csrf_token',
133 133 'csrf_token', reify=True)
134 134 config.set_request_property('appenlight.lib.request.safe_json_body',
135 135 'safe_json_body', reify=True)
136 136 config.set_request_property('appenlight.lib.request.unsafe_json_body',
137 137 'unsafe_json_body', reify=True)
138 138 config.add_request_method('appenlight.lib.request.add_flash_to_headers',
139 139 'add_flash_to_headers')
140 140 config.add_request_method('appenlight.lib.request.get_authomatic',
141 141 'authomatic', reify=True)
142 142
143 143 config.include('pyramid_redis_sessions')
144 144 config.include('pyramid_tm')
145 145 config.include('pyramid_jinja2')
146 config.include('pyramid_mailer')
146 147 config.include('appenlight_client.ext.pyramid_tween')
147 148 config.include('ziggurat_foundations.ext.pyramid.sign_in')
148 149 es_server_list = aslist(settings['elasticsearch.nodes'])
149 150 redis_url = settings['redis.url']
150 151 log.warning('Elasticsearch server list: {}'.format(es_server_list))
151 152 log.warning('Redis server: {}'.format(redis_url))
152 153 config.registry.es_conn = pyelasticsearch.ElasticSearch(es_server_list)
153 154 config.registry.redis_conn = redis.StrictRedis.from_url(redis_url)
154 155
155 156 config.registry.redis_lockmgr = Redlock([settings['redis.redlock.url'], ],
156 157 retry_count=0, retry_delay=0)
157 # mailer
158 config.registry.mailer = Mailer.from_settings(settings)
158 # mailer bw compat
159 config.registry.mailer = config.registry.getUtility(IMailer)
159 160
160 161 # Configure sessions
161 162 session_factory = session_factory_from_settings(settings)
162 163 config.set_session_factory(session_factory)
163 164
164 165 # Configure renderers and event subscribers
165 166 config.add_jinja2_extension('jinja2.ext.loopcontrols')
166 167 config.add_jinja2_search_path('appenlight:templates')
167 168 # event subscribers
168 169 config.add_subscriber("appenlight.subscribers.application_created",
169 170 "pyramid.events.ApplicationCreated")
170 171 config.add_subscriber("appenlight.subscribers.add_renderer_globals",
171 172 "pyramid.events.BeforeRender")
172 173 config.add_subscriber('appenlight.subscribers.new_request',
173 174 'pyramid.events.NewRequest')
174 175 config.add_view_predicate('context_type_class',
175 176 'appenlight.predicates.contextTypeClass')
176 177
177 178 register_datastores(es_conn=config.registry.es_conn,
178 179 redis_conn=config.registry.redis_conn,
179 180 redis_lockmgr=config.registry.redis_lockmgr)
180 181
181 182 # base stuff and scan
182 183
183 184 # need to ensure webassets exists otherwise config.override_asset()
184 185 # throws exception
185 186 if not os.path.exists(settings['webassets.dir']):
186 187 os.mkdir(settings['webassets.dir'])
187 188 config.add_static_view(path='appenlight:webassets',
188 189 name='static', cache_max_age=3600)
189 190 config.override_asset(to_override='appenlight:webassets/',
190 191 override_with=settings['webassets.dir'])
191 192
192 193 config.include('appenlight.views')
193 194 config.include('appenlight.views.admin')
194 195 config.scan(ignore=['appenlight.migrations', 'appenlight.scripts',
195 196 'appenlight.tests'])
196 197
197 198 config.add_directive('register_appenlight_plugin',
198 199 register_appenlight_plugin)
199 200
200 201 for entry_point in iter_entry_points(group='appenlight.plugins'):
201 202 plugin = entry_point.load()
202 203 plugin.includeme(config)
203 204
204 205 # include other appenlight plugins explictly if needed
205 206 includes = aslist(settings.get('appenlight.includes', []))
206 207 for inc in includes:
207 208 config.include(inc)
208 209
209 210 # run this after everything registers in configurator
210 211
211 212 def pre_commit():
212 213 jinja_env = config.get_jinja2_environment()
213 214 jinja_env.filters['tojson'] = json.dumps
214 215 jinja_env.filters['toJSONUnsafe'] = jinja2_filters.toJSONUnsafe
215 216
216 217 config.action(None, pre_commit, order=PHASE3_CONFIG + 999)
217 218
218 219 def wrap_config_celery():
219 220 configure_celery(config.registry)
220 221
221 222 config.action(None, wrap_config_celery, order=PHASE3_CONFIG + 999)
222 223
223 224 app = config.make_wsgi_app()
224 225 return app
@@ -1,185 +1,190 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
4 4 #
5 5 # Licensed under the Apache License, Version 2.0 (the "License");
6 6 # you may not use this file except in compliance with the License.
7 7 # You may obtain a copy of the License at
8 8 #
9 9 # http://www.apache.org/licenses/LICENSE-2.0
10 10 #
11 11 # Unless required by applicable law or agreed to in writing, software
12 12 # distributed under the License is distributed on an "AS IS" BASIS,
13 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 14 # See the License for the specific language governing permissions and
15 15 # limitations under the License.
16 16
17 17 import mock
18 18 import os
19 19 import pytest
20 20 import transaction
21 21 from datetime import datetime
22 22
23 23 from alembic.config import Config
24 24 from alembic import command
25 25 from collections import OrderedDict
26 26 from zope.sqlalchemy import mark_changed
27 27 from pyramid.paster import get_appsettings
28 28 from pyramid import testing
29 29
30 from appenlight.models import Base, DBSession
31
32 30
33 31 @pytest.fixture
34 def base_app(request):
32 def base_app(request, mocker):
33 # disable email sending
34 mocker.patch('pyramid_mailer.mailer_factory_from_settings', mocker.Mock())
35
35 36 from appenlight import main
36 37 import transaction
37 38 current_dir = os.path.dirname(os.path.abspath(__file__))
38 39 path = os.path.join(current_dir, '../../../../',
39 40 os.environ.get("APPENLIGHT_INI", 'testing.ini'))
40 41 # appsettings from ini
41 42 app_settings = get_appsettings(path, name="appenlight")
42 43 app = main({}, **app_settings)
43 44 app_request = testing.DummyRequest(base_url='https://appenlight.com')
44 45 app_request.tm = transaction.manager
45 46 app_request.add_flash_to_headers = mock.Mock()
46 47 testing.setUp(registry=app.registry, request=app_request)
47 48
48 49 def teardown():
49 50 testing.tearDown()
50 51
51 52 request.addfinalizer(teardown)
52 53
53 54 return app
54 55
55 56
56 57 @pytest.fixture
57 58 def with_migrations(request, base_app):
58 59 settings = base_app.registry.settings
59 60 alembic_cfg = Config()
60 61 alembic_cfg.set_main_option("script_location",
61 62 "ziggurat_foundations:migrations")
62 63 alembic_cfg.set_main_option("sqlalchemy.url", settings["sqlalchemy.url"])
63 64 command.upgrade(alembic_cfg, "head")
64 65 alembic_cfg = Config()
65 66 alembic_cfg.set_main_option("script_location", "appenlight:migrations")
66 67 alembic_cfg.set_main_option("sqlalchemy.url", settings["sqlalchemy.url"])
67 68 command.upgrade(alembic_cfg, "head")
68 69
69 70 for plugin_name, config in base_app.registry.appenlight_plugins.items():
70 71 if config['sqlalchemy_migrations']:
71 72 alembic_cfg = Config()
72 73 alembic_cfg.set_main_option("script_location",
73 74 config['sqlalchemy_migrations'])
74 75 alembic_cfg.set_main_option(
75 76 "sqlalchemy.url",
76 77 base_app.registry.settings["sqlalchemy.url"])
77 78 command.upgrade(alembic_cfg, "head")
78 79
79 80
80 81 @pytest.fixture
81 82 def default_data(base_app):
82 83 from appenlight.models.services.config import ConfigService
83 84 from appenlight.lib import get_callable
84 85 transaction.begin()
85 86 ConfigService.setup_default_values()
86 87 for plugin_name, config in base_app.registry.appenlight_plugins.items():
87 88 if config['default_values_setter']:
88 89 get_callable(config['default_values_setter'])()
89 90 transaction.commit()
90 91
91 92
92 93 @pytest.fixture
93 94 def clean_tables(request):
95 from appenlight.models import Base, DBSession
96
94 97 def fin():
95 98 tables = Base.metadata.tables.keys()
96 99 transaction.begin()
97 100 for t in tables:
98 101 if not t.startswith('alembic_'):
99 102 DBSession.execute('truncate %s cascade' % t)
100 103 session = DBSession()
101 104 mark_changed(session)
102 105 transaction.commit()
103 106
104 107 request.addfinalizer(fin)
105 108
106 109
107 110 @pytest.fixture
108 111 def default_user():
112 from appenlight.models import DBSession
109 113 from appenlight.models.user import User
110 114 from appenlight.models.auth_token import AuthToken
111 115 transaction.begin()
112 116 session = DBSession()
113 117 user = User(id=1,
114 118 user_name='testuser',
115 119 status=1,
116 120 email='foo@barbaz99.com')
117 121 session.add(user)
118 122 token = AuthToken(token='1234')
119 123 user.auth_tokens.append(token)
120 124 session.execute("SELECT nextval('users_id_seq')")
121 125 transaction.commit()
122 126 return user
123 127
124 128
125 129 @pytest.fixture
126 130 def default_application(default_user):
131 from appenlight.models import DBSession
127 132 from appenlight.models.application import Application
128 133
129 134 transaction.begin()
130 135 session = DBSession()
131 136 application = Application(
132 137 resource_id=1, resource_name='testapp', api_key='xxxx')
133 138 session.add(application)
134 139 default_user.resources.append(application)
135 140 session.execute("SELECT nextval('resources_resource_id_seq')")
136 141 transaction.commit()
137 142 return application
138 143
139 144
140 145 @pytest.fixture
141 146 def report_type_matrix():
142 147 from appenlight.models.report import REPORT_TYPE_MATRIX
143 148 return REPORT_TYPE_MATRIX
144 149
145 150
146 151 @pytest.fixture
147 152 def chart_series():
148 153 series = []
149 154
150 155 for x in range(1, 7):
151 156 tmp_list = [('key', 'X'), ('0_1', x)]
152 157 if x % 2 == 0:
153 158 tmp_list.append(('0_2', x))
154 159 if x % 3 == 0:
155 160 tmp_list.append(('0_3', x))
156 161
157 162 series.append(
158 163 OrderedDict(tmp_list)
159 164 )
160 165 return series
161 166
162 167
163 168 @pytest.fixture
164 169 def log_schema():
165 170 from appenlight.validators import LogListSchema
166 171 schema = LogListSchema().bind(utcnow=datetime.utcnow())
167 172 return schema
168 173
169 174 @pytest.fixture
170 175 def general_metrics_schema():
171 176 from appenlight.validators import GeneralMetricsListSchema
172 177 schema = GeneralMetricsListSchema().bind(utcnow=datetime.utcnow())
173 178 return schema
174 179
175 180 @pytest.fixture
176 181 def request_metrics_schema():
177 182 from appenlight.validators import MetricsListSchema
178 183 schema = MetricsListSchema().bind(utcnow=datetime.utcnow())
179 184 return schema
180 185
181 186 @pytest.fixture
182 187 def report_05_schema():
183 188 from appenlight.validators import ReportListSchema_0_5
184 189 schema = ReportListSchema_0_5().bind(utcnow=datetime.utcnow())
185 190 return schema
General Comments 0
You need to be logged in to leave comments. Login now