Completed
Pull Request — master (#48)
by
unknown
01:53
created

JwtAuthenticator::getJwsLifetime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
declare(strict_types = 1);
4
5
/*
6
 * This file is part of the AppleApnPush package
7
 *
8
 * (c) Vitaliy Zhuk <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code
12
 */
13
14
namespace Apple\ApnPush\Protocol\Http\Authenticator;
15
16
use Apple\ApnPush\Jwt\JwtInterface;
17
use Apple\ApnPush\Protocol\Http\Request;
18
use Jose\Factory\JWKFactory;
19
use Jose\Factory\JWSFactory;
20
21
/**
22
 * Authenticate request via Json Web Token
23
 */
24
class JwtAuthenticator implements AuthenticatorInterface
25
{
26
    private const ALGORITHM = 'ES256';
27
28
    /**
29
     * @var JwtInterface
30
     */
31
    private $jwt;
32
33
    /**
34
     * @var string
35
     */
36
    private $jws = '';
37
38
    /**
39
     * @var \DateInterval
40
     */
41
    private $jwsLifetime = null;
42
43
    /**
44
     * @var \DateTime
45
     */
46
    private $jwsValidTo = null;
47
48
    /**
49
     * Constructor.
50
     *
51
     * @param JwtInterface  $jwt
52
     * @param \DateInterval $jwsLifetime
53
     */
54
    public function __construct(JwtInterface $jwt, \DateInterval $jwsLifetime = null)
55
    {
56
        $this->jwt = $jwt;
57
58
        $this->jwsLifetime = is_null($jwsLifetime) ? new \DateInterval('P1H') : $jwsLifetime;
59
        if ($jwsLifetime->invert) {
60
            throw new \InvalidArgumentException('JWS lifetime must not be inverted');
61
        }
62
63
        $this->jwsLifetime = $jwsLifetime;
64
    }
65
66
    /**
67
     * Get jws lifetime
68
     *
69
     * @return \DateInterval
70
    */
71
    public function getJwsLifetime() : \DateInterval
72
    {
73
        return $this->jwsLifetime;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function authenticate(Request $request): Request
80
    {
81
        $now = new \DateTime();
82
        if ($this->jws === '' || $this->jwsValidTo < $now) {
83
            $this->jws = $this->createJwsContent();
84
            $this->jwsValidTo = ($now)->add($this->jwsLifetime);
85
        }
86
87
        $request = $request->withHeader('authorization', sprintf('bearer %s', $this->jws));
88
89
        return $request;
90
    }
91
92
    /**
93
     * Create the content of JWS by Json Web Token
94
     *
95
     * @return string
96
     */
97
    private function createJwsContent(): string
98
    {
99
        $jwk = JWKFactory::createFromKeyFile($this->jwt->getPath(), '', [
100
            'kid' => $this->jwt->getKey(),
101
            'alg' => self::ALGORITHM,
102
            'use' => 'sig',
103
        ]);
104
105
        $payload = [
106
            'iss' => $this->jwt->getTeamId(),
107
            'iat' => time(),
108
        ];
109
110
        $header = [
111
            'alg' => self::ALGORITHM,
112
            'kid' => $jwk->get('kid'),
113
        ];
114
115
        return JWSFactory::createJWSToCompactJSON(
116
            $payload,
117
            $jwk,
118
            $header
119
        );
120
    }
121
}
122