##// END OF EJS Templates
authn: Refactored the auth-plugins-settings base view....
johbo -
r84:6b27093c default
parent child Browse files
Show More
@@ -1,217 +1,199 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
47
48 # TODO: Think about replacing the htmlfill stuff.
48 # TODO: Think about replacing the htmlfill stuff.
49 def _render_and_fill(self, template, template_context, request,
49 def _render_and_fill(self, template, template_context, request,
50 form_defaults, validation_errors):
50 form_defaults, validation_errors):
51 """
51 """
52 Helper to render a template and fill the HTML form fields with
52 Helper to render a template and fill the HTML form fields with
53 defaults. Also displays the form errors.
53 defaults. Also displays the form errors.
54 """
54 """
55 # Render template to string.
55 # Render template to string.
56 html = render(template, template_context, request=request)
56 html = render(template, template_context, request=request)
57
57
58 # Fill the HTML form fields with default values and add error messages.
58 # Fill the HTML form fields with default values and add error messages.
59 html = formencode.htmlfill.render(
59 html = formencode.htmlfill.render(
60 html,
60 html,
61 defaults=form_defaults,
61 defaults=form_defaults,
62 errors=validation_errors,
62 errors=validation_errors,
63 prefix_error=False,
63 prefix_error=False,
64 encoding="UTF-8",
64 encoding="UTF-8",
65 force_defaults=False)
65 force_defaults=False)
66
66
67 return html
67 return html
68
68
69 def settings_get(self):
69 def settings_get(self, errors={}):
70 """
70 """
71 View that displays the plugin settings as a form.
71 View that displays the plugin settings as a form.
72 """
72 """
73 form_defaults = {}
74 validation_errors = None
75 schema = self.plugin.get_settings_schema()
73 schema = self.plugin.get_settings_schema()
76
74
77 # Get default values for the form.
75 # Get default values for the form.
78 for node in schema.children:
76 for node in schema.children:
79 value = self.plugin.get_setting_by_name(node.name) or node.default
77 value = self.plugin.get_setting_by_name(node.name)
80 form_defaults[node.name] = value
78 if value:
79 node.default = value
81
80
82 template_context = {
81 template_context = {
82 'errors': errors,
83 'plugin': self.context.plugin,
83 'resource': self.context,
84 'resource': self.context,
84 'plugin': self.context.plugin
85 }
85 }
86
86
87 return Response(self._render_and_fill(
87 return template_context
88 'rhodecode:templates/admin/auth/plugin_settings.html',
89 template_context,
90 self.request,
91 form_defaults,
92 validation_errors))
93
88
94 def settings_post(self):
89 def settings_post(self):
95 """
90 """
96 View that validates and stores the plugin settings.
91 View that validates and stores the plugin settings.
97 """
92 """
98 schema = self.plugin.get_settings_schema()
93 schema = self.plugin.get_settings_schema()
99 try:
94 try:
100 valid_data = schema.deserialize(self.request.params)
95 valid_data = schema.deserialize(self.request.params)
101 except colander.Invalid, e:
96 except colander.Invalid, e:
102 # Display error message and display form again.
97 # Display error message and display form again.
103 form_defaults = self.request.params
104 validation_errors = e.asdict()
105 self.request.session.flash(
98 self.request.session.flash(
106 _('Errors exist when saving plugin settings. '
99 _('Errors exist when saving plugin settings. '
107 'Please check the form inputs.'),
100 'Please check the form inputs.'),
108 queue='error')
101 queue='error')
109
102 return self.settings_get(errors=e.asdict())
110 template_context = {
111 'resource': self.context,
112 'plugin': self.context.plugin
113 }
114
115 return Response(self._render_and_fill(
116 'rhodecode:templates/admin/auth/plugin_settings.html',
117 template_context,
118 self.request,
119 form_defaults,
120 validation_errors))
121
103
122 # Store validated data.
104 # Store validated data.
123 for name, value in valid_data.items():
105 for name, value in valid_data.items():
124 self.plugin.create_or_update_setting(name, value)
106 self.plugin.create_or_update_setting(name, value)
125 Session.commit()
107 Session.commit()
126
108
127 # Display success message and redirect.
109 # Display success message and redirect.
128 self.request.session.flash(
110 self.request.session.flash(
129 _('Auth settings updated successfully.'),
111 _('Auth settings updated successfully.'),
130 queue='success')
112 queue='success')
131 redirect_to = self.request.resource_path(
113 redirect_to = self.request.resource_path(
132 self.context, route_name='auth_home')
114 self.context, route_name='auth_home')
133 return HTTPFound(redirect_to)
115 return HTTPFound(redirect_to)
134
116
135
117
136 # TODO: Ongoing migration in these views.
118 # TODO: Ongoing migration in these views.
137 # - Maybe we should also use a colander schema for these views.
119 # - Maybe we should also use a colander schema for these views.
138 class AuthSettingsView(object):
120 class AuthSettingsView(object):
139 def __init__(self, context, request):
121 def __init__(self, context, request):
140 self.context = context
122 self.context = context
141 self.request = request
123 self.request = request
142
124
143 # TODO: Move this into a utility function. It is needed in all view
125 # TODO: Move this into a utility function. It is needed in all view
144 # classes during migration. Maybe a mixin?
126 # classes during migration. Maybe a mixin?
145
127
146 # Some of the decorators rely on this attribute to be present on the
128 # Some of the decorators rely on this attribute to be present on the
147 # class of the decorated method.
129 # class of the decorated method.
148 self._rhodecode_user = request.user
130 self._rhodecode_user = request.user
149
131
150 @LoginRequired()
132 @LoginRequired()
151 @HasPermissionAllDecorator('hg.admin')
133 @HasPermissionAllDecorator('hg.admin')
152 def index(self, defaults={}, errors=None, prefix_error=False):
134 def index(self, defaults={}, errors=None, prefix_error=False):
153 authn_registry = self.request.registry.getUtility(IAuthnPluginRegistry)
135 authn_registry = self.request.registry.getUtility(IAuthnPluginRegistry)
154 enabled_plugins = SettingsModel().get_auth_plugins()
136 enabled_plugins = SettingsModel().get_auth_plugins()
155
137
156 # Create template context and render it.
138 # Create template context and render it.
157 template_context = {
139 template_context = {
158 'resource': self.context,
140 'resource': self.context,
159 'available_plugins': authn_registry.get_plugins(),
141 'available_plugins': authn_registry.get_plugins(),
160 'enabled_plugins': enabled_plugins,
142 'enabled_plugins': enabled_plugins,
161 }
143 }
162 html = render('rhodecode:templates/admin/auth/auth_settings.html',
144 html = render('rhodecode:templates/admin/auth/auth_settings.html',
163 template_context,
145 template_context,
164 request=self.request)
146 request=self.request)
165
147
166 # Create form default values and fill the form.
148 # Create form default values and fill the form.
167 form_defaults = {
149 form_defaults = {
168 'auth_plugins': ','.join(enabled_plugins)
150 'auth_plugins': ','.join(enabled_plugins)
169 }
151 }
170 form_defaults.update(defaults)
152 form_defaults.update(defaults)
171 html = formencode.htmlfill.render(
153 html = formencode.htmlfill.render(
172 html,
154 html,
173 defaults=form_defaults,
155 defaults=form_defaults,
174 errors=errors,
156 errors=errors,
175 prefix_error=prefix_error,
157 prefix_error=prefix_error,
176 encoding="UTF-8",
158 encoding="UTF-8",
177 force_defaults=False)
159 force_defaults=False)
178
160
179 return Response(html)
161 return Response(html)
180
162
181 @LoginRequired()
163 @LoginRequired()
182 @HasPermissionAllDecorator('hg.admin')
164 @HasPermissionAllDecorator('hg.admin')
183 @auth.CSRFRequired()
165 @auth.CSRFRequired()
184 def auth_settings(self):
166 def auth_settings(self):
185 try:
167 try:
186 form = AuthSettingsForm()()
168 form = AuthSettingsForm()()
187 form_result = form.to_python(self.request.params)
169 form_result = form.to_python(self.request.params)
188 plugins = ','.join(form_result['auth_plugins'])
170 plugins = ','.join(form_result['auth_plugins'])
189 setting = SettingsModel().create_or_update_setting(
171 setting = SettingsModel().create_or_update_setting(
190 'auth_plugins', plugins)
172 'auth_plugins', plugins)
191 Session().add(setting)
173 Session().add(setting)
192 Session().commit()
174 Session().commit()
193
175
194 cache_manager = get_auth_cache_manager()
176 cache_manager = get_auth_cache_manager()
195 cache_manager.clear()
177 cache_manager.clear()
196 self.request.session.flash(
178 self.request.session.flash(
197 _('Auth settings updated successfully.'),
179 _('Auth settings updated successfully.'),
198 queue='success')
180 queue='success')
199 except formencode.Invalid as errors:
181 except formencode.Invalid as errors:
200 e = errors.error_dict or {}
182 e = errors.error_dict or {}
201 self.request.session.flash(
183 self.request.session.flash(
202 _('Errors exist when saving plugin setting. '
184 _('Errors exist when saving plugin setting. '
203 'Please check the form inputs.'),
185 'Please check the form inputs.'),
204 queue='error')
186 queue='error')
205 return self.index(
187 return self.index(
206 defaults=errors.value,
188 defaults=errors.value,
207 errors=e,
189 errors=e,
208 prefix_error=False)
190 prefix_error=False)
209 except Exception:
191 except Exception:
210 log.exception('Exception in auth_settings')
192 log.exception('Exception in auth_settings')
211 self.request.session.flash(
193 self.request.session.flash(
212 _('Error occurred during update of auth settings.'),
194 _('Error occurred during update of auth settings.'),
213 queue='error')
195 queue='error')
214
196
215 redirect_to = self.request.resource_path(
197 redirect_to = self.request.resource_path(
216 self.context, route_name='auth_home')
198 self.context, route_name='auth_home')
217 return HTTPFound(redirect_to)
199 return HTTPFound(redirect_to)
General Comments 0
You need to be logged in to leave comments. Login now