Skip to content

Commit c794c6c

Browse files
committed
Add PrimaryKeySessionAuthenticator
1 parent 4cc012b commit c794c6c

2 files changed

Lines changed: 551 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Authentication\Authenticator;
5+
6+
use ArrayAccess;
7+
use Authentication\Identifier\IdentifierInterface;
8+
use Cake\Http\Exception\UnauthorizedException;
9+
use Psr\Http\Message\ResponseInterface;
10+
use Psr\Http\Message\ServerRequestInterface;
11+
12+
/**
13+
* Session Authenticator with only ID
14+
*/
15+
class PrimaryKeySessionAuthenticator extends SessionAuthenticator
16+
{
17+
/**
18+
* @param \Authentication\Identifier\IdentifierInterface $identifier
19+
* @param array<string, mixed> $config
20+
*/
21+
public function __construct(IdentifierInterface $identifier, array $config = [])
22+
{
23+
$config += [
24+
'identify' => false, // Not in use
25+
];
26+
27+
parent::__construct($identifier, $config);
28+
}
29+
30+
/**
31+
* Authenticate a user using session data.
32+
*
33+
* @param \Psr\Http\Message\ServerRequestInterface $request The request to authenticate with.
34+
* @return \Authentication\Authenticator\ResultInterface
35+
*/
36+
public function authenticate(ServerRequestInterface $request): ResultInterface
37+
{
38+
$sessionKey = $this->getConfig('sessionKey');
39+
/** @var \Cake\Http\Session $session */
40+
$session = $request->getAttribute('session');
41+
42+
$userId = $session->read($sessionKey);
43+
if (!$userId) {
44+
return new Result(null, Result::FAILURE_IDENTITY_NOT_FOUND);
45+
}
46+
47+
$user = $this->_identifier->identify(['id' => $userId]);
48+
if (!$user) {
49+
return new Result(null, Result::FAILURE_IDENTITY_NOT_FOUND);
50+
}
51+
52+
return new Result($user, Result::SUCCESS);
53+
}
54+
55+
/**
56+
* @inheritDoc
57+
*/
58+
public function persistIdentity(ServerRequestInterface $request, ResponseInterface $response, $identity): array
59+
{
60+
$sessionKey = $this->getConfig('sessionKey');
61+
/** @var \Cake\Http\Session $session */
62+
$session = $request->getAttribute('session');
63+
64+
if (!$session->check($sessionKey)) {
65+
$session->renew();
66+
$session->write($sessionKey, $identity['id']);
67+
}
68+
69+
return [
70+
'request' => $request,
71+
'response' => $response,
72+
];
73+
}
74+
75+
/**
76+
* Impersonates a user
77+
*
78+
* @param \Psr\Http\Message\ServerRequestInterface $request The request
79+
* @param \Psr\Http\Message\ResponseInterface $response The response
80+
* @param \ArrayAccess $impersonator User who impersonates
81+
* @param \ArrayAccess $impersonated User impersonated
82+
* @return array
83+
*/
84+
public function impersonate(
85+
ServerRequestInterface $request,
86+
ResponseInterface $response,
87+
ArrayAccess $impersonator,
88+
ArrayAccess $impersonated,
89+
): array {
90+
$sessionKey = $this->getConfig('sessionKey');
91+
$impersonateSessionKey = $this->getConfig('impersonateSessionKey');
92+
/** @var \Cake\Http\Session $session */
93+
$session = $request->getAttribute('session');
94+
if ($session->check($impersonateSessionKey)) {
95+
throw new UnauthorizedException(
96+
'You are impersonating a user already. ' .
97+
'Stop the current impersonation before impersonating another user.',
98+
);
99+
}
100+
$session->write($impersonateSessionKey, $impersonator['id']);
101+
$session->write($sessionKey, $impersonated['id']);
102+
$this->setConfig('identify', true);
103+
104+
return [
105+
'request' => $request,
106+
'response' => $response,
107+
];
108+
}
109+
}

0 commit comments

Comments
 (0)