Skip to content

Commit dff2807

Browse files
committed
Merge branch 'release/v4.3.0'
2 parents 06c650b + ee4918e commit dff2807

22 files changed

+391
-31
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [4.3.0] - 2018-12-30
8+
### Added
9+
- Reverse active column option
10+
- Support for Nextcloud 16
11+
- Set default value for "provide avatar" option
12+
- Set hash algorithm parameters
13+
714
## [4.2.1] - 2018-12-22
815
### Fixed
916
- SQL error when same column names given in several tables
@@ -112,6 +119,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
112119
### Changed
113120
- Supported version of ownCloud, Nextcloud: ownCloud 10, Nextcloud 12
114121

122+
[4.3.0]: https://github.com/nextcloud/user_sql/compare/v4.2.1...v4.3.0
115123
[4.2.1]: https://github.com/nextcloud/user_sql/compare/v4.2.0...v4.2.1
116124
[4.2.0]: https://github.com/nextcloud/user_sql/compare/v4.1.0...v4.2.0
117125
[4.1.0]: https://github.com/nextcloud/user_sql/compare/v4.0.1...v4.1.0

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ Name | Description | Details
4949
--- | --- | ---
5050
**Allow display name change** | With this option enabled user can change its display name. The display name change is propagated to the database. | Optional.<br/>Default: false.<br/>Requires: user *Display name* column.
5151
**Allow password change** | Can user change its password. The password change is propagated to the database. See [Hash algorithms](#hash-algorithms). | Optional.<br/>Default: false.
52+
**Allow providing avatar** | Can user provide its avatar. The value is used when column *Provide avatar* is not set. | Optional.<br/>Default: false.
5253
**Case-insensitive username** | Whether user query should be case-sensitive or case-insensitive. | Optional.<br/>Default: false.
54+
**Reverse active column** | Reverse value of active column in user table. | Optional.<br/>Default: false.
5355
**Use cache** | Use database query results cache. The cache can be cleared any time with the *Clear cache* button click. | Optional.<br/>Default: false.
5456
**Hash algorithm** | How users passwords are stored in the database. See [Hash algorithms](#hash-algorithms). | Mandatory.
5557
**Email sync** | Sync e-mail address with the Nextcloud.<br/>- *None* - Disables this feature. This is the default option.<br/>- *Synchronise only once* - Copy the e-mail address to the Nextcloud preferences if its not set.<br/>- *Nextcloud always wins* - Always copy the e-mail address to the database. This updates the user table.<br/>- *SQL always wins* - Always copy the e-mail address to the Nextcloud preferences. | Optional.<br/>Default: *None*.<br/>Requires: user *Email* column.
@@ -186,12 +188,12 @@ Courier hexadecimal MD5 | No salt supported. | {MD5}X03MO1qnZdYdgyfeuILPmQ==
186188
Courier base64-encoded SHA1 | No salt supported. | {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
187189
Courier base64-encoded SHA256 | No salt supported. | {SHA256}XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=
188190
Unix (Crypt) | See [crypt](http://php.net/manual/en/function.crypt.php). | $2y$10$5rsN1fmoSkaRy9bqhozAXOr0mn0QiVIfd2L04Bbk1Go9MjdvotwBq
189-
Argon2 (Crypt) | Requires PHP >= 7.2.<br/>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
190-
Blowfish (Crypt) | Uses default parameters. See [password_hash](http://php.net/manual/en/function.password-hash.php). | $2y$10$5rsN1fmoSkaRy9bqhozAXOr0mn0QiVIfd2L04Bbk1Go9MjdvotwBq
191+
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
192+
Blowfish (Crypt) | See [password_hash](http://php.net/manual/en/function.password-hash.php). | $2y$10$5rsN1fmoSkaRy9bqhozAXOr0mn0QiVIfd2L04Bbk1Go9MjdvotwBq
191193
Extended DES (Crypt) | | cDRpdxPmHpzS.
192194
MD5 (Crypt) | | $1$RzaFbNcU$u9adfTY/Q6za6nu0Ogrl1/
193-
SHA256 (Crypt) | Generates hash with 5000 rounds. | $5$rounds=5000$VIYD0iHkg7uY9SRc$v2XLS/9dvfFN84mzGvW9wxnVt9Xd/urXaaTkpW8EwD1
194-
SHA512 (Crypt) | Generates hash with 5000 rounds. | $6$rounds=5000$yH.Q0OL4qbCOUJ3q$Xry5EVFva3wKnfo8/ktrugmBd8tcl34NK6rXInv1HhmdSUNLEm0La9JnA57rqwQ.9/Bz513MD4tvmmISLUIHs/
195+
SHA256 (Crypt) | | $5$rounds=5000$VIYD0iHkg7uY9SRc$v2XLS/9dvfFN84mzGvW9wxnVt9Xd/urXaaTkpW8EwD1
196+
SHA512 (Crypt) | | $6$rounds=5000$yH.Q0OL4qbCOUJ3q$Xry5EVFva3wKnfo8/ktrugmBd8tcl34NK6rXInv1HhmdSUNLEm0La9JnA57rqwQ.9/Bz513MD4tvmmISLUIHs/
195197
Standard DES (Crypt) | | yTBnb7ab/N072
196198
Drupal 7 | See [phpass](http://www.openwall.com/phpass/). | $S$DC7eCpJQ3SUQtW4Bp.vKb2rpeaffi4iqk9OpYwJyEoSMsezn67Sl
197199
Joomla MD5 Encryption | Generates 32 chars salt. | 14d21b49b0f13e2acba962b6b0039edd:haJK0yTvBXTNMh76xwEw5RYEVpJsN8us

appinfo/info.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Retrieve the users and groups info. Allow the users to change their passwords.
99
Sync the users' email addresses with the addresses stored by Nextcloud.
1010
</description>
11-
<version>4.2.1</version>
11+
<version>4.3.0</version>
1212
<licence>agpl</licence>
1313
<author>Marcin Łojewski</author>
1414
<author>Andreas Böhler</author>
@@ -22,7 +22,7 @@
2222
<category>auth</category>
2323
<dependencies>
2424
<php min-version="7.0"/>
25-
<nextcloud min-version="14" max-version="15"/>
25+
<nextcloud min-version="14" max-version="16"/>
2626
</dependencies>
2727
<settings>
2828
<admin>\OCA\UserSQL\Settings\Admin</admin>

appinfo/routes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@
6161
"url" => "/settings/autocomplete/table/group",
6262
"verb" => "POST"
6363
],
64+
[
65+
"name" => "settings#cryptoParams",
66+
"url" => "/settings/crypto/params",
67+
"verb" => "GET"
68+
],
6469
]
6570
]
6671
);

css/settings.css

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
float: right;
3434
}
3535

36+
#user_sql .main .inner-fieldset {
37+
border-bottom: 1px solid var(--color-border);
38+
border-top: 1px solid var(--color-border);
39+
margin: 8px 0;
40+
padding: 8px 0 8px 16px;
41+
}
42+
3643
#user_sql .msg {
3744
left: 0;
3845
padding: 3px;
@@ -43,16 +50,23 @@
4350
}
4451

4552
#user_sql .msg.error {
46-
background-color: #d2322d;
47-
color: #fff;
53+
background-color: var(--color-error);
54+
color: var(--color-primary-text);
4855
}
4956

5057
#user_sql .msg.success {
51-
background-color: #47a447;
52-
color: #fff;
58+
background-color: var(--color-success);
59+
color: var(--color-primary-text);
5360
}
5461

5562
#user_sql .msg.waiting {
56-
background-color: #ff8f00;
57-
color: #fff;
58-
}
63+
background-color: var(--color-warning);
64+
color: var(--color-primary-text);
65+
}
66+
67+
#user_sql .loading {
68+
display: inline-block;
69+
height: 32px;
70+
margin: 5px 0;
71+
width: 32px;
72+
}

js/settings.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,49 @@ user_sql.adminSettingsUI = function () {
5858
});
5959
};
6060

61+
var cryptoParams = function () {
62+
var cryptoChanged = function () {
63+
var content = $("#opt-crypto_params_content");
64+
var loading = $("#opt-crypto_params_loading");
65+
66+
content.hide();
67+
loading.show();
68+
69+
$.get(OC.generateUrl("/apps/user_sql/settings/crypto/params"), {cryptoClass: $("#opt-crypto_class").val()},
70+
function (data) {
71+
content.empty();
72+
loading.hide();
73+
74+
if (data.status === "success") {
75+
for (var index = 0, length = data.data.length; index < length; ++index) {
76+
var param = $("<div></div>");
77+
var label = $("<label></label>").attr({for: "opt-crypto_param_" + index});
78+
var title = $("<span></span>").text(data.data[index]["name"]);
79+
var input = $("<input/>").attr({
80+
type: "number",
81+
id: "opt-crypto_param_" + index,
82+
name: "opt-crypto_param_" + index,
83+
step: 1,
84+
min: data.data[index]["min"],
85+
max: data.data[index]["max"],
86+
value: data.data[index]["value"]
87+
});
88+
89+
label.append(title);
90+
param.append(label);
91+
param.append(input);
92+
content.append(param);
93+
content.show();
94+
}
95+
}
96+
}, "json");
97+
};
98+
$("#opt-crypto_class").change(function () {
99+
cryptoChanged();
100+
});
101+
cryptoChanged();
102+
};
103+
61104
$("#user_sql-db_connection_verify").click(function (event) {
62105
return click(event, "/apps/user_sql/settings/db/verify");
63106
});
@@ -89,11 +132,13 @@ user_sql.adminSettingsUI = function () {
89132
"#db-table-group-column-admin, #db-table-group-column-name, #db-table-group-column-gid",
90133
"/apps/user_sql/settings/autocomplete/table/group"
91134
);
135+
136+
cryptoParams();
92137
}
93138
};
94139

95140
$(document).ready(function () {
96141
if ($(form_id)) {
97142
user_sql.adminSettingsUI();
98143
}
99-
});
144+
});

lib/Backend/UserBackend.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,12 @@ public function checkPassword(string $uid, string $password)
343343
private function getPasswordAlgorithm()
344344
{
345345
$cryptoType = $this->properties[Opt::CRYPTO_CLASS];
346-
$passwordAlgorithm = new $cryptoType($this->localization);
346+
$cryptoParam0 = $this->properties[Opt::CRYPTO_PARAM_0];
347+
$cryptoParam1 = $this->properties[Opt::CRYPTO_PARAM_1];
348+
$cryptoParam2 = $this->properties[Opt::CRYPTO_PARAM_2];
349+
$passwordAlgorithm = new $cryptoType(
350+
$this->localization, $cryptoParam0, $cryptoParam1, $cryptoParam2
351+
);
347352

348353
if ($passwordAlgorithm === null) {
349354
$this->logger->error(
@@ -555,7 +560,7 @@ public function canChangeAvatar(string $uid): bool
555560
);
556561

557562
if (empty($this->properties[DB::USER_AVATAR_COLUMN])) {
558-
return false;
563+
return !empty($this->properties[Opt::PROVIDE_AVATAR]);
559564
}
560565

561566
$user = $this->userRepository->findByUid($uid);

lib/Constant/Opt.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ final class Opt
3131
const APPEND_SALT = "opt.append_salt";
3232
const CASE_INSENSITIVE_USERNAME = "opt.case_insensitive_username";
3333
const CRYPTO_CLASS = "opt.crypto_class";
34+
const CRYPTO_PARAM_0 = "opt.crypto_param_0";
35+
const CRYPTO_PARAM_1 = "opt.crypto_param_1";
36+
const CRYPTO_PARAM_2 = "opt.crypto_param_2";
3437
const EMAIL_SYNC = "opt.email_sync";
3538
const HOME_LOCATION = "opt.home_location";
3639
const HOME_MODE = "opt.home_mode";
3740
const NAME_CHANGE = "opt.name_change";
3841
const PASSWORD_CHANGE = "opt.password_change";
3942
const PREPEND_SALT = "opt.prepend_salt";
43+
const PROVIDE_AVATAR = "opt.provide_avatar";
4044
const QUOTA_SYNC = "opt.quota_sync";
45+
const REVERSE_ACTIVE = "opt.reverse_active";
4146
const USE_CACHE = "opt.use_cache";
4247
}

lib/Controller/SettingsController.php

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@
2828
use OC\DB\ConnectionFactory;
2929
use OCA\UserSQL\Cache;
3030
use OCA\UserSQL\Constant\App;
31+
use OCA\UserSQL\Constant\Opt;
32+
use OCA\UserSQL\Crypto\IPasswordAlgorithm;
3133
use OCA\UserSQL\Platform\PlatformFactory;
3234
use OCA\UserSQL\Properties;
3335
use OCP\AppFramework\Controller;
3436
use OCP\IL10N;
3537
use OCP\ILogger;
3638
use OCP\IRequest;
39+
use ReflectionClass;
40+
use ReflectionException;
3741

3842
/**
3943
* The settings controller.
@@ -72,7 +76,8 @@ class SettingsController extends Controller
7276
public function __construct(
7377
$appName, IRequest $request, ILogger $logger, IL10N $localization,
7478
Properties $properties, Cache $cache
75-
) {
79+
)
80+
{
7681
parent::__construct($appName, $request);
7782
$this->appName = $appName;
7883
$this->logger = $logger;
@@ -193,6 +198,16 @@ public function saveProperties()
193198
];
194199
}
195200

201+
if (!$this->validateCryptoParams()) {
202+
return [
203+
"status" => "error", "data" => [
204+
"message" => $this->localization->t(
205+
"Hash algorithm parameter is out of range."
206+
)
207+
]
208+
];
209+
}
210+
196211
foreach ($properties as $key => $value) {
197212
$reqValue = $this->request->getParam(str_replace(".", "-", $key));
198213
$appValue = $this->properties[$key];
@@ -208,6 +223,9 @@ public function saveProperties()
208223
"Property '$key' has been set to: " . $value,
209224
["app" => $this->appName]
210225
);
226+
} elseif (!is_bool($appValue) && !isset($reqValue)) {
227+
unset($this->properties[$key]);
228+
211229
}
212230
}
213231

@@ -225,6 +243,48 @@ public function saveProperties()
225243
];
226244
}
227245

246+
/**
247+
* Validate request crypto params.
248+
*
249+
* @return bool TRUE if crypto params are correct FALSE otherwise.
250+
*/
251+
private function validateCryptoParams()
252+
{
253+
$cryptoClass = $this->request->getParam("opt-crypto_class");
254+
$configuration = $this->cryptoClassConfiguration($cryptoClass);
255+
256+
for ($i = 0; $i < count($configuration); ++$i) {
257+
$reqParam = $this->request->getParam(
258+
"opt-crypto_param_" . $i, null
259+
);
260+
$cryptoParam = $configuration[$i];
261+
262+
if (is_null($reqParam) || $reqParam < $cryptoParam->min
263+
|| $reqParam > $cryptoParam->max
264+
) {
265+
return false;
266+
}
267+
}
268+
269+
return true;
270+
}
271+
272+
/**
273+
* Get a crypto class configuration from request.
274+
*
275+
* @param $cryptoClass string Crypto class name.
276+
*
277+
* @return array A crypto class configuration.
278+
*/
279+
private function cryptoClassConfiguration($cryptoClass)
280+
{
281+
/**
282+
* @var $passwordAlgorithm IPasswordAlgorithm
283+
*/
284+
$passwordAlgorithm = new $cryptoClass($this->localization);
285+
return $passwordAlgorithm->configuration();
286+
}
287+
228288
/**
229289
* Clear the application cache memory.
230290
*
@@ -367,4 +427,40 @@ public function groupTableAutocomplete()
367427

368428
return $columns;
369429
}
430+
431+
/**
432+
* Get parameters for a password algorithm.
433+
*
434+
* @return array Password algorithm parameters.
435+
* @throws ReflectionException Whenever Opt class cannot be initiated.
436+
*/
437+
public function cryptoParams()
438+
{
439+
$this->logger->debug(
440+
"Entering cryptoParams()", ["app" => $this->appName]
441+
);
442+
443+
$cryptoClass = $this->request->getParam("cryptoClass");
444+
$configuration = $this->cryptoClassConfiguration($cryptoClass);
445+
446+
if ($cryptoClass === $this->properties[Opt::CRYPTO_CLASS]) {
447+
foreach ($configuration as $key => $value) {
448+
$opt = new ReflectionClass("OCA\UserSQL\Constant\Opt");
449+
$param = $this->properties[$opt->getConstant(
450+
"CRYPTO_PARAM_" . $key
451+
)];
452+
453+
if (!is_null($param)) {
454+
$value->value = $param;
455+
}
456+
}
457+
}
458+
459+
$this->logger->debug(
460+
"Returning cryptoParams(): count(" . count($configuration) . ")",
461+
["app" => $this->appName]
462+
);
463+
464+
return ["status" => "success", "data" => (array)$configuration];
465+
}
370466
}

lib/Crypto/AbstractAlgorithm.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,12 @@ public function checkPassword($password, $dbHash, $salt = null)
7474
* @inheritdoc
7575
*/
7676
public abstract function getPasswordHash($password, $salt = null);
77+
78+
/**
79+
* @inheritdoc
80+
*/
81+
public function configuration()
82+
{
83+
return [];
84+
}
7785
}

0 commit comments

Comments
 (0)