GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 1d0c52...9650d4 )
by François
02:18
created

Storage::setVootToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 2
1
<?php
2
/**
3
 *  Copyright (C) 2016 SURFnet.
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU Affero General Public License as
7
 *  published by the Free Software Foundation, either version 3 of the
8
 *  License, or (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU Affero General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU Affero General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace SURFnet\VPN\Server;
20
21
use PDO;
22
use SURFnet\VPN\Common\RandomInterface;
23
24
class Storage
25
{
26
    /** @var \PDO */
27
    private $db;
28
29
    /** @var \SURFnet\VPN\Common\RandomInterface */
30
    private $random;
31
32
    public function __construct(PDO $db, RandomInterface $random)
33
    {
34
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
35
        $this->db = $db;
36
        // enable foreign keys
37
        $this->db->query('PRAGMA foreign_keys = ON');
38
39
        $this->random = $random;
40
    }
41
42
    public function getUsers()
43
    {
44
        $stmt = $this->db->prepare(
45
            'SELECT external_user_id, is_disabled
46
             FROM users'
47
        );
48
        $stmt->execute();
49
50
        $userList = [];
51
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result) {
52
            $userList[] = [
53
                'user_id' => $result['external_user_id'],
54
                'is_disabled' => boolval($result['is_disabled']),
55
            ];
56
        }
57
58
        return $userList;
59
    }
60
61 View Code Duplication
    public function getUserCertificateStatus($commonName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
    {
63
        $stmt = $this->db->prepare(
64
            'SELECT 
65
                u.external_user_id AS external_user_id, 
66
                u.is_disabled AS user_is_disabled, 
67
                c.is_disabled AS certificate_is_disabled 
68
             FROM users u, certificates c 
69
             WHERE c.common_name = :common_name'
70
        );
71
72
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
73
        $stmt->execute();
74
75
        return $stmt->fetch(PDO::FETCH_ASSOC);
76
    }
77
78
    private function getUserId($externalUserId)
79
    {
80
        $stmt = $this->db->prepare(
81
            'SELECT user_id
82
             FROM users
83
             WHERE external_user_id = :external_user_id'
84
        );
85
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
86
        $stmt->execute();
87
88
        if (false !== $result = $stmt->fetch(PDO::FETCH_ASSOC)) {
89
            return $result['user_id'];
90
        }
91
92
        // user does not exist yet, add it
93
        $stmt = $this->db->prepare(
94
            'INSERT INTO users (external_user_id, user_id) VALUES(:external_user_id, :user_id)'
95
        );
96
97
        $userId = $this->random->get(16);
98
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
99
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
100
        $stmt->execute();
101
102
        return $userId;
103
    }
104
105
    public function setVootToken($externalUserId, $vootToken)
106
    {
107
        $userId = $this->getUserId($externalUserId);
108
        $stmt = $this->db->prepare(
109
            'INSERT INTO voot_tokens (user_id, voot_token) VALUES(:user_id, :voot_token)'
110
        );
111
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
112
        $stmt->bindValue(':voot_token', $vootToken, PDO::PARAM_STR);
113
114
        $stmt->execute();
115
116
        return 1 === $stmt->rowCount();
117
    }
118
119 View Code Duplication
    public function hasVootToken($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
    {
121
        $userId = $this->getUserId($externalUserId);
122
        $stmt = $this->db->prepare(
123
            'SELECT COUNT(*)
124
             FROM voot_tokens
125
             WHERE user_id = :user_id'
126
        );
127
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
128
        $stmt->execute();
129
130
        return 1 === intval($stmt->fetchColumn());
131
    }
132
133 View Code Duplication
    public function deleteVootToken($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
134
    {
135
        $userId = $this->getUserId($externalUserId);
136
        $stmt = $this->db->prepare(
137
            'DELETE FROM voot_tokens WHERE user_id = :user_id'
138
        );
139
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
140
141
        $stmt->execute();
142
143
        return 1 === $stmt->rowCount();
144
    }
145
146 View Code Duplication
    public function hasTotpSecret($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
    {
148
        $userId = $this->getUserId($externalUserId);
149
        $stmt = $this->db->prepare(
150
            'SELECT COUNT(*)
151
             FROM totp_secrets
152
             WHERE user_id = :user_id'
153
        );
154
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
155
        $stmt->execute();
156
157
        return 1 === intval($stmt->fetchColumn());
158
    }
159
160
    public function getTotpSecret($externalUserId)
161
    {
162
        $userId = $this->getUserId($externalUserId);
163
        $stmt = $this->db->prepare(
164
            'SELECT totp_secret
165
             FROM totp_secrets
166
             WHERE user_id = :user_id'
167
        );
168
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
169
        $stmt->execute();
170
171
        return $stmt->fetchColumn();
172
    }
173
174
    public function setTotpSecret($externalUserId, $totpSecret)
175
    {
176
        $userId = $this->getUserId($externalUserId);
177
        $stmt = $this->db->prepare(
178
            'INSERT INTO totp_secrets (user_id, totp_secret) VALUES(:user_id, :totp_secret)'
179
        );
180
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
181
        $stmt->bindValue(':totp_secret', $totpSecret, PDO::PARAM_STR);
182
183
        $stmt->execute();
184
185
        return 1 === $stmt->rowCount();
186
    }
187
188 View Code Duplication
    public function deleteTotpSecret($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
189
    {
190
        $userId = $this->getUserId($externalUserId);
191
        $stmt = $this->db->prepare(
192
            'DELETE FROM totp_secrets WHERE user_id = :user_id'
193
        );
194
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
195
196
        $stmt->execute();
197
198
        return 1 === $stmt->rowCount();
199
    }
200
201 View Code Duplication
    public function deleteUser($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
    {
203
        $stmt = $this->db->prepare(
204
            'DELETE FROM users WHERE external_user_id = :external_user_id'
205
        );
206
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
207
208
        $stmt->execute();
209
210
        return 1 === $stmt->rowCount();
211
    }
212
213 View Code Duplication
    public function addCertificate($externalUserId, $commonName, $displayName, $validFrom, $validTo)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
    {
215
        $userId = $this->getUserId($externalUserId);
216
        $stmt = $this->db->prepare(
217
            'INSERT INTO certificates (common_name, user_id, display_name, valid_from, valid_to) VALUES(:common_name, :user_id, :display_name, :valid_from, :valid_to)'
218
        );
219
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
220
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
221
        $stmt->bindValue(':display_name', $displayName, PDO::PARAM_STR);
222
        $stmt->bindValue(':valid_from', $validFrom, PDO::PARAM_INT);
223
        $stmt->bindValue(':valid_to', $validTo, PDO::PARAM_INT);
224
225
        $stmt->execute();
226
227
        return 1 === $stmt->rowCount();
228
    }
229
230
    public function getCertificates($externalUserId)
231
    {
232
        $userId = $this->getUserId($externalUserId);
233
        $stmt = $this->db->prepare(
234
            'SELECT common_name, display_name, valid_from, valid_to, is_disabled
235
             FROM certificates
236
             WHERE user_id = :user_id'
237
        );
238
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
239
        $stmt->execute();
240
241
        $certificateList = [];
242
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result) {
243
            $certificateList[] = [
244
                'common_name' => $result['common_name'],
245
                'display_name' => $result['display_name'],
246
                'valid_from' => intval($result['valid_from']),
247
                'valid_to' => intval($result['valid_to']),
248
                'is_disabled' => boolval($result['is_disabled']),
249
            ];
250
        }
251
252
        return $certificateList;
253
    }
254
255 View Code Duplication
    public function disableCertificate($commonName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
    {
257
        $stmt = $this->db->prepare(
258
            'UPDATE certificates SET is_disabled = 1 WHERE common_name = :common_name'
259
        );
260
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
261
262
        $stmt->execute();
263
264
        return 1 === $stmt->rowCount();
265
    }
266
267 View Code Duplication
    public function enableCertificate($commonName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
268
    {
269
        $stmt = $this->db->prepare(
270
            'UPDATE certificates SET is_disabled = 0 WHERE common_name = :common_name'
271
        );
272
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
273
274
        $stmt->execute();
275
276
        return 1 === $stmt->rowCount();
277
    }
278
279 View Code Duplication
    public function disableUser($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
    {
281
        $stmt = $this->db->prepare(
282
            'UPDATE users SET is_disabled = 1 WHERE external_user_id = :external_user_id'
283
        );
284
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
285
286
        $stmt->execute();
287
288
        // XXX it seems on update the rowCount is always 1, even if nothing was
289
        // modified?
290
        return 1 === $stmt->rowCount();
291
    }
292
293 View Code Duplication
    public function enableUser($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
294
    {
295
        $stmt = $this->db->prepare(
296
            'UPDATE users SET is_disabled = 0 WHERE external_user_id = :external_user_id'
297
        );
298
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
299
300
        $stmt->execute();
301
302
        // XXX it seems on update the rowCount is always 1, even if nothing was
303
        // modified?
304
        return 1 === $stmt->rowCount();
305
    }
306
307 View Code Duplication
    public function isDisabledUser($externalUserId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
    {
309
        $stmt = $this->db->prepare(
310
            'SELECT COUNT(*)
311
             FROM users
312
             WHERE external_user_id = :external_user_id AND is_disabled = 1'
313
        );
314
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
315
        $stmt->execute();
316
317
        return 1 === intval($stmt->fetchColumn());
318
    }
319
320 View Code Duplication
    public function clientConnect($profileId, $commonName, $ip4, $ip6, $connectedAt)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
321
    {
322
        $stmt = $this->db->prepare(
323
            'INSERT INTO connection_log (
324
                profile_id,
325
                common_name,
326
                ip4,
327
                ip6,
328
                connected_at
329
             ) 
330
             VALUES(
331
                :profile_id, 
332
                :common_name,
333
                :ip4,
334
                :ip6,
335
                :connected_at
336
             )'
337
        );
338
339
        $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR);
340
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
341
        $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR);
342
        $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR);
343
        $stmt->bindValue(':connected_at', $connectedAt, PDO::PARAM_INT);
344
345
        $stmt->execute();
346
347
        return 1 === $stmt->rowCount();
348
    }
349
350
    public function clientDisconnect($profileId, $commonName, $ip4, $ip6, $connectedAt, $disconnectedAt, $bytesTransferred)
351
    {
352
        $stmt = $this->db->prepare(
353
            'UPDATE connection_log
354
                SET 
355
                    disconnected_at = :disconnected_at, 
356
                    bytes_transferred = :bytes_transferred
357
                WHERE 
358
                    profile_id = :profile_id AND
359
                    common_name = :common_name AND
360
                    ip4 = :ip4 AND
361
                    ip6 = :ip6 AND
362
                    connected_at = :connected_at
363
            '
364
        );
365
366
        $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR);
367
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
368
        $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR);
369
        $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR);
370
        $stmt->bindValue(':connected_at', $connectedAt, PDO::PARAM_INT);
371
        $stmt->bindValue(':disconnected_at', $disconnectedAt, PDO::PARAM_INT);
372
        $stmt->bindValue(':bytes_transferred', $bytesTransferred, PDO::PARAM_INT);
373
374
        $stmt->execute();
375
376
        return 1 === $stmt->rowCount();
377
    }
378
379 View Code Duplication
    public function getLogEntry($dateTimeUnix, $ipAddress)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
380
    {
381
        $stmt = $this->db->prepare(
382
            'SELECT profile_id, common_name, ip4, ip6, connected_at, disconnected_at
383
             FROM connection_log
384
             WHERE
385
                (ip4 = :ip_address OR ip6 = :ip_address)
386
                AND connected_at < :date_time_unix
387
                AND (disconnected_at > :date_time_unix OR disconnected_at IS NULL)'
388
        );
389
        $stmt->bindValue(':ip_address', $ipAddress, PDO::PARAM_STR);
390
        $stmt->bindValue(':date_time_unix', $dateTimeUnix, PDO::PARAM_STR);
391
        $stmt->execute();
392
393
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
394
    }
395
396
    public function recordTotpKey($externalUserId, $totpKey, $timeUnix)
397
    {
398
        $userId = $this->getUserId($externalUserId);
399
        $stmt = $this->db->prepare(
400
            'INSERT INTO totp_log (
401
                user_id,
402
                totp_key,
403
                time_unix
404
             ) 
405
             VALUES(
406
                :user_id, 
407
                :totp_key,
408
                :time_unix
409
             )'
410
        );
411
412
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
413
        $stmt->bindValue(':totp_key', $totpKey, PDO::PARAM_STR);
414
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
415
416
        $stmt->execute();
417
418
        return 1 === $stmt->rowCount();
419
    }
420
421 View Code Duplication
    public function cleanConnectionLog($timeUnix)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
422
    {
423
        $stmt = $this->db->prepare(
424
            sprintf(
425
                'DELETE FROM connection_log
426
                    WHERE connected_at < :time_unix'
427
            )
428
        );
429
430
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
431
432
        return $stmt->execute();
433
    }
434
435 View Code Duplication
    public function cleanTotpLog($timeUnix)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
436
    {
437
        $stmt = $this->db->prepare(
438
            sprintf(
439
                'DELETE FROM totp_log
440
                    WHERE time_unix < :time_unix'
441
            )
442
        );
443
444
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
445
446
        return $stmt->execute();
447
    }
448
449
    public function motd()
450
    {
451
        $stmt = $this->db->prepare(
452
            'SELECT motd_message FROM motd'
453
        );
454
455
        $stmt->execute();
456
457
        return $stmt->fetchColumn();
458
    }
459
460 View Code Duplication
    public function setMotd($motdMessage)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
461
    {
462
        $this->deleteMotd();
463
464
        $stmt = $this->db->prepare(
465
            'INSERT INTO motd (motd_message) VALUES(:motd_message)'
466
        );
467
468
        $stmt->bindValue(':motd_message', $motdMessage, PDO::PARAM_STR);
469
        $stmt->execute();
470
471
        return 1 === $stmt->rowCount();
472
    }
473
474
    public function deleteMotd()
475
    {
476
        $stmt = $this->db->prepare(
477
            'DELETE FROM motd'
478
        );
479
480
        $stmt->execute();
481
482
        return 1 === $stmt->rowCount();
483
    }
484
485
    public function init()
486
    {
487
        $queryList = [
488
            'CREATE TABLE IF NOT EXISTS users (
489
                user_id VARCHAR(255) PRIMARY KEY,
490
                external_user_id VARCHAR(255) UNIQUE NOT NULL,
491
                is_disabled BOOLEAN DEFAULT 0
492
            )',
493
            'CREATE TABLE IF NOT EXISTS voot_tokens (
494
                voot_token VARCHAR(255) NOT NULL PRIMARY KEY,   
495
                user_id VARCHAR(255) UNIQUE NOT NULL REFERENCES users(user_id) ON DELETE CASCADE
496
            )',
497
            'CREATE TABLE IF NOT EXISTS totp_secrets (
498
                totp_secret VARCHAR(255) NOT NULL PRIMARY KEY,   
499
                user_id VARCHAR(255) UNIQUE NOT NULL REFERENCES users(user_id) ON DELETE CASCADE
500
            )',
501
            'CREATE TABLE IF NOT EXISTS certificates (
502
                common_name VARCHAR(255) NOT NULL PRIMARY KEY,
503
                user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
504
                display_name VARCHAR(255) NOT NULL,
505
                valid_from INTEGER NOT NULL,
506
                valid_to INTEGER NOT NULL,
507
                is_disabled BOOLEAN DEFAULT 0
508
            )',
509
            'CREATE TABLE IF NOT EXISTS connection_log (
510
                common_name VARCHAR(255) NOT NULL REFERENCES certificates(common_name),
511
                profile_id VARCHAR(255) NOT NULL,
512
                ip4 VARCHAR(255) NOT NULL,
513
                ip6 VARCHAR(255) NOT NULL,
514
                connected_at INTEGER NOT NULL,
515
                disconnected_at INTEGER DEFAULT NULL,
516
                bytes_transferred INTEGER DEFAULT NULL                
517
            )',
518
            'CREATE TABLE IF NOT EXISTS totp_log (
519
                user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
520
                totp_key VARCHAR(255) NOT NULL,
521
                time_unix INTEGER NOT NULL
522
            )',
523
            'CREATE TABLE IF NOT EXISTS motd (
524
                motd_message TEXT
525
            )',
526
        ];
527
528
        foreach ($queryList as $query) {
529
            $this->db->query($query);
530
        }
531
    }
532
}
533