UserInfo   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Importance

Changes 7
Bugs 1 Features 0
Metric Value
eloc 58
c 7
b 1
f 0
dl 0
loc 160
rs 10
wmc 28

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getPairwiseSubjectIdentifierAlgorithm() 0 3 1
A calculateSubjectIdentifier() 0 16 4
A getClaimValues() 0 6 2
A getClaimsFromClaimScope() 0 15 4
A getUserinfo() 0 14 1
A isPairwiseSubjectIdentifierSupported() 0 3 1
A enablePairwiseSubject() 0 3 1
A getSectorIdentifierHost() 0 14 4
B getUserClaim() 0 24 9
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2019 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\OpenIdConnect\UserInfo;
15
16
use OAuth2Framework\Component\Core\Client\Client;
17
use OAuth2Framework\Component\Core\UserAccount\UserAccount;
18
use OAuth2Framework\Component\OpenIdConnect\UserInfo\Claim\ClaimManager;
19
use OAuth2Framework\Component\OpenIdConnect\UserInfo\Claim\ClaimSourceManager;
20
use OAuth2Framework\Component\OpenIdConnect\UserInfo\Pairwise\PairwiseSubjectIdentifierAlgorithm;
21
use OAuth2Framework\Component\OpenIdConnect\UserInfo\ScopeSupport\UserInfoScopeSupportManager;
22
23
class UserInfo
24
{
25
    /**
26
     * @var null|PairwiseSubjectIdentifierAlgorithm
27
     */
28
    private $pairwiseAlgorithm;
29
30
    /**
31
     * @var UserInfoScopeSupportManager
32
     */
33
    private $userinfoScopeSupportManager;
34
35
    /**
36
     * @var ClaimSourceManager
37
     */
38
    private $claimSourceManager;
39
40
    /**
41
     * @var ClaimManager
42
     */
43
    private $claimManager;
44
45
    /**
46
     * UserInfo constructor.
47
     */
48
    public function __construct(UserInfoScopeSupportManager $userinfoScopeSupportManager, ClaimManager $claimManager, ClaimSourceManager $claimSourceManager)
49
    {
50
        $this->userinfoScopeSupportManager = $userinfoScopeSupportManager;
51
        $this->claimManager = $claimManager;
52
        $this->claimSourceManager = $claimSourceManager;
53
    }
54
55
    public function getUserinfo(Client $client, UserAccount $userAccount, string $redirectUri, array $requestedClaims, ?string $scope, ?string $claimsLocales): array
56
    {
57
        $requestedClaims = array_merge(
58
            $this->getClaimsFromClaimScope($scope),
59
            $requestedClaims
60
        );
61
        $claims = $this->getClaimValues($userAccount, $requestedClaims, $claimsLocales);
62
        /*$claims = array_merge(
63
            $claims,
64
            $this->claimSourceManager->getUserInfo($userAccount, $scope, [])
65
        );*/
66
        $claims['sub'] = $this->calculateSubjectIdentifier($client, $userAccount, $redirectUri);
67
68
        return $claims;
69
    }
70
71
    public function enablePairwiseSubject(PairwiseSubjectIdentifierAlgorithm $pairwiseAlgorithm): void
72
    {
73
        $this->pairwiseAlgorithm = $pairwiseAlgorithm;
74
    }
75
76
    public function isPairwiseSubjectIdentifierSupported(): bool
77
    {
78
        return null !== $this->pairwiseAlgorithm;
79
    }
80
81
    public function getPairwiseSubjectIdentifierAlgorithm(): ?PairwiseSubjectIdentifierAlgorithm
82
    {
83
        return $this->pairwiseAlgorithm;
84
    }
85
86
    private function getClaimsFromClaimScope(?string $scope): array
87
    {
88
        $result = [];
89
        $scope = $scope ?? '';
90
91
        foreach (explode(' ', $scope) as $scp) {
92
            if ($this->userinfoScopeSupportManager->has($scp)) {
93
                $scope_claims = $this->userinfoScopeSupportManager->get($scp)->getAssociatedClaims();
94
                foreach ($scope_claims as $scope_claim) {
95
                    $result[$scope_claim] = null;
96
                }
97
            }
98
        }
99
100
        return $result;
101
    }
102
103
    private function getClaimValues(UserAccount $userAccount, array $requestedClaims, ?string $claimsLocales): array
104
    {
105
        $result = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
106
        $claimsLocales = null === $claimsLocales ? [] : array_unique(explode(' ', $claimsLocales));
107
108
        return $this->claimManager->getUserInfo($userAccount, $requestedClaims, $claimsLocales);
109
        /*foreach ($requestedClaims as $claim => $config) {
110
            foreach ($claimsLocales as $claims_locale) {
111
                $claim_locale = $this->computeClaimWithLocale($claim, $claims_locale);
112
                $claim_value = $this->getUserClaim($userAccount, $claim_locale, $config);
113
                if (null !== $claim_value) {
114
                    $result[$claim_locale] = $claim_value;
115
116
                    break;
117
                }
118
            }
119
        }*/
120
    }
121
122
    /**
123
     * @return null|mixed
124
     */
125
    private function getUserClaim(UserAccount $userAccount, string $claimName, ?array $config)
0 ignored issues
show
Unused Code introduced by
The method getUserClaim() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
126
    {
127
        // FIXME: "acr" claim support has to be added.
128
        if ($userAccount->has($claimName)) {
129
            $claim = $userAccount->get($claimName);
130
            switch (true) {
131
                case \is_array($config) && \array_key_exists('value', $config):
132
                    if ($claim === $config['value']) {
133
                        return $claim;
134
                    }
135
136
                    break;
137
                case \is_array($config) && \array_key_exists('values', $config) && \is_array($config['values']):
138
                    if (\in_array($claim, $config['values'], true)) {
139
                        return $claim;
140
                    }
141
142
                    break;
143
                default:
144
                    return $claim;
145
            }
146
        }
147
148
        return null;
149
    }
150
151
    private function calculateSubjectIdentifier(Client $client, UserAccount $userAccount, string $redirectUri): string
152
    {
153
        $sub = $userAccount->getUserAccountId()->getValue();
154
        if (null === $this->pairwiseAlgorithm) {
155
            return $sub;
156
        }
157
        if ($client->has('subject_type') && ('pairwise' === $client->get('subject_type'))) {
158
            $sectorIdentifierHost = $this->getSectorIdentifierHost($client, $redirectUri);
159
160
            return $this->pairwiseAlgorithm->calculateSubjectIdentifier(
161
                $userAccount,
162
                $sectorIdentifierHost
163
            );
164
        }
165
166
        return $sub;
167
    }
168
169
    private function getSectorIdentifierHost(Client $client, string $redirectUri): string
170
    {
171
        $uri = $redirectUri;
172
173
        if (true === $client->has('sector_identifier_uri')) {
174
            $uri = $client->get('sector_identifier_uri');
175
        }
176
177
        $data = \Safe\parse_url($uri);
0 ignored issues
show
Bug introduced by
It seems like $uri can also be of type null; however, parameter $url of Safe\parse_url() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

177
        $data = \Safe\parse_url(/** @scrutinizer ignore-type */ $uri);
Loading history...
178
        if (!\is_array($data) || !\array_key_exists('host', $data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always false.
Loading history...
179
            throw new \InvalidArgumentException(\Safe\sprintf('Invalid Sector Identifier Uri "%s".', $uri));
180
        }
181
182
        return $data['host'];
183
    }
184
}
185