Completed
Push — master ( cef25e...758dfd )
by Hilmi Erdem
02:56
created

DatabaseAccessTokenRepository::getFuture()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
cc 1
eloc 2
nc 1
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
    public function __construct(ConnectionInterface $connection, $table, $expires)
41
    {
42
        $this->table = $table;
43
        $this->expires = $expires;
44
        $this->connection = $connection;
45
    }
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
    public function retrieve($authenticatableId, $token)
56
    {
57
        $token = $this->find($authenticatableId, $token)->first();
58
59
        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
    public function retrieveByAttributes(array $queryParams, array $attributes = ['*'])
71
    {
72
        $query = $this->getTable();
73
74
        foreach ($queryParams as $column => $value) {
75
            $query = $query->where($column, $value);
76
        }
77
78
        $token = $query->first($attributes);
79
80
        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
    public function store($authenticatableId, $token, $expiresAt = null)
93
    {
94
        $payload = $this->getAccessTokenPayload($authenticatableId, $token, $expiresAt);
95
96
        $id = $this->getTable()->insertGetId($payload);
97
        $payload['id'] = $id;
98
99
        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
    public function update($authenticatableId, $token, $expiresAt)
112
    {
113
        return (bool) $this->find($authenticatableId, $token)->update([
114
            'expires_at' => (string) $expiresAt,
115
        ]);
116
    }
117
118
    /**
119
     * Delete a resource from the storage.
120
     *
121
     * @param  string $token The encrypted token of the authenticatable.
122
     *
123
     * @return int
124
     */
125
    public function delete($token)
126
    {
127
        return $this->getTable()->where('token', $token)->delete();
128
    }
129
130
    /**
131
     * Delete expired access tokens from the storage.
132
     *
133
     * @return void
134
     */
135
    public function deleteExpired()
136
    {
137
        $this->getTable()->where('expires_at', '<=', (string) $this->getNow())->delete();
138
    }
139
140
    /**
141
     * Get a new find query.
142
     *
143
     * @param  int    $authenticatableId
144
     * @param  string $token
145
     *
146
     * @return \Illuminate\Database\Query\Builder
147
     */
148
    private function find($authenticatableId, $token)
149
    {
150
        return $this->getTable()->where('authenticatable_id', $authenticatableId)->where('token', $token);
151
    }
152
153
    /**
154
     * Get an access token payload.
155
     *
156
     * @param  int         $authenticatableId
157
     * @param  string      $token
158
     * @param  string|null $expiresAt
159
     *
160
     * @return array
161
     */
162
    private function getAccessTokenPayload($authenticatableId, $token, $expiresAt)
163
    {
164
        $expiresAt = $expiresAt ? $expiresAt : $this->makeExpiresAt();
165
166
        $payload = [
167
            'authenticatable_id' => $authenticatableId,
168
            'token'              => $token,
169
            'created_at'         => (string) $this->getNow(),
170
            'expires_at'         => (string) $expiresAt,
171
        ];
172
173
        return $payload;
174
    }
175
176
    /**
177
     * Filter the given database response and only return if it is not expired.
178
     *
179
     * @param object|stdClass|array|null $accessToken
180
     *
181
     * @return object|stdClass|array|null
182
     */
183
    private function filterExpiredAccessToken($accessToken)
184
    {
185
        if ($accessToken && ! $this->accessTokenExpired((object) $accessToken)) {
186
            return $accessToken;
187
        }
188
    }
189
190
    /**
191
     * Determine if the token has expired.
192
     *
193
     * @param  stdClass $accessToken
194
     *
195
     * @return bool
196
     */
197
    private function accessTokenExpired(stdClass $accessToken)
198
    {
199
        $expiresAt = $accessToken->expires_at ? new Carbon($accessToken->expires_at) : $this->makeExpiresAt();
200
201
        return $this->getNow()->gte($expiresAt);
202
    }
203
204
    /**
205
     * Make the expires at property from configuration.
206
     *
207
     * @return Carbon
208
     */
209
    private function makeExpiresAt()
210
    {
211
        return $this->getFuture($this->expires);
212
    }
213
214
    /**
215
     * Get the current time.
216
     *
217
     * @return Carbon
218
     */
219
    private function getNow()
220
    {
221
        return Carbon::now();
222
    }
223
224
    /**
225
     * Get the time after given minutes.
226
     *
227
     * @param  int $minutesLater
228
     *
229
     * @return Carbon
230
     */
231
    private function getFuture($minutesLater)
232
    {
233
        return $this->getNow()->addMinutes($minutesLater);
234
    }
235
236
    /**
237
     * Begin a new database query against the table.
238
     *
239
     * @return \Illuminate\Database\Query\Builder
240
     */
241
    private function getTable()
242
    {
243
        return $this->getConnection()->table($this->table);
244
    }
245
246
    /**
247
     * Get the database connection instance.
248
     *
249
     * @return ConnectionInterface
250
     */
251
    private function getConnection()
252
    {
253
        return $this->connection;
254
    }
255
}
256