AuthenticationMiddleware::shibboleth()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 19.4658

Importance

Changes 0
Metric Value
eloc 10
c 0
b 0
f 0
dl 0
loc 20
ccs 2
cts 12
cp 0.1666
rs 9.6111
cc 5
nc 4
nop 2
crap 19.4658
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(private readonly UserRepository $userRepository, private readonly Site $site)
20
    {
21 5
    }
22
23
    /**
24
     * Load current user from session if exists and still valid.
25
     */
26 5
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
27
    {
28
        /** @var SessionInterface $session */
29 5
        $session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
30
        /** @var array $serverParams */
31 5
        $serverParams = $request->getServerParams();
32
33 5
        $this->shibboleth($session, $serverParams);
34
35 5
        if ($session->has('user')) {
36 4
            $user = $this->userRepository->getOneById($session->get('user'));
37
38 4
            if ($user && $user->canLogin()) {
39 2
                User::setCurrent($user);
40
            }
41
42
            // If we were supposed to be logged in, but the user is not available anymore, that means the user
43
            // was forcibly logged out (likely deleted), so we clear his entire session
44 4
            if (!User::getCurrent()) {
45 2
                $session->clear();
46
            }
47
        }
48
49 5
        return $handler->handle($request);
50
    }
51
52
    /**
53
     * Check if Shibboleth session is available and if the user is already created in the database.
54
     */
55 5
    private function shibboleth(SessionInterface $session, array $serverParams): void
56
    {
57 5
        if (array_key_exists('Shib-Identity-Provider', $serverParams) && !$session->has('user')) {
58
            // User has Shibboleth session but no user session
59
            if (array_key_exists('mail', $serverParams)) {
60
                // Check for the user in the db
61
                $user = $this->userRepository->getOneByEmail($serverParams['mail'], $this->site);
62
63
                if (!$user) {
64
                    $login = $this->generateShibbolethLogin($serverParams);
65
66
                    // Create user if a Shibboleth session is found but user cannot be found in the db
67
                    $user = $this->userRepository->createShibboleth(
68
                        $login,
69
                        $serverParams['mail'],
70
                        $this->site
71
                    );
72
                }
73
74
                $session->set('user', $user->getId());
75
            }
76
        }
77
    }
78
79
    /**
80
     * Generate login for aai users based on received attributes.
81
     *
82
     * @return string $login
83
     */
84
    private function generateShibbolethLogin(array $serverParams): string
85
    {
86
        if (array_key_exists('uid', $serverParams)) {
87
            if (array_key_exists('homeOrganization', $serverParams)) {
88
                $login = match ($serverParams['homeOrganization']) {
89
                    'unil.ch' => '-unil-' . $serverParams['uid'],
90
                    'unine.ch' => '-unine-' . $serverParams['uid'],
91
                    default => '-aai-' . $serverParams['uid'],
92
                };
93
            } else {
94
                $login = '-aai-' . $serverParams['uid'];
95
            }
96
        } else {
97
            $login = $serverParams['mail'];
98
        }
99
100
        return $login;
101
    }
102
}
103