Passed
Pull Request — master (#30)
by Daniel
03:08
created

JwtBearer::getRequired()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Sainsburys\Guzzle\Oauth2\GrantType;
4
5
use Firebase\JWT\JWT;
6
use GuzzleHttp\ClientInterface;
7
use GuzzleHttp\RequestOptions;
8
use InvalidArgumentException;
9
use Psr\Http\Message\UriInterface;
10
use SplFileObject;
11
12
/**
13
 * JSON Web Token (JWT) Bearer Token Profiles for OAuth 2.0.
14
 *
15
 * @link http://tools.ietf.org/html/draft-jones-oauth-jwt-bearer-04
16
 */
17
class JwtBearer extends GrantTypeBase
18
{
19
    const CONFIG_PRIVATE_KEY = 'private_key';
20
21
    protected $grantType = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
22
23
    /**
24
     * @param ClientInterface $client
25
     * @param array           $config
26
     */
27 4
    public function __construct(ClientInterface $client, array $config = [])
28
    {
29 4
        parent::__construct($client, $config);
30
31 2
        if (!($this->config[self::CONFIG_PRIVATE_KEY] instanceof SplFileObject)) {
32 1
            throw new InvalidArgumentException('private_key needs to be instance of SplFileObject');
33
        }
34 1
    }
35
36
    /**
37
     * {@inheritdoc}
38
     */
39 4
    protected function getRequired()
40
    {
41 4
        return array_merge(parent::getRequired(), [self::CONFIG_PRIVATE_KEY => null]);
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 1
    protected function getAdditionalOptions()
48
    {
49
        return [
50 1
            RequestOptions::FORM_PARAMS => [
51 1
                'assertion' => $this->computeJwt(),
52 1
            ],
53 1
        ];
54
    }
55
56
    /**
57
     * Compute JWT, signing with provided private key.
58
     *
59
     * @return string
60
     */
61 1
    protected function computeJwt()
62
    {
63 1
        $baseUri = $this->client->getConfig('base_uri');
64
65
        $payload = [
66 1
            'iss' => $this->config[self::CONFIG_CLIENT_ID],
67 1
            'aud' => sprintf('%s/%s', rtrim(($baseUri instanceof UriInterface ? $baseUri->__toString() : ''), '/'), ltrim($this->config[self::CONFIG_TOKEN_URL], '/')),
68 1
            'exp' => time() + 60 * 60,
69 1
            'iat' => time(),
70 1
        ];
71
72 1
        return JWT::encode($payload, $this->readPrivateKey($this->config[self::CONFIG_PRIVATE_KEY]), 'RS256');
73
    }
74
75
    /**
76
     * Read private key.
77
     *
78
     * @param SplFileObject $privateKey
79
     *
80
     * @return string
81
     */
82 1
    protected function readPrivateKey(SplFileObject $privateKey)
83
    {
84 1
        $key = '';
85 1
        while (!$privateKey->eof()) {
86 1
            $key .= $privateKey->fgets();
87 1
        }
88
89 1
        return $key;
90
    }
91
}
92