##// END OF EJS Templates
authn: Make the legacy plugin import more robust if something fails during import.
johbo -
r134:5edcb8e3 default
parent child Browse files
Show More
@@ -1,118 +1,121 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import importlib
22 import importlib
23
23
24 from pkg_resources import iter_entry_points
24 from pkg_resources import iter_entry_points
25 from pyramid.authentication import SessionAuthenticationPolicy
25 from pyramid.authentication import SessionAuthenticationPolicy
26
26
27 from rhodecode.authentication.registry import AuthenticationPluginRegistry
27 from rhodecode.authentication.registry import AuthenticationPluginRegistry
28 from rhodecode.authentication.routes import root_factory
28 from rhodecode.authentication.routes import root_factory
29 from rhodecode.authentication.routes import AuthnRootResource
29 from rhodecode.authentication.routes import AuthnRootResource
30 from rhodecode.config.routing import ADMIN_PREFIX
30 from rhodecode.config.routing import ADMIN_PREFIX
31 from rhodecode.model.settings import SettingsModel
31 from rhodecode.model.settings import SettingsModel
32
32
33
33
34 log = logging.getLogger(__name__)
34 log = logging.getLogger(__name__)
35
35
36 # Legacy plugins are stored with this prefix in 'auth_plugins'.
36 # Legacy plugins are stored with this prefix in 'auth_plugins'.
37 legacy_plugin_prefix = 'py:'
37 legacy_plugin_prefix = 'py:'
38
38
39
39
40 # TODO: Currently this is only used to discover the authentication plugins.
40 # TODO: Currently this is only used to discover the authentication plugins.
41 # Later on this may be used in a generic way to look up and include all kinds
41 # Later on this may be used in a generic way to look up and include all kinds
42 # of supported enterprise plugins. Therefore this has to be moved and
42 # of supported enterprise plugins. Therefore this has to be moved and
43 # refactored to a real 'plugin look up' machinery.
43 # refactored to a real 'plugin look up' machinery.
44 # TODO: When refactoring this think about splitting it up into distinct
44 # TODO: When refactoring this think about splitting it up into distinct
45 # discover, load and include phases.
45 # discover, load and include phases.
46 def _discover_plugins(config, entry_point='enterprise.plugins1'):
46 def _discover_plugins(config, entry_point='enterprise.plugins1'):
47 _discovered_plugins = {}
47 _discovered_plugins = {}
48
48
49 for ep in iter_entry_points(entry_point):
49 for ep in iter_entry_points(entry_point):
50 plugin_id = 'egg:{}#{}'.format(ep.dist.project_name, ep.name)
50 plugin_id = 'egg:{}#{}'.format(ep.dist.project_name, ep.name)
51 log.debug('Plugin discovered: "%s"', plugin_id)
51 log.debug('Plugin discovered: "%s"', plugin_id)
52 module = ep.load()
52 module = ep.load()
53 plugin = module(plugin_id=plugin_id)
53 plugin = module(plugin_id=plugin_id)
54 config.include(plugin.includeme)
54 config.include(plugin.includeme)
55
55
56 return _discovered_plugins
56 return _discovered_plugins
57
57
58
58
59 def _discover_legacy_plugins(config, prefix=legacy_plugin_prefix):
59 def _discover_legacy_plugins(config, prefix=legacy_plugin_prefix):
60 """
60 """
61 Function that imports the legacy plugins stored in the 'auth_plugins'
61 Function that imports the legacy plugins stored in the 'auth_plugins'
62 setting in database which are using the specified prefix. Normally 'py:' is
62 setting in database which are using the specified prefix. Normally 'py:' is
63 used for the legacy plugins.
63 used for the legacy plugins.
64 """
64 """
65 auth_plugins = SettingsModel().get_setting_by_name('auth_plugins')
65 auth_plugins = SettingsModel().get_setting_by_name('auth_plugins')
66 enabled_plugins = auth_plugins.app_settings_value
66 enabled_plugins = auth_plugins.app_settings_value
67 legacy_plugins = [id_ for id_ in enabled_plugins if id_.startswith(prefix)]
67 legacy_plugins = [id_ for id_ in enabled_plugins if id_.startswith(prefix)]
68
68
69 log.debug('Importing these legacy authentication plugins {}'.format(
69 log.debug('Importing these legacy authentication plugins {}'.format(
70 legacy_plugins))
70 legacy_plugins))
71
71
72 for plugin_id in legacy_plugins:
72 for plugin_id in legacy_plugins:
73 module_name = plugin_id.split(prefix, 1)[-1]
73 module_name = plugin_id.split(prefix, 1)[-1]
74 try:
74 try:
75 log.debug('Import %s', module_name)
76 module = importlib.import_module(module_name)
75 module = importlib.import_module(module_name)
77 plugin = module.plugin_factory(plugin_id=plugin_id)
76 plugin = module.plugin_factory(plugin_id=plugin_id)
78 config.include(plugin.includeme)
77 config.include(plugin.includeme)
79 except ImportError as e:
78 except ImportError as e:
80 log.error(
79 log.error(
81 'Error while importing legacy authentication plugin '
80 'ImportError while importing legacy authentication plugin '
81 '"{}": {}'.format(plugin_id, e.message))
82 except Exception as e:
83 log.error(
84 'Exception while importing legacy authentication plugin '
82 '"{}": {}'.format(plugin_id, e.message))
85 '"{}": {}'.format(plugin_id, e.message))
83
86
84
87
85 def includeme(config):
88 def includeme(config):
86 # Set authentication policy.
89 # Set authentication policy.
87 authn_policy = SessionAuthenticationPolicy()
90 authn_policy = SessionAuthenticationPolicy()
88 config.set_authentication_policy(authn_policy)
91 config.set_authentication_policy(authn_policy)
89
92
90 # Create authentication plugin registry and add it to the pyramid registry.
93 # Create authentication plugin registry and add it to the pyramid registry.
91 authn_registry = AuthenticationPluginRegistry(config.get_settings())
94 authn_registry = AuthenticationPluginRegistry(config.get_settings())
92 config.add_directive('add_authn_plugin', authn_registry.add_authn_plugin)
95 config.add_directive('add_authn_plugin', authn_registry.add_authn_plugin)
93 config.registry.registerUtility(authn_registry)
96 config.registry.registerUtility(authn_registry)
94
97
95 # Create authentication traversal root resource.
98 # Create authentication traversal root resource.
96 authn_root_resource = root_factory()
99 authn_root_resource = root_factory()
97 config.add_directive('add_authn_resource',
100 config.add_directive('add_authn_resource',
98 authn_root_resource.add_authn_resource)
101 authn_root_resource.add_authn_resource)
99
102
100 # Add the authentication traversal route.
103 # Add the authentication traversal route.
101 config.add_route('auth_home',
104 config.add_route('auth_home',
102 ADMIN_PREFIX + '/auth*traverse',
105 ADMIN_PREFIX + '/auth*traverse',
103 factory=root_factory)
106 factory=root_factory)
104 # Add the authentication settings root views.
107 # Add the authentication settings root views.
105 config.add_view('rhodecode.authentication.views.AuthSettingsView',
108 config.add_view('rhodecode.authentication.views.AuthSettingsView',
106 attr='index',
109 attr='index',
107 request_method='GET',
110 request_method='GET',
108 route_name='auth_home',
111 route_name='auth_home',
109 context=AuthnRootResource)
112 context=AuthnRootResource)
110 config.add_view('rhodecode.authentication.views.AuthSettingsView',
113 config.add_view('rhodecode.authentication.views.AuthSettingsView',
111 attr='auth_settings',
114 attr='auth_settings',
112 request_method='POST',
115 request_method='POST',
113 route_name='auth_home',
116 route_name='auth_home',
114 context=AuthnRootResource)
117 context=AuthnRootResource)
115
118
116 # Auto discover authentication plugins and include their configuration.
119 # Auto discover authentication plugins and include their configuration.
117 _discover_plugins(config)
120 _discover_plugins(config)
118 _discover_legacy_plugins(config)
121 _discover_legacy_plugins(config)
General Comments 0
You need to be logged in to leave comments. Login now