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:
Ferdinand Thiessen 2024-08-21 20:23:27 +02:00
parent f4f0316a55
commit 127cacdd19
No known key found for this signature in database
GPG key ID: 45FAE7268762B400
7 changed files with 143 additions and 6 deletions

View file

@ -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',

View file

@ -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',

View file

@ -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;
}
}

View file

@ -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;
}
}

View 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;
}

View file

@ -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());
}
}

View file

@ -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());
}
}