Passed
Pull Request — master (#32)
by
unknown
08:05
created

IdTokenResponse::getBuilder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 10
c 2
b 0
f 0
dl 0
loc 16
ccs 0
cts 13
cp 0
rs 9.9332
cc 1
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 * @author Steve Rhoades <[email protected]>
4
 * @license http://opensource.org/licenses/MIT MIT
5
 */
6
namespace OpenIDConnectServer;
7
8
use \DateTimeImmutable;
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\Key;
16
use Lcobucci\JWT\Signer\Rsa\Sha256;
17
use Lcobucci\JWT\Configuration;
18
19
class IdTokenResponse extends BearerTokenResponse
20
{
21
    /**
22
     * @var IdentityProviderInterface
23
     */
24
    protected $identityProvider;
25
26
    /**
27
     * @var ClaimExtractor
28
     */
29
    protected $claimExtractor;
30
31
    /**
32
     * @var Configuration
33
     */
34
    private $config;
35
36
    public function __construct(
37
        IdentityProviderInterface $identityProvider,
38
        ClaimExtractor $claimExtractor,
39
        Configuration $config
40
    ) {
41
        $this->identityProvider = $identityProvider;
42
        $this->claimExtractor   = $claimExtractor;
43
        $this->config           = $config;
44
    }
45
46
    protected function getBuilder(AccessTokenEntityInterface $accessToken, UserEntityInterface $userEntity)
47
    {
48
        $dateTimeImmutableObject = new DateTimeImmutable();
49
50
        // Add required id_token claims
51
        $builder = $this->config
52
            ->builder()
53
            ->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

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