AuthenticationMiddleware   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Test Coverage

Coverage 41.67%

Importance

Changes 0
Metric Value
wmc 14
eloc 32
dl 0
loc 85
c 0
b 0
f 0
ccs 15
cts 36
cp 0.4167
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A shibboleth() 0 20 5
A generateShibbolethLogin() 0 17 3
A __construct() 0 4 1
A process() 0 24 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Middleware;
6
7
use Application\Enum\Site;
8
use Application\Model\User;
9
use Application\Repository\UserRepository;
10
use Mezzio\Session\SessionInterface;
11
use Mezzio\Session\SessionMiddleware;
12
use Psr\Http\Message\ResponseInterface;
13
use Psr\Http\Message\ServerRequestInterface;
14
use Psr\Http\Server\MiddlewareInterface;
15
use Psr\Http\Server\RequestHandlerInterface;
16
17
class AuthenticationMiddleware implements MiddlewareInterface
18
{
19 5
    public function __construct(
20
        private readonly UserRepository $userRepository,
21
        private readonly Site $site,
22 5
    ) {}
23
24
    /**
25
     * Load current user from session if exists and still valid.
26
     */
27 5
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
28
    {
29
        /** @var SessionInterface $session */
30 5
        $session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
31
        /** @var array $serverParams */
32 5
        $serverParams = $request->getServerParams();
33
34 5
        $this->shibboleth($session, $serverParams);
35
36 5
        if ($session->has('user')) {
37 4
            $user = $this->userRepository->getOneById($session->get('user'));
38
39 4
            if ($user && $user->canLogin()) {
40 2
                User::setCurrent($user);
41
            }
42
43
            // If we were supposed to be logged in, but the user is not available anymore, that means the user
44
            // was forcibly logged out (likely deleted), so we clear his entire session
45 4
            if (!User::getCurrent()) {
46 2
                $session->clear();
47
            }
48
        }
49
50 5
        return $handler->handle($request);
51
    }
52
53
    /**
54
     * Check if Shibboleth session is available and if the user is already created in the database.
55
     */
56 5
    private function shibboleth(SessionInterface $session, array $serverParams): void
57
    {
58 5
        if (array_key_exists('Shib-Identity-Provider', $serverParams) && !$session->has('user')) {
59
            // User has Shibboleth session but no user session
60
            if (array_key_exists('mail', $serverParams)) {
61
                // Check for the user in the db
62
                $user = $this->userRepository->getOneByEmail($serverParams['mail'], $this->site);
63
64
                if (!$user) {
65
                    $login = $this->generateShibbolethLogin($serverParams);
66
67
                    // Create user if a Shibboleth session is found but user cannot be found in the db
68
                    $user = $this->userRepository->createShibboleth(
69
                        $login,
70
                        $serverParams['mail'],
71
                        $this->site,
72
                    );
73
                }
74
75
                $session->set('user', $user->getId());
76
            }
77
        }
78
    }
79
80
    /**
81
     * Generate login for aai users based on received attributes.
82
     *
83
     * @return string $login
84
     */
85
    private function generateShibbolethLogin(array $serverParams): string
86
    {
87
        if (array_key_exists('uid', $serverParams)) {
88
            if (array_key_exists('homeOrganization', $serverParams)) {
89
                $login = match ($serverParams['homeOrganization']) {
90
                    'unil.ch' => '-unil-' . $serverParams['uid'],
91
                    'unine.ch' => '-unine-' . $serverParams['uid'],
92
                    default => '-aai-' . $serverParams['uid'],
93
                };
94
            } else {
95
                $login = '-aai-' . $serverParams['uid'];
96
            }
97
        } else {
98
            $login = $serverParams['mail'];
99
        }
100
101
        return $login;
102
    }
103
}
104