Skip to content

Commit 0820938

Browse files
committed
Auth transport can be applied when existing middleware stack
1 parent 866a8e8 commit 0820938

File tree

2 files changed

+104
-6
lines changed

2 files changed

+104
-6
lines changed

src/Middleware/ApplyAuthenticationMiddleware.php

+38-5
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,27 @@ class ApplyAuthenticationMiddleware
2222
*/
2323
private $request_attribute_name;
2424

25+
/**
26+
* @var bool
27+
*/
28+
private $apply_on_exit;
29+
2530
/**
2631
* @param string $request_attribute_name
32+
* @param bool $apply_on_exit
2733
*/
28-
public function __construct($request_attribute_name = '')
34+
public function __construct($request_attribute_name = '', $apply_on_exit = false)
2935
{
3036
$this->request_attribute_name = $request_attribute_name;
37+
$this->apply_on_exit = (bool) $apply_on_exit;
38+
}
39+
40+
/**
41+
* @return bool
42+
*/
43+
public function applyOnExit()
44+
{
45+
return $this->apply_on_exit;
3146
}
3247

3348
/**
@@ -38,19 +53,37 @@ public function __construct($request_attribute_name = '')
3853
*/
3954
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
4055
{
41-
$transport = $this->getTransportFrom($request);
42-
43-
if ($transport instanceof TransportInterface && !$transport->isEmpty() && !$transport->isApplied()) {
44-
list($request, $response) = $transport->applyTo($request, $response);
56+
if (!$this->apply_on_exit) {
57+
list($request, $response) = $this->apply($request, $response);
4558
}
4659

4760
if ($next) {
4861
$response = $next($request, $response);
4962
}
5063

64+
if ($this->apply_on_exit) {
65+
$response = $this->apply($request, $response)[1];
66+
}
67+
5168
return $response;
5269
}
5370

71+
/**
72+
* @param ServerRequestInterface $request
73+
* @param ResponseInterface $response
74+
* @return array
75+
*/
76+
private function apply(ServerRequestInterface $request, ResponseInterface $response)
77+
{
78+
$transport = $this->getTransportFrom($request);
79+
80+
if ($transport instanceof TransportInterface && !$transport->isEmpty() && !$transport->isApplied()) {
81+
list($request, $response) = $transport->applyTo($request, $response);
82+
}
83+
84+
return [$request, $response];
85+
}
86+
5487
/**
5588
* Get authentication response transport from request.
5689
*

test/src/ApplyAuthenticationMiddlewareTest.php

+66-1
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,73 @@ public function testUserIsAuthenticated()
6161
/** @var ServerRequestInterface $request */
6262
$request = $this->request->withAttribute('test_transport', new AuthorizationTransport($session_adapter, $user, $session, [1, 2, 3]));
6363

64+
$middleware = new ApplyAuthenticationMiddleware('test_transport');
65+
$this->assertFalse($middleware->applyOnExit());
66+
67+
/** @var ResponseInterface $response */
68+
$response = call_user_func($middleware, $request, $this->response);
69+
70+
$this->assertInstanceOf(ResponseInterface::class, $response);
71+
72+
$set_cookie_header = $response->getHeaderLine('Set-Cookie');
73+
74+
$this->assertNotEmpty($set_cookie_header);
75+
$this->assertContains($session_cookie_name, $set_cookie_header);
76+
$this->assertContains('my-session-id', $set_cookie_header);
77+
}
78+
79+
/**
80+
* Test if next middleware in stack is called.
81+
*/
82+
public function testNextIsCalled()
83+
{
6484
/** @var ResponseInterface $response */
65-
$response = call_user_func(new ApplyAuthenticationMiddleware('test_transport'), $request, $this->response);
85+
$response = call_user_func(new ApplyAuthenticationMiddleware('test_transport'), $this->request, $this->response, function (ServerRequestInterface $request, ResponseInterface $response, callable $next = null) {
86+
$response = $response->withHeader('X-Test', 'Yes, found!');
87+
88+
if ($next) {
89+
$response = $next($request, $response);
90+
}
91+
92+
return $response;
93+
});
94+
95+
$this->assertInstanceOf(ResponseInterface::class, $response);
96+
$this->assertSame('Yes, found!', $response->getHeaderLine('X-Test'));
97+
}
98+
99+
/**
100+
* Test if authentication is applied based on request attribute.
101+
*/
102+
public function testUserIsAuthentiatedOnExit()
103+
{
104+
$user = new AuthenticatedUser(1, '[email protected]', 'Ilija Studen', '123');
105+
$user_repository = new UserRepository([
106+
'[email protected]' => new AuthenticatedUser(1, '[email protected]', 'Ilija Studen', '123'),
107+
]);
108+
$session_repository = new SessionRepository([new Session('my-session-id', '[email protected]')]);
109+
110+
$session_cookie_name = 'test-session-cookie';
111+
112+
$session_adapter = new BrowserSessionAdapter($user_repository, $session_repository, $this->cookies, $session_cookie_name);
113+
$session = $session_adapter->authenticate($user, []);
114+
115+
/** @var ServerRequestInterface $request */
116+
$request = $this->request->withAttribute('test_transport', new AuthorizationTransport($session_adapter, $user, $session, [1, 2, 3]));
117+
118+
$middleware = new ApplyAuthenticationMiddleware('test_transport', true);
119+
$this->assertTrue($middleware->applyOnExit());
120+
121+
/** @var ResponseInterface $response */
122+
$response = call_user_func($middleware, $request, $this->response, function (ServerRequestInterface $request, ResponseInterface $response, callable $next = null) {
123+
$this->assertEmpty($response->getHeaderLine('Set-Cookie'));
124+
125+
if ($next) {
126+
$response = $next($request, $response);
127+
}
128+
129+
return $response;
130+
});
66131

67132
$this->assertInstanceOf(ResponseInterface::class, $response);
68133

0 commit comments

Comments
 (0)