views.py
183 lines
| 6.6 KiB
| text/x-python
|
PythonLexer
r5608 | # Copyright (C) 2012-2024 RhodeCode GmbH | |||
r1 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
import colander | ||||
import formencode.htmlfill | ||||
import logging | ||||
from pyramid.httpexceptions import HTTPFound | ||||
from pyramid.renderers import render | ||||
from pyramid.response import Response | ||||
r2351 | from rhodecode.apps._base import BaseAppView | |||
r2845 | from rhodecode.authentication.base import get_authn_registry | |||
r2366 | from rhodecode.lib import helpers as h | |||
r2351 | from rhodecode.lib.auth import ( | |||
LoginRequired, HasPermissionAllDecorator, CSRFRequired) | ||||
r1 | from rhodecode.model.forms import AuthSettingsForm | |||
from rhodecode.model.meta import Session | ||||
from rhodecode.model.settings import SettingsModel | ||||
log = logging.getLogger(__name__) | ||||
r2351 | class AuthnPluginViewBase(BaseAppView): | |||
r1 | ||||
r2351 | def load_default_context(self): | |||
c = self._get_local_tmpl_context() | ||||
self.plugin = self.context.plugin | ||||
return c | ||||
r1 | ||||
Martin Bornhold
|
r173 | @LoginRequired() | ||
@HasPermissionAllDecorator('hg.admin') | ||||
r90 | def settings_get(self, defaults=None, errors=None): | |||
r1 | """ | |||
View that displays the plugin settings as a form. | ||||
""" | ||||
r2351 | c = self.load_default_context() | |||
r90 | defaults = defaults or {} | |||
errors = errors or {} | ||||
r1 | schema = self.plugin.get_settings_schema() | |||
r237 | # Compute default values for the form. Priority is: | |||
# 1. Passed to this method 2. DB value 3. Schema default | ||||
r90 | for node in schema: | |||
Martin Bornhold
|
r285 | if node.name not in defaults: | ||
defaults[node.name] = self.plugin.get_setting_by_name( | ||||
r2681 | node.name, node.default) | |||
r1 | ||||
template_context = { | ||||
r90 | 'defaults': defaults, | |||
r84 | 'errors': errors, | |||
'plugin': self.context.plugin, | ||||
r1 | 'resource': self.context, | |||
} | ||||
r2351 | return self._get_template_context(c, **template_context) | |||
r1 | ||||
Martin Bornhold
|
r173 | @LoginRequired() | ||
@HasPermissionAllDecorator('hg.admin') | ||||
r2351 | @CSRFRequired() | |||
r1 | def settings_post(self): | |||
""" | ||||
View that validates and stores the plugin settings. | ||||
""" | ||||
r2351 | _ = self.request.translate | |||
self.load_default_context() | ||||
r1 | schema = self.plugin.get_settings_schema() | |||
Martin Bornhold
|
r291 | data = self.request.params | ||
r1 | try: | |||
Martin Bornhold
|
r291 | valid_data = schema.deserialize(data) | ||
r1092 | except colander.Invalid as e: | |||
r1 | # Display error message and display form again. | |||
r2366 | h.flash( | |||
r1 | _('Errors exist when saving plugin settings. ' | |||
r84 | 'Please check the form inputs.'), | |||
r2366 | category='error') | |||
Martin Bornhold
|
r291 | defaults = {key: data[key] for key in data if key in schema} | ||
r90 | return self.settings_get(errors=e.asdict(), defaults=defaults) | |||
r1 | ||||
# Store validated data. | ||||
for name, value in valid_data.items(): | ||||
self.plugin.create_or_update_setting(name, value) | ||||
r506 | Session().commit() | |||
r4220 | SettingsModel().invalidate_settings_cache() | |||
r1 | ||||
r5140 | authn_registry = get_authn_registry(self.request.registry) | |||
authn_registry.invalidate_auth_plugins_cache() | ||||
r1 | # Display success message and redirect. | |||
r2366 | h.flash(_('Auth settings updated successfully.'), category='success') | |||
r4220 | redirect_to = self.request.resource_path(self.context, route_name='auth_home') | |||
r1 | return HTTPFound(redirect_to) | |||
r2351 | class AuthSettingsView(BaseAppView): | |||
def load_default_context(self): | ||||
c = self._get_local_tmpl_context() | ||||
return c | ||||
r1 | ||||
@LoginRequired() | ||||
@HasPermissionAllDecorator('hg.admin') | ||||
r90 | def index(self, defaults=None, errors=None, prefix_error=False): | |||
r2351 | c = self.load_default_context() | |||
r90 | defaults = defaults or {} | |||
r440 | authn_registry = get_authn_registry(self.request.registry) | |||
r52 | enabled_plugins = SettingsModel().get_auth_plugins() | |||
r1 | ||||
# Create template context and render it. | ||||
template_context = { | ||||
'resource': self.context, | ||||
'available_plugins': authn_registry.get_plugins(), | ||||
'enabled_plugins': enabled_plugins, | ||||
} | ||||
r1282 | html = render('rhodecode:templates/admin/auth/auth_settings.mako', | |||
r2351 | self._get_template_context(c, **template_context), | |||
self.request) | ||||
r1 | ||||
# Create form default values and fill the form. | ||||
form_defaults = { | ||||
r2659 | 'auth_plugins': ',\n'.join(enabled_plugins) | |||
r1 | } | |||
form_defaults.update(defaults) | ||||
html = formencode.htmlfill.render( | ||||
html, | ||||
defaults=form_defaults, | ||||
errors=errors, | ||||
prefix_error=prefix_error, | ||||
encoding="UTF-8", | ||||
force_defaults=False) | ||||
return Response(html) | ||||
@LoginRequired() | ||||
@HasPermissionAllDecorator('hg.admin') | ||||
r2351 | @CSRFRequired() | |||
r1 | def auth_settings(self): | |||
r2351 | _ = self.request.translate | |||
r1 | try: | |||
r2351 | form = AuthSettingsForm(self.request.translate)() | |||
form_result = form.to_python(self.request.POST) | ||||
r1 | plugins = ','.join(form_result['auth_plugins']) | |||
setting = SettingsModel().create_or_update_setting( | ||||
'auth_plugins', plugins) | ||||
Session().add(setting) | ||||
Session().commit() | ||||
r4220 | SettingsModel().invalidate_settings_cache() | |||
r2366 | h.flash(_('Auth settings updated successfully.'), category='success') | |||
r1 | except formencode.Invalid as errors: | |||
e = errors.error_dict or {} | ||||
r2366 | h.flash(_('Errors exist when saving plugin setting. ' | |||
'Please check the form inputs.'), category='error') | ||||
r1 | return self.index( | |||
defaults=errors.value, | ||||
errors=e, | ||||
prefix_error=False) | ||||
except Exception: | ||||
log.exception('Exception in auth_settings') | ||||
r2366 | h.flash(_('Error occurred during update of auth settings.'), | |||
category='error') | ||||
r1 | ||||
r5140 | authn_registry = get_authn_registry(self.request.registry) | |||
authn_registry.invalidate_auth_plugins_cache() | ||||
r4220 | redirect_to = self.request.resource_path(self.context, route_name='auth_home') | |||
r1 | return HTTPFound(redirect_to) | |||