diff --git a/data/www/js/auth.js b/data/www/js/auth.js index f61fb43..d31193f 100644 --- a/data/www/js/auth.js +++ b/data/www/js/auth.js @@ -85,13 +85,18 @@ jQuery(document).ready(function ($) { $(document).on('click', '.user-delete', function () { if (confirm(l.js_auth_user_delete_confirmation)) { const $tr = $(this).parents('tr:eq(0)'); - $tr.remove(); updateTable(); $.ajax({ method: 'DELETE', url: '/auth/user/delete', headers: {'Content-Type': 'application/json'}, data: JSON.stringify({id: getId($(this))}), + success: function(data) { + $tr.remove(); + }, + error: function(data) { + $('.alert-error').html(data.responseJSON.message).removeClass('hidden'); + } }); } }); diff --git a/data/www/js/slideshow.js b/data/www/js/slideshow.js index fedc915..6168909 100644 --- a/data/www/js/slideshow.js +++ b/data/www/js/slideshow.js @@ -115,8 +115,11 @@ jQuery(document).ready(function ($) { }); $(document).on('change', '.modal-slide select.trigger', function () { + const $modal = $(this).parents('.modal-slide:eq(0)'); const $target = $(this).parents('.widget:eq(0)').find('.target'); const $datetimepicker = $(this).parents('.widget:eq(0)').find('.datetimepicker'); + const $durationGroup = $modal.find('.slide-duration-group'); + const $scheduleEndGroup = $modal.find('.slide-schedule-end-group'); const isDateTime = $(this).val() === 'datetime'; const isLoop = $(this).val() === 'loop'; @@ -126,7 +129,9 @@ jQuery(document).ready(function ($) { const hideDateTimeField = !isDateTime; $target.toggleClass('hidden', hideCronField); - $datetimepicker.toggleClass('hidden', hideDateTimeField) + $datetimepicker.toggleClass('hidden', hideDateTimeField); + // $durationGroup.toggleClass('hidden', !isLoop); + // $scheduleEndGroup.toggleClass('hidden', isLoop); if (flushValue) { $target.val(''); diff --git a/lang/en.json b/lang/en.json index ae16078..00ab541 100644 --- a/lang/en.json +++ b/lang/en.json @@ -74,6 +74,7 @@ "auth_user_form_label_username": "Username", "auth_user_form_label_password": "Password", "auth_user_form_button_cancel": "Cancel", + "auth_user_delete_at_least_one_account": "You must have at least one active user while using authentication feature", "js_auth_user_delete_confirmation": "Are you sure?", "settings_page_title": "Settings", diff --git a/lang/fr.json b/lang/fr.json index ce356f3..cb597f1 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -74,6 +74,7 @@ "auth_user_form_label_username": "Nom d'utilisateur", "auth_user_form_label_password": "Mot de passe", "auth_user_form_button_cancel": "Annuler", + "auth_user_delete_at_least_one_account": "Vous devez avoir au moins un utilisateur actif lorsque vous activez la gestion de l'authentification", "js_auth_user_delete_confirmation": "Êtes-vous sûr ?", "settings_page_title": "Paramètres", diff --git a/src/controller/AuthController.py b/src/controller/AuthController.py index ca92a8b..9ef5a3f 100644 --- a/src/controller/AuthController.py +++ b/src/controller/AuthController.py @@ -70,6 +70,8 @@ class AuthController(ObController): return jsonify({'status': 'ok'}) def auth_user_delete(self): + if self._model_store.user().count_all_enabled() == 1: + return jsonify({'status': 'error', 'message': self.t('auth_user_delete_at_least_one_account')}), 400 data = request.get_json() self._model_store.user().delete(data.get('id')) return jsonify({'status': 'ok'}) diff --git a/src/controller/SettingsController.py b/src/controller/SettingsController.py index 802ea30..2d0c6ab 100644 --- a/src/controller/SettingsController.py +++ b/src/controller/SettingsController.py @@ -21,8 +21,8 @@ class SettingsController(ObController): def settings_variable_edit(self): self._model_store.variable().update_form(request.form['id'], request.form['value']) - self._post_update(request.form['id']) - return redirect(url_for('settings_variable_list')) + forward = self._post_update(request.form['id']) + return forward if forward is not None else redirect(url_for('settings_variable_list')) def _post_update(self, id: str): variable = self._model_store.variable().get(id) @@ -38,6 +38,8 @@ class SettingsController(ObController): if variable.name == 'auth_enabled': self.reload_web_server() + if variable.as_bool(): + return redirect(url_for('logout')) if variable.name == 'lang': self._model_store.lang().set_lang(variable.value) diff --git a/src/interface/ObController.py b/src/interface/ObController.py index 88494c4..9362806 100644 --- a/src/interface/ObController.py +++ b/src/interface/ObController.py @@ -28,4 +28,7 @@ class ObController(abc.ABC): return self._plugin def reload_web_server(self): - self._web_server.reload() \ No newline at end of file + self._web_server.reload() + + def t(self, token) -> Union[Dict, str]: + return self._model_store.lang().translate(token) diff --git a/src/manager/UserManager.py b/src/manager/UserManager.py index b91e803..82de2be 100644 --- a/src/manager/UserManager.py +++ b/src/manager/UserManager.py @@ -56,8 +56,8 @@ class UserManager(ModelManager): def get_one_by_username(self, username: str, enabled: bool = None) -> Optional[User]: return self.get_one_by(query=lambda v: v['username'] == username and (enabled is None or v['enabled'] == enabled)) - def count_all(self): - return len(self.get_all()) + def count_all_enabled(self): + return len(self.get_enabled_users()) def get_all(self, sort: bool = False) -> List[User]: raw_users = self._db.get_all() diff --git a/src/service/WebServer.py b/src/service/WebServer.py index db5c39a..951a15c 100644 --- a/src/service/WebServer.py +++ b/src/service/WebServer.py @@ -22,6 +22,7 @@ class WebServer: def __init__(self, project_dir: str, model_store: ModelStore, template_renderer: TemplateRenderer): self._app = None + self._auth_enabled = False self._login_manager = None self._project_dir = project_dir self._model_store = model_store @@ -40,6 +41,7 @@ class WebServer: self.setup() def setup(self) -> None: + self._auth_enabled = self._model_store.variable().map().get('auth_enabled').as_bool() self._setup_flask_app() self._setup_web_globals() self._setup_web_errors() @@ -69,29 +71,22 @@ class WebServer: if self._debug: self._app.config['TEMPLATES_AUTO_RELOAD'] = True - def _setup_flask_login(self) -> bool: - auth_module = self._model_store.variable().map().get('auth_enabled').as_bool() - - if not auth_module: - return auth_module - + def _setup_flask_login(self): self._app.config['SECRET_KEY'] = self._model_store.config().map().get('secret_key') self._login_manager = LoginManager() self._login_manager.init_app(self._app) self._login_manager.login_view = 'login' - if self._model_store.user().count_all() == 0: + if self._auth_enabled and self._model_store.user().count_all_enabled() == 0: self._model_store.user().add_form(User(username="admin", password="admin", enabled=True)) @self._login_manager.user_loader def load_user(user_id): return self._model_store.user().get(user_id) - return auth_module - def _setup_web_controllers(self) -> None: def auth_required(f): - if not self._login_manager: + if not self._auth_enabled: return f def decorated_function(*args, **kwargs): diff --git a/views/auth/list.jinja.html b/views/auth/list.jinja.html index 93f00c0..150480a 100644 --- a/views/auth/list.jinja.html +++ b/views/auth/list.jinja.html @@ -23,6 +23,11 @@ {{ HOOK(H_AUTH_TOOLBAR_ACTIONS_END) }} + + +

{{ l.auth_user_panel_active }}

diff --git a/views/base.jinja.html b/views/base.jinja.html index 3979864..0bba1ab 100755 --- a/views/base.jinja.html +++ b/views/base.jinja.html @@ -46,7 +46,8 @@ Obscreen - {% if (current_user and current_user.is_authenticated) or not current_user %} + + {% if not AUTH_ENABLED or (current_user and current_user.is_authenticated) %}