Completed
Push — master ( 676e2f...9d7ce2 )
by Michael
02:17
created

TokenGenerator::parseParams()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 5
nop 3
1
<?php
2
3
namespace Schnittstabil\Csrf\TokenService;
4
5
use Base64Url\Base64Url;
6
7
/**
8
 * A TokenGenerator.
9
 */
10
class TokenGenerator
11
{
12
    protected $sign;
13
    protected $ttl;
14
    protected $base64url;
15
16
    /**
17
     * Create a new TokenGenerator.
18
     *
19
     * `$ttl` is used for calculating the expiration time of the tokens, its default value (1440sec === 24min)
20
     * correspond to the default `session.gc_maxlifetime`.
21
     *
22
     * @see http://php.net/manual/en/session.configuration.php Documentation of `session.gc-maxlifetime`
23
     *
24
     * @param callable $sign Callable used for generating the token signatures
25
     * @param int      $ttl  Default Time to Live in seconds
26
     */
27
    public function __construct(callable $sign, $ttl = 1440)
28
    {
29
        if (!is_int($ttl)) {
30
            throw new \InvalidArgumentException('ttl is not an integer');
31
        }
32
33
        if ($ttl <= 0) {
34
            throw new \InvalidArgumentException('ttl is non-positive');
35
        }
36
37
        $this->sign = $sign;
38
        $this->ttl = $ttl;
39
        $this->base64url = new Base64Url();
40
    }
41
42
    /**
43
     * Parse __invoke parameter.
44
     *
45
     * @param string $nonce Value used to associate a client session
46
     * @param int    $iat   The time that the token was issued, defaults to `time()`
47
     * @param int    $exp   The expiration time, defaults to `$iat + $this->ttl`
48
     *
49
     * @throws \InvalidArgumentException For invalid $iat, $exp and $nonce arguments
50
     */
51
    protected function parseParams($nonce, $iat = null, $exp = null)
52
    {
53
        if (!is_int($iat)) {
54
            throw new \InvalidArgumentException('iat is not an integer');
55
        }
56
57
        if (!is_int($exp)) {
58
            throw new \InvalidArgumentException('exp is not an integer');
59
        }
60
61
        if ($exp < $iat) {
62
            throw new \InvalidArgumentException('exp before iat');
63
        }
64
65
        if (!is_string($nonce)) {
66
            throw new \InvalidArgumentException('nonce is not an string');
67
        }
68
    }
69
70
    /**
71
     * Generate the payload of a CSRF token.
72
     *
73
     * @param string $nonce Value used to associate a client session
74
     * @param int    $iat   The time that the token was issued, defaults to `time()`
75
     * @param int    $exp   The expiration time
76
     *
77
     * @return \stdClass
78
     */
79
    protected function generatePayload($nonce, $iat, $exp)
80
    {
81
        $payload = new \stdClass();
82
        $payload->nonce = $nonce;
83
        $payload->iat = $iat;
84
        $payload->ttl = $exp - $iat;
85
        $payload->exp = $exp;
86
87
        return $payload;
88
    }
89
90
    /**
91
     * Generate a CSRF token.
92
     *
93
     * @param string $nonce Value used to associate a client session
94
     * @param int    $iat   The time that the token was issued, defaults to `time()`
95
     * @param int    $exp   The expiration time, defaults to `$iat + $this->ttl`
96
     *
97
     * @return string
98
     *
99
     * @throws \InvalidArgumentException For invalid $iat, $exp and $nonce arguments
100
     */
101
    public function __invoke($nonce, $iat = null, $exp = null)
102
    {
103
        if ($iat === null) {
104
            $iat = time();
105
        }
106
107
        if ($exp === null) {
108
            $exp = $iat + $this->ttl;
109
        }
110
111
        $this->parseParams($nonce, $iat, $exp);
112
113
        $payload = $this->generatePayload($nonce, $iat, $exp);
114
        $payloadBase64 = $this->base64url->encode(json_encode($payload));
115
        $sign = $this->sign;
116
117
        return $payloadBase64.'.'.$sign($payloadBase64);
118
    }
119
}
120