Passed
Push — master ( 78046b...920042 )
by Steve
12:41
created

IdTokenResponse::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 2
c 1
b 0
f 1
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * @author Steve Rhoades <[email protected]>
4
 * @license http://opensource.org/licenses/MIT MIT
5
 */
6
namespace OpenIDConnectServer;
7
8
use Lcobucci\JWT\Signer\Key\LocalFileReference;
9
use OpenIDConnectServer\Repositories\IdentityProviderInterface;
10
use OpenIDConnectServer\Entities\ClaimSetInterface;
11
use League\OAuth2\Server\Entities\UserEntityInterface;
12
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
13
use League\OAuth2\Server\Entities\ScopeEntityInterface;
14
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
15
use Lcobucci\JWT\Signer\Rsa\Sha256;
16
17
class IdTokenResponse extends BearerTokenResponse
18
{
19
    /**
20
     * @var IdentityProviderInterface
21
     */
22
    protected $identityProvider;
23
24
    /**
25
     * @var ClaimExtractor
26
     */
27
    protected $claimExtractor;
28
29 5
    public function __construct(
30
        IdentityProviderInterface $identityProvider,
31
        ClaimExtractor $claimExtractor
32
    ) {
33 5
        $this->identityProvider = $identityProvider;
34 5
        $this->claimExtractor   = $claimExtractor;
35 5
    }
36
37 2
    protected function getBuilder(AccessTokenEntityInterface $accessToken, UserEntityInterface $userEntity)
38
    {
39 2
        if (class_exists("Lcobucci\JWT\Token\Builder")) {
40
            $claimsFormatter = \Lcobucci\JWT\Encoding\ChainedFormatter::withUnixTimestampDates();
0 ignored issues
show
Bug introduced by
The type Lcobucci\JWT\Encoding\ChainedFormatter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
41
            $builder = new \Lcobucci\JWT\Token\Builder(new \Lcobucci\JWT\Encoding\JoseEncoder(), $claimsFormatter);
0 ignored issues
show
Bug introduced by
The type Lcobucci\JWT\Encoding\JoseEncoder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type Lcobucci\JWT\Token\Builder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
42
        } else {
43 2
            $builder = new \Lcobucci\JWT\Builder();
44
        }
45
46
        // Add required id_token claims
47
        $builder
48 2
            ->permittedFor($accessToken->getClient()->getIdentifier())
0 ignored issues
show
Bug introduced by
$accessToken->getClient()->getIdentifier() of type string is incompatible with the type Lcobucci\JWT\list expected by parameter $audiences of Lcobucci\JWT\Builder::permittedFor(). ( Ignorable by Annotation )

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

48
            ->permittedFor(/** @scrutinizer ignore-type */ $accessToken->getClient()->getIdentifier())
Loading history...
49 2
            ->issuedBy('https://' . $_SERVER['HTTP_HOST'])
50 2
            ->issuedAt(new \DateTimeImmutable())
51 2
            ->expiresAt($accessToken->getExpiryDateTime())
52 2
            ->relatedTo($userEntity->getIdentifier());
53
54 2
        return $builder;
55
    }
56
57
    /**
58
     * @param AccessTokenEntityInterface $accessToken
59
     * @return array
60
     */
61 5
    protected function getExtraParams(AccessTokenEntityInterface $accessToken)
62
    {
63 5
        if (false === $this->isOpenIDRequest($accessToken->getScopes())) {
64 1
            return [];
65
        }
66
67
        /** @var UserEntityInterface $userEntity */
68 4
        $userEntity = $this->identityProvider->getUserEntityByIdentifier($accessToken->getUserIdentifier());
69
70 4
        if (false === is_a($userEntity, UserEntityInterface::class)) {
71 1
            throw new \RuntimeException('UserEntity must implement UserEntityInterface');
72 3
        } else if (false === is_a($userEntity, ClaimSetInterface::class)) {
73 1
            throw new \RuntimeException('UserEntity must implement ClaimSetInterface');
74
        }
75
76
        // Add required id_token claims
77 2
        $builder = $this->getBuilder($accessToken, $userEntity);
78
79
        // Need a claim factory here to reduce the number of claims by provided scope.
80 2
        $claims = $this->claimExtractor->extract($accessToken->getScopes(), $userEntity->getClaims());
81
82 2
        foreach ($claims as $claimName => $claimValue) {
83 1
            $builder = $builder->withClaim($claimName, $claimValue);
84
        }
85
86 2
        $token = $builder->getToken(
87 2
            new Sha256(),
88 2
            LocalFileReference::file($this->privateKey->getKeyPath(), (string) $this->privateKey->getPassPhrase())
89
        );
90
91
        return [
92 2
            'id_token' => $token->toString()
93
        ];
94
    }
95
96
    /**
97
     * @param ScopeEntityInterface[] $scopes
98
     * @return bool
99
     */
100 5
    private function isOpenIDRequest($scopes)
101
    {
102
        // Verify scope and make sure openid exists.
103 5
        $valid  = false;
104
105 5
        foreach ($scopes as $scope) {
106 5
            if ($scope->getIdentifier() === 'openid') {
107 4
                $valid = true;
108 4
                break;
109
            }
110
        }
111
112 5
        return $valid;
113
    }
114
115
}
116