From 924886dd9a9057c77280124465f95d1698adcffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Tue, 10 Jul 2018 22:19:50 +0200 Subject: [PATCH 01/20] Hash configuration --- lib/Crypto/AbstractAlgorithm.php | 8 ++++++++ lib/Crypto/CryptArgon2.php | 21 +++++++++++++++++++++ lib/Crypto/CryptBlowfish.php | 13 +++++++++++++ lib/Crypto/CryptExtendedDES.php | 15 ++++++++++++++- lib/Crypto/CryptSHA256.php | 13 +++++++++++++ lib/Crypto/CryptSHA512.php | 13 +++++++++++++ lib/Crypto/IPasswordAlgorithm.php | 9 +++++++++ lib/Crypto/Phpass.php | 13 +++++++++++++ tests/Crypto/CryptExtendedDESTest.php | 2 +- 9 files changed, 105 insertions(+), 2 deletions(-) diff --git a/lib/Crypto/AbstractAlgorithm.php b/lib/Crypto/AbstractAlgorithm.php index 9556d78..09bbbe6 100644 --- a/lib/Crypto/AbstractAlgorithm.php +++ b/lib/Crypto/AbstractAlgorithm.php @@ -74,4 +74,12 @@ abstract class AbstractAlgorithm implements IPasswordAlgorithm * @inheritdoc */ public abstract function getPasswordHash($password); + + /** + * @inheritdoc + */ + public function configuration() + { + return []; + } } diff --git a/lib/Crypto/CryptArgon2.php b/lib/Crypto/CryptArgon2.php index ed4aafb..535f1e8 100644 --- a/lib/Crypto/CryptArgon2.php +++ b/lib/Crypto/CryptArgon2.php @@ -100,6 +100,27 @@ class CryptArgon2 extends AbstractAlgorithm ); } + /** + * @inheritdoc + */ + public function configuration() + { + return [ + [ + "name" => "memoryCost", "visible_name" => "Memory cost (KiB)", + "default" => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, "min" => 1, "max" => 1048576 + ], + [ + "name" => "timeCost", "visible_name" => "Time cost", + "default" => PASSWORD_ARGON2_DEFAULT_TIME_COST, "min" => 1, "max" => 1024 + ], + [ + "name" => "threads", "visible_name" => "Threads", + "default" => PASSWORD_ARGON2_DEFAULT_THREADS, "min" => 1, "max" => 1024 + ] + ]; + } + /** * @inheritdoc */ diff --git a/lib/Crypto/CryptBlowfish.php b/lib/Crypto/CryptBlowfish.php index 6e1b8a5..a3e2577 100644 --- a/lib/Crypto/CryptBlowfish.php +++ b/lib/Crypto/CryptBlowfish.php @@ -67,6 +67,19 @@ class CryptBlowfish extends AbstractAlgorithm ); } + /** + * @inheritdoc + */ + public function configuration() + { + return [ + [ + "name" => "cost", "visible_name" => "Cost", "default" => 10, + "min" => 4, "max" => 31 + ] + ]; + } + /** * Get the algorithm name. * diff --git a/lib/Crypto/CryptExtendedDES.php b/lib/Crypto/CryptExtendedDES.php index d6654c4..235e563 100644 --- a/lib/Crypto/CryptExtendedDES.php +++ b/lib/Crypto/CryptExtendedDES.php @@ -48,6 +48,19 @@ class CryptExtendedDES extends AbstractCrypt $this->iterationCount = $iterationCount; } + /** + * @inheritdoc + */ + public function configuration() + { + return [ + [ + "name" => "iterations", "visible_name" => "Iterations", "default" => 1000, + "min" => 0, "max" => 16777215 + ] + ]; + } + /** * @inheritdoc */ @@ -76,7 +89,7 @@ class CryptExtendedDES extends AbstractCrypt while ($number) { $rem = $number % $base; $number = (int)($number / $base); - $arr[] = $alphabet[$rem]; + $chars[] = $alphabet[$rem]; } return str_pad(implode($chars), 4, ".", STR_PAD_RIGHT); diff --git a/lib/Crypto/CryptSHA256.php b/lib/Crypto/CryptSHA256.php index b4e2b41..75515eb 100644 --- a/lib/Crypto/CryptSHA256.php +++ b/lib/Crypto/CryptSHA256.php @@ -49,6 +49,19 @@ class CryptSHA256 extends AbstractCrypt $this->rounds = $rounds; } + /** + * @inheritdoc + */ + public function configuration() + { + return [ + [ + "name" => "rounds", "visible_name" => "Rounds", "default" => 5000, + "min" => 1000, "max" => 999999999 + ] + ]; + } + /** * @inheritdoc */ diff --git a/lib/Crypto/CryptSHA512.php b/lib/Crypto/CryptSHA512.php index e32238f..b638175 100644 --- a/lib/Crypto/CryptSHA512.php +++ b/lib/Crypto/CryptSHA512.php @@ -49,6 +49,19 @@ class CryptSHA512 extends AbstractCrypt $this->rounds = $rounds; } + /** + * @inheritdoc + */ + public function configuration() + { + return [ + [ + "name" => "rounds", "visible_name" => "Rounds", "default" => 5000, + "min" => 1000, "max" => 999999999 + ] + ]; + } + /** * @inheritdoc */ diff --git a/lib/Crypto/IPasswordAlgorithm.php b/lib/Crypto/IPasswordAlgorithm.php index 47ba961..1f33356 100644 --- a/lib/Crypto/IPasswordAlgorithm.php +++ b/lib/Crypto/IPasswordAlgorithm.php @@ -56,4 +56,13 @@ interface IPasswordAlgorithm * @return boolean True if the password is correct, false otherwise. */ public function checkPassword($password, $dbHash); + + /** + * Configuration for the algorithm. + * The return array should contain entries which define keys: + * name, visible_name, default, min, max. + * + * @return array The configuration array. + */ + public function configuration(); } diff --git a/lib/Crypto/Phpass.php b/lib/Crypto/Phpass.php index d193917..dae4eab 100644 --- a/lib/Crypto/Phpass.php +++ b/lib/Crypto/Phpass.php @@ -143,6 +143,19 @@ class Phpass extends AbstractAlgorithm return $output; } + /** + * @inheritdoc + */ + public function configuration() + { + return [ + [ + "name" => "iterations", "visible_name" => "Iterations (log2)", + "default" => 8, "min" => 4, "max" => 31 + ] + ]; + } + /** * @inheritdoc */ diff --git a/tests/Crypto/CryptExtendedDESTest.php b/tests/Crypto/CryptExtendedDESTest.php index c5627e0..5f820b6 100644 --- a/tests/Crypto/CryptExtendedDESTest.php +++ b/tests/Crypto/CryptExtendedDESTest.php @@ -41,7 +41,7 @@ class CryptExtendedDESTest extends TestCase public function testCheckPassword() { $this->assertTrue( - $this->crypto->checkPassword("password", "..UZoIyj/Hy/c") + $this->crypto->checkPassword("password", "cDRpdxPmHpzS.") ); } From e0c6d419854f736305d9054f003891c715439a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sat, 29 Sep 2018 18:09:15 +0200 Subject: [PATCH 02/20] Leftover lines break the admin page --- templates/admin.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/templates/admin.php b/templates/admin.php index 7d2725f..8f05648 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -71,16 +71,6 @@ function print_select_options( echo ""; } - -#54: Merge develop-14 into develop Conflicts -Resolved all conflicts -2 conflicting files -CHANGELOG.md -CHANGELOG.md -admin.php -templates/admin.php -templates/admin.php -Resolved echo ""; echo ""; } From 1b0467d070bc3879e8717dd759c1a4fb28abb073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sun, 28 Oct 2018 18:36:53 +0100 Subject: [PATCH 03/20] No configuration for Drupal7 --- lib/Crypto/Drupal7.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/Crypto/Drupal7.php b/lib/Crypto/Drupal7.php index 567e342..85024f4 100644 --- a/lib/Crypto/Drupal7.php +++ b/lib/Crypto/Drupal7.php @@ -34,6 +34,14 @@ class Drupal7 extends Phpass */ const DRUPAL_HASH_LENGTH = 55; + /** + * @inheritdoc + */ + public function configuration() + { + return []; + } + /** * @inheritdoc */ From a61f9fc7d7918fa72d42dff0a961c8557b13b7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sun, 16 Dec 2018 18:00:43 +0100 Subject: [PATCH 04/20] Version 4.3.0-dev --- CHANGELOG.md | 3 +++ appinfo/info.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f07ac7..d189cf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] + ## [4.2.0] - 2018-12-16 ### Added - Support for Nextcloud 15 @@ -108,6 +110,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Supported version of ownCloud, Nextcloud: ownCloud 10, Nextcloud 12 +[Unreleased]: https://github.com/nextcloud/user_sql/compare/v4.2.0...develop [4.2.0]: https://github.com/nextcloud/user_sql/compare/v4.1.0...v4.2.0 [4.1.0]: https://github.com/nextcloud/user_sql/compare/v4.0.1...v4.1.0 [4.0.1]: https://github.com/nextcloud/user_sql/compare/v4.0.0...v4.0.1 diff --git a/appinfo/info.xml b/appinfo/info.xml index 83ded89..01f2a2a 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -8,7 +8,7 @@ Retrieve the users and groups info. Allow the users to change their passwords. Sync the users' email addresses with the addresses stored by Nextcloud. - 4.2.0 + 4.3.0-dev agpl Marcin Łojewski Andreas Böhler From d5b5c36b1ccb342ac79b4bd1a5a70000d10a2bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sat, 22 Dec 2018 11:04:41 +0100 Subject: [PATCH 05/20] issue#85 Revers active column checkbox --- CHANGELOG.md | 2 ++ README.md | 1 + appinfo/info.xml | 2 +- lib/Constant/Opt.php | 1 + lib/Query/QueryProvider.php | 5 ++++- templates/admin.php | 3 ++- 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d189cf9..b40801f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Reverse active column option ## [4.2.0] - 2018-12-16 ### Added diff --git a/README.md b/README.md index 87061c4..65cfb89 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Name | Description | Details **Allow display name change** | With this option enabled user can change its display name. The display name change is propagated to the database. | Optional.
Default: false.
Requires: user *Display name* column. **Allow password change** | Can user change its password. The password change is propagated to the database. See [Hash algorithms](#hash-algorithms). | Optional.
Default: false. **Case-insensitive username** | Whether user query should be case-sensitive or case-insensitive. | Optional.
Default: false. +**Reverse active column** | Reverse value of active column in user table. | Optional.
Default: false. **Use cache** | Use database query results cache. The cache can be cleared any time with the *Clear cache* button click. | Optional.
Default: false. **Hash algorithm** | How users passwords are stored in the database. See [Hash algorithms](#hash-algorithms). | Mandatory. **Email sync** | Sync e-mail address with the Nextcloud.
- *None* - Disables this feature. This is the default option.
- *Synchronise only once* - Copy the e-mail address to the Nextcloud preferences if its not set.
- *Nextcloud always wins* - Always copy the e-mail address to the database. This updates the user table.
- *SQL always wins* - Always copy the e-mail address to the Nextcloud preferences. | Optional.
Default: *None*.
Requires: user *Email* column. diff --git a/appinfo/info.xml b/appinfo/info.xml index 01f2a2a..ecb2963 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -22,7 +22,7 @@ auth - + \OCA\UserSQL\Settings\Admin diff --git a/lib/Constant/Opt.php b/lib/Constant/Opt.php index 5093210..6cdc6c2 100644 --- a/lib/Constant/Opt.php +++ b/lib/Constant/Opt.php @@ -38,5 +38,6 @@ final class Opt const PASSWORD_CHANGE = "opt.password_change"; const PREPEND_SALT = "opt.prepend_salt"; const QUOTA_SYNC = "opt.quota_sync"; + const REVERSE_ACTIVE = "opt.reverse_active"; const USE_CACHE = "opt.use_cache"; } diff --git a/lib/Query/QueryProvider.php b/lib/Query/QueryProvider.php index cd027d0..03b1f5b 100644 --- a/lib/Query/QueryProvider.php +++ b/lib/Query/QueryProvider.php @@ -22,6 +22,7 @@ namespace OCA\UserSQL\Query; use OCA\UserSQL\Constant\DB; +use OCA\UserSQL\Constant\Opt; use OCA\UserSQL\Constant\Query; use OCA\UserSQL\Properties; @@ -86,6 +87,8 @@ class QueryProvider implements \ArrayAccess $searchParam = Query::SEARCH_PARAM; $uidParam = Query::UID_PARAM; + $reverseActiveOpt = $this->properties[Opt::REVERSE_ACTIVE]; + $groupColumns = "$gGID AS gid, " . (empty($gName) ? $gGID : $gName) . " AS name, " . @@ -96,7 +99,7 @@ class QueryProvider implements \ArrayAccess (empty($uEmail) ? "null" : $uEmail) . " AS email, " . (empty($uQuota) ? "null" : $uQuota) . " AS quota, " . (empty($uHome) ? "null" : $uHome) . " AS home, " . - (empty($uActive) ? "true" : $uActive) . " AS active, " . + (empty($uActive) ? "true" : (empty($reverseActiveOpt) ? "" : "NOT ") . $uActive) . " AS active, " . (empty($uAvatar) ? "false" : $uAvatar) . " AS avatar, " . (empty($uSalt) ? "null" : $uSalt) . " AS salt"; diff --git a/templates/admin.php b/templates/admin.php index c00b06e..0a5f042 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -110,7 +110,8 @@ function print_select_options(
+ print_checkbox_input($l, "opt-case_insensitive_username", "Case-insensitive username", $_["opt.case_insensitive_username"]); + print_checkbox_input($l, "opt-reverse_active", "Reverse active column", $_["opt.reverse_active"]); ?>
"> From ed53272ad94e7c0c208f3228729dbd475540f6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sat, 22 Dec 2018 19:19:59 +0100 Subject: [PATCH 06/20] Support for Nextcloud 16 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b40801f..2e0cec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added - Reverse active column option +- Support for Nextcloud 16 ## [4.2.0] - 2018-12-16 ### Added From 63cd9d330ebb4735cab16750e3be6edf3911cbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sun, 23 Dec 2018 23:13:20 +0100 Subject: [PATCH 07/20] div for crypto params --- templates/admin.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/admin.php b/templates/admin.php index 0a5f042..2bac565 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -131,7 +131,9 @@ function print_select_options( } } - print_select_options($l, "opt-crypto_class", "Hash algorithm", $hashes, $_["opt.crypto_class"]); + print_select_options($l, "opt-crypto_class", "Hash algorithm", $hashes, $_["opt.crypto_class"]); ?> +
+ "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_["opt.email_sync"]); print_select_options($l, "opt-quota_sync", "Quota sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_["opt.quota_sync"]); print_select_options($l, "opt-home_mode", "Home mode", ["" => "Default", "query" => "Query", "static" => "Static"], $_["opt.home_mode"]); From 436c1d930d154af7bda9a93f3a6b83cd85656d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sun, 23 Dec 2018 23:49:32 +0100 Subject: [PATCH 08/20] Setting crypto params from admin panel initial impl --- appinfo/routes.php | 5 ++++ js/settings.js | 38 ++++++++++++++++++++++++++- lib/Controller/SettingsController.php | 32 ++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 8224fa4..dde5395 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -61,6 +61,11 @@ $application->registerRoutes( "url" => "/settings/autocomplete/table/group", "verb" => "POST" ], + [ + "name" => "settings#cryptoParams", + "url" => "/settings/crypto/params", + "verb" => "GET" + ], ] ] ); diff --git a/js/settings.js b/js/settings.js index 0a42eaf..a0f6b14 100644 --- a/js/settings.js +++ b/js/settings.js @@ -58,6 +58,40 @@ user_sql.adminSettingsUI = function () { }); }; + var cryptoParams = function () { + var cryptoChanged = function () { + var div = $("#opt-crypto_params"); + div.empty(); + + var cryptoClass = $("#opt-crypto_class").val(); + $.get(OC.generateUrl("/apps/user_sql/settings/crypto/params"), cryptoClass, function (data) { + if (data.status === "success") { + for (var index = 0, length = data.data.length; index < length; ++index) { + div.append("
"); + } + } + }, "json"); + }; + $("#opt-crypto_class").change(function () { + cryptoChanged(); + }); + cryptoChanged(); + }; + $("#user_sql-db_connection_verify").click(function (event) { return click(event, "/apps/user_sql/settings/db/verify"); }); @@ -89,6 +123,8 @@ user_sql.adminSettingsUI = function () { "#db-table-group-column-admin, #db-table-group-column-name, #db-table-group-column-gid", "/apps/user_sql/settings/autocomplete/table/group" ); + + cryptoParams(); } }; @@ -96,4 +132,4 @@ $(document).ready(function () { if ($(form_id)) { user_sql.adminSettingsUI(); } -}); \ No newline at end of file +}); diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index a192daf..a590a08 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -367,4 +367,36 @@ class SettingsController extends Controller return $columns; } + + /** + * TODO + * + * @return array TODO + */ + public function cryptoParams() + { + // TODO implement + // TODO add current values + return [ + "status" => "success", + "data" => [ + [ + "name" => "memoryCost", + "visible_name" => "Memory cost (KiB)", + "default" => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, + "min" => 1, "max" => 1048576 + ], + [ + "name" => "timeCost", "visible_name" => "Time cost", + "default" => PASSWORD_ARGON2_DEFAULT_TIME_COST, "min" => 1, + "max" => 1024 + ], + [ + "name" => "threads", "visible_name" => "Threads", + "default" => PASSWORD_ARGON2_DEFAULT_THREADS, "min" => 1, + "max" => 1024 + ] + ] + ]; + } } From 5045c7d931ad1fb13b948993166ade6a39602c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Mon, 24 Dec 2018 14:47:55 +0100 Subject: [PATCH 09/20] Setting crypto params from admin panel pt II --- css/settings.css | 9 ++++++++- js/settings.js | 6 ++++-- lib/Controller/SettingsController.php | 14 +++++++------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/css/settings.css b/css/settings.css index 33f454a..61f1a41 100644 --- a/css/settings.css +++ b/css/settings.css @@ -55,4 +55,11 @@ #user_sql .msg.waiting { background-color: #ff8f00; color: #fff; -} \ No newline at end of file +} + +#user_sql .loading { + display: inline-block; + height: 32px; + margin: 5px 0; + width: 32px; +} diff --git a/js/settings.js b/js/settings.js index a0f6b14..52e4d38 100644 --- a/js/settings.js +++ b/js/settings.js @@ -62,15 +62,17 @@ user_sql.adminSettingsUI = function () { var cryptoChanged = function () { var div = $("#opt-crypto_params"); div.empty(); + div.append(""); var cryptoClass = $("#opt-crypto_class").val(); $.get(OC.generateUrl("/apps/user_sql/settings/crypto/params"), cryptoClass, function (data) { + div.empty(); if (data.status === "success") { for (var index = 0, length = data.data.length; index < length; ++index) { div.append("
"); } } diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index a590a08..2beb36c 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -375,25 +375,25 @@ class SettingsController extends Controller */ public function cryptoParams() { + sleep(3); // TODO implement // TODO add current values return [ "status" => "success", "data" => [ [ - "name" => "memoryCost", - "visible_name" => "Memory cost (KiB)", - "default" => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, + "name" => "Memory cost (KiB)", + "value" => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, "min" => 1, "max" => 1048576 ], [ - "name" => "timeCost", "visible_name" => "Time cost", - "default" => PASSWORD_ARGON2_DEFAULT_TIME_COST, "min" => 1, + "name" => "Time cost", + "value" => PASSWORD_ARGON2_DEFAULT_TIME_COST, "min" => 1, "max" => 1024 ], [ - "name" => "threads", "visible_name" => "Threads", - "default" => PASSWORD_ARGON2_DEFAULT_THREADS, "min" => 1, + "name" => "Threads", + "value" => PASSWORD_ARGON2_DEFAULT_THREADS, "min" => 1, "max" => 1024 ] ] From 93e769bfe52d303a33647582dcf136453fedd5b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Mon, 24 Dec 2018 15:28:05 +0100 Subject: [PATCH 10/20] Dedicated class for crypto parameters --- lib/Crypto/CryptArgon2.php | 21 +++++------ lib/Crypto/CryptBlowfish.php | 8 +--- lib/Crypto/CryptExtendedDES.php | 8 +--- lib/Crypto/CryptSHA256.php | 8 +--- lib/Crypto/CryptSHA512.php | 8 +--- lib/Crypto/IPasswordAlgorithm.php | 3 +- lib/Crypto/Phpass.php | 8 +--- lib/Model/CryptoParam.php | 63 +++++++++++++++++++++++++++++++ 8 files changed, 83 insertions(+), 44 deletions(-) create mode 100644 lib/Model/CryptoParam.php diff --git a/lib/Crypto/CryptArgon2.php b/lib/Crypto/CryptArgon2.php index 3c198d4..a1a22e3 100644 --- a/lib/Crypto/CryptArgon2.php +++ b/lib/Crypto/CryptArgon2.php @@ -21,6 +21,7 @@ namespace OCA\UserSQL\Crypto; +use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** @@ -106,18 +107,14 @@ class CryptArgon2 extends AbstractAlgorithm public function configuration() { return [ - [ - "name" => "memoryCost", "visible_name" => "Memory cost (KiB)", - "default" => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, "min" => 1, "max" => 1048576 - ], - [ - "name" => "timeCost", "visible_name" => "Time cost", - "default" => PASSWORD_ARGON2_DEFAULT_TIME_COST, "min" => 1, "max" => 1024 - ], - [ - "name" => "threads", "visible_name" => "Threads", - "default" => PASSWORD_ARGON2_DEFAULT_THREADS, "min" => 1, "max" => 1024 - ] + new CryptoParam( + "Memory cost (KiB)", PASSWORD_ARGON2_DEFAULT_MEMORY_COST, 1, + 1048576 + ), + new CryptoParam( + "Time cost", PASSWORD_ARGON2_DEFAULT_TIME_COST, 1, 1024 + ), + new CryptoParam("Threads", PASSWORD_ARGON2_DEFAULT_THREADS, 1, 1024) ]; } diff --git a/lib/Crypto/CryptBlowfish.php b/lib/Crypto/CryptBlowfish.php index 3d48ade..a76d187 100644 --- a/lib/Crypto/CryptBlowfish.php +++ b/lib/Crypto/CryptBlowfish.php @@ -21,6 +21,7 @@ namespace OCA\UserSQL\Crypto; +use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** @@ -72,12 +73,7 @@ class CryptBlowfish extends AbstractAlgorithm */ public function configuration() { - return [ - [ - "name" => "cost", "visible_name" => "Cost", "default" => 10, - "min" => 4, "max" => 31 - ] - ]; + return [new CryptoParam("Cost", 10, 4, 31)]; } /** diff --git a/lib/Crypto/CryptExtendedDES.php b/lib/Crypto/CryptExtendedDES.php index 235e563..6bd2f30 100644 --- a/lib/Crypto/CryptExtendedDES.php +++ b/lib/Crypto/CryptExtendedDES.php @@ -21,6 +21,7 @@ namespace OCA\UserSQL\Crypto; +use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** @@ -53,12 +54,7 @@ class CryptExtendedDES extends AbstractCrypt */ public function configuration() { - return [ - [ - "name" => "iterations", "visible_name" => "Iterations", "default" => 1000, - "min" => 0, "max" => 16777215 - ] - ]; + return [new CryptoParam("Iterations", 1000, 0, 16777215)]; } /** diff --git a/lib/Crypto/CryptSHA256.php b/lib/Crypto/CryptSHA256.php index 75515eb..72a372d 100644 --- a/lib/Crypto/CryptSHA256.php +++ b/lib/Crypto/CryptSHA256.php @@ -21,6 +21,7 @@ namespace OCA\UserSQL\Crypto; +use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** @@ -54,12 +55,7 @@ class CryptSHA256 extends AbstractCrypt */ public function configuration() { - return [ - [ - "name" => "rounds", "visible_name" => "Rounds", "default" => 5000, - "min" => 1000, "max" => 999999999 - ] - ]; + return [new CryptoParam("Rounds", 5000, 1000, 999999999)]; } /** diff --git a/lib/Crypto/CryptSHA512.php b/lib/Crypto/CryptSHA512.php index b638175..2cc9a33 100644 --- a/lib/Crypto/CryptSHA512.php +++ b/lib/Crypto/CryptSHA512.php @@ -21,6 +21,7 @@ namespace OCA\UserSQL\Crypto; +use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** @@ -54,12 +55,7 @@ class CryptSHA512 extends AbstractCrypt */ public function configuration() { - return [ - [ - "name" => "rounds", "visible_name" => "Rounds", "default" => 5000, - "min" => 1000, "max" => 999999999 - ] - ]; + return [new CryptoParam("Rounds", 5000, 1000, 999999999)]; } /** diff --git a/lib/Crypto/IPasswordAlgorithm.php b/lib/Crypto/IPasswordAlgorithm.php index 5650c17..54c70b1 100644 --- a/lib/Crypto/IPasswordAlgorithm.php +++ b/lib/Crypto/IPasswordAlgorithm.php @@ -61,8 +61,7 @@ interface IPasswordAlgorithm /** * Configuration for the algorithm. - * The return array should contain entries which define keys: - * name, visible_name, default, min, max. + * The return array should contain entries of class CryptoParam * * @return array The configuration array. */ diff --git a/lib/Crypto/Phpass.php b/lib/Crypto/Phpass.php index 3693a6e..b038d3f 100644 --- a/lib/Crypto/Phpass.php +++ b/lib/Crypto/Phpass.php @@ -21,6 +21,7 @@ namespace OCA\UserSQL\Crypto; +use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** @@ -160,12 +161,7 @@ class Phpass extends AbstractAlgorithm */ public function configuration() { - return [ - [ - "name" => "iterations", "visible_name" => "Iterations (log2)", - "default" => 8, "min" => 4, "max" => 31 - ] - ]; + return [new CryptoParam("Iterations (log2)", 8, 4, 31)]; } /** diff --git a/lib/Model/CryptoParam.php b/lib/Model/CryptoParam.php new file mode 100644 index 0000000..81a24fc --- /dev/null +++ b/lib/Model/CryptoParam.php @@ -0,0 +1,63 @@ + + * @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 . + */ + +namespace OCA\UserSQL\Model; + +/** + * A parameter of a hash algorithm. + * + * @author Marcin Łojewski + */ +class CryptoParam +{ + /** + * @var string Parameter name. + */ + public $name; + /** + * @var int Parameter default value. + */ + public $value; + /** + * @var int Minimal value for parameter. + */ + public $min; + /** + * @var int Maximum value for parameter. + */ + public $max; + + /** + * Class constructor. + * + * @param $name string Parameter name. + * @param $value int Parameter default value. + * @param $min int Minimal value for parameter. + * @param $max int Maximum value for parameter. + */ + public function __construct($name, $value, $min, $max) + { + $this->name = $name; + $this->value = $value; + $this->min = $min; + $this->max = $max; + } +} From ac3e386915c8f9a9f36e600dcd26abe193a4a2ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Mon, 24 Dec 2018 21:30:44 +0100 Subject: [PATCH 11/20] JS + CSS --- css/settings.css | 29 ++++++++++++++++++++------ js/settings.js | 50 ++++++++++++++++++++++----------------------- templates/admin.php | 5 ++++- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/css/settings.css b/css/settings.css index 61f1a41..097dd56 100644 --- a/css/settings.css +++ b/css/settings.css @@ -33,6 +33,23 @@ float: right; } +#user_sql .main .inner-fieldset { + border-bottom: 1px solid var(--color-border); + border-top: 1px solid var(--color-border); + margin: 16px 0; + padding: 8px 32px; +} + +#user_sql .main .inner-fieldset > legend { + background-color: var(--color-background-dark); + border-radius: var(--border-radius-pill); + border: 1px solid var(--color-border-dark); + color: var(--color-text-lighter); + font-size: 11px; + font-weight: bold; + padding: 3px 6px; +} + #user_sql .msg { left: 0; padding: 3px; @@ -43,18 +60,18 @@ } #user_sql .msg.error { - background-color: #d2322d; - color: #fff; + background-color: var(--color-error); + color: var(--color-primary-text); } #user_sql .msg.success { - background-color: #47a447; - color: #fff; + background-color: var(--color-success); + color: var(--color-primary-text); } #user_sql .msg.waiting { - background-color: #ff8f00; - color: #fff; + background-color: var(--color-warning); + color: var(--color-primary-text); } #user_sql .loading { diff --git a/js/settings.js b/js/settings.js index 52e4d38..dbe55d7 100644 --- a/js/settings.js +++ b/js/settings.js @@ -60,33 +60,33 @@ user_sql.adminSettingsUI = function () { var cryptoParams = function () { var cryptoChanged = function () { - var div = $("#opt-crypto_params"); - div.empty(); - div.append(""); + var content = $("#opt-crypto_params_content"); + var loading = $("#opt-crypto_params_loading"); - var cryptoClass = $("#opt-crypto_class").val(); - $.get(OC.generateUrl("/apps/user_sql/settings/crypto/params"), cryptoClass, function (data) { - div.empty(); - if (data.status === "success") { - for (var index = 0, length = data.data.length; index < length; ++index) { - div.append("
"); + content.hide(); + loading.show(); + + $.get(OC.generateUrl("/apps/user_sql/settings/crypto/params"), {cryptoClass: $("#opt-crypto_class").val()}, + function (data) { + content.empty(); + loading.hide(); + + if (data.status === "success") { + if (data.data.length > 0) { + content.append("" + $("#opt-crypto_class option:selected").text() + "") + } + for (var index = 0, length = data.data.length; index < length; ++index) { + content.append("
"); + content.show(); + } } - } - }, "json"); + }, "json"); }; $("#opt-crypto_class").change(function () { cryptoChanged(); diff --git a/templates/admin.php b/templates/admin.php index 2bac565..f5fcce8 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -132,7 +132,10 @@ function print_select_options( } print_select_options($l, "opt-crypto_class", "Hash algorithm", $hashes, $_["opt.crypto_class"]); ?> -
+ + "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_["opt.email_sync"]); print_select_options($l, "opt-quota_sync", "Quota sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_["opt.quota_sync"]); From 04e06bf3b53ff47a736bf6c23e6ffd622f5bc812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Mon, 24 Dec 2018 21:43:55 +0100 Subject: [PATCH 12/20] No legend --- css/settings.css | 14 ++------------ js/settings.js | 3 --- templates/admin.php | 9 ++++++--- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/css/settings.css b/css/settings.css index 097dd56..9fae0e2 100644 --- a/css/settings.css +++ b/css/settings.css @@ -36,18 +36,8 @@ #user_sql .main .inner-fieldset { border-bottom: 1px solid var(--color-border); border-top: 1px solid var(--color-border); - margin: 16px 0; - padding: 8px 32px; -} - -#user_sql .main .inner-fieldset > legend { - background-color: var(--color-background-dark); - border-radius: var(--border-radius-pill); - border: 1px solid var(--color-border-dark); - color: var(--color-text-lighter); - font-size: 11px; - font-weight: bold; - padding: 3px 6px; + margin: 8px 0; + padding: 8px 0 8px 16px; } #user_sql .msg { diff --git a/js/settings.js b/js/settings.js index dbe55d7..979770b 100644 --- a/js/settings.js +++ b/js/settings.js @@ -72,9 +72,6 @@ user_sql.adminSettingsUI = function () { loading.hide(); if (data.status === "success") { - if (data.data.length > 0) { - content.append("" + $("#opt-crypto_class option:selected").text() + "") - } for (var index = 0, length = data.data.length; index < length; ++index) { content.append("
From d6150f9505ee37c803f6f4d3c00733d9bf9b8978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Mon, 24 Dec 2018 23:46:30 +0100 Subject: [PATCH 13/20] Getting crypto parameters --- lib/Constant/Opt.php | 3 ++ lib/Controller/SettingsController.php | 65 ++++++++++++++++----------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lib/Constant/Opt.php b/lib/Constant/Opt.php index 6cdc6c2..beb8e21 100644 --- a/lib/Constant/Opt.php +++ b/lib/Constant/Opt.php @@ -31,6 +31,9 @@ final class Opt const APPEND_SALT = "opt.append_salt"; const CASE_INSENSITIVE_USERNAME = "opt.case_insensitive_username"; const CRYPTO_CLASS = "opt.crypto_class"; + const CRYPTO_PARAM_0 = "opt.crypto_param_0"; + const CRYPTO_PARAM_1 = "opt.crypto_param_1"; + const CRYPTO_PARAM_2 = "opt.crypto_param_2"; const EMAIL_SYNC = "opt.email_sync"; const HOME_LOCATION = "opt.home_location"; const HOME_MODE = "opt.home_mode"; diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 2beb36c..5532f23 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -28,12 +28,16 @@ use OC\DB\Connection; use OC\DB\ConnectionFactory; use OCA\UserSQL\Cache; use OCA\UserSQL\Constant\App; +use OCA\UserSQL\Constant\Opt; +use OCA\UserSQL\Crypto\IPasswordAlgorithm; use OCA\UserSQL\Platform\PlatformFactory; use OCA\UserSQL\Properties; use OCP\AppFramework\Controller; use OCP\IL10N; use OCP\ILogger; use OCP\IRequest; +use ReflectionClass; +use ReflectionException; /** * The settings controller. @@ -72,7 +76,8 @@ class SettingsController extends Controller public function __construct( $appName, IRequest $request, ILogger $logger, IL10N $localization, Properties $properties, Cache $cache - ) { + ) + { parent::__construct($appName, $request); $this->appName = $appName; $this->logger = $logger; @@ -369,34 +374,42 @@ class SettingsController extends Controller } /** - * TODO + * Get parameters for a password algorithm. * - * @return array TODO + * @return array Password algorithm parameters. + * @throws ReflectionException Whenever Opt class cannot be initiated. */ public function cryptoParams() { - sleep(3); - // TODO implement - // TODO add current values - return [ - "status" => "success", - "data" => [ - [ - "name" => "Memory cost (KiB)", - "value" => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, - "min" => 1, "max" => 1048576 - ], - [ - "name" => "Time cost", - "value" => PASSWORD_ARGON2_DEFAULT_TIME_COST, "min" => 1, - "max" => 1024 - ], - [ - "name" => "Threads", - "value" => PASSWORD_ARGON2_DEFAULT_THREADS, "min" => 1, - "max" => 1024 - ] - ] - ]; + $this->logger->debug( + "Entering cryptoParams()", ["app" => $this->appName] + ); + + /** + * @var $passwordAlgorithm IPasswordAlgorithm + */ + $cryptoClass = $this->request->getParam("cryptoClass"); + $passwordAlgorithm = new $cryptoClass($this->localization); + $configuration = $passwordAlgorithm->configuration(); + + if ($cryptoClass === $this->properties[Opt::CRYPTO_CLASS]) { + foreach ($configuration as $key => $value) { + $opt = new ReflectionClass("OCA\UserSQL\Constant\Opt"); + $param = $this->properties[$opt->getConstant( + "CRYPTO_PARAM_" . $key + )]; + + if (!empty($param)) { + $value->value = $param; + } + } + } + + $this->logger->debug( + "Returning cryptoParams(): count(" . count($configuration) . ")", + ["app" => $this->appName] + ); + + return ["status" => "success", "data" => (array)$configuration]; } } From a3a2a90d875f5549f0a331eb0bd654b33a907aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Mon, 24 Dec 2018 23:51:05 +0100 Subject: [PATCH 14/20] Move CryptoParam to different namespace --- lib/Crypto/CryptArgon2.php | 1 - lib/Crypto/CryptBlowfish.php | 1 - lib/Crypto/CryptExtendedDES.php | 1 - lib/Crypto/CryptSHA256.php | 1 - lib/Crypto/CryptSHA512.php | 1 - lib/{Model => Crypto}/CryptoParam.php | 2 +- lib/Crypto/Phpass.php | 1 - 7 files changed, 1 insertion(+), 7 deletions(-) rename lib/{Model => Crypto}/CryptoParam.php (98%) diff --git a/lib/Crypto/CryptArgon2.php b/lib/Crypto/CryptArgon2.php index a1a22e3..ddbfe0a 100644 --- a/lib/Crypto/CryptArgon2.php +++ b/lib/Crypto/CryptArgon2.php @@ -21,7 +21,6 @@ namespace OCA\UserSQL\Crypto; -use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** diff --git a/lib/Crypto/CryptBlowfish.php b/lib/Crypto/CryptBlowfish.php index a76d187..fb9e28b 100644 --- a/lib/Crypto/CryptBlowfish.php +++ b/lib/Crypto/CryptBlowfish.php @@ -21,7 +21,6 @@ namespace OCA\UserSQL\Crypto; -use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** diff --git a/lib/Crypto/CryptExtendedDES.php b/lib/Crypto/CryptExtendedDES.php index 6bd2f30..8cde30a 100644 --- a/lib/Crypto/CryptExtendedDES.php +++ b/lib/Crypto/CryptExtendedDES.php @@ -21,7 +21,6 @@ namespace OCA\UserSQL\Crypto; -use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** diff --git a/lib/Crypto/CryptSHA256.php b/lib/Crypto/CryptSHA256.php index 72a372d..91063ef 100644 --- a/lib/Crypto/CryptSHA256.php +++ b/lib/Crypto/CryptSHA256.php @@ -21,7 +21,6 @@ namespace OCA\UserSQL\Crypto; -use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** diff --git a/lib/Crypto/CryptSHA512.php b/lib/Crypto/CryptSHA512.php index 2cc9a33..1cafee5 100644 --- a/lib/Crypto/CryptSHA512.php +++ b/lib/Crypto/CryptSHA512.php @@ -21,7 +21,6 @@ namespace OCA\UserSQL\Crypto; -use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** diff --git a/lib/Model/CryptoParam.php b/lib/Crypto/CryptoParam.php similarity index 98% rename from lib/Model/CryptoParam.php rename to lib/Crypto/CryptoParam.php index 81a24fc..d694cf2 100644 --- a/lib/Model/CryptoParam.php +++ b/lib/Crypto/CryptoParam.php @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -namespace OCA\UserSQL\Model; +namespace OCA\UserSQL\Crypto; /** * A parameter of a hash algorithm. diff --git a/lib/Crypto/Phpass.php b/lib/Crypto/Phpass.php index b038d3f..7edd728 100644 --- a/lib/Crypto/Phpass.php +++ b/lib/Crypto/Phpass.php @@ -21,7 +21,6 @@ namespace OCA\UserSQL\Crypto; -use OCA\UserSQL\Model\CryptoParam; use OCP\IL10N; /** From 7f84113bca305b16a8520dfc5baf66fa14e6106b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Tue, 25 Dec 2018 10:01:53 +0100 Subject: [PATCH 15/20] Handle 0s and 1s --- js/settings.js | 24 +++++++++++----- lib/Controller/SettingsController.php | 2 +- lib/Properties.php | 41 +++++++++++++++++++++------ 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/js/settings.js b/js/settings.js index 979770b..cf49ac5 100644 --- a/js/settings.js +++ b/js/settings.js @@ -73,13 +73,23 @@ user_sql.adminSettingsUI = function () { if (data.status === "success") { for (var index = 0, length = data.data.length; index < length; ++index) { - content.append("
"); + var param = $("
"); + var label = $("").attr({for: "opt-crypto_param_" + index}); + var title = $("").text(data.data[index]["name"]); + var input = $("").attr({ + type: "number", + id: "opt-crypto_param_" + index, + name: "opt-crypto_param_" + index, + step: 1, + min: data.data[index]["min"], + max: data.data[index]["max"], + value: data.data[index]["value"] + }); + + label.append(title); + param.append(label); + param.append(input); + content.append(param); content.show(); } } diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 5532f23..70de2f5 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -399,7 +399,7 @@ class SettingsController extends Controller "CRYPTO_PARAM_" . $key )]; - if (!empty($param)) { + if (!is_null($param)) { $value->value = $param; } } diff --git a/lib/Properties.php b/lib/Properties.php index b030b82..6e20ef8 100644 --- a/lib/Properties.php +++ b/lib/Properties.php @@ -70,7 +70,8 @@ class Properties implements \ArrayAccess */ public function __construct( $AppName, IConfig $config, ILogger $logger, Cache $cache - ) { + ) + { $this->appName = $AppName; $this->config = $config; $this->logger = $logger; @@ -99,10 +100,12 @@ class Properties implements \ArrayAccess foreach ($params as $param) { $value = $this->config->getAppValue($this->appName, $param, null); - if ($value === App::FALSE_VALUE) { - $value = false; - } elseif ($value === App::TRUE_VALUE) { - $value = true; + if ($this->isBooleanParam($param)) { + if ($value === App::FALSE_VALUE) { + $value = false; + } elseif ($value === App::TRUE_VALUE) { + $value = true; + } } $this->data[$param] = $value; @@ -116,6 +119,24 @@ class Properties implements \ArrayAccess ); } + /** + * Is given parameter a boolean parameter. + * + * @param $param string Parameter name. + * + * @return bool Is a boolean parameter. + */ + private function isBooleanParam($param) + { + return in_array( + $param, [ + Opt::APPEND_SALT, Opt::CASE_INSENSITIVE_USERNAME, + Opt::NAME_CHANGE, Opt::PASSWORD_CHANGE, Opt::PREPEND_SALT, + Opt::REVERSE_ACTIVE, Opt::USE_CACHE + ] + ); + } + /** * Return an array with all supported parameters. * @@ -186,10 +207,12 @@ class Properties implements \ArrayAccess { $this->config->setAppValue($this->appName, $offset, $value); - if ($value === App::FALSE_VALUE) { - $value = false; - } elseif ($value === App::TRUE_VALUE) { - $value = true; + if ($this->isBooleanParam($offset)) { + if ($value === App::FALSE_VALUE) { + $value = false; + } elseif ($value === App::TRUE_VALUE) { + $value = true; + } } $this->data[$offset] = $value; From 2da835b0171ccdd3efc196ef0428e1a8e123ebec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Wed, 26 Dec 2018 12:02:19 +0100 Subject: [PATCH 16/20] Crypto params validation --- lib/Controller/SettingsController.php | 61 ++++++++++++++++++++++++--- lib/Properties.php | 37 ++++++++-------- 2 files changed, 75 insertions(+), 23 deletions(-) diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 70de2f5..ef06b2d 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -198,6 +198,16 @@ class SettingsController extends Controller ]; } + if (!$this->validateCryptoParams()) { + return [ + "status" => "error", "data" => [ + "message" => $this->localization->t( + "Hash algorithm parameter is out of range." + ) + ] + ]; + } + foreach ($properties as $key => $value) { $reqValue = $this->request->getParam(str_replace(".", "-", $key)); $appValue = $this->properties[$key]; @@ -213,6 +223,9 @@ class SettingsController extends Controller "Property '$key' has been set to: " . $value, ["app" => $this->appName] ); + } elseif (!is_bool($appValue) && !isset($reqValue)) { + unset($this->properties[$key]); + } } @@ -230,6 +243,48 @@ class SettingsController extends Controller ]; } + /** + * Validate request crypto params. + * + * @return bool TRUE if crypto params are correct FALSE otherwise. + */ + private function validateCryptoParams() + { + $cryptoClass = $this->request->getParam("opt-crypto_class"); + $configuration = $this->cryptoClassConfiguration($cryptoClass); + + for ($i = 0; $i < count($configuration); ++$i) { + $reqParam = $this->request->getParam( + "opt-crypto_param_" . $i, null + ); + $cryptoParam = $configuration[$i]; + + if (is_null($reqParam) || $reqParam < $cryptoParam->min + || $reqParam > $cryptoParam->max + ) { + return false; + } + } + + return true; + } + + /** + * Get a crypto class configuration from request. + * + * @param $cryptoClass string Crypto class name. + * + * @return array A crypto class configuration. + */ + private function cryptoClassConfiguration($cryptoClass) + { + /** + * @var $passwordAlgorithm IPasswordAlgorithm + */ + $passwordAlgorithm = new $cryptoClass($this->localization); + return $passwordAlgorithm->configuration(); + } + /** * Clear the application cache memory. * @@ -385,12 +440,8 @@ class SettingsController extends Controller "Entering cryptoParams()", ["app" => $this->appName] ); - /** - * @var $passwordAlgorithm IPasswordAlgorithm - */ $cryptoClass = $this->request->getParam("cryptoClass"); - $passwordAlgorithm = new $cryptoClass($this->localization); - $configuration = $passwordAlgorithm->configuration(); + $configuration = $this->cryptoClassConfiguration($cryptoClass); if ($cryptoClass === $this->properties[Opt::CRYPTO_CLASS]) { foreach ($configuration as $key => $value) { diff --git a/lib/Properties.php b/lib/Properties.php index 6e20ef8..5affa85 100644 --- a/lib/Properties.php +++ b/lib/Properties.php @@ -119,24 +119,6 @@ class Properties implements \ArrayAccess ); } - /** - * Is given parameter a boolean parameter. - * - * @param $param string Parameter name. - * - * @return bool Is a boolean parameter. - */ - private function isBooleanParam($param) - { - return in_array( - $param, [ - Opt::APPEND_SALT, Opt::CASE_INSENSITIVE_USERNAME, - Opt::NAME_CHANGE, Opt::PASSWORD_CHANGE, Opt::PREPEND_SALT, - Opt::REVERSE_ACTIVE, Opt::USE_CACHE - ] - ); - } - /** * Return an array with all supported parameters. * @@ -162,6 +144,24 @@ class Properties implements \ArrayAccess return $params; } + /** + * Is given parameter a boolean parameter. + * + * @param $param string Parameter name. + * + * @return bool Is a boolean parameter. + */ + private function isBooleanParam($param) + { + return in_array( + $param, [ + Opt::APPEND_SALT, Opt::CASE_INSENSITIVE_USERNAME, + Opt::NAME_CHANGE, Opt::PASSWORD_CHANGE, Opt::PREPEND_SALT, + Opt::REVERSE_ACTIVE, Opt::USE_CACHE + ] + ); + } + /** * Store properties in the cache memory. */ @@ -229,6 +229,7 @@ class Properties implements \ArrayAccess */ public function offsetUnset($offset) { + $this->config->deleteAppValue($this->appName, $offset); unset($this->data[$offset]); } } From 3b586365a7fe12fc22850449df5194bc160576b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Wed, 26 Dec 2018 12:38:37 +0100 Subject: [PATCH 17/20] use crypto params --- lib/Backend/UserBackend.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Backend/UserBackend.php b/lib/Backend/UserBackend.php index 27927e4..7d910d9 100644 --- a/lib/Backend/UserBackend.php +++ b/lib/Backend/UserBackend.php @@ -343,7 +343,12 @@ final class UserBackend extends ABackend implements private function getPasswordAlgorithm() { $cryptoType = $this->properties[Opt::CRYPTO_CLASS]; - $passwordAlgorithm = new $cryptoType($this->localization); + $cryptoParam0 = $this->properties[Opt::CRYPTO_PARAM_0]; + $cryptoParam1 = $this->properties[Opt::CRYPTO_PARAM_1]; + $cryptoParam2 = $this->properties[Opt::CRYPTO_PARAM_2]; + $passwordAlgorithm = new $cryptoType( + $this->localization, $cryptoParam0, $cryptoParam1, $cryptoParam2 + ); if ($passwordAlgorithm === null) { $this->logger->error( From 8370f4b8d00d889e6a918c694ab4c315c1f437a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Wed, 26 Dec 2018 12:58:15 +0100 Subject: [PATCH 18/20] issue#86 Problem with "Provide avatar" field with user_sql 4.2.1 --- CHANGELOG.md | 1 + README.md | 1 + lib/Backend/UserBackend.php | 2 +- lib/Constant/Opt.php | 1 + templates/admin.php | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed22287..4334e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - Reverse active column option - Support for Nextcloud 16 +- Set default value for "provide avatar" option ## [4.2.1] - 2018-12-22 ### Fixed diff --git a/README.md b/README.md index 65cfb89..4eed489 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Name | Description | Details --- | --- | --- **Allow display name change** | With this option enabled user can change its display name. The display name change is propagated to the database. | Optional.
Default: false.
Requires: user *Display name* column. **Allow password change** | Can user change its password. The password change is propagated to the database. See [Hash algorithms](#hash-algorithms). | Optional.
Default: false. +**Allow providing avatar** | Can user provide its avatar. The value is used when column *Provide avatar* is not set. | Optional.
Default: false. **Case-insensitive username** | Whether user query should be case-sensitive or case-insensitive. | Optional.
Default: false. **Reverse active column** | Reverse value of active column in user table. | Optional.
Default: false. **Use cache** | Use database query results cache. The cache can be cleared any time with the *Clear cache* button click. | Optional.
Default: false. diff --git a/lib/Backend/UserBackend.php b/lib/Backend/UserBackend.php index 27927e4..b8c1a5d 100644 --- a/lib/Backend/UserBackend.php +++ b/lib/Backend/UserBackend.php @@ -555,7 +555,7 @@ final class UserBackend extends ABackend implements ); if (empty($this->properties[DB::USER_AVATAR_COLUMN])) { - return false; + return !empty($this->properties[Opt::PROVIDE_AVATAR]); } $user = $this->userRepository->findByUid($uid); diff --git a/lib/Constant/Opt.php b/lib/Constant/Opt.php index 6cdc6c2..94e9db5 100644 --- a/lib/Constant/Opt.php +++ b/lib/Constant/Opt.php @@ -37,6 +37,7 @@ final class Opt const NAME_CHANGE = "opt.name_change"; const PASSWORD_CHANGE = "opt.password_change"; const PREPEND_SALT = "opt.prepend_salt"; + const PROVIDE_AVATAR = "opt.provide_avatar"; const QUOTA_SYNC = "opt.quota_sync"; const REVERSE_ACTIVE = "opt.reverse_active"; const USE_CACHE = "opt.use_cache"; diff --git a/templates/admin.php b/templates/admin.php index 0a5f042..d799b32 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -110,6 +110,7 @@ function print_select_options(
Date: Sun, 30 Dec 2018 20:43:19 +0100 Subject: [PATCH 19/20] Update merge --- CHANGELOG.md | 1 + README.md | 8 ++++---- lib/Properties.php | 5 ++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4334e2d..88a554c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Reverse active column option - Support for Nextcloud 16 - Set default value for "provide avatar" option +- Set hash algorithm parameters ## [4.2.1] - 2018-12-22 ### Fixed diff --git a/README.md b/README.md index 4eed489..5888a6d 100644 --- a/README.md +++ b/README.md @@ -188,12 +188,12 @@ Courier hexadecimal MD5 | No salt supported. | {MD5}X03MO1qnZdYdgyfeuILPmQ== Courier base64-encoded SHA1 | No salt supported. | {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g= Courier base64-encoded SHA256 | No salt supported. | {SHA256}XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg= Unix (Crypt) | See [crypt](http://php.net/manual/en/function.crypt.php). | $2y$10$5rsN1fmoSkaRy9bqhozAXOr0mn0QiVIfd2L04Bbk1Go9MjdvotwBq -Argon2 (Crypt) | Requires PHP >= 7.2.
Uses default parameters. See [password_hash](http://php.net/manual/en/function.password-hash.php). | $argon2i$v=19$m=1024,t=2,p=2$NnpSNlRNLlZobnJHUDh0Sw$oW5E1cfdPzLWfkTvQFUyzTR00R0aLwEdYwldcqW6Pmo -Blowfish (Crypt) | Uses default parameters. See [password_hash](http://php.net/manual/en/function.password-hash.php). | $2y$10$5rsN1fmoSkaRy9bqhozAXOr0mn0QiVIfd2L04Bbk1Go9MjdvotwBq +Argon2 (Crypt) | Requires PHP >= 7.2. See [password_hash](http://php.net/manual/en/function.password-hash.php). | $argon2i$v=19$m=1024,t=2,p=2$NnpSNlRNLlZobnJHUDh0Sw$oW5E1cfdPzLWfkTvQFUyzTR00R0aLwEdYwldcqW6Pmo +Blowfish (Crypt) | See [password_hash](http://php.net/manual/en/function.password-hash.php). | $2y$10$5rsN1fmoSkaRy9bqhozAXOr0mn0QiVIfd2L04Bbk1Go9MjdvotwBq Extended DES (Crypt) | | cDRpdxPmHpzS. MD5 (Crypt) | | $1$RzaFbNcU$u9adfTY/Q6za6nu0Ogrl1/ -SHA256 (Crypt) | Generates hash with 5000 rounds. | $5$rounds=5000$VIYD0iHkg7uY9SRc$v2XLS/9dvfFN84mzGvW9wxnVt9Xd/urXaaTkpW8EwD1 -SHA512 (Crypt) | Generates hash with 5000 rounds. | $6$rounds=5000$yH.Q0OL4qbCOUJ3q$Xry5EVFva3wKnfo8/ktrugmBd8tcl34NK6rXInv1HhmdSUNLEm0La9JnA57rqwQ.9/Bz513MD4tvmmISLUIHs/ +SHA256 (Crypt) | | $5$rounds=5000$VIYD0iHkg7uY9SRc$v2XLS/9dvfFN84mzGvW9wxnVt9Xd/urXaaTkpW8EwD1 +SHA512 (Crypt) | | $6$rounds=5000$yH.Q0OL4qbCOUJ3q$Xry5EVFva3wKnfo8/ktrugmBd8tcl34NK6rXInv1HhmdSUNLEm0La9JnA57rqwQ.9/Bz513MD4tvmmISLUIHs/ Standard DES (Crypt) | | yTBnb7ab/N072 Drupal 7 | See [phpass](http://www.openwall.com/phpass/). | $S$DC7eCpJQ3SUQtW4Bp.vKb2rpeaffi4iqk9OpYwJyEoSMsezn67Sl Joomla MD5 Encryption | Generates 32 chars salt. | 14d21b49b0f13e2acba962b6b0039edd:haJK0yTvBXTNMh76xwEw5RYEVpJsN8us diff --git a/lib/Properties.php b/lib/Properties.php index 5affa85..36413f5 100644 --- a/lib/Properties.php +++ b/lib/Properties.php @@ -70,8 +70,7 @@ class Properties implements \ArrayAccess */ public function __construct( $AppName, IConfig $config, ILogger $logger, Cache $cache - ) - { + ) { $this->appName = $AppName; $this->config = $config; $this->logger = $logger; @@ -157,7 +156,7 @@ class Properties implements \ArrayAccess $param, [ Opt::APPEND_SALT, Opt::CASE_INSENSITIVE_USERNAME, Opt::NAME_CHANGE, Opt::PASSWORD_CHANGE, Opt::PREPEND_SALT, - Opt::REVERSE_ACTIVE, Opt::USE_CACHE + Opt::PROVIDE_AVATAR, Opt::REVERSE_ACTIVE, Opt::USE_CACHE ] ); } From ee4918e8c2ac683ca7a5483666c40feb310043ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sun, 30 Dec 2018 20:47:06 +0100 Subject: [PATCH 20/20] Update version info --- CHANGELOG.md | 4 ++-- appinfo/info.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88a554c..4cedb58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [4.3.0] - 2018-12-30 ### Added - Reverse active column option - Support for Nextcloud 16 @@ -119,7 +119,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Supported version of ownCloud, Nextcloud: ownCloud 10, Nextcloud 12 -[Unreleased]: https://github.com/nextcloud/user_sql/compare/v4.2.1...develop +[4.3.0]: https://github.com/nextcloud/user_sql/compare/v4.2.1...v4.3.0 [4.2.1]: https://github.com/nextcloud/user_sql/compare/v4.2.0...v4.2.1 [4.2.0]: https://github.com/nextcloud/user_sql/compare/v4.1.0...v4.2.0 [4.1.0]: https://github.com/nextcloud/user_sql/compare/v4.0.1...v4.1.0 diff --git a/appinfo/info.xml b/appinfo/info.xml index ecb2963..0ee2286 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -8,7 +8,7 @@ Retrieve the users and groups info. Allow the users to change their passwords. Sync the users' email addresses with the addresses stored by Nextcloud. - 4.3.0-dev + 4.3.0 agpl Marcin Łojewski Andreas Böhler