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 ( aff5f5...d962fa )
by François
02:15
created

Storage::deleteMotd()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 0
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 PDOException;
23
use SURFnet\VPN\Common\RandomInterface;
24
25
class Storage
26
{
27
    /** @var \PDO */
28
    private $db;
29
30
    /** @var \SURFnet\VPN\Common\RandomInterface */
31
    private $random;
32
33
    public function __construct(PDO $db, RandomInterface $random)
34
    {
35
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
36
        $this->db = $db;
37
        // enable foreign keys
38
        $this->db->query('PRAGMA foreign_keys = ON');
39
40
        $this->random = $random;
41
    }
42
43
    public function getUsers()
44
    {
45
        $stmt = $this->db->prepare(
46
            'SELECT external_user_id, is_disabled
47
             FROM users'
48
        );
49
        $stmt->execute();
50
51
        $userList = [];
52
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result) {
53
            $userList[] = [
54
                'user_id' => $result['external_user_id'],
55
                'is_disabled' => boolval($result['is_disabled']),
56
            ];
57
        }
58
59
        return $userList;
60
    }
61
62 View Code Duplication
    public function getUserCertificateInfo($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...
63
    {
64
        $stmt = $this->db->prepare(
65
            'SELECT 
66
                u.external_user_id AS user_id, 
67
                u.is_disabled AS user_is_disabled,
68
                c.display_name AS display_name,
69
                c.is_disabled AS certificate_is_disabled 
70
             FROM users u, certificates c 
71
             WHERE c.common_name = :common_name'
72
        );
73
74
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
75
        $stmt->execute();
76
77
        return $stmt->fetch(PDO::FETCH_ASSOC);
78
    }
79
80
    private function getUserId($externalUserId)
81
    {
82
        $stmt = $this->db->prepare(
83
            'SELECT user_id
84
             FROM users
85
             WHERE external_user_id = :external_user_id'
86
        );
87
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
88
        $stmt->execute();
89
90
        if (false !== $result = $stmt->fetch(PDO::FETCH_ASSOC)) {
91
            return $result['user_id'];
92
        }
93
94
        // user does not exist yet, add it
95
        $stmt = $this->db->prepare(
96
            'INSERT INTO users (external_user_id, user_id) VALUES(:external_user_id, :user_id)'
97
        );
98
99
        $userId = $this->random->get(16);
100
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
101
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
102
        $stmt->execute();
103
104
        return $userId;
105
    }
106
107
    public function setVootToken($externalUserId, $vootToken)
108
    {
109
        $userId = $this->getUserId($externalUserId);
110
        $stmt = $this->db->prepare(
111
            'INSERT INTO voot_tokens (user_id, voot_token) VALUES(:user_id, :voot_token)'
112
        );
113
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
114
        $stmt->bindValue(':voot_token', $vootToken, PDO::PARAM_STR);
115
116
        $stmt->execute();
117
118
        return 1 === $stmt->rowCount();
119
    }
120
121 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...
122
    {
123
        $userId = $this->getUserId($externalUserId);
124
        $stmt = $this->db->prepare(
125
            'SELECT COUNT(*)
126
             FROM voot_tokens
127
             WHERE user_id = :user_id'
128
        );
129
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
130
        $stmt->execute();
131
132
        return 1 === intval($stmt->fetchColumn());
133
    }
134
135 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...
136
    {
137
        $userId = $this->getUserId($externalUserId);
138
        $stmt = $this->db->prepare(
139
            'DELETE FROM voot_tokens WHERE user_id = :user_id'
140
        );
141
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
142
143
        $stmt->execute();
144
145
        return 1 === $stmt->rowCount();
146
    }
147
148 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...
149
    {
150
        $userId = $this->getUserId($externalUserId);
151
        $stmt = $this->db->prepare(
152
            'SELECT COUNT(*)
153
             FROM totp_secrets
154
             WHERE user_id = :user_id'
155
        );
156
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
157
        $stmt->execute();
158
159
        return 1 === intval($stmt->fetchColumn());
160
    }
161
162
    public function getTotpSecret($externalUserId)
163
    {
164
        $userId = $this->getUserId($externalUserId);
165
        $stmt = $this->db->prepare(
166
            'SELECT totp_secret
167
             FROM totp_secrets
168
             WHERE user_id = :user_id'
169
        );
170
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
171
        $stmt->execute();
172
173
        return $stmt->fetchColumn();
174
    }
175
176 View Code Duplication
    public function setTotpSecret($externalUserId, $totpSecret)
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...
177
    {
178
        $userId = $this->getUserId($externalUserId);
179
        $stmt = $this->db->prepare(
180
            'INSERT INTO totp_secrets (user_id, totp_secret) VALUES(:user_id, :totp_secret)'
181
        );
182
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
183
        $stmt->bindValue(':totp_secret', $totpSecret, PDO::PARAM_STR);
184
185
        try {
186
            $stmt->execute();
187
        } catch (PDOException $e) {
188
            // unable to add the TOTP secret, probably uniqueness contrains
189
            return false;
190
        }
191
192
        return true;
193
    }
194
195 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...
196
    {
197
        $userId = $this->getUserId($externalUserId);
198
        $stmt = $this->db->prepare(
199
            'DELETE FROM totp_secrets WHERE user_id = :user_id'
200
        );
201
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
202
203
        $stmt->execute();
204
205
        return 1 === $stmt->rowCount();
206
    }
207
208 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...
209
    {
210
        $stmt = $this->db->prepare(
211
            'DELETE FROM users WHERE external_user_id = :external_user_id'
212
        );
213
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
214
215
        $stmt->execute();
216
217
        return 1 === $stmt->rowCount();
218
    }
219
220 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...
221
    {
222
        $userId = $this->getUserId($externalUserId);
223
        $stmt = $this->db->prepare(
224
            'INSERT INTO certificates (common_name, user_id, display_name, valid_from, valid_to) VALUES(:common_name, :user_id, :display_name, :valid_from, :valid_to)'
225
        );
226
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
227
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
228
        $stmt->bindValue(':display_name', $displayName, PDO::PARAM_STR);
229
        $stmt->bindValue(':valid_from', $validFrom, PDO::PARAM_INT);
230
        $stmt->bindValue(':valid_to', $validTo, PDO::PARAM_INT);
231
232
        $stmt->execute();
233
234
        return 1 === $stmt->rowCount();
235
    }
236
237
    public function getCertificates($externalUserId)
238
    {
239
        $userId = $this->getUserId($externalUserId);
240
        $stmt = $this->db->prepare(
241
            'SELECT common_name, display_name, valid_from, valid_to, is_disabled
242
             FROM certificates
243
             WHERE user_id = :user_id'
244
        );
245
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
246
        $stmt->execute();
247
248
        $certificateList = [];
249
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result) {
250
            $certificateList[] = [
251
                'common_name' => $result['common_name'],
252
                'display_name' => $result['display_name'],
253
                'valid_from' => intval($result['valid_from']),
254
                'valid_to' => intval($result['valid_to']),
255
                'is_disabled' => boolval($result['is_disabled']),
256
            ];
257
        }
258
259
        return $certificateList;
260
    }
261
262 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...
263
    {
264
        $stmt = $this->db->prepare(
265
            'UPDATE certificates SET is_disabled = 1 WHERE common_name = :common_name'
266
        );
267
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
268
269
        $stmt->execute();
270
271
        return 1 === $stmt->rowCount();
272
    }
273
274 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...
275
    {
276
        $stmt = $this->db->prepare(
277
            'UPDATE certificates SET is_disabled = 0 WHERE common_name = :common_name'
278
        );
279
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
280
281
        $stmt->execute();
282
283
        return 1 === $stmt->rowCount();
284
    }
285
286 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...
287
    {
288
        $stmt = $this->db->prepare(
289
            'UPDATE users SET is_disabled = 1 WHERE external_user_id = :external_user_id'
290
        );
291
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
292
293
        $stmt->execute();
294
295
        // XXX it seems on update the rowCount is always 1, even if nothing was
296
        // modified?
297
        return 1 === $stmt->rowCount();
298
    }
299
300 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...
301
    {
302
        $stmt = $this->db->prepare(
303
            'UPDATE users SET is_disabled = 0 WHERE external_user_id = :external_user_id'
304
        );
305
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
306
307
        $stmt->execute();
308
309
        // XXX it seems on update the rowCount is always 1, even if nothing was
310
        // modified?
311
        return 1 === $stmt->rowCount();
312
    }
313
314 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...
315
    {
316
        $stmt = $this->db->prepare(
317
            'SELECT COUNT(*)
318
             FROM users
319
             WHERE external_user_id = :external_user_id AND is_disabled = 1'
320
        );
321
        $stmt->bindValue(':external_user_id', $externalUserId, PDO::PARAM_STR);
322
        $stmt->execute();
323
324
        return 1 === intval($stmt->fetchColumn());
325
    }
326
327
    public function getAllLogEntries()
328
    {
329
        $stmt = $this->db->prepare(
330
            'SELECT c.user_id, l.common_name, l.connected_at, l.disconnected_at, l.bytes_transferred
331
             FROM connection_log l, certificates c
332
             WHERE c.common_name = l.common_name'
333
        );
334
335
        $stmt->execute();
336
337
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
338
    }
339
340 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...
341
    {
342
        $stmt = $this->db->prepare(
343
            'INSERT INTO connection_log (
344
                profile_id,
345
                common_name,
346
                ip4,
347
                ip6,
348
                connected_at
349
             ) 
350
             VALUES(
351
                :profile_id, 
352
                :common_name,
353
                :ip4,
354
                :ip6,
355
                :connected_at
356
             )'
357
        );
358
359
        $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR);
360
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
361
        $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR);
362
        $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR);
363
        $stmt->bindValue(':connected_at', $connectedAt, PDO::PARAM_INT);
364
365
        $stmt->execute();
366
367
        return 1 === $stmt->rowCount();
368
    }
369
370
    public function clientDisconnect($profileId, $commonName, $ip4, $ip6, $connectedAt, $disconnectedAt, $bytesTransferred)
371
    {
372
        $stmt = $this->db->prepare(
373
            'UPDATE connection_log
374
                SET 
375
                    disconnected_at = :disconnected_at, 
376
                    bytes_transferred = :bytes_transferred
377
                WHERE 
378
                    profile_id = :profile_id AND
379
                    common_name = :common_name AND
380
                    ip4 = :ip4 AND
381
                    ip6 = :ip6 AND
382
                    connected_at = :connected_at
383
            '
384
        );
385
386
        $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR);
387
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
388
        $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR);
389
        $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR);
390
        $stmt->bindValue(':connected_at', $connectedAt, PDO::PARAM_INT);
391
        $stmt->bindValue(':disconnected_at', $disconnectedAt, PDO::PARAM_INT);
392
        $stmt->bindValue(':bytes_transferred', $bytesTransferred, PDO::PARAM_INT);
393
394
        $stmt->execute();
395
396
        return 1 === $stmt->rowCount();
397
    }
398
399 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...
400
    {
401
        $stmt = $this->db->prepare(
402
            'SELECT profile_id, common_name, ip4, ip6, connected_at, disconnected_at
403
             FROM connection_log
404
             WHERE
405
                (ip4 = :ip_address OR ip6 = :ip_address)
406
                AND connected_at < :date_time_unix
407
                AND (disconnected_at > :date_time_unix OR disconnected_at IS NULL)'
408
        );
409
        $stmt->bindValue(':ip_address', $ipAddress, PDO::PARAM_STR);
410
        $stmt->bindValue(':date_time_unix', $dateTimeUnix, PDO::PARAM_STR);
411
        $stmt->execute();
412
413
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
414
    }
415
416 View Code Duplication
    public function recordTotpKey($externalUserId, $totpKey, $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...
417
    {
418
        $userId = $this->getUserId($externalUserId);
419
        $stmt = $this->db->prepare(
420
            'INSERT INTO totp_log (
421
                user_id,
422
                totp_key,
423
                time_unix
424
             ) 
425
             VALUES(
426
                :user_id, 
427
                :totp_key,
428
                :time_unix
429
             )'
430
        );
431
432
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
433
        $stmt->bindValue(':totp_key', $totpKey, PDO::PARAM_STR);
434
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
435
436
        try {
437
            $stmt->execute();
438
        } catch (PDOException $e) {
439
            // unable to record the TOTP, probably uniqueness contrains
440
            return false;
441
        }
442
443
        return true;
444
    }
445
446 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...
447
    {
448
        $stmt = $this->db->prepare(
449
            sprintf(
450
                'DELETE FROM connection_log
451
                    WHERE connected_at < :time_unix'
452
            )
453
        );
454
455
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
456
457
        return $stmt->execute();
458
    }
459
460 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...
461
    {
462
        $stmt = $this->db->prepare(
463
            sprintf(
464
                'DELETE FROM totp_log
465
                    WHERE time_unix < :time_unix'
466
            )
467
        );
468
469
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
470
471
        return $stmt->execute();
472
    }
473
474
    public function motd()
475
    {
476
        $stmt = $this->db->prepare(
477
            'SELECT motd_message FROM motd'
478
        );
479
480
        $stmt->execute();
481
482
        return $stmt->fetchColumn();
483
    }
484
485 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...
486
    {
487
        $this->deleteMotd();
488
489
        $stmt = $this->db->prepare(
490
            'INSERT INTO motd (motd_message) VALUES(:motd_message)'
491
        );
492
493
        $stmt->bindValue(':motd_message', $motdMessage, PDO::PARAM_STR);
494
        $stmt->execute();
495
496
        return 1 === $stmt->rowCount();
497
    }
498
499
    public function deleteMotd()
500
    {
501
        $stmt = $this->db->prepare(
502
            'DELETE FROM motd'
503
        );
504
505
        $stmt->execute();
506
507
        return 1 === $stmt->rowCount();
508
    }
509
510
    public function init()
511
    {
512
        $queryList = [
513
            'CREATE TABLE IF NOT EXISTS users (
514
                user_id VARCHAR(255) PRIMARY KEY,
515
                external_user_id VARCHAR(255) UNIQUE NOT NULL,
516
                is_disabled BOOLEAN DEFAULT 0
517
            )',
518
            'CREATE TABLE IF NOT EXISTS voot_tokens (
519
                voot_token VARCHAR(255) NOT NULL PRIMARY KEY,   
520
                user_id VARCHAR(255) UNIQUE NOT NULL REFERENCES users(user_id) ON DELETE CASCADE
521
            )',
522
            'CREATE TABLE IF NOT EXISTS totp_secrets (
523
                totp_secret VARCHAR(255) NOT NULL PRIMARY KEY,   
524
                user_id VARCHAR(255) UNIQUE NOT NULL REFERENCES users(user_id) ON DELETE CASCADE
525
            )',
526
            'CREATE TABLE IF NOT EXISTS certificates (
527
                common_name VARCHAR(255) NOT NULL PRIMARY KEY,
528
                display_name VARCHAR(255) NOT NULL,
529
                valid_from INTEGER NOT NULL,
530
                valid_to INTEGER NOT NULL,
531
                is_disabled BOOLEAN DEFAULT 0,
532
                user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE
533
            )',
534
            'CREATE TABLE IF NOT EXISTS connection_log (
535
                common_name VARCHAR(255) NOT NULL REFERENCES certificates(common_name),
536
                profile_id VARCHAR(255) NOT NULL,
537
                ip4 VARCHAR(255) NOT NULL,
538
                ip6 VARCHAR(255) NOT NULL,
539
                connected_at INTEGER NOT NULL,
540
                disconnected_at INTEGER DEFAULT NULL,
541
                bytes_transferred INTEGER DEFAULT NULL                
542
            )',
543
            'CREATE TABLE IF NOT EXISTS totp_log (
544
                totp_key VARCHAR(255) NOT NULL,
545
                time_unix INTEGER NOT NULL,
546
                user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
547
                UNIQUE(user_id, totp_key)
548
            )',
549
            'CREATE TABLE IF NOT EXISTS motd (
550
                motd_message TEXT NOT NULL
551
            )',
552
        ];
553
554
        foreach ($queryList as $query) {
555
            $this->db->query($query);
556
        }
557
    }
558
}
559