diff --git a/css/settings.css b/css/settings.css index 0f90ec3..33f454a 100644 --- a/css/settings.css +++ b/css/settings.css @@ -1,29 +1,58 @@ -.statusmessage { - background-color: #DDDDFF; +#user_sql .main { + overflow: auto; } -.errormessage { - background-color: #FFDDDD; +#user_sql .main > div { + float: left; + width: 380px; } -.successmessage { - background-color: #DDFFDD; -} - -.statusmessage, .errormessage, .successmessage { - display: none; - padding: 1px; -} - -#sql-1 p label:first-child, -#sql-2 p label:first-child, -#sql-3 p label:first-child, -#sql-4 p label:first-child, -#sql-5 p label:first-child, -#sql-6 p label:first-child, -#sql-7 p label:first-child { +#user_sql .main div > label > span { display: inline-block; - text-align: right; - width: 300px; - padding-right: 10px; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap; + width: 120px; } + +#user_sql .main div > label > input, +#user_sql .main div > label > select { + width: 257px; +} + +#user_sql .main div > input[type="checkbox"] { + min-height: auto; +} + +#user_sql .main .button-right { + overflow: auto; +} + +#user_sql .main .button-right > input[type="submit"] { + float: right; +} + +#user_sql .msg { + left: 0; + padding: 3px; + position: fixed; + text-align: center; + width: 100%; + z-index: 100; +} + +#user_sql .msg.error { + background-color: #d2322d; + color: #fff; +} + +#user_sql .msg.success { + background-color: #47a447; + color: #fff; +} + +#user_sql .msg.waiting { + background-color: #ff8f00; + color: #fff; +} \ No newline at end of file diff --git a/js/settings.js b/js/settings.js index 4b63b53..0098601 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1,321 +1,98 @@ -// settings.js of user_sql +var user_sql = user_sql || {}; +var form_id = "#user_sql"; -// declare namespace -var user_sql = user_sql || - {}; - -/** - * init admin settings view - */ user_sql.adminSettingsUI = function () { + var app_id = "user_sql"; - if ($('#sqlDiv').length > 0) { - // enable tabs on settings page - $('#sqlDiv').tabs(); + if ($(form_id).length > 0) { - // Attach auto-completion to all column fields - $('#col_username, #col_password, #col_displayname, #col_active, #col_email, #col_gethome').autocomplete({ - source: function (request, response) { - var post = $('#sqlForm').serializeArray(); - var domain = $('#sql_domain_chooser option:selected').val(); - - post.push({ - name: 'function', - value: 'getColumnAutocomplete' - }); - - post.push({ - name: 'domain', - value: domain - }); - - post.push({ - name: 'request', - value: request.term - }); - - // Ajax foobar - $.post(OC.filePath('user_sql', 'ajax', 'settings.php'), post, response, 'json'); - }, - minLength: 0, - open: function () { - $(this).attr('state', 'open'); - }, - close: function () { - $(this).attr('state', 'closed'); - } - }).focus(function () { - if ($(this).attr('state') != 'open') { - $(this).autocomplete("search"); - } - }); - - // Attach auto-completion to all group column fields - $('#col_group_name, #col_group_username').autocomplete({ - source: function (request, response) { - var post = $('#sqlForm').serializeArray(); - var domain = $('#sql_domain_chooser option:selected').val(); - - post.push({ - name: 'groupTable', - value: 'true' - }); - - post.push({ - name: 'function', - value: 'getColumnAutocomplete' - }); - - post.push({ - name: 'domain', - value: domain - }); - - post.push({ - name: 'request', - value: request.term - }); - - // Ajax foobar - $.post(OC.filePath('user_sql', 'ajax', 'settings.php'), post, response, 'json'); - }, - minLength: 0, - open: function () { - $(this).attr('state', 'open'); - }, - close: function () { - $(this).attr('state', 'closed'); - } - }).focus(function () { - if ($(this).attr('state') != 'open') { - $(this).autocomplete("search"); - } - }); - - // Attach auto-completion to all table fields - $('#sql_table, #sql_group_table').autocomplete({ - source: function (request, response) { - var post = $('#sqlForm').serializeArray(); - var domain = $('#sql_domain_chooser option:selected').val(); - - post.push({ - name: 'function', - value: 'getTableAutocomplete' - }); - - post.push({ - name: 'domain', - value: domain - }); - - post.push({ - name: 'request', - value: request.term - }); - - // Ajax foobar - $.post(OC.filePath('user_sql', 'ajax', 'settings.php'), post, response, 'json'); - }, - minLength: 0, - open: function () { - $(this).attr('state', 'open'); - }, - close: function () { - $(this).attr('state', 'closed'); - } - }).focus(function () { - if ($(this).attr('state') != 'open') { - $(this).autocomplete("search"); - } - }); - - // Verify the SQL database settings - $('#sqlVerify').click(function (event) { + var click = function (event, path) { event.preventDefault(); - var post = $('#sqlForm').serializeArray(); - var domain = $('#sql_domain_chooser option:selected').val(); + var post = $(form_id).serializeArray(); + var msg = $("#user_sql-msg"); + var msg_body = $("#user_sql-msg-body"); - post.push({ - name: 'function', - value: 'verifySettings' - }); + msg_body.html(t(app_id, "Waiting...")); + msg.addClass("waiting"); + msg.slideDown(); - post.push({ - name: 'domain', - value: domain - }); + $.post(OC.generateUrl(path), post, function (data) { + msg_body.html(data.data.message); + msg.removeClass("error"); + msg.removeClass("success"); + msg.removeClass("waiting"); - $('#sql_verify_message').show(); - $('#sql_success_message').hide(); - $('#sql_error_message').hide(); - $('#sql_update_message').hide(); - // Ajax foobar - $.post(OC.filePath('user_sql', 'ajax', 'settings.php'), post, function (data) { - $('#sql_verify_message').hide(); - if (data.status == 'success') { - $('#sql_success_message').html(data.data.message); - $('#sql_success_message').show(); - window.setTimeout(function () { - $('#sql_success_message').hide(); - }, 10000); + if (data.status === "success") { + msg.addClass("success"); } else { - $('#sql_error_message').html(data.data.message); - $('#sql_error_message').show(); + msg.addClass("error"); } - }, 'json'); + + window.setTimeout(function () { + msg.slideUp(); + }, 10000); + }, "json"); + return false; - }); + }; - // Save the settings for a domain - $('#sqlSubmit').click(function (event) { - event.preventDefault(); - - var post = $('#sqlForm').serializeArray(); - var domain = $('#sql_domain_chooser option:selected').val(); - - post.push({ - name: 'function', - value: 'saveSettings' - }); - - post.push({ - name: 'domain', - value: domain - }); - - $('#sql_update_message').show(); - $('#sql_success_message').hide(); - $('#sql_verify_message').hide(); - $('#sql_error_message').hide(); - // Ajax foobar - $.post(OC.filePath('user_sql', 'ajax', 'settings.php'), post, function (data) { - $('#sql_update_message').hide(); - if (data.status == 'success') { - $('#sql_success_message').html(data.data.message); - $('#sql_success_message').show(); - window.setTimeout(function () { - $('#sql_success_message').hide(); - }, 10000); - } else { - $('#sql_error_message').html(data.data.message); - $('#sql_error_message').show(); + var autocomplete = function (ids, path) { + $(ids).autocomplete({ + source: function (request, response) { + var post = $(form_id).serializeArray(); + $.post(OC.generateUrl(path), post, response, "json"); + }, + minLength: 0, + open: function () { + $(this).attr("state", "open"); + }, + close: function () { + $(this).attr("state", "closed"); } - }, 'json'); - return false; - }); - - // Attach event handler to the domain chooser - $('#sql_domain_chooser').change(function () { - user_sql.loadDomainSettings($('#sql_domain_chooser option:selected').val()); - }); - - $('#set_gethome_mode').change(function () { - user_sql.setGethomeMode(); - }); - - $('#set_enable_gethome').change(function () { - user_sql.setGethomeMode(); - }); - } -}; - -user_sql.setGethomeMode = function () { - var enabled = $('#set_enable_gethome').prop('checked'); - if (enabled) { - $('#set_gethome_mode').prop('disabled', false); - var val = $('#set_gethome_mode option:selected').val(); - if (val === 'query') { - $('#set_gethome').prop('disabled', true); - $('#col_gethome').prop('disabled', false); - } - else if (val === 'static') { - $('#set_gethome').prop('disabled', false); - $('#col_gethome').prop('disabled', true); - } - else { - $('#set_gethome').prop('disabled', true); - $('#col_gethome').prop('disabled', true); - } - } - else { - $('#set_gethome_mode').prop('disabled', true); - $('#set_gethome').prop('disabled', true); - $('#col_gethome').prop('disabled', true); - } -}; - -/** - * Load the settings for the selected domain - * @param string domain The domain to load - */ -user_sql.loadDomainSettings = function (domain) { - $('#sql_success_message').hide(); - $('#sql_error_message').hide(); - $('#sql_verify_message').hide(); - $('#sql_loading_message').show(); - var post = [ - { - name: 'appname', - value: 'user_sql' - }, - { - name: 'function', - value: 'loadSettingsForDomain' - }, - { - name: 'domain', - value: domain - } - ]; - $.post(OC.filePath('user_sql', 'ajax', 'settings.php'), post, function (data) { - $('#sql_loading_message').hide(); - if (data.status == 'success') { - for (key in data.settings) { - if (key == 'set_strip_domain') { - if (data.settings[key] == 'true') - $('#' + key).prop('checked', true); - else - $('#' + key).prop('checked', false); - } - else if (key == 'set_allow_pwchange') { - if (data.settings[key] == 'true') - $('#' + key).prop('checked', true); - else - $('#' + key).prop('checked', false); - } - else if (key == 'set_active_invert') { - if (data.settings[key] == 'true') - $('#' + key).prop('checked', true); - else - $('#' + key).prop('checked', false); - } - else if (key == 'set_enable_gethome') { - if (data.settings[key] == 'true') - $('#' + key).prop('checked', true); - else - $('#' + key).prop('checked', false); - } - else { - $('#' + key).val(data.settings[key]); - } + }).focus(function () { + if ($(this).attr("state") !== "open") { + $(this).autocomplete("search"); } - } - else { - $('#sql_error_message').html(data.data.message); - $('#sql_error_message').show(); - } - user_sql.setGethomeMode(); - }, 'json' - ); + }); + }; + + $("#user_sql-db_connection_verify").click(function (event) { + return click(event, "/apps/user_sql/settings/db/verify"); + }); + + $("#user_sql-clear_cache").click(function (event) { + return click(event, "/apps/user_sql/settings/cache/clear"); + }); + + $("#user_sql-save").click(function (event) { + return click(event, "/apps/user_sql/settings/properties"); + }); + + autocomplete( + "#db-table-user, #db-table-user_group, #db-table-group", + "/apps/user_sql/settings/autocomplete/table" + ); + + autocomplete( + "#db-table-user-column-uid, #db-table-user-column-email, #db-table-user-column-home, #db-table-user-column-password, #db-table-user-column-name, #db-table-user-column-avatar", + "/apps/user_sql/settings/autocomplete/table/user" + ); + + autocomplete( + "#db-table-user_group-column-uid, #db-table-user_group-column-gid", + "/apps/user_sql/settings/autocomplete/table/user_group" + ); + + autocomplete( + "#db-table-group-column-admin, #db-table-group-column-name, #db-table-group-column-gid", + "/apps/user_sql/settings/autocomplete/table/group" + ); + } }; -// Run our JS if the SQL settings are present $(document).ready(function () { - if ($('#sqlDiv')) { + if ($(form_id)) { user_sql.adminSettingsUI(); - user_sql.loadDomainSettings($('#sql_domain_chooser option:selected').val()); - user_sql.setGethomeMode(); } -}); - +}); \ No newline at end of file diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index c8bf37f..7a95d6c 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -175,6 +175,24 @@ class SettingsController extends Controller $properties = $this->properties->getArray(); + try { + $this->getConnection(); + } catch (Exception $exception) { + $this->logger->debug( + "Returning saveProperties(): error", + ["app" => $this->appName] + ); + + return [ + "status" => "error", + "data" => [ + "message" => $this->localization->t( + "Error connecting to the database: " + ) . $exception->getMessage() + ] + ]; + } + foreach ($properties as $key => $value) { $reqValue = $this->request->getParam(str_replace(".", "-", $key)); $appValue = $this->properties[$key]; diff --git a/templates/admin.php b/templates/admin.php index 7bf64a1..2e30058 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -1,273 +1,182 @@ + * @author Marcin Łojewski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 Affero 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 . + */ + +use OCP\IL10N; + script('user_sql', 'settings'); style('user_sql', 'settings'); -$cfgClass = 'section'; + +function print_text_input(IL10N $l, $id, $label, $value = "") +{ + echo "
"; +} + +function print_checkbox_input(IL10N $l, $id, $label, $value = "", $div = true) +{ + if ($div) { + echo "
"; + } + echo ""; + echo ""; + if ($div) { + echo "
"; + } +} + +function print_select_options( + IL10N $l, $id, $label, $options = [], $select = false +) { + echo "
"; +} + ?> - -
-

t('SQL User Backend')); ?>

- -
- -
- - - - -
-

- 'MySQL', 'pgsql' => 'PostgreSQL'); ?> - -

- -

-

- -

-

- -

-

- -

-

- -

- + + +
+

+ t("This is the place for ")); ?> + t("User and Group SQL Backends")); ?> + t(" app settings. Please see the documentation for more information.")); ?> + +

+
+
+
+

t("Database connection")); ?>

+

t("Define your database connection parameters.")); ?>

+
"MySQL", "pgsql" => "PostgreSQL"]; + print_select_options($l, "db-driver", "SQL driver", $drivers, $_['db.driver']); + print_text_input($l, "db-hostname", "Hostname", $_['db.hostname']); + print_text_input($l, "db-database", "Database", $_['db.database']); + print_text_input($l, "db-username", "Username", $_['db.username']); + print_text_input($l, "db-password", "Password", $_['db.password']); ?> +
+ "> +
-
-

-

- -

-

- -

-

- -

- >
- t('Allow changing passwords. Imposes a security risk if password salts are not recreated.')); ?> -

- t('Only the encryption types "System","password_hash" and "Joomla2" are safe.')); ?>

- -

-

- -

- getVisibleName(); - } - ?> - -

- -

-

- -

/>
- t("Invert the logic of the active column (for blocked users in the SQL DB)")); ?> -

- -
- -
- -

-

- -

- 'No Synchronisation', - 'initial' => 'Synchronise only once', - 'forceoc' => 'Nextcloud always wins', - 'forcesql' => 'SQL always wins' - ); ?> - -

- -
- -
- -


- t('Append this string, e.g. a domain name, to each user name. The @-sign is automatically inserted.')); ?> -

- -

/>
- t("Strip Domain Part including @-sign from Username when logging in and retrieving username lists")); ?> -

- -
- -
-

/>

- -

- 'SQL Column', 'static' => 'Static (with Variables)'); ?> - -

- -

-

- -


- t('You can use the placeholders %%u to specify the user ID (before appending the default domain), %%ud to specify the user ID (after appending the default domain) and %%d to specify the default domain')); ?> -

- -
-
-

-

- -

-

- -

-

- -
- - - - -
t('Saving...')); ?>
-
t('Loading...')); ?>
-
t('Verifying...')); ?>
-
-
- -
+
+

t("Options")); ?>

+

t("Here are all currently supported options.")); ?>

+
+
+ "> +
+ getVisibleName(); + } + } catch (Throwable $e) { + } + } + + print_select_options($l, "opt-crypto_class", "Hashing algorithm", $hashing, $_['opt.crypto_class']); + print_select_options($l, "opt-email_sync", "Email sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_['opt.email_sync']); + print_select_options($l, "opt-home_mode", "Home mode", ["" => "Default", "query" => "Query", "static" => "Static"], $_['opt.home_mode']); + print_text_input($l, "opt-home_location", "Home Location", $_['opt.home_location']); ?> +
+
+
+

t("User table")); ?>

+

t("Table containing user accounts.")); ?>

+
+

t("Columns")); ?>

+ +
+
+
+

t("Group table")); ?>

+

t("Group definitions table.")); ?>

+
+

t("Columns")); ?>

+ +
+
+
+

t("User group table")); ?>

+

t("Associative table which maps users to groups.")); ?>

+
+

t("Columns")); ?>

+ +
+
+
+
+ + + +
+ \ No newline at end of file