Merge branch 'QA_5_2'
Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
commit
ae27f1606f
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -42,7 +42,7 @@ jobs:
|
||||
apk add --update --no-cache \
|
||||
php\$V-cli php\$V-mysqli php\$V-session php\$V-mbstring php\$V-ctype php\$V-sodium \
|
||||
php\$V-iconv php\$V-xml php\$V-tokenizer php\$V-xmlwriter php\$V-simplexml \
|
||||
php\$V-dom php\$V-json php\$V-bz2 php\$V-curl php\$V-gd php\$V-zip \
|
||||
php\$V-dom php\$V-json php\$V-bz2 php\$V-curl php\$V-gd php\$V-zip php\$V-bcmath \
|
||||
musl-locales musl-locales-lang \
|
||||
gettext composer git && \
|
||||
composer config version "$(php -r "define('VERSION_SUFFIX', ''); require_once('src/Version.php'); echo \PhpMyAdmin\Version::VERSION;")" && \
|
||||
|
||||
@ -5467,7 +5467,7 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$identifier of static method PhpMyAdmin\\\\Util\\:\\:backquote\\(\\) expects string\\|Stringable\\|null, mixed given\\.$#"
|
||||
count: 4
|
||||
count: 3
|
||||
path: src/CreateAddField.php
|
||||
|
||||
-
|
||||
@ -5491,8 +5491,8 @@ parameters:
|
||||
path: src/CreateAddField.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$string of function trim expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
message: "#^Parameter \\#1 \\$string of function rtrim expects string, mixed given\\.$#"
|
||||
count: 2
|
||||
path: src/CreateAddField.php
|
||||
|
||||
-
|
||||
@ -15715,3 +15715,38 @@ parameters:
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/CBORDecoderTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) with 'attestation' and array\\{challenge\\: non\\-falsy\\-string, rp\\: array\\{name\\: string, id\\: string\\}, user\\: array\\{id\\: string, name\\: string, displayName\\: string\\}, pubKeyCredParams\\: non\\-empty\\-array\\<int, array\\{alg\\: int, type\\: 'public\\-key'\\}\\>, authenticatorSelection\\: array\\<string, string\\>, timeout\\: int\\<1, max\\>, attestation\\: non\\-empty\\-string\\} will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/CustomServerTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) with 'challenge' and array\\{challenge\\: non\\-empty\\-string, rp\\: array\\{name\\: string, id\\: string\\}, user\\: array\\{id\\: string, name\\: string, displayName\\: string\\}, pubKeyCredParams\\: array\\<int, array\\{alg\\: int, type\\: 'public\\-key'\\}\\>, authenticatorSelection\\: array\\<string, string\\>, timeout\\: int\\<1, max\\>, attestation\\: non\\-empty\\-string\\} will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/CustomServerTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) with 'pubKeyCredParams' and array\\{challenge\\: non\\-falsy\\-string, rp\\: array\\{name\\: string, id\\: string\\}, user\\: array\\{id\\: string, name\\: string, displayName\\: string\\}, pubKeyCredParams\\: array\\<int, array\\{alg\\: int, type\\: 'public\\-key'\\}\\>, authenticatorSelection\\: array\\<string, string\\>, timeout\\: int\\<1, max\\>, attestation\\: non\\-empty\\-string\\} will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/CustomServerTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNull\\(\\) with null will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/CustomServerTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) with 'attestation' and array\\{challenge\\: non\\-falsy\\-string, rp\\: array\\{name\\: string, id\\: string\\}, user\\: array\\{id\\: string, name\\: string, displayName\\: string\\}, pubKeyCredParams\\: non\\-empty\\-array\\<int, array\\{alg\\: int, type\\: 'public\\-key'\\}\\>, authenticatorSelection\\: array\\<string, string\\>, timeout\\: int\\<1, max\\>, attestation\\: non\\-empty\\-string\\} will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/WebauthnLibServerTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) with 'challenge' and array\\{challenge\\: non\\-empty\\-string, rp\\: array\\{name\\: string, id\\: string\\}, user\\: array\\{id\\: string, name\\: string, displayName\\: string\\}, pubKeyCredParams\\: array\\<int, array\\{alg\\: int, type\\: 'public\\-key'\\}\\>, authenticatorSelection\\: array\\<string, string\\>, timeout\\: int\\<1, max\\>, attestation\\: non\\-empty\\-string\\} will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/WebauthnLibServerTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) with 'pubKeyCredParams' and array\\{challenge\\: non\\-falsy\\-string, rp\\: array\\{name\\: string, id\\: string\\}, user\\: array\\{id\\: string, name\\: string, displayName\\: string\\}, pubKeyCredParams\\: array\\<int, array\\{alg\\: int, type\\: 'public\\-key'\\}\\>, authenticatorSelection\\: array\\<string, string\\>, timeout\\: int\\<1, max\\>, attestation\\: non\\-empty\\-string\\} will always evaluate to true\\.$#"
|
||||
count: 1
|
||||
path: tests/unit/WebAuthn/WebauthnLibServerTest.php
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ function addColumnToIndex (sourceArray, arrayIndex, indexChoice, colIndex): void
|
||||
columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val());
|
||||
});
|
||||
|
||||
displayName = '[' + columnNames.join(', ') + ']';
|
||||
displayName = '[' + columnNames.join(', ').trimRight() + ']';
|
||||
}
|
||||
|
||||
$.each(columns, function () {
|
||||
|
||||
@ -13,6 +13,7 @@ use function implode;
|
||||
use function in_array;
|
||||
use function json_decode;
|
||||
use function preg_replace;
|
||||
use function rtrim;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
@ -64,7 +65,7 @@ class CreateAddField
|
||||
}
|
||||
|
||||
$definition = $this->getStatementPrefix($isCreateTable) . Table::generateFieldSpec(
|
||||
trim($_POST['field_name'][$i]),
|
||||
rtrim($_POST['field_name'][$i]),
|
||||
$_POST['field_type'][$i],
|
||||
$_POST['field_length'][$i],
|
||||
$_POST['field_attribute'][$i],
|
||||
@ -153,7 +154,7 @@ class CreateAddField
|
||||
|
||||
$indexFields = [];
|
||||
foreach ($index['columns'] as $key => $column) {
|
||||
$indexFields[$key] = Util::backquote($_POST['field_name'][$column['col_index']]);
|
||||
$indexFields[$key] = Util::backquote(rtrim($_POST['field_name'][$column['col_index']]));
|
||||
if (! $column['size']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -120,8 +120,8 @@ final class CustomServer implements Server
|
||||
): array {
|
||||
try {
|
||||
$attestationCredential = $this->getAttestationCredential($attestationResponse);
|
||||
} catch (Throwable) {
|
||||
throw new WebAuthnException('Invalid authenticator response.');
|
||||
} catch (Throwable $exception) {
|
||||
throw new WebAuthnException('Invalid authenticator response.', (int) $exception->getCode(), $exception);
|
||||
}
|
||||
|
||||
$creationOptions = json_decode($credentialCreationOptions, true);
|
||||
|
||||
129
tests/unit/WebAuthn/CustomServerTest.php
Normal file
129
tests/unit/WebAuthn/CustomServerTest.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\WebAuthn;
|
||||
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\WebAuthn\CustomServer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Throwable;
|
||||
|
||||
use function hex2bin;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\WebAuthn\CustomServer
|
||||
* @covers \PhpMyAdmin\WebAuthn\CBORDecoder
|
||||
* @covers \PhpMyAdmin\WebAuthn\DataStream
|
||||
*/
|
||||
final class CustomServerTest extends TestCase
|
||||
{
|
||||
public function testGetCredentialCreationOptions(): void
|
||||
{
|
||||
$server = new CustomServer();
|
||||
$options = $server->getCredentialCreationOptions('user_name', 'user_id', 'test.localhost');
|
||||
self::assertArrayHasKey('challenge', $options);
|
||||
self::assertNotEmpty($options['challenge']);
|
||||
self::assertArrayHasKey('pubKeyCredParams', $options);
|
||||
self::assertNotEmpty($options['pubKeyCredParams']);
|
||||
self::assertArrayHasKey('attestation', $options);
|
||||
self::assertNotEmpty($options['attestation']);
|
||||
self::assertSame('phpMyAdmin (test.localhost)', $options['rp']['name']);
|
||||
self::assertSame('test.localhost', $options['rp']['id']);
|
||||
self::assertSame('user_name', $options['user']['name']);
|
||||
self::assertSame('user_name', $options['user']['displayName']);
|
||||
self::assertSame('user_id', $options['user']['id']);
|
||||
self::assertArrayHasKey('authenticatorAttachment', $options['authenticatorSelection']);
|
||||
self::assertSame('cross-platform', $options['authenticatorSelection']['authenticatorAttachment']);
|
||||
}
|
||||
|
||||
public function testGetCredentialRequestOptions(): void
|
||||
{
|
||||
$server = new CustomServer();
|
||||
$options = $server->getCredentialRequestOptions(
|
||||
'user_name',
|
||||
'userHandle1',
|
||||
'test.localhost',
|
||||
[['type' => 'public-key', 'id' => 'cHVibGljS2V5Q3JlZGVudGlhbElkMQ']],
|
||||
);
|
||||
self::assertNotEmpty($options['challenge']);
|
||||
self::assertSame(
|
||||
[['type' => 'public-key', 'id' => 'cHVibGljS2V5Q3JlZGVudGlhbElkMQ==']],
|
||||
$options['allowCredentials'],
|
||||
);
|
||||
self::assertSame(60000, $options['timeout']);
|
||||
self::assertSame('none', $options['attestation']);
|
||||
self::assertSame('discouraged', $options['userVerification']);
|
||||
}
|
||||
|
||||
/** @see https://github.com/web-auth/webauthn-framework/blob/v3.3.12/tests/library/Functional/AssertionTest.php#L46 */
|
||||
public function testParseAndValidateAssertionResponse(): void
|
||||
{
|
||||
$server = new CustomServer();
|
||||
|
||||
$uriStub = self::createStub(UriInterface::class);
|
||||
$uriStub->method('getHost')->willReturn('localhost');
|
||||
$request = self::createStub(ServerRequest::class);
|
||||
$request->method('getUri')->willReturn($uriStub);
|
||||
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
$authenticatorResponse = '{"id":"eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w","type":"public-key","rawId":"eHouz/Zi7+BmByHjJ/tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp/B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB+w==","response":{"authenticatorData":"SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAAew==","clientDataJSON":"eyJjaGFsbGVuZ2UiOiJHMEpiTExuZGVmM2EwSXkzUzJzU1FBOHVPNFNPX3plNkZaTUF1UEk2LXhJIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0MyIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ==","signature":"MEUCIEY/vcNkbo/LdMTfLa24ZYLlMMVMRd8zXguHBvqud9AJAiEAwCwpZpvcMaqCrwv85w/8RGiZzE+gOM61ffxmgEDeyhM=","userHandle":null}}';
|
||||
$challenge = 'G0JbLLndef3a0Iy3S2sSQA8uO4SO/ze6FZMAuPI6+xI=';
|
||||
|
||||
$allowedCredentials = [
|
||||
[
|
||||
'type' => 'public-key',
|
||||
'id' => 'eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w',
|
||||
],
|
||||
];
|
||||
|
||||
$throwable = null;
|
||||
try {
|
||||
$server->parseAndValidateAssertionResponse(
|
||||
$authenticatorResponse,
|
||||
$allowedCredentials,
|
||||
$challenge,
|
||||
$request,
|
||||
);
|
||||
} catch (Throwable $throwable) {
|
||||
throw $throwable;
|
||||
}
|
||||
|
||||
/** @psalm-suppress RedundantCondition */
|
||||
self::assertNull($throwable);
|
||||
}
|
||||
|
||||
/** @see https://github.com/web-auth/webauthn-framework/blob/v3.3.12/tests/library/Functional/NoneAttestationStatementTest.php#L45 */
|
||||
public function testParseAndValidateAttestationResponse(): void
|
||||
{
|
||||
$uriStub = self::createStub(UriInterface::class);
|
||||
$uriStub->method('getHost')->willReturn('localhost');
|
||||
$request = self::createStub(ServerRequest::class);
|
||||
$request->method('getUri')->willReturn($uriStub);
|
||||
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
$options = '{"rp":{"name":"My Application"},"pubKeyCredParams":[{"type":"public-key","alg":-7}],"challenge":"9WqgpRIYvGMCUYiFT20o1U7hSD193k11zu4tKP7wRcrE26zs1zc4LHyPinvPGS86wu6bDvpwbt8Xp2bQ3VBRSQ==","attestation":"none","user":{"name":"test@foo.com","id":"MJr5sD0WitVwZM0eoSO6kWhyseT67vc3oQdk\/k1VdZQ=","displayName":"Test PublicKeyCredentialUserEntity"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"}}';
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
$response = '{"id":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK","type":"public-key","rawId":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB/MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1+RIuTF9DUtEJZEEK","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiI5V3FncFJJWXZHTUNVWWlGVDIwbzFVN2hTRDE5M2sxMXp1NHRLUDd3UmNyRTI2enMxemM0TEh5UGludlBHUzg2d3U2YkR2cHdidDhYcDJiUTNWQlJTUSIsImNsaWVudEV4dGVuc2lvbnMiOnt9LCJoYXNoQWxnb3JpdGhtIjoiU0hBLTI1NiIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0=","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjkSZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAAAAAAAAAAAAAAAAAAAAAAAAAYJjIobiMfS7pLMMQTjIzBw3+hADjTsu6nVoWkEO3TrVYkdnFQfzDW2cVEYtnL4ErykiC295iEnvZTzRvbGIKI7mOYjYp2DoOoUVcZptFbLLjRtqZtfkSLkxfQ1LRCWRBCqUBAgMmIAEhWCAcPxwKyHADVjTgTsat4R/Jax6PWte50A8ZasMm4w6RxCJYILt0FCiGwC6rBrh3ySNy0yiUjZpNGAhW+aM9YYyYnUTJ"}}';
|
||||
|
||||
$server = new CustomServer();
|
||||
$credential = $server->parseAndValidateAttestationResponse($response, $options, $request);
|
||||
|
||||
self::assertSame(
|
||||
[
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'publicKeyCredentialId' => 'mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK',
|
||||
'type' => 'public-key',
|
||||
'transports' => [],
|
||||
'attestationType' => 'none',
|
||||
'aaguid' => hex2bin('00000000000000000000000000000000'),
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'credentialPublicKey' => 'pQECAyYgASFYIBw_HArIcANWNOBOxq3hH8lrHo9a17nQDxlqwybjDpHEIlggu3QUKIbALqsGuHfJI3LTKJSNmk0YCFb5oz1hjJidRMk',
|
||||
'userHandle' => 'MJr5sD0WitVwZM0eoSO6kWhyseT67vc3oQdk_k1VdZQ',
|
||||
'counter' => 0,
|
||||
],
|
||||
$credential,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -4,10 +4,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\WebAuthn;
|
||||
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\TwoFactor;
|
||||
use PhpMyAdmin\WebAuthn\WebauthnLibServer;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Webauthn\Server as WebauthnServer;
|
||||
use Webauthn\TrustPath\EmptyTrustPath;
|
||||
|
||||
@ -15,7 +17,7 @@ use function base64_encode;
|
||||
use function class_exists;
|
||||
|
||||
#[CoversClass(WebauthnLibServer::class)]
|
||||
class WebauthnLibServerTest extends TestCase
|
||||
final class WebauthnLibServerTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
@ -32,8 +34,11 @@ class WebauthnLibServerTest extends TestCase
|
||||
{
|
||||
$server = new WebauthnLibServer(self::createStub(TwoFactor::class));
|
||||
$options = $server->getCredentialCreationOptions('user_name', 'user_id', 'test.localhost');
|
||||
self::assertArrayHasKey('challenge', $options);
|
||||
self::assertNotEmpty($options['challenge']);
|
||||
self::assertArrayHasKey('pubKeyCredParams', $options);
|
||||
self::assertNotEmpty($options['pubKeyCredParams']);
|
||||
self::assertArrayHasKey('attestation', $options);
|
||||
self::assertNotEmpty($options['attestation']);
|
||||
self::assertSame('phpMyAdmin (test.localhost)', $options['rp']['name']);
|
||||
self::assertSame('test.localhost', $options['rp']['id']);
|
||||
@ -70,7 +75,12 @@ class WebauthnLibServerTest extends TestCase
|
||||
];
|
||||
|
||||
$server = new WebauthnLibServer($twoFactor);
|
||||
$options = $server->getCredentialRequestOptions('user_name', 'userHandle1', 'test.localhost', []);
|
||||
$options = $server->getCredentialRequestOptions(
|
||||
'user_name',
|
||||
'userHandle1',
|
||||
'test.localhost',
|
||||
[['type' => 'public-key', 'id' => 'cHVibGljS2V5Q3JlZGVudGlhbElkMQ==']],
|
||||
);
|
||||
self::assertNotEmpty($options['challenge']);
|
||||
self::assertSame('test.localhost', $options['rpId']);
|
||||
self::assertSame(
|
||||
@ -78,4 +88,119 @@ class WebauthnLibServerTest extends TestCase
|
||||
$options['allowCredentials'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/web-auth/webauthn-framework/blob/v3.3.12/tests/library/Functional/AssertionTest.php#L46
|
||||
*
|
||||
* @requires extension bcmath
|
||||
*/
|
||||
public function testParseAndValidateAssertionResponse(): void
|
||||
{
|
||||
$twoFactor = self::createStub(TwoFactor::class);
|
||||
$twoFactor->user = 'foo';
|
||||
$twoFactor->config = [
|
||||
'backend' => 'WebAuthn',
|
||||
'settings' => [
|
||||
'userHandle' => 'Zm9v',
|
||||
'credentials' => [
|
||||
'eHouz/Zi7+BmByHjJ/tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp/B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB+w==' => [
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'publicKeyCredentialId' => 'eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w',
|
||||
'type' => 'public-key',
|
||||
'transports' => [],
|
||||
'attestationType' => 'none',
|
||||
'aaguid' => '00000000-0000-0000-0000-000000000000',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'credentialPublicKey' => 'pQECAyYgASFYIJV56vRrFusoDf9hm3iDmllcxxXzzKyO9WruKw4kWx7zIlgg_nq63l8IMJcIdKDJcXRh9hoz0L-nVwP1Oxil3_oNQYs',
|
||||
'userHandle' => 'Zm9v',
|
||||
'counter' => 100,
|
||||
'otherUI' => null,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$server = new WebauthnLibServer($twoFactor);
|
||||
|
||||
$uriStub = self::createStub(UriInterface::class);
|
||||
$uriStub->method('getHost')->willReturn('localhost');
|
||||
$request = self::createStub(ServerRequest::class);
|
||||
$request->method('getUri')->willReturn($uriStub);
|
||||
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
$authenticatorResponse = '{"id":"eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w","type":"public-key","rawId":"eHouz/Zi7+BmByHjJ/tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp/B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB+w==","response":{"authenticatorData":"SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAAew==","clientDataJSON":"eyJjaGFsbGVuZ2UiOiJHMEpiTExuZGVmM2EwSXkzUzJzU1FBOHVPNFNPX3plNkZaTUF1UEk2LXhJIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0MyIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ==","signature":"MEUCIEY/vcNkbo/LdMTfLa24ZYLlMMVMRd8zXguHBvqud9AJAiEAwCwpZpvcMaqCrwv85w/8RGiZzE+gOM61ffxmgEDeyhM=","userHandle":null}}';
|
||||
$challenge = 'G0JbLLndef3a0Iy3S2sSQA8uO4SO/ze6FZMAuPI6+xI=';
|
||||
|
||||
$allowedCredentials = [
|
||||
[
|
||||
'type' => 'public-key',
|
||||
'id' => 'eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w',
|
||||
],
|
||||
];
|
||||
|
||||
$server->parseAndValidateAssertionResponse($authenticatorResponse, $allowedCredentials, $challenge, $request);
|
||||
|
||||
/**
|
||||
* @psalm-suppress TypeDoesNotContainType
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
self::assertSame(
|
||||
[
|
||||
'eHouz/Zi7+BmByHjJ/tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp/B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB+w==' => [
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'publicKeyCredentialId' => 'eHouz_Zi7-BmByHjJ_tx9h4a1WZsK4IzUmgGjkhyOodPGAyUqUp_B9yUkflXY3yHWsNtsrgCXQ3HjAIFUeZB-w',
|
||||
'type' => 'public-key',
|
||||
'transports' => [],
|
||||
'attestationType' => 'none',
|
||||
'trustPath' => ['type' => 'Webauthn\\TrustPath\\EmptyTrustPath'],
|
||||
'aaguid' => '00000000-0000-0000-0000-000000000000',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'credentialPublicKey' => 'pQECAyYgASFYIJV56vRrFusoDf9hm3iDmllcxxXzzKyO9WruKw4kWx7zIlgg_nq63l8IMJcIdKDJcXRh9hoz0L-nVwP1Oxil3_oNQYs',
|
||||
'userHandle' => 'Zm9v',
|
||||
'counter' => 123,
|
||||
'otherUI' => null,
|
||||
],
|
||||
],
|
||||
$twoFactor->config['settings']['credentials'],
|
||||
);
|
||||
}
|
||||
|
||||
/** @see https://github.com/web-auth/webauthn-framework/blob/v3.3.12/tests/library/Functional/NoneAttestationStatementTest.php#L45 */
|
||||
public function testParseAndValidateAttestationResponse(): void
|
||||
{
|
||||
$twoFactor = self::createStub(TwoFactor::class);
|
||||
$twoFactor->user = '';
|
||||
$twoFactor->config = ['backend' => 'WebAuthn', 'settings' => ['userHandle' => '', 'credentials' => []]];
|
||||
|
||||
$uriStub = self::createStub(UriInterface::class);
|
||||
$uriStub->method('getHost')->willReturn('localhost');
|
||||
$request = self::createStub(ServerRequest::class);
|
||||
$request->method('getUri')->willReturn($uriStub);
|
||||
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
$options = '{"rp":{"name":"My Application"},"pubKeyCredParams":[{"type":"public-key","alg":-7}],"challenge":"9WqgpRIYvGMCUYiFT20o1U7hSD193k11zu4tKP7wRcrE26zs1zc4LHyPinvPGS86wu6bDvpwbt8Xp2bQ3VBRSQ==","attestation":"none","user":{"name":"test@foo.com","id":"MJr5sD0WitVwZM0eoSO6kWhyseT67vc3oQdk\/k1VdZQ=","displayName":"Test PublicKeyCredentialUserEntity"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"}}';
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
$response = '{"id":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK","type":"public-key","rawId":"mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB/MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1+RIuTF9DUtEJZEEK","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiI5V3FncFJJWXZHTUNVWWlGVDIwbzFVN2hTRDE5M2sxMXp1NHRLUDd3UmNyRTI2enMxemM0TEh5UGludlBHUzg2d3U2YkR2cHdidDhYcDJiUTNWQlJTUSIsImNsaWVudEV4dGVuc2lvbnMiOnt9LCJoYXNoQWxnb3JpdGhtIjoiU0hBLTI1NiIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0=","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjkSZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2NBAAAAAAAAAAAAAAAAAAAAAAAAAAAAYJjIobiMfS7pLMMQTjIzBw3+hADjTsu6nVoWkEO3TrVYkdnFQfzDW2cVEYtnL4ErykiC295iEnvZTzRvbGIKI7mOYjYp2DoOoUVcZptFbLLjRtqZtfkSLkxfQ1LRCWRBCqUBAgMmIAEhWCAcPxwKyHADVjTgTsat4R/Jax6PWte50A8ZasMm4w6RxCJYILt0FCiGwC6rBrh3ySNy0yiUjZpNGAhW+aM9YYyYnUTJ"}}';
|
||||
|
||||
$server = new WebauthnLibServer($twoFactor);
|
||||
$credential = $server->parseAndValidateAttestationResponse($response, $options, $request);
|
||||
|
||||
self::assertSame(
|
||||
[
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'publicKeyCredentialId' => 'mMihuIx9LukswxBOMjMHDf6EAONOy7qdWhaQQ7dOtViR2cVB_MNbZxURi2cvgSvKSILb3mISe9lPNG9sYgojuY5iNinYOg6hRVxmm0VssuNG2pm1-RIuTF9DUtEJZEEK',
|
||||
'type' => 'public-key',
|
||||
'transports' => [],
|
||||
'attestationType' => 'none',
|
||||
'trustPath' => ['type' => 'Webauthn\\TrustPath\\EmptyTrustPath'],
|
||||
'aaguid' => '00000000-0000-0000-0000-000000000000',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'credentialPublicKey' => 'pQECAyYgASFYIBw_HArIcANWNOBOxq3hH8lrHo9a17nQDxlqwybjDpHEIlggu3QUKIbALqsGuHfJI3LTKJSNmk0YCFb5oz1hjJidRMk',
|
||||
'userHandle' => 'MJr5sD0WitVwZM0eoSO6kWhyseT67vc3oQdk_k1VdZQ',
|
||||
'counter' => 0,
|
||||
'otherUI' => null,
|
||||
],
|
||||
$credential,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user