mirror of
https://github.com/nextcloud/server.git
synced 2026-04-29 10:03:32 -04:00
feat(Security): Allow setting password context for validation and generation
Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de> Co-authored-by: Joas Schilling <213943+nickvergessen@users.noreply.github.com> Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
f4f0316a55
commit
127cacdd19
7 changed files with 143 additions and 6 deletions
|
|
@ -678,6 +678,7 @@ return array(
|
|||
'OCP\\Security\\Ip\\IFactory' => $baseDir . '/lib/public/Security/Ip/IFactory.php',
|
||||
'OCP\\Security\\Ip\\IRange' => $baseDir . '/lib/public/Security/Ip/IRange.php',
|
||||
'OCP\\Security\\Ip\\IRemoteAddress' => $baseDir . '/lib/public/Security/Ip/IRemoteAddress.php',
|
||||
'OCP\\Security\\PasswordContext' => $baseDir . '/lib/public/Security/PasswordContext.php',
|
||||
'OCP\\Security\\RateLimiting\\ILimiter' => $baseDir . '/lib/public/Security/RateLimiting/ILimiter.php',
|
||||
'OCP\\Security\\RateLimiting\\IRateLimitExceededException' => $baseDir . '/lib/public/Security/RateLimiting/IRateLimitExceededException.php',
|
||||
'OCP\\Security\\VerificationToken\\IVerificationToken' => $baseDir . '/lib/public/Security/VerificationToken/IVerificationToken.php',
|
||||
|
|
|
|||
|
|
@ -711,6 +711,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\Security\\Ip\\IFactory' => __DIR__ . '/../../..' . '/lib/public/Security/Ip/IFactory.php',
|
||||
'OCP\\Security\\Ip\\IRange' => __DIR__ . '/../../..' . '/lib/public/Security/Ip/IRange.php',
|
||||
'OCP\\Security\\Ip\\IRemoteAddress' => __DIR__ . '/../../..' . '/lib/public/Security/Ip/IRemoteAddress.php',
|
||||
'OCP\\Security\\PasswordContext' => __DIR__ . '/../../..' . '/lib/public/Security/PasswordContext.php',
|
||||
'OCP\\Security\\RateLimiting\\ILimiter' => __DIR__ . '/../../..' . '/lib/public/Security/RateLimiting/ILimiter.php',
|
||||
'OCP\\Security\\RateLimiting\\IRateLimitExceededException' => __DIR__ . '/../../..' . '/lib/public/Security/RateLimiting/IRateLimitExceededException.php',
|
||||
'OCP\\Security\\VerificationToken\\IVerificationToken' => __DIR__ . '/../../..' . '/lib/public/Security/VerificationToken/IVerificationToken.php',
|
||||
|
|
|
|||
|
|
@ -9,15 +9,34 @@ declare(strict_types=1);
|
|||
namespace OCP\Security\Events;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Security\PasswordContext;
|
||||
|
||||
/**
|
||||
* Event to request a secure password to be generated
|
||||
* @since 18.0.0
|
||||
*/
|
||||
class GenerateSecurePasswordEvent extends Event {
|
||||
/** @var null|string */
|
||||
private $password;
|
||||
private ?string $password;
|
||||
|
||||
/**
|
||||
* Request a secure password to be generated.
|
||||
*
|
||||
* By default passwords are generated for the user account context,
|
||||
* this can be adjusted by passing another `PasswordContext`.
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function __construct(
|
||||
private PasswordContext $context = PasswordContext::ACCOUNT,
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->password = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the generated password.
|
||||
*
|
||||
* If a password generator is registered and successfully generated a password
|
||||
* that password can get read back. Otherwise `null` is returned.
|
||||
* @since 18.0.0
|
||||
*/
|
||||
public function getPassword(): ?string {
|
||||
|
|
@ -25,9 +44,20 @@ class GenerateSecurePasswordEvent extends Event {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the generated password.
|
||||
*
|
||||
* This is used by password generators to set the generated password.
|
||||
* @since 18.0.0
|
||||
*/
|
||||
public function setPassword(string $password): void {
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context this password should generated for.
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function getContext(): PasswordContext {
|
||||
return $this->context;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,26 +9,41 @@ declare(strict_types=1);
|
|||
namespace OCP\Security\Events;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Security\PasswordContext;
|
||||
|
||||
/**
|
||||
* This event can be emitted to request a validation of a password.
|
||||
*
|
||||
* If a password policy app is installed and the password
|
||||
* is invalid, an `\OCP\HintException` will be thrown.
|
||||
* @since 18.0.0
|
||||
*/
|
||||
class ValidatePasswordPolicyEvent extends Event {
|
||||
/** @var string */
|
||||
private $password;
|
||||
|
||||
/**
|
||||
* @since 18.0.0
|
||||
* @since 31.0.0 - $context parameter added
|
||||
*/
|
||||
public function __construct(string $password) {
|
||||
public function __construct(
|
||||
private string $password,
|
||||
private PasswordContext $context = PasswordContext::ACCOUNT,
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password that should be validated.
|
||||
* @since 18.0.0
|
||||
*/
|
||||
public function getPassword(): string {
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context this password should validated for.
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function getContext(): PasswordContext {
|
||||
return $this->context;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
29
lib/public/Security/PasswordContext.php
Normal file
29
lib/public/Security/PasswordContext.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCP\Security;
|
||||
|
||||
/**
|
||||
* Define the context in which a password is used.
|
||||
* This allows setting a context for password validation and password generation.
|
||||
*
|
||||
* @package OCP\Security
|
||||
* @since 31.0.0
|
||||
*/
|
||||
enum PasswordContext {
|
||||
/**
|
||||
* Password used for an user account
|
||||
* @since 31.0.0
|
||||
*/
|
||||
case ACCOUNT;
|
||||
|
||||
/**
|
||||
* Password used for (public) shares
|
||||
* @since 31.0.0
|
||||
*/
|
||||
case SHARING;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Test\Security\Events;
|
||||
|
||||
use OCP\Security\Events\GenerateSecurePasswordEvent;
|
||||
use OCP\Security\PasswordContext;
|
||||
|
||||
class GenerateSecurePasswordEventTest extends \Test\TestCase {
|
||||
|
||||
public function testDefaultProperties() {
|
||||
$event = new GenerateSecurePasswordEvent();
|
||||
$this->assertNull($event->getPassword());
|
||||
$this->assertEquals(PasswordContext::ACCOUNT, $event->getContext());
|
||||
}
|
||||
|
||||
public function testSettingPassword() {
|
||||
$event = new GenerateSecurePasswordEvent();
|
||||
$event->setPassword('example');
|
||||
$this->assertEquals('example', $event->getPassword());
|
||||
}
|
||||
|
||||
public function testSettingContext() {
|
||||
$event = new GenerateSecurePasswordEvent(PasswordContext::SHARING);
|
||||
$this->assertEquals(PasswordContext::SHARING, $event->getContext());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace Test\Security\Events;
|
||||
|
||||
use OCP\Security\Events\ValidatePasswordPolicyEvent;
|
||||
use OCP\Security\PasswordContext;
|
||||
|
||||
class ValidatePasswordPolicyEventTest extends \Test\TestCase {
|
||||
|
||||
public function testDefaultProperties() {
|
||||
$password = 'example';
|
||||
$event = new ValidatePasswordPolicyEvent($password);
|
||||
$this->assertEquals($password, $event->getPassword());
|
||||
$this->assertEquals(PasswordContext::ACCOUNT, $event->getContext());
|
||||
}
|
||||
|
||||
public function testSettingContext() {
|
||||
$event = new ValidatePasswordPolicyEvent('example', PasswordContext::SHARING);
|
||||
$this->assertEquals(PasswordContext::SHARING, $event->getContext());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue