##// END OF EJS Templates
authn: Remove usage of colander.serialize to generate form defaults.
Martin Bornhold -
r284:f65fe1f1 default
parent child Browse files
Show More
@@ -1,191 +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 db_value = self.plugin.get_setting_by_name(
62 value = self.plugin.get_setting_by_name(
63 node.name, colander.null)
63 node.name, node.default)
64 defaults.setdefault(node.name, db_value)
64 defaults.setdefault(node.name, value)
65 defaults = schema.serialize(defaults)
66
65
67 template_context = {
66 template_context = {
68 'defaults': defaults,
67 'defaults': defaults,
69 'errors': errors,
68 'errors': errors,
70 'plugin': self.context.plugin,
69 'plugin': self.context.plugin,
71 'resource': self.context,
70 'resource': self.context,
72 }
71 }
73
72
74 return template_context
73 return template_context
75
74
76 @LoginRequired()
75 @LoginRequired()
77 @HasPermissionAllDecorator('hg.admin')
76 @HasPermissionAllDecorator('hg.admin')
78 @auth.CSRFRequired()
77 @auth.CSRFRequired()
79 def settings_post(self):
78 def settings_post(self):
80 """
79 """
81 View that validates and stores the plugin settings.
80 View that validates and stores the plugin settings.
82 """
81 """
83 schema = self.plugin.get_settings_schema()
82 schema = self.plugin.get_settings_schema()
84 try:
83 try:
85 valid_data = schema.deserialize(self.request.params)
84 valid_data = schema.deserialize(self.request.params)
86 except colander.Invalid, e:
85 except colander.Invalid, e:
87 # Display error message and display form again.
86 # Display error message and display form again.
88 self.request.session.flash(
87 self.request.session.flash(
89 _('Errors exist when saving plugin settings. '
88 _('Errors exist when saving plugin settings. '
90 'Please check the form inputs.'),
89 'Please check the form inputs.'),
91 queue='error')
90 queue='error')
92 defaults = schema.flatten(self.request.params)
91 defaults = schema.flatten(self.request.params)
93 return self.settings_get(errors=e.asdict(), defaults=defaults)
92 return self.settings_get(errors=e.asdict(), defaults=defaults)
94
93
95 # Store validated data.
94 # Store validated data.
96 for name, value in valid_data.items():
95 for name, value in valid_data.items():
97 self.plugin.create_or_update_setting(name, value)
96 self.plugin.create_or_update_setting(name, value)
98 Session.commit()
97 Session.commit()
99
98
100 # Display success message and redirect.
99 # Display success message and redirect.
101 self.request.session.flash(
100 self.request.session.flash(
102 _('Auth settings updated successfully.'),
101 _('Auth settings updated successfully.'),
103 queue='success')
102 queue='success')
104 redirect_to = self.request.resource_path(
103 redirect_to = self.request.resource_path(
105 self.context, route_name='auth_home')
104 self.context, route_name='auth_home')
106 return HTTPFound(redirect_to)
105 return HTTPFound(redirect_to)
107
106
108
107
109 # TODO: Ongoing migration in these views.
108 # TODO: Ongoing migration in these views.
110 # - Maybe we should also use a colander schema for these views.
109 # - Maybe we should also use a colander schema for these views.
111 class AuthSettingsView(object):
110 class AuthSettingsView(object):
112 def __init__(self, context, request):
111 def __init__(self, context, request):
113 self.context = context
112 self.context = context
114 self.request = request
113 self.request = request
115
114
116 # 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
117 # classes during migration. Maybe a mixin?
116 # classes during migration. Maybe a mixin?
118
117
119 # 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
120 # class of the decorated method.
119 # class of the decorated method.
121 self._rhodecode_user = request.user
120 self._rhodecode_user = request.user
122
121
123 @LoginRequired()
122 @LoginRequired()
124 @HasPermissionAllDecorator('hg.admin')
123 @HasPermissionAllDecorator('hg.admin')
125 def index(self, defaults=None, errors=None, prefix_error=False):
124 def index(self, defaults=None, errors=None, prefix_error=False):
126 defaults = defaults or {}
125 defaults = defaults or {}
127 authn_registry = self.request.registry.getUtility(IAuthnPluginRegistry)
126 authn_registry = self.request.registry.getUtility(IAuthnPluginRegistry)
128 enabled_plugins = SettingsModel().get_auth_plugins()
127 enabled_plugins = SettingsModel().get_auth_plugins()
129
128
130 # Create template context and render it.
129 # Create template context and render it.
131 template_context = {
130 template_context = {
132 'resource': self.context,
131 'resource': self.context,
133 'available_plugins': authn_registry.get_plugins(),
132 'available_plugins': authn_registry.get_plugins(),
134 'enabled_plugins': enabled_plugins,
133 'enabled_plugins': enabled_plugins,
135 }
134 }
136 html = render('rhodecode:templates/admin/auth/auth_settings.html',
135 html = render('rhodecode:templates/admin/auth/auth_settings.html',
137 template_context,
136 template_context,
138 request=self.request)
137 request=self.request)
139
138
140 # Create form default values and fill the form.
139 # Create form default values and fill the form.
141 form_defaults = {
140 form_defaults = {
142 'auth_plugins': ','.join(enabled_plugins)
141 'auth_plugins': ','.join(enabled_plugins)
143 }
142 }
144 form_defaults.update(defaults)
143 form_defaults.update(defaults)
145 html = formencode.htmlfill.render(
144 html = formencode.htmlfill.render(
146 html,
145 html,
147 defaults=form_defaults,
146 defaults=form_defaults,
148 errors=errors,
147 errors=errors,
149 prefix_error=prefix_error,
148 prefix_error=prefix_error,
150 encoding="UTF-8",
149 encoding="UTF-8",
151 force_defaults=False)
150 force_defaults=False)
152
151
153 return Response(html)
152 return Response(html)
154
153
155 @LoginRequired()
154 @LoginRequired()
156 @HasPermissionAllDecorator('hg.admin')
155 @HasPermissionAllDecorator('hg.admin')
157 @auth.CSRFRequired()
156 @auth.CSRFRequired()
158 def auth_settings(self):
157 def auth_settings(self):
159 try:
158 try:
160 form = AuthSettingsForm()()
159 form = AuthSettingsForm()()
161 form_result = form.to_python(self.request.params)
160 form_result = form.to_python(self.request.params)
162 plugins = ','.join(form_result['auth_plugins'])
161 plugins = ','.join(form_result['auth_plugins'])
163 setting = SettingsModel().create_or_update_setting(
162 setting = SettingsModel().create_or_update_setting(
164 'auth_plugins', plugins)
163 'auth_plugins', plugins)
165 Session().add(setting)
164 Session().add(setting)
166 Session().commit()
165 Session().commit()
167
166
168 cache_manager = get_auth_cache_manager()
167 cache_manager = get_auth_cache_manager()
169 cache_manager.clear()
168 cache_manager.clear()
170 self.request.session.flash(
169 self.request.session.flash(
171 _('Auth settings updated successfully.'),
170 _('Auth settings updated successfully.'),
172 queue='success')
171 queue='success')
173 except formencode.Invalid as errors:
172 except formencode.Invalid as errors:
174 e = errors.error_dict or {}
173 e = errors.error_dict or {}
175 self.request.session.flash(
174 self.request.session.flash(
176 _('Errors exist when saving plugin setting. '
175 _('Errors exist when saving plugin setting. '
177 'Please check the form inputs.'),
176 'Please check the form inputs.'),
178 queue='error')
177 queue='error')
179 return self.index(
178 return self.index(
180 defaults=errors.value,
179 defaults=errors.value,
181 errors=e,
180 errors=e,
182 prefix_error=False)
181 prefix_error=False)
183 except Exception:
182 except Exception:
184 log.exception('Exception in auth_settings')
183 log.exception('Exception in auth_settings')
185 self.request.session.flash(
184 self.request.session.flash(
186 _('Error occurred during update of auth settings.'),
185 _('Error occurred during update of auth settings.'),
187 queue='error')
186 queue='error')
188
187
189 redirect_to = self.request.resource_path(
188 redirect_to = self.request.resource_path(
190 self.context, route_name='auth_home')
189 self.context, route_name='auth_home')
191 return HTTPFound(redirect_to)
190 return HTTPFound(redirect_to)
General Comments 0
You need to be logged in to leave comments. Login now