diff --git a/CHANGELOG.md b/CHANGELOG.md index bd804e5..ad3bea0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [Unreleased] + +### Changed + +- `Innmind\HttpAuthentication\Authenticator::__invoke()` now returns an `Innmind\Immutable\Attempt` +- All resolvers now return an `Innmind\Immutable\Attempt` + ## 4.0.0 - 2023-11-01 ### Changed diff --git a/composer.json b/composer.json index 800cb9e..0ad9421 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ }, "require": { "php": "~8.2", + "innmind/immutable": "~5.18", "innmind/http": "~7.0" }, "autoload": { diff --git a/src/Any.php b/src/Any.php index a65b156..fb36908 100644 --- a/src/Any.php +++ b/src/Any.php @@ -6,7 +6,7 @@ use Innmind\Http\ServerRequest; use Innmind\Immutable\{ Sequence, - Maybe, + Attempt, }; final class Any implements Authenticator @@ -22,12 +22,12 @@ public function __construct(Authenticator ...$authenticators) $this->authenticators = Sequence::of(...$authenticators); } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { - /** @var Maybe */ + /** @var Attempt */ return $this->authenticators->reduce( - Maybe::nothing(), - static fn(Maybe $identity, $authenticate) => $identity->otherwise( + Attempt::error(new \LogicException('No authenticator defined')), + static fn(Attempt $identity, $authenticate) => $identity->recover( static fn() => $authenticate($request), ), ); diff --git a/src/Authenticator.php b/src/Authenticator.php index a3e047e..9c5c5d9 100644 --- a/src/Authenticator.php +++ b/src/Authenticator.php @@ -4,12 +4,12 @@ namespace Innmind\HttpAuthentication; use Innmind\Http\ServerRequest; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; interface Authenticator { /** - * @return Maybe + * @return Attempt */ - public function __invoke(ServerRequest $request): Maybe; + public function __invoke(ServerRequest $request): Attempt; } diff --git a/src/ValidateAuthorizationHeader.php b/src/ValidateAuthorizationHeader.php index 2e1c3c9..ff85028 100644 --- a/src/ValidateAuthorizationHeader.php +++ b/src/ValidateAuthorizationHeader.php @@ -7,7 +7,7 @@ ServerRequest, Header\Authorization, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class ValidateAuthorizationHeader implements Authenticator { @@ -18,7 +18,7 @@ public function __construct(Authenticator $authenticate) $this->authenticate = $authenticate; } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { if (!$request->headers()->contains('Authorization')) { return ($this->authenticate)($request); @@ -27,6 +27,7 @@ public function __invoke(ServerRequest $request): Maybe return $request ->headers() ->find(Authorization::class) + ->attempt(static fn() => new \RuntimeException('No Authorization header')) ->flatMap(fn() => ($this->authenticate)($request)); } } diff --git a/src/ViaAuthorization.php b/src/ViaAuthorization.php index 0ca8b68..838c881 100644 --- a/src/ViaAuthorization.php +++ b/src/ViaAuthorization.php @@ -10,7 +10,7 @@ Header\AuthorizationValue, }; use Innmind\Immutable\{ - Maybe, + Attempt, Predicate\Instance, }; @@ -23,13 +23,14 @@ public function __construct(Resolver $resolve) $this->resolve = $resolve; } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { return $request ->headers() ->find(Authorization::class) ->flatMap(static fn($header) => $header->values()->find(static fn() => true)) ->keep(Instance::of(AuthorizationValue::class)) + ->attempt(static fn() => new \RuntimeException('Failed to resolve identity')) ->flatMap(fn($value) => ($this->resolve)($value)); } } diff --git a/src/ViaAuthorization/NullResolver.php b/src/ViaAuthorization/NullResolver.php index 6b1e653..b7d2497 100644 --- a/src/ViaAuthorization/NullResolver.php +++ b/src/ViaAuthorization/NullResolver.php @@ -5,13 +5,13 @@ use Innmind\HttpAuthentication\Identity; use Innmind\Http\Header\AuthorizationValue; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class NullResolver implements Resolver { - public function __invoke(AuthorizationValue $value): Maybe + public function __invoke(AuthorizationValue $value): Attempt { - /** @var Maybe */ - return Maybe::nothing(); + /** @var Attempt */ + return Attempt::error(new \LogicException('Not implemented')); } } diff --git a/src/ViaAuthorization/Resolver.php b/src/ViaAuthorization/Resolver.php index 4c01bfb..c5135ca 100644 --- a/src/ViaAuthorization/Resolver.php +++ b/src/ViaAuthorization/Resolver.php @@ -5,12 +5,12 @@ use Innmind\HttpAuthentication\Identity; use Innmind\Http\Header\AuthorizationValue; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; interface Resolver { /** - * @return Maybe + * @return Attempt */ - public function __invoke(AuthorizationValue $value): Maybe; + public function __invoke(AuthorizationValue $value): Attempt; } diff --git a/src/ViaBasicAuthorization.php b/src/ViaBasicAuthorization.php index 300d8d9..003c2b3 100644 --- a/src/ViaBasicAuthorization.php +++ b/src/ViaBasicAuthorization.php @@ -8,7 +8,7 @@ ServerRequest, Header\Authorization, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class ViaBasicAuthorization implements Authenticator { @@ -19,12 +19,13 @@ public function __construct(Resolver $resolve) $this->resolve = $resolve; } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { return $request ->headers() ->find(Authorization::class) ->filter(static fn($header) => $header->scheme() === 'Basic') + ->attempt(static fn() => new \RuntimeException('Failed to resolve identity')) ->flatMap(function($header) { [$user, $password] = \explode(':', \base64_decode($header->parameter(), true)); diff --git a/src/ViaBasicAuthorization/NullResolver.php b/src/ViaBasicAuthorization/NullResolver.php index e77c1de..9ee4c15 100644 --- a/src/ViaBasicAuthorization/NullResolver.php +++ b/src/ViaBasicAuthorization/NullResolver.php @@ -4,13 +4,13 @@ namespace Innmind\HttpAuthentication\ViaBasicAuthorization; use Innmind\HttpAuthentication\Identity; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class NullResolver implements Resolver { - public function __invoke(string $user, string $password): Maybe + public function __invoke(string $user, string $password): Attempt { - /** @var Maybe */ - return Maybe::nothing(); + /** @var Attempt */ + return Attempt::error(new \LogicException('Not implemented')); } } diff --git a/src/ViaBasicAuthorization/Resolver.php b/src/ViaBasicAuthorization/Resolver.php index 4d5a0d5..d5ac2fb 100644 --- a/src/ViaBasicAuthorization/Resolver.php +++ b/src/ViaBasicAuthorization/Resolver.php @@ -4,12 +4,12 @@ namespace Innmind\HttpAuthentication\ViaBasicAuthorization; use Innmind\HttpAuthentication\Identity; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; interface Resolver { /** - * @return Maybe + * @return Attempt */ - public function __invoke(string $user, string $password): Maybe; + public function __invoke(string $user, string $password): Attempt; } diff --git a/src/ViaForm.php b/src/ViaForm.php index 9a6ba7c..1311ddd 100644 --- a/src/ViaForm.php +++ b/src/ViaForm.php @@ -8,7 +8,10 @@ ServerRequest, Method, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\{ + Maybe, + Attempt, +}; final class ViaForm implements Authenticator { @@ -19,10 +22,11 @@ public function __construct(Resolver $resolve) $this->resolve = $resolve; } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { return Maybe::just($request) ->filter(static fn($request) => $request->method() === Method::post) + ->attempt(static fn() => new \RuntimeException('Failed to resolve identity')) ->flatMap(fn($request) => ($this->resolve)($request->form())); } } diff --git a/src/ViaForm/NullResolver.php b/src/ViaForm/NullResolver.php index 7023dbe..251f6a2 100644 --- a/src/ViaForm/NullResolver.php +++ b/src/ViaForm/NullResolver.php @@ -5,13 +5,13 @@ use Innmind\HttpAuthentication\Identity; use Innmind\Http\ServerRequest\Form; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class NullResolver implements Resolver { - public function __invoke(Form $form): Maybe + public function __invoke(Form $form): Attempt { - /** @var Maybe */ - return Maybe::nothing(); + /** @var Attempt */ + return Attempt::error(new \LogicException('Not implemented')); } } diff --git a/src/ViaForm/Resolver.php b/src/ViaForm/Resolver.php index fcd4e5a..82110b2 100644 --- a/src/ViaForm/Resolver.php +++ b/src/ViaForm/Resolver.php @@ -5,12 +5,12 @@ use Innmind\HttpAuthentication\Identity; use Innmind\Http\ServerRequest\Form; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; interface Resolver { /** - * @return Maybe + * @return Attempt */ - public function __invoke(Form $form): Maybe; + public function __invoke(Form $form): Attempt; } diff --git a/src/ViaStorage.php b/src/ViaStorage.php index f6a18e5..5015b87 100644 --- a/src/ViaStorage.php +++ b/src/ViaStorage.php @@ -5,7 +5,7 @@ use Innmind\HttpAuthentication\ViaStorage\Storage; use Innmind\Http\ServerRequest; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class ViaStorage implements Authenticator { @@ -18,12 +18,13 @@ public function __construct(Authenticator $authenticate, Storage $storage) $this->storage = $storage; } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { return $this ->storage ->get($request) - ->otherwise( + ->attempt(static fn() => new \RuntimeException('Identity not in storage')) + ->recover( fn() => ($this->authenticate)($request)->map( function($identity) use ($request) { $this->storage->set($request, $identity); diff --git a/src/ViaUrlAuthority.php b/src/ViaUrlAuthority.php index a5ff394..29b8e25 100644 --- a/src/ViaUrlAuthority.php +++ b/src/ViaUrlAuthority.php @@ -9,7 +9,7 @@ User, Password, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class ViaUrlAuthority implements Authenticator { @@ -20,14 +20,14 @@ public function __construct(Resolver $resolve) $this->resolve = $resolve; } - public function __invoke(ServerRequest $request): Maybe + public function __invoke(ServerRequest $request): Attempt { $user = $request->url()->authority()->userInformation()->user(); $password = $request->url()->authority()->userInformation()->password(); if ($user->equals(User::none()) && $password->equals(Password::none())) { - /** @var Maybe */ - return Maybe::nothing(); + /** @var Attempt */ + return Attempt::error(new \RuntimeException('No authentication provided')); } return ($this->resolve)($user, $password); diff --git a/src/ViaUrlAuthority/NullResolver.php b/src/ViaUrlAuthority/NullResolver.php index a323d8f..e3e5014 100644 --- a/src/ViaUrlAuthority/NullResolver.php +++ b/src/ViaUrlAuthority/NullResolver.php @@ -8,13 +8,13 @@ User, Password, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; final class NullResolver implements Resolver { - public function __invoke(User $user, Password $password): Maybe + public function __invoke(User $user, Password $password): Attempt { - /** @var Maybe */ - return Maybe::nothing(); + /** @var Attempt */ + return Attempt::error(new \LogicException('Not implemented')); } } diff --git a/src/ViaUrlAuthority/Resolver.php b/src/ViaUrlAuthority/Resolver.php index 121c58c..6748d0f 100644 --- a/src/ViaUrlAuthority/Resolver.php +++ b/src/ViaUrlAuthority/Resolver.php @@ -8,12 +8,12 @@ User, Password, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; interface Resolver { /** - * @return Maybe + * @return Attempt */ - public function __invoke(User $user, Password $password): Maybe; + public function __invoke(User $user, Password $password): Attempt; } diff --git a/tests/AnyTest.php b/tests/AnyTest.php index c15a994..826d02b 100644 --- a/tests/AnyTest.php +++ b/tests/AnyTest.php @@ -14,7 +14,7 @@ ProtocolVersion, }; use Innmind\Url\Url; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class AnyTest extends TestCase @@ -55,17 +55,17 @@ public function testInvokation() ->expects($this->once()) ->method('__invoke') ->with($request) - ->willReturn(Maybe::nothing()); + ->willReturn(Attempt::error(new \Exception)); $notImplemented ->expects($this->once()) ->method('__invoke') ->with($request) - ->willReturn(Maybe::nothing()); + ->willReturn(Attempt::error(new \Exception)); $expected ->expects($this->once()) ->method('__invoke') ->with($request) - ->willReturn(Maybe::just($identity = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($identity = $this->createMock(Identity::class))); $notCalled ->expects($this->never()) ->method('__invoke'); diff --git a/tests/ValidateAuthorizationHeaderTest.php b/tests/ValidateAuthorizationHeaderTest.php index 4df3e99..7c2eff1 100644 --- a/tests/ValidateAuthorizationHeaderTest.php +++ b/tests/ValidateAuthorizationHeaderTest.php @@ -19,7 +19,7 @@ Header\Value\Value, }; use Innmind\Url\Url; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class ValidateAuthorizationHeaderTest extends TestCase @@ -48,7 +48,7 @@ public function testForwardAuthenticationWhenNoHeader() ->expects($this->once()) ->method('__invoke') ->with($request) - ->willReturn(Maybe::just($expected = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($expected = $this->createMock(Identity::class))); $this->assertSame($expected, $validate($request)->match( static fn($identity) => $identity, @@ -101,7 +101,7 @@ public function testForwardAuthenticationWhenValidHeader() ->expects($this->once()) ->method('__invoke') ->with($request) - ->willReturn(Maybe::just($expected = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($expected = $this->createMock(Identity::class))); $this->assertSame($expected, $validate($request)->match( static fn($identity) => $identity, diff --git a/tests/ViaAuthorizationTest.php b/tests/ViaAuthorizationTest.php index db94730..7e55a8e 100644 --- a/tests/ViaAuthorizationTest.php +++ b/tests/ViaAuthorizationTest.php @@ -21,7 +21,7 @@ Header\AuthorizationValue, }; use Innmind\Url\Url; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class ViaAuthorizationTest extends TestCase @@ -87,7 +87,7 @@ public function testInvokation() ->expects($this->once()) ->method('__invoke') ->with($expected) - ->willReturn(Maybe::just($identity = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($identity = $this->createMock(Identity::class))); $request = ServerRequest::of( Url::of('/'), Method::get, diff --git a/tests/ViaBasicAuthorizationTest.php b/tests/ViaBasicAuthorizationTest.php index 5ff51ce..439bac8 100644 --- a/tests/ViaBasicAuthorizationTest.php +++ b/tests/ViaBasicAuthorizationTest.php @@ -20,7 +20,7 @@ Header\Authorization, }; use Innmind\Url\Url; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class ViaBasicAuthorizationTest extends TestCase @@ -108,7 +108,7 @@ public function testInvokation() ->expects($this->once()) ->method('__invoke') ->with('foo', 'bar') - ->willReturn(Maybe::just($identity = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($identity = $this->createMock(Identity::class))); $request = ServerRequest::of( Url::of('/'), Method::get, diff --git a/tests/ViaFormTest.php b/tests/ViaFormTest.php index 22755f8..d725dae 100644 --- a/tests/ViaFormTest.php +++ b/tests/ViaFormTest.php @@ -16,7 +16,7 @@ ProtocolVersion, }; use Innmind\Url\Url; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class ViaFormTest extends TestCase @@ -63,7 +63,7 @@ public function testInvokation() ->expects($this->once()) ->method('__invoke') ->with($request->form()) - ->willReturn(Maybe::just($identity = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($identity = $this->createMock(Identity::class))); $this->assertSame($identity, $authenticate($request)->match( static fn($identity) => $identity, diff --git a/tests/ViaStorageTest.php b/tests/ViaStorageTest.php index a540472..3d348df 100644 --- a/tests/ViaStorageTest.php +++ b/tests/ViaStorageTest.php @@ -15,7 +15,7 @@ ProtocolVersion, }; use Innmind\Url\Url; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class ViaStorageTest extends TestCase @@ -46,7 +46,7 @@ public function testAuthenticateViaInnerAuthenticator() ->expects($this->once()) ->method('__invoke') ->with($request) - ->willReturn(Maybe::just($identity = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($identity = $this->createMock(Identity::class))); $this->assertSame($identity, $authenticate($request)->match( static fn($identity) => $identity, diff --git a/tests/ViaUrlAuthorityTest.php b/tests/ViaUrlAuthorityTest.php index 9a8522f..1dba920 100644 --- a/tests/ViaUrlAuthorityTest.php +++ b/tests/ViaUrlAuthorityTest.php @@ -16,7 +16,7 @@ Method, ProtocolVersion, }; -use Innmind\Immutable\Maybe; +use Innmind\Immutable\Attempt; use PHPUnit\Framework\TestCase; class ViaUrlAuthorityTest extends TestCase @@ -62,7 +62,7 @@ public function testInvokation() ->expects($this->once()) ->method('__invoke') ->with($user, $password) - ->willReturn(Maybe::just($identity = $this->createMock(Identity::class))); + ->willReturn(Attempt::result($identity = $this->createMock(Identity::class))); $request = ServerRequest::of( $url, Method::get,