Completed
Push — master ( 96bb9e...dc511e )
by Hilmi Erdem
02:05
created

DatabaseAccessTokenRepository::tokenExpired()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Erdemkeren\TemporaryAccess;
4
5
use stdClass;
6
use Carbon\Carbon;
7
use Illuminate\Database\ConnectionInterface;
8
use Erdemkeren\TemporaryAccess\Contracts\AccessTokenRepositoryInterface;
9
10
final class DatabaseAccessTokenRepository implements AccessTokenRepositoryInterface
11
{
12
    /**
13
     * The connection.
14
     *
15
     * @var ConnectionInterface
16
     */
17
    private $connection;
18
19
    /**
20
     * The temporary access token table.
21
     *
22
     * @var string
23
     */
24
    private $table;
25
26
    /**
27
     * The number of seconds a token should last.
28
     *
29
     * @var int
30
     */
31
    private $expires;
32
33
    /**
34
     * DatabaseAccessTokenRepository constructor.
35
     *
36
     * @param ConnectionInterface $connection The database connection interface.
37
     * @param string              $table      The name of the database table.
38
     * @param int                 $expires    The default expire time in minutes.
39
     */
40 11
    public function __construct(ConnectionInterface $connection, $table, $expires)
41
    {
42 11
        $this->table = $table;
43 11
        $this->expires = $expires;
44 11
        $this->connection = $connection;
45 11
    }
46
47
    /**
48
     * Retrieve an access token from the storage.
49
     *
50
     * @param  int    $authenticatableId The unique identifier of the authenticatable who has the access.
51
     * @param  string $token             The encrypted token of the authenticatable.
52
     *
53
     * @return stdClass|array|bool
54
     */
55 2
    public function retrieve($authenticatableId, $token)
56
    {
57 2
        $token = $this->find($authenticatableId, $token)->first();
58
59 2
        return $this->filterExpiredAccessToken($token);
60
    }
61
62
    /**
63
     * Retrieve the first valid resource by the given attributes.
64
     *
65
     * @param  array $queryParams The key - value pairs to match.
66
     * @param  array $attributes  The attributes to be returned from the storage.
67
     *
68
     * @return stdClass|array|null
69
     */
70 3
    public function retrieveByAttributes(array $queryParams, array $attributes = ['*'])
71
    {
72 3
        $query = $this->getTable();
73
74 3
        foreach ($queryParams as $column => $value) {
75 3
            $query = $query->where($column, $value);
76 3
        }
77
78 3
        $token = $query->first($attributes);
79
80 3
        return $this->filterExpiredAccessToken($token);
81
    }
82
83
    /**
84
     * Store a new access token in the storage.
85
     *
86
     * @param  int         $authenticatableId The unique identifier of the authenticatable who has the access.
87
     * @param  string      $token             The encrypted token of the authenticatable.
88
     * @param  string|null $expiresAt         The expiration date of the access token.
89
     *
90
     * @return array
91
     */
92 2
    public function store($authenticatableId, $token, $expiresAt = null)
93
    {
94 2
        $payload = $this->getAccessTokenPayload($authenticatableId, $token, $expiresAt);
95
96 2
        $id = $this->getTable()->insertGetId($payload);
97 2
        $payload['id'] = $id;
98
99 2
        return $payload;
100
    }
101
102
    /**
103
     * Update the expire date of the given access token in the storage.
104
     *
105
     * @param  int    $authenticatableId The unique identifier of the authenticatable.
106
     * @param  string $token             The encrypted token to be updated.
107
     * @param  string $expiresAt         The new expiration date of the access token.
108
     *
109
     * @return bool
110
     */
111 1
    public function update($authenticatableId, $token, $expiresAt)
112
    {
113 1
        return (bool) $this->find($authenticatableId, $token)->update([
114 1
            'expires_at' => (string) $expiresAt,
115 1
        ]);
116
    }
117
118
    /**
119
     * Delete a resource from the storage.
120
     *
121
     * @param  int    $authenticatableId The unique identifier of the authenticatable.
122
     * @param  string $token             The encrypted token of the authenticatable.
123
     *
124
     * @return int
125
     */
126 1
    public function delete($authenticatableId, $token)
127
    {
128 1
        return (bool) $this->find($authenticatableId, $token)->delete();
129
    }
130
131
    /**
132
     * Delete expired access tokens from the storage.
133
     *
134
     * @return void
135
     */
136 1
    public function deleteExpired()
137
    {
138 1
        $this->getTable()->where('expires_at', '<=', (string) $this->getNow())->delete();
139 1
    }
140
141
    /**
142
     * Get a new find query.
143
     *
144
     * @param  int    $authenticatableId
145
     * @param  string $token
146
     *
147
     * @return \Illuminate\Database\Query\Builder
148
     */
149 4
    private function find($authenticatableId, $token)
150
    {
151 4
        return $this->getTable()->where('authenticatable_id', $authenticatableId)->where('token', $token);
152
    }
153
154
    /**
155
     * Get an access token payload.
156
     *
157
     * @param  int         $authenticatableId
158
     * @param  string      $token
159
     * @param  string|null $expiresAt
160
     *
161
     * @return array
162
     */
163 2
    private function getAccessTokenPayload($authenticatableId, $token, $expiresAt)
164
    {
165 2
        $expiresAt = $expiresAt ? $expiresAt : $this->makeExpiresAt();
166
167
        $payload = [
168 2
            'authenticatable_id' => $authenticatableId,
169 2
            'token'              => $token,
170 2
            'created_at'         => (string) $this->getNow(),
171 2
            'expires_at'         => (string) $expiresAt,
172 2
        ];
173
174 2
        return $payload;
175
    }
176
177
    /**
178
     * Filter the given database response and only return if it is not expired.
179
     *
180
     * @param stdClass|array|null $accessToken
181
     *
182
     * @return stdClass|array|null
183
     */
184 5
    private function filterExpiredAccessToken($accessToken)
185
    {
186 5
        if ($accessToken && ! $this->accessTokenExpired((object) $accessToken)) {
187 2
            return $accessToken;
188
        }
189 3
    }
190
191
    /**
192
     * Determine if the token has expired.
193
     *
194
     * @param  stdClass $accessToken
195
     *
196
     * @return bool
197
     */
198 4
    private function accessTokenExpired(stdClass $accessToken)
199
    {
200 4
        $expiresAt = $accessToken->expires_at ? new Carbon($accessToken->expires_at) : $this->makeExpiresAt();
201
202 4
        return $this->getNow()->gte($expiresAt);
203
    }
204
205
    /**
206
     * Make the expires at property from configuration.
207
     *
208
     * @return Carbon
209
     */
210 1
    private function makeExpiresAt()
211
    {
212 1
        return $this->getFuture($this->expires);
213
    }
214
215
    /**
216
     * Get the current time.
217
     *
218
     * @return Carbon
219
     */
220 7
    private function getNow()
221
    {
222 7
        return Carbon::now();
223
    }
224
225
    /**
226
     * Get the time after given minutes.
227
     *
228
     * @param  int $minutesLater
229
     *
230
     * @return Carbon
231
     */
232 1
    private function getFuture($minutesLater)
233
    {
234 1
        return $this->getNow()->addMinutes($minutesLater);
235
    }
236
237
    /**
238
     * Begin a new database query against the table.
239
     *
240
     * @return \Illuminate\Database\Query\Builder
241
     */
242 10
    private function getTable()
243
    {
244 10
        return $this->getConnection()->table($this->table);
245
    }
246
247
    /**
248
     * Get the database connection instance.
249
     *
250
     * @return ConnectionInterface
251
     */
252 10
    private function getConnection()
253
    {
254 10
        return $this->connection;
255
    }
256
}
257