tests(unit): fix RequireTwoFactorAuthenticationTest
This commit is contained in:
parent
d7d5da6beb
commit
ce7c913e18
5 changed files with 55 additions and 51 deletions
|
@ -50,9 +50,7 @@ class RequireTwoFactorAuthentication
|
||||||
// send them right through, nothing else needs to be checked.
|
// send them right through, nothing else needs to be checked.
|
||||||
//
|
//
|
||||||
// If the level is set as admin and the user is not an admin, pass them through as well.
|
// If the level is set as admin and the user is not an admin, pass them through as well.
|
||||||
if ($level === self::LEVEL_NONE || $user->has2FAEnabled()) {
|
if ($level === self::LEVEL_NONE || $user->has2FAEnabled() || ($level === self::LEVEL_ADMIN && !$user->root_admin)) {
|
||||||
return $next($request);
|
|
||||||
} elseif ($level === self::LEVEL_ADMIN && !$user->root_admin) {
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.0.2 || ^8.1 || ^8.2",
|
"php": "^8.1 || ^8.2",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
|
4
composer.lock
generated
4
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "1e13394cf95fb955fbf12cb9f71e215d",
|
"content-hash": "04a0ce5d940be3c570a4705b0d009641",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "aws/aws-crt-php",
|
"name": "aws/aws-crt-php",
|
||||||
|
@ -12074,7 +12074,7 @@
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.0.2 || ^8.1 || ^8.2",
|
"php": "^8.1 || ^8.2",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
|
|
@ -24,20 +24,16 @@ class SecurityKeyFactory extends Factory
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'uuid' => Uuid::uuid4()->toString(),
|
'uuid' => Uuid::uuid4()->toString(),
|
||||||
|
'user_id' => User::factory(),
|
||||||
'name' => $this->faker->word,
|
'name' => $this->faker->word,
|
||||||
'type' => 'public-key',
|
'type' => 'public-key',
|
||||||
'transports' => [],
|
'transports' => [],
|
||||||
'attestation_type' => 'none',
|
'attestation_type' => 'none',
|
||||||
'trust_path' => new EmptyTrustPath(),
|
'trust_path' => new EmptyTrustPath(),
|
||||||
|
'user_handle' => function (array $attributes) {
|
||||||
|
return User::find($attributes['user_id'])->uuid;
|
||||||
|
},
|
||||||
'counter' => 0,
|
'counter' => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withUser(User $user): self
|
|
||||||
{
|
|
||||||
return $this->state([
|
|
||||||
'user_id' => $user->id,
|
|
||||||
'user_handle' => $user->uuid,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
@ -39,6 +40,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertTrue($user->use_totp);
|
$this->assertTrue($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
@ -49,21 +51,21 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$middleware->handle($this->request, $this->getClosureAssertions());
|
$middleware->handle($this->request, $this->getClosureAssertions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNoRequirementUserWithWebauthn2fa()
|
public function testNoRequirementUserWithSecurityKey2fa()
|
||||||
{
|
{
|
||||||
// Disable the 2FA requirement
|
// Disable the 2FA requirement
|
||||||
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_NONE);
|
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_NONE);
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\User $user */
|
/** @var \Pterodactyl\Models\User $user */
|
||||||
$user = User::factory()
|
$user = User::factory()
|
||||||
->has(SecurityKey::factory()->count(1))
|
->make(['use_totp' => false])
|
||||||
->create(['use_totp' => false]);
|
->setRelation('securityKeys', SecurityKey::factory()->count(1)->make());
|
||||||
$this->setRequestUserModel($user);
|
$this->setRequestUserModel($user);
|
||||||
|
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
$this->assertNotEmpty($user->securityKeys);
|
$this->assertTrue($user->securityKeys->isNotEmpty());
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
@ -102,7 +104,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
$this->assertEmpty($user->securityKeys);
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
@ -123,6 +125,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertTrue($user->use_totp);
|
$this->assertTrue($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
@ -133,21 +136,21 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$middleware->handle($this->request, $this->getClosureAssertions());
|
$middleware->handle($this->request, $this->getClosureAssertions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAllRequirementRuserWithWebauthn2fa()
|
public function testAllRequirementUserWithSecurityKey2fa()
|
||||||
{
|
{
|
||||||
// Disable the 2FA requirement
|
// Disable the 2FA requirement
|
||||||
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_ALL);
|
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_ALL);
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\User $user */
|
/** @var \Pterodactyl\Models\User $user */
|
||||||
$user = User::factory()
|
$user = User::factory()
|
||||||
->has(SecurityKey::factory()->count(1))
|
->make(['use_totp' => false])
|
||||||
->create(['use_totp' => false]);
|
->setRelation('securityKeys', SecurityKey::factory()->count(1)->make());
|
||||||
$this->setRequestUserModel($user);
|
$this->setRequestUserModel($user);
|
||||||
|
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
$this->assertNotEmpty($user->securityKeys);
|
$this->assertTrue($user->securityKeys->isNotEmpty());
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
@ -184,6 +187,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
$this->assertFalse($user->root_admin);
|
$this->assertFalse($user->root_admin);
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
|
@ -207,6 +211,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
$this->assertTrue($user->root_admin);
|
$this->assertTrue($user->root_admin);
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
|
@ -228,6 +233,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertTrue($user->use_totp);
|
$this->assertTrue($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
$this->assertFalse($user->root_admin);
|
$this->assertFalse($user->root_admin);
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
|
@ -249,6 +255,7 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$this->assertTrue($user->use_totp);
|
$this->assertTrue($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isEmpty());
|
||||||
$this->assertTrue($user->root_admin);
|
$this->assertTrue($user->root_admin);
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
|
@ -260,45 +267,22 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$middleware->handle($this->request, $this->getClosureAssertions());
|
$middleware->handle($this->request, $this->getClosureAssertions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAdminRequirementUserWithWebauthn2fa()
|
public function testAdminRequirementUserWithSecurityKey2fa()
|
||||||
{
|
|
||||||
// Disable the 2FA requirement
|
|
||||||
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_ADMIN);
|
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\User $user */
|
|
||||||
$user = User::factory()->has(SecurityKey::factory()->count(1))->create(['use_totp' => false]);
|
|
||||||
$this->setRequestUserModel($user);
|
|
||||||
|
|
||||||
$this->assertFalse($user->use_totp);
|
|
||||||
$this->assertEmpty($user->totp_secret);
|
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
|
||||||
$this->assertFalse($user->root_admin);
|
|
||||||
$this->assertNotEmpty($user->securityKeys);
|
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
|
||||||
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
|
||||||
$this->request->shouldReceive('isJson')->withNoArgs()->andReturn(true);
|
|
||||||
|
|
||||||
/** @var \Pterodactyl\Http\Middleware\RequireTwoFactorAuthentication $controller */
|
|
||||||
$middleware = $this->app->make(RequireTwoFactorAuthentication::class);
|
|
||||||
$middleware->handle($this->request, $this->getClosureAssertions());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testAdminRequirementAdminUserWithWebauthn2fa()
|
|
||||||
{
|
{
|
||||||
// Disable the 2FA requirement
|
// Disable the 2FA requirement
|
||||||
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_ADMIN);
|
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_ADMIN);
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\User $user */
|
/** @var \Pterodactyl\Models\User $user */
|
||||||
$user = User::factory()
|
$user = User::factory()
|
||||||
->has(SecurityKey::factory()->count(1))
|
->make(['use_totp' => false])
|
||||||
->create(['use_totp' => false, 'root_admin' => true]);
|
->setRelation('securityKeys', SecurityKey::factory()->count(1)->make());
|
||||||
$this->setRequestUserModel($user);
|
$this->setRequestUserModel($user);
|
||||||
|
|
||||||
$this->assertFalse($user->use_totp);
|
$this->assertFalse($user->use_totp);
|
||||||
$this->assertEmpty($user->totp_secret);
|
$this->assertEmpty($user->totp_secret);
|
||||||
$this->assertEmpty($user->totp_authenticated_at);
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
$this->assertTrue($user->root_admin);
|
$this->assertFalse($user->root_admin);
|
||||||
|
$this->assertTrue($user->securityKeys->isNotEmpty());
|
||||||
$this->assertNotEmpty($user->securityKeys);
|
$this->assertNotEmpty($user->securityKeys);
|
||||||
|
|
||||||
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
|
@ -310,6 +294,32 @@ class RequireTwoFactorAuthenticationTest extends MiddlewareTestCase
|
||||||
$middleware->handle($this->request, $this->getClosureAssertions());
|
$middleware->handle($this->request, $this->getClosureAssertions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAdminRequirementAdminUserWithSecurityKey2fa()
|
||||||
|
{
|
||||||
|
// Disable the 2FA requirement
|
||||||
|
config()->set('pterodactyl.auth.2fa_required', RequireTwoFactorAuthentication::LEVEL_ADMIN);
|
||||||
|
|
||||||
|
/** @var \Pterodactyl\Models\User $user */
|
||||||
|
$user = User::factory()
|
||||||
|
->make(['use_totp' => false, 'root_admin' => true])
|
||||||
|
->setRelation('securityKeys', SecurityKey::factory()->count(1)->make());
|
||||||
|
$this->setRequestUserModel($user);
|
||||||
|
|
||||||
|
$this->assertFalse($user->use_totp);
|
||||||
|
$this->assertEmpty($user->totp_secret);
|
||||||
|
$this->assertEmpty($user->totp_authenticated_at);
|
||||||
|
$this->assertTrue($user->securityKeys->isNotEmpty());
|
||||||
|
$this->assertTrue($user->root_admin);
|
||||||
|
|
||||||
|
$this->request->shouldReceive('getRequestUri')->withNoArgs()->andReturn('/');
|
||||||
|
$this->request->shouldReceive('route->getName')->withNoArgs()->andReturn(null);
|
||||||
|
$this->request->shouldReceive('isJson')->withNoArgs()->andReturn(true);
|
||||||
|
|
||||||
|
/** @var \Pterodactyl\Http\Middleware\RequireTwoFactorAuthentication $controller */
|
||||||
|
$middleware = $this->app->make(RequireTwoFactorAuthentication::class);
|
||||||
|
$middleware->handle($this->request, $this->getClosureAssertions());
|
||||||
|
}
|
||||||
|
|
||||||
public function testAdminRequirementGuestUser()
|
public function testAdminRequirementGuestUser()
|
||||||
{
|
{
|
||||||
// Disable the 2FA requirement
|
// Disable the 2FA requirement
|
||||||
|
|
Loading…
Reference in a new issue