diff --git a/ChangeLog.md b/ChangeLog.md index 09de73f..7fcc6af 100755 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,6 +3,11 @@ Web Authentication change log ## ?.?.? / ????-??-?? +## 2.0.1 / 2020-12-23 + +* Fixed `ISession::transmit()` not being called after authentication + (@thekid) + ## 2.0.0 / 2020-10-18 * Added support for redirecting to URLs with fragments (`/#/users/123`) diff --git a/src/main/php/web/auth/SessionBased.class.php b/src/main/php/web/auth/SessionBased.class.php index 05f91f2..dc76b02 100755 --- a/src/main/php/web/auth/SessionBased.class.php +++ b/src/main/php/web/auth/SessionBased.class.php @@ -56,10 +56,10 @@ public function filter($req, $res, $invocation) { $user= $result; } - // Register in session + // Register in session, then continue with invocation $session->register('user', $user); - $req->pass('user', $user); - return $invocation->proceed($req, $res); + $session->transmit($res); + return $invocation->proceed($req->pass('user', $user), $res); } } } \ No newline at end of file diff --git a/src/test/php/web/auth/unittest/SessionBasedTest.class.php b/src/test/php/web/auth/unittest/SessionBasedTest.class.php index 137077d..daef3c9 100755 --- a/src/test/php/web/auth/unittest/SessionBasedTest.class.php +++ b/src/test/php/web/auth/unittest/SessionBasedTest.class.php @@ -4,11 +4,11 @@ use unittest\Assert; use web\auth\{SessionBased, Flow}; use web\io\{TestInput, TestOutput}; -use web\session\ForTesting; +use web\session\{ForTesting, Transport}; use web\{Request, Response}; class SessionBasedTest { - private $sessions, $flow; + private $sessions; /** * Invokes handle() function @@ -22,19 +22,22 @@ private function handle($headers, $handler) { $handler->handle($req, $res); } + private function authenticate($result) { + return newinstance(Flow::class, [], [ + 'authenticate' => function($req, $res, $invocation) use($result) { + return $result; + } + ]); + } + #[Before] - public function setUp() { + public function sessions() { $this->sessions= new ForTesting(); - $this->flow= new class() extends Flow { - public function authenticate($req, $res, $invocation) { - // ... - } - }; } #[Test] public function can_create() { - new SessionBased($this->flow, $this->sessions); + new SessionBased($this->authenticate(null), $this->sessions); } #[Test] @@ -42,7 +45,7 @@ public function required() { $session= $this->sessions->create(); $session->register('user', ['username' => 'test']); - $auth= new SessionBased($this->flow, $this->sessions); + $auth= new SessionBased($this->authenticate(null), $this->sessions); $this->handle(['Cookie' => 'session='.$session->id()], $auth->required(function($req, $res) use(&$user) { $user= $req->value('user')['username']; })); @@ -52,7 +55,7 @@ public function required() { #[Test] public function handler_not_invoked_if_required_auth_missing() { - $auth= new SessionBased($this->flow, $this->sessions); + $auth= new SessionBased($this->authenticate(null), $this->sessions); $this->handle([], $auth->required(function($req, $res) { throw new IllegalStateException('Should not be reached'); })); @@ -60,7 +63,7 @@ public function handler_not_invoked_if_required_auth_missing() { #[Test] public function optional_without_session() { - $auth= new SessionBased($this->flow, $this->sessions); + $auth= new SessionBased($this->authenticate(null), $this->sessions); $this->handle([], $auth->optional(function($req, $res) use(&$user) { $user= $req->value('user')['username'] ?? 'guest'; })); @@ -73,7 +76,7 @@ public function optional_with_session() { $session= $this->sessions->create(); $session->register('user', ['username' => 'test']); - $auth= new SessionBased($this->flow, $this->sessions); + $auth= new SessionBased($this->authenticate(null), $this->sessions); $this->handle(['Cookie' => 'session='.$session->id()], $auth->optional(function($req, $res) use(&$user) { $user= $req->value('user')['username'] ?? 'guest'; })); @@ -85,11 +88,27 @@ public function optional_with_session() { public function optional_with_session_without_user() { $session= $this->sessions->create(); - $auth= new SessionBased($this->flow, $this->sessions); + $auth= new SessionBased($this->authenticate(null), $this->sessions); $this->handle(['Cookie' => 'session='.$session->id()], $auth->optional(function($req, $res) use(&$user) { $user= $req->value('user')['username'] ?? 'guest'; })); Assert::equals('guest', $user); } + + #[Test] + public function session_is_attached_after_authentication() { + $user= ['username' => 'test']; + $attached= null; + + $auth= new SessionBased($this->authenticate($user), $this->sessions->via(newinstance(Transport::class, [], [ + 'locate' => function($sessions, $request) { return null; }, + 'attach' => function($sessions, $response, $session) use(&$attached) { $attached= $session; }, + 'detach' => function($sessions, $response, $session) { } + ]))); + $this->handle([], $auth->required(function($req, $res) { })); + + Assert::notEquals(null, $attached); + Assert::equals($user, $attached->value('user')); + } } \ No newline at end of file