1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
<?php
namespace JsonApi\Middlewares;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class Authentication
{
// der Schlüssel des Request-Attributs, in dem der Stud.IP-Nutzer
// gefunden werden kann:
// $user = $request->getAttribute(Authentication::USER_KEY);
const USER_KEY = 'studip-user';
/**
* Der Konstruktor.
*
* @param \Closure $authenticator eine Closure, die den Nutzernamen und
* das Passwort als Argumente erhält und
* damit entweder einen Stud.IP-User-Objekt
* oder null zurückgibt
* @param array $excluded_strategies
*/
public function __construct(
// a callable accepting two arguments username and password and
// returning either null or a Stud.IP user object
private readonly \Closure $authenticator,
private readonly array $excluded_strategies = []
) {
}
/**
* Hier muss die Autorisierung implementiert werden.
*
* @param Request $request das Request-Objekt
* @param RequestHandler $handler der PSR-15 Request Handler
*
* @return ResponseInterface das neue Response-Objekt
*
* @SuppressWarnings(PHPMD.Superglobals)
*/
public function __invoke(Request $request, RequestHandler $handler)
{
$guards = $this->getGuards($request);
foreach ($guards as $guard) {
if ($guard->check()) {
$request = $this->provideUser($request, $guard->user());
return $handler->handle($request);
}
}
return $this->generateChallenges($guards);
}
// according to RFC 2616
private function generateChallenges(array $guards): Response
{
$response = new Response(401);
foreach ($guards as $guard) {
$response = $guard->addChallenge($response);
}
return $response;
}
/**
* @SuppressWarnings(PHPMD.Superglobals)
*/
private function provideUser(Request $request, \User $user): Request
{
if (
!isset($GLOBALS['user'])
|| 'nobody' === $GLOBALS['user']->id
) {
$GLOBALS['user'] = new \Seminar_User($user);
$GLOBALS['auth'] = new \Seminar_Auth();
$GLOBALS['auth']->auth = [
'uid' => $user->id,
'uname' => $user->username,
'perm' => $user->perms,
];
$GLOBALS['perm'] = new \Seminar_Perm();
$GLOBALS['MAIL_VALIDATE_BOX'] = false;
if (isset($GLOBALS['sess'])) {
$GLOBALS['sess']->delete();
}
setTempLanguage($user->id);
}
return $request->withAttribute(self::USER_KEY, $user);
}
/**
* @param Request $request
*
* @return array
*/
protected function getGuards(Request $request): array
{
$guards = [
'session' => new Auth\SessionStrategy(),
'basic' => new Auth\HttpBasicAuthStrategy($request, $this->authenticator),
'oauth2' => new Auth\OAuth2Strategy($request, $this->authenticator),
];
foreach ($this->excluded_strategies as $strategy) {
unset($guards[$strategy]);
}
return $guards;
}
}
|