Skip to content

Commit

Permalink
clarification
Browse files Browse the repository at this point in the history
  • Loading branch information
fezfez committed Nov 4, 2023
1 parent dd93227 commit 417ca62
Show file tree
Hide file tree
Showing 21 changed files with 166 additions and 318 deletions.
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
stopOnIncomplete="false"
stopOnSkipped="false"
bootstrap="vendor/autoload.php"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
cacheDirectory=".phpunit.cache">
<coverage/>
<testsuites>
Expand Down
1 change: 0 additions & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0"?>
<psalm
errorLevel="1"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
Expand Down
38 changes: 21 additions & 17 deletions src/JwtAuthentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,12 @@ public function __construct(
$this->decodeToken = new DecodeToken($parser ?? new Parser(new JoseEncoder()), $logger);
}

/**
* Process a request in PSR-15 style and return a response.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$scheme = $request->getUri()->getScheme();
$host = $request->getUri()->getHost();

/* HTTP allowed only if secure is false or server is in relaxed array. */
if ($scheme !== 'https' && $this->options->secure === true && ! in_array($host, $this->options->relaxed)) {
if (! $this->isConfigurationSecure($request)) {
throw new RuntimeException(sprintf(
'Insecure use of middleware over %s denied by configuration.',
strtoupper($scheme),
strtoupper($request->getUri()->getScheme()),
));
}

Expand All @@ -92,16 +85,27 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $handler->handle($request);
}

/* Add decoded token to request as attribute when requested. */
$request = $request->withAttribute($this->options->attribute, $jwtDecodedToken);
$request = $this->options->before->__invoke(
$request->withAttribute($this->options->attribute, $jwtDecodedToken),
$jwtDecodedToken,
);

return $this->options->after->__invoke($handler->handle($request), $jwtDecodedToken);
}

/* Modify $request before calling next middleware. */
$request = $this->options->before->__invoke($request, $jwtDecodedToken);
/**
* HTTP allowed only if secure is false or server is in relaxed array.
*/
private function isConfigurationSecure(ServerRequestInterface $request): bool
{
if ($request->getUri()->getScheme() === 'https') {
return true;
}

/* Everything ok, call next middleware. */
$response = $handler->handle($request);
if ($this->options->secure === false) {
return true;
}

/* Modify $response before returning. */
return $this->options->after->__invoke($response, $jwtDecodedToken);
return in_array($request->getUri()->getHost(), $this->options->relaxed);
}
}
25 changes: 25 additions & 0 deletions src/JwtAuthentication/IgnoreHttpMethodRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Tuupola\Middleware\JwtAuthentication;

use Psr\Http\Message\ServerRequestInterface;

use function in_array;

/**
* Rule to decide by HTTP verb whether the request should be authenticated or not.
*/
final class IgnoreHttpMethodRule implements RuleInterface
{
/** @param string[] $ignoreHttpMethod */
public function __construct(private readonly array $ignoreHttpMethod = ['OPTIONS'])
{
}

public function __invoke(ServerRequestInterface $request): bool
{
return ! in_array($request->getMethod(), $this->ignoreHttpMethod);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
use Tuupola\Middleware\JwtAuthentificationError;
use Tuupola\Middleware\JwtAuthentificationAclError;

class NullError implements JwtAuthentificationError
class NullAclError implements JwtAuthentificationAclError
{
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Throwable $exception): ResponseInterface
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

use Lcobucci\JWT\Token\Plain;
use Psr\Http\Message\ResponseInterface;
use Tuupola\Middleware\JwtAuthentificationAfter;
use Tuupola\Middleware\JwtAuthentificationAfterHandler;

class NullAfter implements JwtAuthentificationAfter
class NullAfterHandler implements JwtAuthentificationAfterHandler
{
public function __invoke(ResponseInterface $response, Plain $token): ResponseInterface
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

use Lcobucci\JWT\Token\Plain;
use Psr\Http\Message\ServerRequestInterface;
use Tuupola\Middleware\JwtAuthentificationBefore;
use Tuupola\Middleware\JwtAuthentificationBeforeHandler;

class NullBefore implements JwtAuthentificationBefore
class NullBeforeHandler implements JwtAuthentificationBeforeHandler
{
public function __invoke(ServerRequestInterface $request, Plain $token): ServerRequestInterface
{
Expand Down
54 changes: 0 additions & 54 deletions src/JwtAuthentication/RequestMethodRule.php

This file was deleted.

91 changes: 46 additions & 45 deletions src/JwtAuthentication/RequestPathRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,12 @@

declare(strict_types=1);

/*
Copyright (c) 2015-2022 Mika Tuupola
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/**
* @see https://github.com/tuupola/slim-jwt-auth
* @see https://appelsiini.net/projects/slim-jwt-auth
*/

namespace Tuupola\Middleware\JwtAuthentication;

use Psr\Http\Message\ServerRequestInterface;

use function array_filter;
use function array_map;
use function explode;
use function implode;
use function preg_match;
Expand All @@ -44,40 +16,69 @@
/**
* Rule to decide by request path whether the request should be authenticated or not.
*/

final class RequestPathRule implements RuleInterface
{
/** @var string[] */
private readonly array $mustBeAuthOnUri;
/** @var string[] */
private readonly array $ignoreAuthOnUri;

/**
* @param string[] $path
* @param string[] $ignore
* @param string[] $mustBeAuthOnUri
* @param string[] $ignoreAuthOnUri
*/
public function __construct(
private readonly array $path = ['/'],
private readonly array $ignore = []
array $mustBeAuthOnUri = ['/'],
array $ignoreAuthOnUri = []
) {
$this->mustBeAuthOnUri = array_map(static fn (string $mustBeAuthOnUri): string => rtrim($mustBeAuthOnUri, '/'), $mustBeAuthOnUri);
$this->ignoreAuthOnUri = array_map(static fn (string $ignoreAuthOnUri): string => rtrim($ignoreAuthOnUri, '/'), $ignoreAuthOnUri);
}

public function __invoke(ServerRequestInterface $request): bool
{
$uri = '/' . $request->getUri()->getPath();
$uri = '/' . implode('/', array_filter(explode('//', $uri)));
$uri = '/' . implode(
'/',
array_filter(explode('//', '/' . $request->getUri()->getPath())),
);

if ($this->shouldIgnoreAuthOnUri($uri)) {
return false;
}

return $this->shouldBeAuthenticate($uri);
}

/* If request path is matches ignore should not authenticate. */
foreach ($this->ignore as $ignore) {
$ignore = rtrim($ignore, '/');
if (! ! preg_match('@^' . $ignore . '(/.*)?$@', $uri)) {
return false;
/**
* If request path is matches ignore should not authenticate.
*/
private function shouldIgnoreAuthOnUri(string $uri): bool
{
foreach ($this->ignoreAuthOnUri as $ignoreAuthOnUri) {
if ($this->match($ignoreAuthOnUri, $uri)) {
return true;
}
}

/* Otherwise check if path matches and we should authenticate. */
foreach ($this->path as $path) {
$path = rtrim($path, '/');
if (! ! preg_match('@^' . $path . '(/.*)?$@', $uri)) {
return false;
}

/**
* Otherwise check if path matches and we should authenticate.
*/
private function shouldBeAuthenticate(string $uri): bool
{
foreach ($this->mustBeAuthOnUri as $mustBeAuthOnUri) {
if ($this->match($mustBeAuthOnUri, $uri)) {
return true;
}
}

return false;
}

private function match(string $value, string $uri): bool
{
return ! ! preg_match('@^' . $value . '(/.*)?$@', $uri);
}
}
29 changes: 0 additions & 29 deletions src/JwtAuthentication/RuleInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,6 @@

declare(strict_types=1);

/*
Copyright (c) 2015-2022 Mika Tuupola
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/**
* @see https://github.com/tuupola/slim-jwt-auth
* @see https://appelsiini.net/projects/slim-jwt-auth
*/

namespace Tuupola\Middleware\JwtAuthentication;

use Psr\Http\Message\ServerRequestInterface;
Expand Down

0 comments on commit 417ca62

Please sign in to comment.