Skip to content

Commit

Permalink
Corona: Separate parser for the bearer token
Browse files Browse the repository at this point in the history
  • Loading branch information
pprkut committed Jan 21, 2025
1 parent e0a9529 commit afaf3f8
Show file tree
Hide file tree
Showing 13 changed files with 551 additions and 99 deletions.
102 changes: 102 additions & 0 deletions src/Lunr/Corona/Parsers/BearerToken/BearerTokenCliParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

/**
* This file contains the request value parser for the bearer token sourced from a cli argument.
*
* SPDX-FileCopyrightText: Copyright 2025 Move Agency Group B.V., Zwolle, The Netherlands
* SPDX-License-Identifier: MIT
*/

namespace Lunr\Corona\Parsers\BearerToken;

use BackedEnum;
use Lunr\Corona\RequestValueInterface;
use Lunr\Corona\RequestValueParserInterface;
use Lunr\Shadow\CliParserInterface;
use RuntimeException;

/**
* Request Value Parser for the bearer token.
*
* @phpstan-import-type CliParameters from CliParserInterface
*/
class BearerTokenCliParser implements RequestValueParserInterface
{

/**
* Parser CLI argument AST.
* @var CliParameters
*/
protected readonly array $params;

/**
* The parsed bearerToken value.
* @var string|null
*/
protected readonly ?string $bearerToken;

/**
* Constructor.
*
* @param CliParameters $params Parsed CLI argument AST
*/
public function __construct(array $params)
{
$this->params = $params;
}

/**
* Destructor.
*/
public function __destruct()
{
// no-op
}

/**
* Return the request value type the parser handles.
*
* @return class-string The FQDN of the type enum the parser handles
*/
public function get_request_value_type(): string
{
return BearerTokenValue::class;
}

/**
* Get a request value.
*
* @param BackedEnum&RequestValueInterface $key The identifier/name of the request value to get
*
* @return string|null The requested value
*/
public function get(BackedEnum&RequestValueInterface $key): ?string
{
return match ($key) {
BearerTokenValue::BearerToken => $this->bearerToken ?? $this->parse(),
default => throw new RuntimeException('Unsupported request value type "' . $key::class . '"'),
};
}

/**
* Parse the bearer token value from the HTTP authorization header.
*
* @return string|null The parsed bearer token
*/
protected function parse(): ?string
{
$token = NULL;

if (array_key_exists('bearer-token', $this->params))
{
$token = $this->params['bearer-token'][0];
}

$this->bearerToken = $token;

return $token;
}

}

?>
95 changes: 95 additions & 0 deletions src/Lunr/Corona/Parsers/BearerToken/BearerTokenParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

/**
* This file contains the request value parser for the bearer token sourced from HTTP authorization headers.
*
* SPDX-FileCopyrightText: Copyright 2025 Move Agency Group B.V., Zwolle, The Netherlands
* SPDX-License-Identifier: MIT
*/

namespace Lunr\Corona\Parsers\BearerToken;

use BackedEnum;
use Lunr\Corona\RequestValueInterface;
use Lunr\Corona\RequestValueParserInterface;
use RuntimeException;

/**
* Request Value Parser for the bearer token.
*/
class BearerTokenParser implements RequestValueParserInterface
{

/**
* The parsed bearerToken value.
* @var string|null
*/
protected readonly ?string $bearerToken;

/**
* Constructor.
*/
public function __construct()
{
// no-op
}

/**
* Destructor.
*/
public function __destruct()
{
// no-op
}

/**
* Return the request value type the parser handles.
*
* @return class-string The FQDN of the type enum the parser handles
*/
public function get_request_value_type(): string
{
return BearerTokenValue::class;
}

/**
* Get a request value.
*
* @param BackedEnum&RequestValueInterface $key The identifier/name of the request value to get
*
* @return string|null The requested value
*/
public function get(BackedEnum&RequestValueInterface $key): ?string
{
return match ($key) {
BearerTokenValue::BearerToken => $this->bearerToken ?? $this->parse(),
default => throw new RuntimeException('Unsupported request value type "' . $key::class . '"'),
};
}

/**
* Parse the bearer token value from the HTTP authorization header.
*
* @return string|null The parsed bearer token
*/
protected function parse(): ?string
{
$token = NULL;

if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER))
{
$matches = [];
if (preg_match('/^Bearer ([^ ]+)$/', $_SERVER['HTTP_AUTHORIZATION'], $matches) === 1)
{
$token = $matches[1];
}
}

$this->bearerToken = $token;

return $token;
}

}

?>
27 changes: 27 additions & 0 deletions src/Lunr/Corona/Parsers/BearerToken/BearerTokenValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/**
* This file contains the bearer token request value.
*
* SPDX-FileCopyrightText: Copyright 2025 Move Agency Group B.V., Zwolle, The Netherlands
* SPDX-License-Identifier: MIT
*/

namespace Lunr\Corona\Parsers\BearerToken;

use Lunr\Corona\RequestValueInterface;

/**
* Request Data Enums
*/
enum BearerTokenValue: string implements RequestValueInterface
{

/**
* Bearer token
*/
case BearerToken = 'bearerToken';

}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/**
* This file contains the BearerTokenCliParserGetTest class.
*
* SPDX-FileCopyrightText: Copyright 2025 Move Agency Group B.V., Zwolle, The Netherlands
* SPDX-License-Identifier: MIT
*/

namespace Lunr\Corona\Parsers\BearerToken\Tests;

use Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser;
use Lunr\Corona\Parsers\BearerToken\BearerTokenValue;
use Lunr\Corona\Tests\Helpers\MockRequestValue;
use RuntimeException;

/**
* This class contains test methods for the BearerTokenCliParser class.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser
*/
class BearerTokenCliParserGetTest extends BearerTokenCliParserTest
{

/**
* Test that get_request_value_type() returns the correct type.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser::get_request_value_type
*/
public function testGetRequestValueType()
{
$this->assertEquals(BearerTokenValue::class, $this->class->get_request_value_type());
}

/**
* Test getting an unsupported value.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser::get
*/
public function testGetUnsupportedValue()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Unsupported request value type "Lunr\Corona\Tests\Helpers\MockRequestValue"');

$this->class->get(MockRequestValue::Foo);
}

/**
* Test getting a parsed bearer token.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser::get
*/
public function testGetParsedBearerToken()
{
$token = '123456789';

$this->set_reflection_property_value('bearerToken', $token);

$value = $this->class->get(BearerTokenValue::BearerToken);

$this->assertEquals($token, $value);
}

/**
* Test getting a bearer token when it's not in the authorization header.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser::get
*/
public function testGetBearerTokenWithMissingCliArgument()
{
$class = new BearerTokenCliParser([]);

$value = $class->get(BearerTokenValue::BearerToken);

$this->assertNull($value);

$property = $this->get_reflection_property('bearerToken');

$this->assertNull($property->getValue($class));
}

/**
* Test getting a parsed bearer token.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser::get
*/
public function testGetBearerToken()
{
$token = '123456789';

$value = $this->class->get(BearerTokenValue::BearerToken);

$this->assertEquals($token, $value);
$this->assertPropertySame('bearerToken', $token);
}

}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* This file contains the BearerTokenCliParserTest class.
*
* SPDX-FileCopyrightText: Copyright 2025 Move Agency Group B.V., Zwolle, The Netherlands
* SPDX-License-Identifier: MIT
*/

namespace Lunr\Corona\Parsers\BearerToken\Tests;

use Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser;
use Lunr\Halo\LunrBaseTest;

/**
* This class contains test methods for the BearerTokenCliParser class.
*
* @covers Lunr\Corona\Parsers\BearerToken\BearerTokenCliParser
*/
abstract class BearerTokenCliParserTest extends LunrBaseTest
{

/**
* Instance of the tested class.
* @var BearerTokenCliParser
*/
protected BearerTokenCliParser $class;

/**
* TestCase Constructor.
*/
public function setUp(): void
{
$token = '123456789';

$ast = [
'bearer-token' => [
$token,
]
];

$this->class = new BearerTokenCliParser($ast);

parent::baseSetUp($this->class);
}

/**
* TestCase Destructor.
*/
public function tearDown(): void
{
unset($this->class);

parent::tearDown();
}

}

?>
Loading

0 comments on commit afaf3f8

Please sign in to comment.