3e921fc07e
Integration Tests / Integration Tests (pull_request) Successful in 52s
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
154 lines
6.9 KiB
PHP
154 lines
6.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace KTXT\AuthenticationProviderPassword\Tests\Integration;
|
|
|
|
/**
|
|
* Exercises PasswordController's own routes, dispatched through the real
|
|
* HTTP kernel. Module routes are served under the "/m/{module_handle}"
|
|
* prefix applied by the router for every controller a module registers.
|
|
*/
|
|
class PasswordControllerTest extends IntegrationTestCase
|
|
{
|
|
private const BASE = '/m/authentication_provider_password';
|
|
|
|
public function testUpdateOwnPassword(): void
|
|
{
|
|
static::createUser('erin@example.test', 'Original-Pass-1!');
|
|
$accessToken = static::loginWithPassword('erin@example.test', 'Original-Pass-1!')['accessToken'];
|
|
|
|
$update = static::authorizedRequest($accessToken, 'POST', self::BASE . '/password/update', [
|
|
'current_password' => 'Original-Pass-1!',
|
|
'new_password' => 'Updated-Pass-1!',
|
|
]);
|
|
|
|
$this->assertSame(200, $update['status'], json_encode($update['body']));
|
|
$this->assertTrue($update['body']['success'] ?? false);
|
|
|
|
// Old password no longer works, new one does
|
|
$oldLogin = static::loginWithPassword('erin@example.test', 'Original-Pass-1!');
|
|
$this->assertSame('failed', $oldLogin['body']['status'] ?? null);
|
|
|
|
$newLogin = static::loginWithPassword('erin@example.test', 'Updated-Pass-1!');
|
|
$this->assertSame('success', $newLogin['body']['status'] ?? null);
|
|
}
|
|
|
|
public function testUpdatePasswordRejectsWrongCurrentPassword(): void
|
|
{
|
|
static::createUser('frank@example.test', 'Original-Pass-2!');
|
|
$accessToken = static::loginWithPassword('frank@example.test', 'Original-Pass-2!')['accessToken'];
|
|
|
|
$update = static::authorizedRequest($accessToken, 'POST', self::BASE . '/password/update', [
|
|
'current_password' => 'not-the-current-password',
|
|
'new_password' => 'Updated-Pass-2!',
|
|
]);
|
|
|
|
$this->assertSame(400, $update['status']);
|
|
|
|
// Original password still works
|
|
$login = static::loginWithPassword('frank@example.test', 'Original-Pass-2!');
|
|
$this->assertSame('success', $login['body']['status'] ?? null);
|
|
}
|
|
|
|
public function testUpdatePasswordRequiresAuthentication(): void
|
|
{
|
|
$update = static::request('POST', self::BASE . '/password/update', [
|
|
'current_password' => 'irrelevant',
|
|
'new_password' => 'irrelevant',
|
|
]);
|
|
|
|
$this->assertSame(401, $update['status']);
|
|
}
|
|
|
|
public function testAdminStatusReflectsEnrollment(): void
|
|
{
|
|
$roleId = static::createRoleWithPermissions(['authentication_provider_password.admin.view']);
|
|
$enrolledUid = static::createUser('grace@example.test', 'Grace-Pass-1!', [$roleId]);
|
|
$unenrolledUid = static::createUser('heidi@example.test');
|
|
$accessToken = static::loginWithPassword('grace@example.test', 'Grace-Pass-1!')['accessToken'];
|
|
|
|
$enrolledStatus = static::authorizedRequest($accessToken, 'POST', self::BASE . '/status', ['uid' => $enrolledUid]);
|
|
$unenrolledStatus = static::authorizedRequest($accessToken, 'POST', self::BASE . '/status', ['uid' => $unenrolledUid]);
|
|
|
|
$this->assertTrue($enrolledStatus['body']['enrolled'] ?? null);
|
|
$this->assertFalse($unenrolledStatus['body']['enrolled'] ?? null);
|
|
}
|
|
|
|
public function testAdminResetSetsAPasswordThatCanLogIn(): void
|
|
{
|
|
$uid = static::createUser('ivan@example.test');
|
|
// Bootstrap an authenticated actor with permission to call the admin endpoint
|
|
$roleId = static::createRoleWithPermissions(['authentication_provider_password.admin.manage']);
|
|
static::createUser('actor1@example.test', 'Actor-Pass-1!', [$roleId]);
|
|
$accessToken = static::loginWithPassword('actor1@example.test', 'Actor-Pass-1!')['accessToken'];
|
|
|
|
$reset = static::authorizedRequest($accessToken, 'POST', self::BASE . '/reset', [
|
|
'uid' => $uid,
|
|
'password' => 'Reset-By-Admin-1!',
|
|
]);
|
|
|
|
$this->assertSame(200, $reset['status'], json_encode($reset['body']));
|
|
$this->assertTrue($reset['body']['success'] ?? false);
|
|
|
|
$login = static::loginWithPassword('ivan@example.test', 'Reset-By-Admin-1!');
|
|
$this->assertSame('success', $login['body']['status'] ?? null);
|
|
}
|
|
|
|
public function testAdminResetRejectsShortPasswords(): void
|
|
{
|
|
$uid = static::createUser('judy@example.test');
|
|
$roleId = static::createRoleWithPermissions(['authentication_provider_password.admin.manage']);
|
|
static::createUser('actor2@example.test', 'Actor-Pass-2!', [$roleId]);
|
|
$accessToken = static::loginWithPassword('actor2@example.test', 'Actor-Pass-2!')['accessToken'];
|
|
|
|
$reset = static::authorizedRequest($accessToken, 'POST', self::BASE . '/reset', [
|
|
'uid' => $uid,
|
|
'password' => 'short',
|
|
]);
|
|
|
|
$this->assertSame(400, $reset['status']);
|
|
}
|
|
|
|
public function testAdminRemoveRevokesLogin(): void
|
|
{
|
|
$uid = static::createUser('kevin@example.test', 'Kevin-Pass-1!');
|
|
$roleId = static::createRoleWithPermissions(['authentication_provider_password.admin.manage']);
|
|
static::createUser('actor3@example.test', 'Actor-Pass-3!', [$roleId]);
|
|
$accessToken = static::loginWithPassword('actor3@example.test', 'Actor-Pass-3!')['accessToken'];
|
|
|
|
$remove = static::authorizedRequest($accessToken, 'POST', self::BASE . '/remove', ['uid' => $uid]);
|
|
$this->assertSame(200, $remove['status']);
|
|
$this->assertTrue($remove['body']['success'] ?? false);
|
|
|
|
$status = static::authorizedRequest($accessToken, 'POST', self::BASE . '/status', ['uid' => $uid]);
|
|
$this->assertFalse($status['body']['enrolled'] ?? null);
|
|
|
|
$login = static::loginWithPassword('kevin@example.test', 'Kevin-Pass-1!');
|
|
$this->assertSame('failed', $login['body']['status'] ?? null);
|
|
}
|
|
|
|
public function testAdminEndpointsRejectActorsWithoutPermission(): void
|
|
{
|
|
$targetUid = static::createUser('mallory-target@example.test', 'Mallory-Target-1!');
|
|
static::createUser('mallory@example.test', 'Mallory-Pass-1!');
|
|
$accessToken = static::loginWithPassword('mallory@example.test', 'Mallory-Pass-1!')['accessToken'];
|
|
|
|
$status = static::authorizedRequest($accessToken, 'POST', self::BASE . '/status', ['uid' => $targetUid]);
|
|
$this->assertSame(403, $status['status']);
|
|
|
|
$reset = static::authorizedRequest($accessToken, 'POST', self::BASE . '/reset', [
|
|
'uid' => $targetUid,
|
|
'password' => 'Should-Not-Apply-1!',
|
|
]);
|
|
$this->assertSame(403, $reset['status']);
|
|
|
|
$remove = static::authorizedRequest($accessToken, 'POST', self::BASE . '/remove', ['uid' => $targetUid]);
|
|
$this->assertSame(403, $remove['status']);
|
|
|
|
// None of the rejected calls should have taken effect
|
|
$login = static::loginWithPassword('mallory-target@example.test', 'Mallory-Target-1!');
|
|
$this->assertSame('success', $login['body']['status'] ?? null);
|
|
}
|
|
}
|