Completed
Push — develop ( 0e4d6e...a935b5 )
by Wisoot
02:16
created

Claim::getDataMergedWithDefault()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 12
nc 4
nop 1
1
<?php
2
3
namespace WWON\JwtGuard;
4
5
use Carbon\Carbon;
6
use Illuminate\Support\Facades\Config;
7
use WWON\JwtGuard\Exceptions\InaccessibleException;
8
use WWON\JwtGuard\Exceptions\MalformedException;
9
use WWON\JwtGuard\Exceptions\TokenExpiredException;
10
11
class Claim
12
{
13
14
    /**
15
     * subject
16
     *
17
     * @var mixed
18
     */
19
    public $sub;
20
21
    /**
22
     * issuer
23
     *
24
     * @var string
25
     */
26
    public $iss;
27
28
    /**
29
     * audience
30
     *
31
     * @var string
32
     */
33
    public $aud;
34
35
    /**
36
     * issued at
37
     *
38
     * @var int
39
     */
40
    public $iat;
41
42
    /**
43
     * expiration time
44
     *
45
     * @var int
46
     */
47
    public $exp;
48
49
    /**
50
     * not before
51
     *
52
     * @var int
53
     */
54
    public $nbf;
55
56
    /**
57
     * not after
58
     *
59
     * @var int
60
     */
61
    public $nat;
62
63
    /**
64
     * JWT identity
65
     *
66
     * @var string
67
     */
68
    public $jti;
69
70
    /**
71
     * leeway for using in comparing time
72
     *
73
     * @var int
74
     */
75
    public $leeway;
76
77
    /**
78
     * refreshable - whether the token can be refreshed
79
     *
80
     * @var bool
81
     */
82
    public $refresh = false;
83
84
    /**
85
     * timestamp when this object is instantiate
86
     *
87
     * @var int
88
     */
89
    protected $now;
90
91
    /**
92
     * Claim constructor
93
     *
94
     * @param array $data
95
     * @throws InaccessibleException
96
     * @throws MalformedException
97
     * @throws TokenExpiredException
98
     */
99
    public function __construct(array $data = [])
100
    {
101
        $data = $this->getDataMergedWithDefault($data);
102
103
        foreach ($data as $key => $value) {
104
            $attribute = camel_case($key);
105
106
            if (property_exists($this, $attribute)) {
107
                $this->{$attribute} = $value;
108
            }
109
        }
110
111
        $this->generateJti();
112
113
        $this->leeway = Config::get('jwt.leeway');
114
115
        $this->validate();
116
    }
117
118
    /**
119
     * getDataMergedWithDefault method
120
     *
121
     * @param array $data
122
     * @return array
123
     */
124
    protected function getDataMergedWithDefault(array $data = [])
125
    {
126
        $this->now = Carbon::now()->timestamp;
127
        $ttl = $this->refresh || !empty($data['refresh'])
128
            ? Config::get('jwt.refresh_ttl')
129
            : Config::get('jwt.ttl');
130
131
        $data = array_merge([
132
            'iss' => Config::get('app.url'),
133
            'iat' => $this->now,
134
            'exp' => intval($this->now + ($ttl * 60)),
135
            'nat' => intval($this->now + (Config::get('jwt.ttl') * 60))
136
        ], $data);
137
138
        return $data;
139
    }
140
141
    /**
142
     * generateJti method
143
     */
144
    protected function generateJti()
145
    {
146
        if (empty($this->jti)) {
147
            $this->jti = md5("{$this->sub}.{$this->iat}." . rand(1000, 1999));
148
        }
149
    }
150
151
    /**
152
     * validate method
153
     *
154
     * @throws InaccessibleException
155
     * @throws MalformedException
156
     * @throws TokenExpiredException
157
     */
158
    protected function validate()
159
    {
160
        $compareTime = $this->now + $this->leeway;
161
162
        if (empty($this->sub)) {
163
            throw new MalformedException;
164
        }
165
166
        if (empty($this->aud)) {
167
            throw new MalformedException;
168
        }
169
170
        if ($this->iat > $this->exp || $this->iat > $this->nat) {
171
            throw new MalformedException;
172
        }
173
174
        if ($this->exp < $compareTime) {
175
            throw new TokenExpiredException;
176
        }
177
    }
178
179
    /**
180
     * validateAccessible method
181
     *
182
     * @throws InaccessibleException
183
     */
184
    public function validateAccessible()
185
    {
186
        $compareTime = $this->now + $this->leeway;
187
188
        if ($this->nat < $compareTime) {
189
            throw new InaccessibleException;
190
        }
191
    }
192
193
    /**
194
     * toArray method
195
     *
196
     * @return array
197
     */
198
    public function toArray()
199
    {
200
        $data = [];
201
        $fields = [
202
            'sub', 'iss', 'aud', 'iat',
203
            'exp', 'nbf', 'nat', 'jti'
204
        ];
205
206
        foreach ($fields as $field) {
207
            if (!empty($this->{$field})) {
208
                $data[$field] = $this->{$field};
209
            }
210
        }
211
212
        if ($this->refresh) {
213
            $data['refresh'] = true;
214
        }
215
216
        return $data;
217
    }
218
219
}