Failed Conditions
Push — ng ( 935f22...b3431d )
by Florent
04:01
created

IdTokenHintDiscovery::find()   D

Complexity

Conditions 9
Paths 24

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 4.909
c 0
b 0
f 0
cc 9
eloc 24
nc 24
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2018 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace OAuth2Framework\Component\Server\AuthorizationEndpoint\UserAccountDiscovery;
15
16
use OAuth2Framework\Component\Server\AuthorizationEndpoint\Authorization;
17
use OAuth2Framework\Component\Server\AuthorizationEndpoint\Exception\CreateRedirectionException;
18
use OAuth2Framework\Component\Server\AuthorizationEndpoint\Exception\RedirectToLoginPageException;
19
use OAuth2Framework\Component\Server\Core\Response\OAuth2Exception;
20
use OAuth2Framework\Component\Server\Core\UserAccount\UserAccountId;
21
use OAuth2Framework\Component\Server\Core\UserAccount\UserAccountRepository;
22
use OAuth2Framework\Component\Server\OpenIdConnect\IdToken;
23
use OAuth2Framework\Component\Server\OpenIdConnect\IdTokenId;
24
use OAuth2Framework\Component\Server\OpenIdConnect\IdTokenLoader;
25
use OAuth2Framework\Component\Server\OpenIdConnect\UserInfo\Pairwise\PairwiseSubjectIdentifierAlgorithm;
26
use Psr\Http\Message\ServerRequestInterface;
27
28
final class IdTokenHintDiscovery implements UserAccountDiscovery
29
{
30
    /**
31
     * @var IdTokenLoader
32
     */
33
    private $idTokenLoader;
34
35
    /**
36
     * @var PairwiseSubjectIdentifierAlgorithm|null
37
     */
38
    private $pairwiseAlgorithm = null;
39
40
    /**
41
     * @var UserAccountRepository
42
     */
43
    private $userAccountRepository;
44
45
    /**
46
     * IdTokenHintExtension constructor.
47
     *
48
     * @param IdTokenLoader         $idTokenLoader
49
     * @param UserAccountRepository $userAccountRepository
50
     */
51
    public function __construct(IdTokenLoader $idTokenLoader, UserAccountRepository $userAccountRepository)
52
    {
53
        $this->idTokenLoader = $idTokenLoader;
54
        $this->userAccountRepository = $userAccountRepository;
55
    }
56
57
    /**
58
     * @param PairwiseSubjectIdentifierAlgorithm $pairwiseAlgorithm
59
     */
60
    public function enablePairwiseSubject(PairwiseSubjectIdentifierAlgorithm $pairwiseAlgorithm)
61
    {
62
        $this->pairwiseAlgorithm = $pairwiseAlgorithm;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function find(ServerRequestInterface $request, Authorization $authorization, callable $next): Authorization
69
    {
70
        $authorization = $next($request, $authorization);
71
        if ($authorization->hasQueryParam('id_token_hint')) {
72
            try {
73
                $idTokenId = IdTokenId::create($authorization->getQueryParam('id_token_hint'));
74
                $idToken = $this->idTokenLoader->load($idTokenId);
75
                if (!$idToken instanceof IdToken) {
76
                    throw new \InvalidArgumentException('The parameter "id_token_hint" does not contain a valid ID Token.');
77
                }
78
                $userAccountId = $idToken->getUserAccountId();
79
                if (null !== $this->pairwiseAlgorithm) {
80
                    $publicId = $this->pairwiseAlgorithm->getPublicIdFromSubjectIdentifier($userAccountId->getValue());
81
                    if (null === $publicId) {
82
                        throw new \InvalidArgumentException('Unable to retrieve the user account using the "id_token_hint" parameter.');
83
                    }
84
                } else {
85
                    $publicId = $userAccountId->getValue();
86
                }
87
                $realUserAccountId = UserAccountId::create($publicId);
88
89
                $tmp = $this->userAccountRepository->find($realUserAccountId);
90
                if (null !== $tmp) {
91
                    if (null !== $authorization->getUserAccount()) {
92
                        if ($tmp->getPublicId()->getValue() !== $authorization->getUserAccount()->getPublicId()->getValue()) {
93
                            throw new RedirectToLoginPageException($authorization);
94
                        }
95
                    }
96
                }
97
            } catch (\InvalidArgumentException $e) {
98
                throw new CreateRedirectionException($authorization, OAuth2Exception::ERROR_INVALID_REQUEST, $e->getMessage());
99
            }
100
        }
101
102
        return $authorization;
103
    }
104
}
105