##// END OF EJS Templates
authn: Only lookup settings from DB if they are really used....
Martin Bornhold -
r285:f9e2ba9b default
parent child Browse files
Show More
@@ -1,190 +1,190 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 colander
21 import colander
22 import formencode.htmlfill
22 import formencode.htmlfill
23 import logging
23 import logging
24
24
25 from pyramid.httpexceptions import HTTPFound
25 from pyramid.httpexceptions import HTTPFound
26 from pyramid.renderers import render
26 from pyramid.renderers import render
27 from pyramid.response import Response
27 from pyramid.response import Response
28
28
29 from rhodecode.authentication.base import get_auth_cache_manager
29 from rhodecode.authentication.base import get_auth_cache_manager
30 from rhodecode.authentication.interface import IAuthnPluginRegistry
30 from rhodecode.authentication.interface import IAuthnPluginRegistry
31 from rhodecode.lib import auth
31 from rhodecode.lib import auth
32 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
32 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
33 from rhodecode.model.forms import AuthSettingsForm
33 from rhodecode.model.forms import AuthSettingsForm
34 from rhodecode.model.meta import Session
34 from rhodecode.model.meta import Session
35 from rhodecode.model.settings import SettingsModel
35 from rhodecode.model.settings import SettingsModel
36 from rhodecode.translation import _
36 from rhodecode.translation import _
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40
40
41 class AuthnPluginViewBase(object):
41 class AuthnPluginViewBase(object):
42
42
43 def __init__(self, context, request):
43 def __init__(self, context, request):
44 self.request = request
44 self.request = request
45 self.context = context
45 self.context = context
46 self.plugin = context.plugin
46 self.plugin = context.plugin
47 self._rhodecode_user = request.user
47 self._rhodecode_user = request.user
48
48
49 @LoginRequired()
49 @LoginRequired()
50 @HasPermissionAllDecorator('hg.admin')
50 @HasPermissionAllDecorator('hg.admin')
51 def settings_get(self, defaults=None, errors=None):
51 def settings_get(self, defaults=None, errors=None):
52 """
52 """
53 View that displays the plugin settings as a form.
53 View that displays the plugin settings as a form.
54 """
54 """
55 defaults = defaults or {}
55 defaults = defaults or {}
56 errors = errors or {}
56 errors = errors or {}
57 schema = self.plugin.get_settings_schema()
57 schema = self.plugin.get_settings_schema()
58
58
59 # Compute default values for the form. Priority is:
59 # Compute default values for the form. Priority is:
60 # 1. Passed to this method 2. DB value 3. Schema default
60 # 1. Passed to this method 2. DB value 3. Schema default
61 for node in schema:
61 for node in schema:
62 value = self.plugin.get_setting_by_name(
62 if node.name not in defaults:
63 defaults[node.name] = self.plugin.get_setting_by_name(
63 node.name, node.default)
64 node.name, node.default)
64 defaults.setdefault(node.name, value)
65
65
66 template_context = {
66 template_context = {
67 'defaults': defaults,
67 'defaults': defaults,
68 'errors': errors,
68 'errors': errors,
69 'plugin': self.context.plugin,
69 'plugin': self.context.plugin,
70 'resource': self.context,
70 'resource': self.context,
71 }
71 }
72
72
73 return template_context
73 return template_context
74
74
75 @LoginRequired()
75 @LoginRequired()
76 @HasPermissionAllDecorator('hg.admin')
76 @HasPermissionAllDecorator('hg.admin')
77 @auth.CSRFRequired()
77 @auth.CSRFRequired()
78 def settings_post(self):
78 def settings_post(self):
79 """
79 """
80 View that validates and stores the plugin settings.
80 View that validates and stores the plugin settings.
81 """
81 """
82 schema = self.plugin.get_settings_schema()
82 schema = self.plugin.get_settings_schema()
83 try:
83 try:
84 valid_data = schema.deserialize(self.request.params)
84 valid_data = schema.deserialize(self.request.params)
85 except colander.Invalid, e:
85 except colander.Invalid, e:
86 # Display error message and display form again.
86 # Display error message and display form again.
87 self.request.session.flash(
87 self.request.session.flash(
88 _('Errors exist when saving plugin settings. '
88 _('Errors exist when saving plugin settings. '
89 'Please check the form inputs.'),
89 'Please check the form inputs.'),
90 queue='error')
90 queue='error')
91 defaults = schema.flatten(self.request.params)
91 defaults = schema.flatten(self.request.params)
92 return self.settings_get(errors=e.asdict(), defaults=defaults)
92 return self.settings_get(errors=e.asdict(), defaults=defaults)
93
93
94 # Store validated data.
94 # Store validated data.
95 for name, value in valid_data.items():
95 for name, value in valid_data.items():
96 self.plugin.create_or_update_setting(name, value)
96 self.plugin.create_or_update_setting(name, value)
97 Session.commit()
97 Session.commit()
98
98
99 # Display success message and redirect.
99 # Display success message and redirect.
100 self.request.session.flash(
100 self.request.session.flash(
101 _('Auth settings updated successfully.'),
101 _('Auth settings updated successfully.'),
102 queue='success')
102 queue='success')
103 redirect_to = self.request.resource_path(
103 redirect_to = self.request.resource_path(
104 self.context, route_name='auth_home')
104 self.context, route_name='auth_home')
105 return HTTPFound(redirect_to)
105 return HTTPFound(redirect_to)
106
106
107
107
108 # TODO: Ongoing migration in these views.
108 # TODO: Ongoing migration in these views.
109 # - Maybe we should also use a colander schema for these views.
109 # - Maybe we should also use a colander schema for these views.
110 class AuthSettingsView(object):
110 class AuthSettingsView(object):
111 def __init__(self, context, request):
111 def __init__(self, context, request):
112 self.context = context
112 self.context = context
113 self.request = request
113 self.request = request
114
114
115 # TODO: Move this into a utility function. It is needed in all view
115 # TODO: Move this into a utility function. It is needed in all view
116 # classes during migration. Maybe a mixin?
116 # classes during migration. Maybe a mixin?
117
117
118 # Some of the decorators rely on this attribute to be present on the
118 # Some of the decorators rely on this attribute to be present on the
119 # class of the decorated method.
119 # class of the decorated method.
120 self._rhodecode_user = request.user
120 self._rhodecode_user = request.user
121
121
122 @LoginRequired()
122 @LoginRequired()
123 @HasPermissionAllDecorator('hg.admin')
123 @HasPermissionAllDecorator('hg.admin')
124 def index(self, defaults=None, errors=None, prefix_error=False):
124 def index(self, defaults=None, errors=None, prefix_error=False):
125 defaults = defaults or {}
125 defaults = defaults or {}
126 authn_registry = self.request.registry.getUtility(IAuthnPluginRegistry)
126 authn_registry = self.request.registry.getUtility(IAuthnPluginRegistry)
127 enabled_plugins = SettingsModel().get_auth_plugins()
127 enabled_plugins = SettingsModel().get_auth_plugins()
128
128
129 # Create template context and render it.
129 # Create template context and render it.
130 template_context = {
130 template_context = {
131 'resource': self.context,
131 'resource': self.context,
132 'available_plugins': authn_registry.get_plugins(),
132 'available_plugins': authn_registry.get_plugins(),
133 'enabled_plugins': enabled_plugins,
133 'enabled_plugins': enabled_plugins,
134 }
134 }
135 html = render('rhodecode:templates/admin/auth/auth_settings.html',
135 html = render('rhodecode:templates/admin/auth/auth_settings.html',
136 template_context,
136 template_context,
137 request=self.request)
137 request=self.request)
138
138
139 # Create form default values and fill the form.
139 # Create form default values and fill the form.
140 form_defaults = {
140 form_defaults = {
141 'auth_plugins': ','.join(enabled_plugins)
141 'auth_plugins': ','.join(enabled_plugins)
142 }
142 }
143 form_defaults.update(defaults)
143 form_defaults.update(defaults)
144 html = formencode.htmlfill.render(
144 html = formencode.htmlfill.render(
145 html,
145 html,
146 defaults=form_defaults,
146 defaults=form_defaults,
147 errors=errors,
147 errors=errors,
148 prefix_error=prefix_error,
148 prefix_error=prefix_error,
149 encoding="UTF-8",
149 encoding="UTF-8",
150 force_defaults=False)
150 force_defaults=False)
151
151
152 return Response(html)
152 return Response(html)
153
153
154 @LoginRequired()
154 @LoginRequired()
155 @HasPermissionAllDecorator('hg.admin')
155 @HasPermissionAllDecorator('hg.admin')
156 @auth.CSRFRequired()
156 @auth.CSRFRequired()
157 def auth_settings(self):
157 def auth_settings(self):
158 try:
158 try:
159 form = AuthSettingsForm()()
159 form = AuthSettingsForm()()
160 form_result = form.to_python(self.request.params)
160 form_result = form.to_python(self.request.params)
161 plugins = ','.join(form_result['auth_plugins'])
161 plugins = ','.join(form_result['auth_plugins'])
162 setting = SettingsModel().create_or_update_setting(
162 setting = SettingsModel().create_or_update_setting(
163 'auth_plugins', plugins)
163 'auth_plugins', plugins)
164 Session().add(setting)
164 Session().add(setting)
165 Session().commit()
165 Session().commit()
166
166
167 cache_manager = get_auth_cache_manager()
167 cache_manager = get_auth_cache_manager()
168 cache_manager.clear()
168 cache_manager.clear()
169 self.request.session.flash(
169 self.request.session.flash(
170 _('Auth settings updated successfully.'),
170 _('Auth settings updated successfully.'),
171 queue='success')
171 queue='success')
172 except formencode.Invalid as errors:
172 except formencode.Invalid as errors:
173 e = errors.error_dict or {}
173 e = errors.error_dict or {}
174 self.request.session.flash(
174 self.request.session.flash(
175 _('Errors exist when saving plugin setting. '
175 _('Errors exist when saving plugin setting. '
176 'Please check the form inputs.'),
176 'Please check the form inputs.'),
177 queue='error')
177 queue='error')
178 return self.index(
178 return self.index(
179 defaults=errors.value,
179 defaults=errors.value,
180 errors=e,
180 errors=e,
181 prefix_error=False)
181 prefix_error=False)
182 except Exception:
182 except Exception:
183 log.exception('Exception in auth_settings')
183 log.exception('Exception in auth_settings')
184 self.request.session.flash(
184 self.request.session.flash(
185 _('Error occurred during update of auth settings.'),
185 _('Error occurred during update of auth settings.'),
186 queue='error')
186 queue='error')
187
187
188 redirect_to = self.request.resource_path(
188 redirect_to = self.request.resource_path(
189 self.context, route_name='auth_home')
189 self.context, route_name='auth_home')
190 return HTTPFound(redirect_to)
190 return HTTPFound(redirect_to)
General Comments 0
You need to be logged in to leave comments. Login now