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 ( 26fa1c...25ce51 )
by François
02:37
created

Storage::getUsers()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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