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 ( deefbf...06457e )
by François
02:40
created

Storage::clientConnect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 12

Duplication

Lines 29
Ratio 61.7 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 29
loc 47
rs 9.0303
c 1
b 0
f 0
cc 1
eloc 12
nc 1
nop 5
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, only for SQLite!
38
        $this->db->query('PRAGMA foreign_keys = ON');
39
40
        $this->random = $random;
41
    }
42
43
    public function getId($userId)
44
    {
45
        $stmt = $this->db->prepare(
46
<<< 'SQL'
47
    SELECT 
48
        id
49
    FROM 
50
        users
51
    WHERE user_id = :user_id
52
SQL
53
        );
54
55
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
56
        $stmt->execute();
57
        if (false !== $result = $stmt->fetch(PDO::FETCH_ASSOC)) {
58
            return $result['id'];
59
        }
60
61
        // user does not exist yet, add it
62
        $stmt = $this->db->prepare(
63
<<< 'SQL'
64
    INSERT INTO 
65
        users (
66
            user_id
67
        )
68
    VALUES (
69
        :user_id
70
    )
71
SQL
72
        );
73
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR);
74
        $stmt->execute();
75
76
        return $this->db->lastInsertId('id');
77
    }
78
79
    public function getUsers()
80
    {
81
        $stmt = $this->db->prepare(
82
<<< 'SQL'
83
    SELECT
84
        user_id, 
85
        is_disabled
86
    FROM 
87
        users
88
SQL
89
        );
90
        $stmt->execute();
91
92
        $userList = [];
93
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result) {
94
            $userList[] = [
95
                'user_id' => $result['user_id'],
96
                'is_disabled' => (bool) $result['is_disabled'],
97
            ];
98
        }
99
100
        return $userList;
101
    }
102
103 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...
104
    {
105
        $stmt = $this->db->prepare(
106
<<< 'SQL'
107
    SELECT 
108
        u.user_id AS user_id, 
109
        u.is_disabled AS user_is_disabled,
110
        c.display_name AS display_name,
111
        c.is_disabled AS certificate_is_disabled 
112
    FROM 
113
        users u, certificates c 
114
    WHERE 
115
        u.id = c.user_id AND 
116
        c.common_name = :common_name
117
SQL
118
        );
119
120
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
121
        $stmt->execute();
122
123
        return $stmt->fetch(PDO::FETCH_ASSOC);
124
    }
125
126 View Code Duplication
    public function getVootToken($userId)
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...
127
    {
128
        $userId = $this->getId($userId);
129
        $stmt = $this->db->prepare(
130
<<< 'SQL'
131
    SELECT
132
        voot_token
133
    FROM 
134
        voot_tokens
135
    WHERE 
136
        user_id = :user_id
137
SQL
138
        );
139
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
140
        $stmt->execute();
141
142
        return $stmt->fetchColumn();
143
    }
144
145 View Code Duplication
    public function setVootToken($userId, $vootToken)
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...
146
    {
147
        $userId = $this->getId($userId);
148
        $stmt = $this->db->prepare(
149
<<< 'SQL'
150
    INSERT INTO voot_tokens 
151
        (user_id, voot_token) 
152
    VALUES
153
        (:user_id, :voot_token)
154
SQL
155
        );
156
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
157
        $stmt->bindValue(':voot_token', $vootToken, PDO::PARAM_STR);
158
159
        $stmt->execute();
160
161
        // XXX deal with errors!
162
        return 1 === $stmt->rowCount();
163
    }
164
165 View Code Duplication
    public function hasVootToken($userId)
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...
166
    {
167
        $userId = $this->getId($userId);
168
        $stmt = $this->db->prepare(
169
<<< 'SQL'
170
    SELECT
171
        COUNT(*)
172
    FROM 
173
        voot_tokens
174
    WHERE 
175
        user_id = :user_id
176
SQL
177
        );
178
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
179
        $stmt->execute();
180
181
        return 1 === (int) $stmt->fetchColumn();
182
    }
183
184 View Code Duplication
    public function deleteVootToken($userId)
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...
185
    {
186
        $userId = $this->getId($userId);
187
        $stmt = $this->db->prepare(
188
<<< 'SQL'
189
    DELETE FROM 
190
        voot_tokens 
191
    WHERE 
192
        user_id = :user_id
193
SQL
194
        );
195
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
196
197
        $stmt->execute();
198
        // XXX error handling!
199
        return 1 === $stmt->rowCount();
200
    }
201
202 View Code Duplication
    public function hasTotpSecret($userId)
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
        $userId = $this->getId($userId);
205
        $stmt = $this->db->prepare(
206
<<< 'SQL'
207
    SELECT
208
        COUNT(*)
209
    FROM 
210
        totp_secrets
211
    WHERE 
212
        user_id = :user_id
213
SQL
214
        );
215
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
216
        $stmt->execute();
217
218
        return 1 === (int) $stmt->fetchColumn();
219
    }
220
221 View Code Duplication
    public function getTotpSecret($userId)
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...
222
    {
223
        $userId = $this->getId($userId);
224
        $stmt = $this->db->prepare(
225
<<< 'SQL'
226
    SELECT
227
        totp_secret
228
    FROM 
229
        totp_secrets
230
    WHERE 
231
        user_id = :user_id
232
SQL
233
        );
234
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
235
        $stmt->execute();
236
237
        return $stmt->fetchColumn();
238
    }
239
240 View Code Duplication
    public function setTotpSecret($userId, $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...
241
    {
242
        $userId = $this->getId($userId);
243
        $stmt = $this->db->prepare(
244
<<< 'SQL'
245
    INSERT INTO totp_secrets 
246
        (user_id, totp_secret) 
247
    VALUES
248
        (:user_id, :totp_secret)
249
SQL
250
        );
251
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
252
        $stmt->bindValue(':totp_secret', $totpSecret, PDO::PARAM_STR);
253
254
        try {
255
            $stmt->execute();
256
257
            return true;
258
        } catch (PDOException $e) {
259
            // unable to add the TOTP secret, probably uniqueness contrains
260
            return false;
261
        }
262
    }
263
264 View Code Duplication
    public function deleteTotpSecret($userId)
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...
265
    {
266
        $userId = $this->getId($userId);
267
        $stmt = $this->db->prepare(
268
<<< 'SQL'
269
    DELETE FROM 
270
        totp_secrets 
271
    WHERE 
272
        user_id = :user_id
273
SQL
274
        );
275
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
276
277
        $stmt->execute();
278
279
        // XXX error handling?
280
        return 1 === $stmt->rowCount();
281
    }
282
283 View Code Duplication
    public function deleteUser($userId)
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...
284
    {
285
        $userId = $this->getId($userId);
286
        $stmt = $this->db->prepare(
287
<<< 'SQL'
288
    DELETE FROM 
289
        users 
290
    WHERE 
291
        id = :user_id
292
SQL
293
        );
294
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
295
296
        $stmt->execute();
297
        // XXX error handling?
298
        return 1 === $stmt->rowCount();
299
    }
300
301 View Code Duplication
    public function addCertificate($userId, $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...
302
    {
303
        $userId = $this->getId($userId);
304
        $stmt = $this->db->prepare(
305
<<< 'SQL'
306
    INSERT INTO certificates 
307
        (common_name, user_id, display_name, valid_from, valid_to)
308
    VALUES
309
        (:common_name, :user_id, :display_name, :valid_from, :valid_to)
310
SQL
311
        );
312
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
313
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
314
        $stmt->bindValue(':display_name', $displayName, PDO::PARAM_STR);
315
        $stmt->bindValue(':valid_from', $validFrom, PDO::PARAM_INT);
316
        $stmt->bindValue(':valid_to', $validTo, PDO::PARAM_INT);
317
318
        $stmt->execute();
319
        // XXX
320
        return 1 === $stmt->rowCount();
321
    }
322
323
    public function getCertificates($userId)
324
    {
325
        $userId = $this->getId($userId);
326
        $stmt = $this->db->prepare(
327
<<< 'SQL'
328
    SELECT
329
        common_name, 
330
        display_name, 
331
        valid_from, 
332
        valid_to, 
333
        is_disabled
334
    FROM 
335
        certificates
336
    WHERE 
337
        user_id = :user_id
338
SQL
339
        );
340
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
341
        $stmt->execute();
342
343
        $certificateList = [];
344
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result) {
345
            $certificateList[] = [
346
                'common_name' => $result['common_name'],
347
                'display_name' => $result['display_name'],
348
                'valid_from' => (int) $result['valid_from'],
349
                'valid_to' => (int) $result['valid_to'],
350
                'is_disabled' => (bool) $result['is_disabled'],
351
            ];
352
        }
353
354
        return $certificateList;
355
    }
356
357 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...
358
    {
359
        $stmt = $this->db->prepare(
360
<<< 'SQL'
361
    UPDATE 
362
        certificates 
363
    SET 
364
        is_disabled = 1 
365
    WHERE
366
        common_name = :common_name
367
SQL
368
        );
369
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
370
371
        $stmt->execute();
372
        // XXX
373
        return 1 === $stmt->rowCount();
374
    }
375
376 View Code Duplication
    public function deleteCertificate($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...
377
    {
378
        $stmt = $this->db->prepare(
379
<<< 'SQL'
380
    DELETE FROM 
381
        certificates 
382
    WHERE 
383
        common_name = :common_name
384
SQL
385
        );
386
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
387
388
        $stmt->execute();
389
        // XXX
390
        return 1 === $stmt->rowCount();
391
    }
392
393 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...
394
    {
395
        $stmt = $this->db->prepare(
396
<<< 'SQL'
397
    UPDATE 
398
        certificates 
399
    SET 
400
        is_disabled = 0 
401
    WHERE 
402
        common_name = :common_name
403
SQL
404
        );
405
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
406
407
        $stmt->execute();
408
        // XXX
409
        return 1 === $stmt->rowCount();
410
    }
411
412 View Code Duplication
    public function disableUser($userId)
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...
413
    {
414
        $userId = $this->getId($userId);
415
        $stmt = $this->db->prepare(
416
<<< 'SQL'
417
    UPDATE
418
        users 
419
    SET 
420
        is_disabled = 1 
421
    WHERE 
422
        id = :user_id
423
SQL
424
        );
425
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
426
427
        $stmt->execute();
428
429
        // XXX it seems on update the rowCount is always 1, even if nothing was
430
        // modified?
431
        return 1 === $stmt->rowCount();
432
    }
433
434 View Code Duplication
    public function enableUser($userId)
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...
435
    {
436
        $userId = $this->getId($userId);
437
        $stmt = $this->db->prepare(
438
<<< 'SQL'
439
    UPDATE
440
        users 
441
    SET 
442
        is_disabled = 0 
443
    WHERE 
444
        id = :user_id
445
SQL
446
        );
447
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
448
449
        $stmt->execute();
450
451
        // XXX it seems on update the rowCount is always 1, even if nothing was
452
        // modified?
453
        return 1 === $stmt->rowCount();
454
    }
455
456 View Code Duplication
    public function isDisabledUser($userId)
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...
457
    {
458
        $userId = $this->getId($userId);
459
        $stmt = $this->db->prepare(
460
<<< 'SQL'
461
    SELECT
462
        COUNT(*)
463
    FROM 
464
        users
465
    WHERE 
466
        id = :user_id 
467
    AND 
468
        is_disabled = 1
469
SQL
470
        );
471
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
472
        $stmt->execute();
473
474
        return 1 === (int) $stmt->fetchColumn();
475
    }
476
477
    public function getAllLogEntries()
478
    {
479
        $stmt = $this->db->prepare(
480
<<< 'SQL'
481
    SELECT 
482
        user_id,
483
        common_name, 
484
        connected_at, 
485
        disconnected_at, 
486
        bytes_transferred
487
    FROM 
488
        connection_log
489
    WHERE
490
        disconnected_at IS NOT NULL
491
    ORDER BY
492
        connected_at
493
SQL
494
        );
495
496
        $stmt->execute();
497
498
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
499
    }
500
501 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...
502
    {
503
        // this query is so complex, because we want to store the user_id in the
504
        // log as well, not just the common_name... the user may delete the
505
        // certificate, or the user account may be deleted...
506
        $stmt = $this->db->prepare(
507
<<< 'SQL'
508
    INSERT INTO connection_log 
509
        (
510
            user_id,
511
            profile_id,
512
            common_name,
513
            ip4,
514
            ip6,
515
            connected_at
516
        ) 
517
    VALUES
518
        (
519
            (
520
                SELECT
521
                    u.user_id
522
                FROM 
523
                    users u, certificates c
524
                WHERE
525
                    u.id = c.user_id
526
                AND
527
                    c.common_name = :common_name
528
            ),                
529
            :profile_id, 
530
            :common_name,
531
            :ip4,
532
            :ip6,
533
            :connected_at
534
        )
535
SQL
536
        );
537
538
        $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR);
539
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
540
        $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR);
541
        $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR);
542
        $stmt->bindValue(':connected_at', $connectedAt, PDO::PARAM_INT);
543
544
        $stmt->execute();
545
        // XXX
546
        return 1 === $stmt->rowCount();
547
    }
548
549
    public function clientDisconnect($profileId, $commonName, $ip4, $ip6, $connectedAt, $disconnectedAt, $bytesTransferred)
550
    {
551
        $stmt = $this->db->prepare(
552
<<< 'SQL'
553
    UPDATE 
554
        connection_log
555
    SET 
556
        disconnected_at = :disconnected_at, 
557
        bytes_transferred = :bytes_transferred
558
    WHERE 
559
        profile_id = :profile_id 
560
    AND
561
        common_name = :common_name 
562
    AND
563
        ip4 = :ip4 
564
    AND
565
        ip6 = :ip6 
566
    AND
567
        connected_at = :connected_at
568
SQL
569
        );
570
571
        $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR);
572
        $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR);
573
        $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR);
574
        $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR);
575
        $stmt->bindValue(':connected_at', $connectedAt, PDO::PARAM_INT);
576
        $stmt->bindValue(':disconnected_at', $disconnectedAt, PDO::PARAM_INT);
577
        $stmt->bindValue(':bytes_transferred', $bytesTransferred, PDO::PARAM_INT);
578
579
        $stmt->execute();
580
581
        // XXX
582
        return 1 === $stmt->rowCount();
583
    }
584
585 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...
586
    {
587
        $stmt = $this->db->prepare(
588
<<< 'SQL'
589
    SELECT 
590
        user_id,
591
        profile_id, 
592
        common_name, 
593
        ip4, 
594
        ip6, 
595
        connected_at, 
596
        disconnected_at
597
    FROM
598
        connection_log
599
    WHERE
600
        (ip4 = :ip_address OR ip6 = :ip_address)
601
    AND 
602
        connected_at < :date_time_unix
603
    AND 
604
        (disconnected_at > :date_time_unix OR disconnected_at IS NULL)
605
SQL
606
        );
607
        $stmt->bindValue(':ip_address', $ipAddress, PDO::PARAM_STR);
608
        $stmt->bindValue(':date_time_unix', $dateTimeUnix, PDO::PARAM_STR);
609
        $stmt->execute();
610
611
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
612
    }
613
614 View Code Duplication
    public function recordTotpKey($userId, $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...
615
    {
616
        $userId = $this->getId($userId);
617
        $stmt = $this->db->prepare(
618
<<< 'SQL'
619
    INSERT INTO totp_log 
620
        (user_id, totp_key, time_unix)
621
    VALUES
622
        (:user_id, :totp_key, :time_unix)
623
SQL
624
        );
625
626
        $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
627
        $stmt->bindValue(':totp_key', $totpKey, PDO::PARAM_STR);
628
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
629
630
        try {
631
            $stmt->execute();
632
        } catch (PDOException $e) {
633
            // unable to record the TOTP, probably uniqueness contrains
634
            return false;
635
        }
636
637
        return true;
638
    }
639
640
    public function cleanConnectionLog($timeUnix)
641
    {
642
        $stmt = $this->db->prepare(
643
<<< 'SQL'
644
    DELETE FROM
645
        connection_log
646
    WHERE
647
        connected_at < :time_unix
648
    AND
649
        disconnected_at IS NOT NULL'
650
SQL
651
        );
652
653
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
654
655
        return $stmt->execute();
656
    }
657
658
    public function cleanTotpLog($timeUnix)
659
    {
660
        $stmt = $this->db->prepare(
661
<<< 'SQL'
662
    DELETE FROM 
663
        totp_log
664
    WHERE 
665
        time_unix < :time_unix'
666
SQL
667
        );
668
669
        $stmt->bindValue(':time_unix', $timeUnix, PDO::PARAM_INT);
670
671
        return $stmt->execute();
672
    }
673
674
    public function motd()
675
    {
676
        $stmt = $this->db->prepare(
677
<<< 'SQL'
678
    SELECT
679
        motd_message 
680
    FROM 
681
        motd
682
SQL
683
        );
684
685
        $stmt->execute();
686
687
        return $stmt->fetchColumn();
688
    }
689
690 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...
691
    {
692
        $this->deleteMotd();
693
694
        $stmt = $this->db->prepare(
695
<<< 'SQL'
696
    INSERT INTO motd 
697
        (motd_message) 
698
    VALUES
699
        (:motd_message)
700
SQL
701
        );
702
703
        $stmt->bindValue(':motd_message', $motdMessage, PDO::PARAM_STR);
704
        $stmt->execute();
705
706
        return 1 === $stmt->rowCount();
707
    }
708
709
    public function deleteMotd()
710
    {
711
        $stmt = $this->db->prepare(
712
<<< 'SQL'
713
    DELETE FROM motd
714
SQL
715
        );
716
717
        $stmt->execute();
718
719
        return 1 === $stmt->rowCount();
720
    }
721
722
    public function init()
723
    {
724
        $queryList = [];
725
        $queryList[] =
726
<<< 'SQL'
727
    CREATE TABLE IF NOT EXISTS users (
728
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
729
        user_id VARCHAR(255) UNIQUE NOT NULL,
730
        is_disabled BOOLEAN DEFAULT 0
731
    )
732
SQL;
733
734
        $queryList[] =
735
<<< 'SQL'
736
    CREATE TABLE IF NOT EXISTS voot_tokens (
737
        voot_token VARCHAR(255) UNIQUE NOT NULL,
738
        user_id INTEGER UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE
739
    )
740
SQL;
741
742
        $queryList[] =
743
<<< 'SQL'
744
    CREATE TABLE IF NOT EXISTS totp_secrets (
745
        totp_secret VARCHAR(255) UNIQUE NOT NULL,
746
        user_id INTEGER UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE
747
    )
748
SQL;
749
750
        $queryList[] =
751
<<< 'SQL'
752
    CREATE TABLE IF NOT EXISTS certificates (
753
        common_name VARCHAR(255) UNIQUE NOT NULL,
754
        display_name VARCHAR(255) NOT NULL,
755
        valid_from INTEGER NOT NULL,
756
        valid_to INTEGER NOT NULL,
757
        is_disabled BOOLEAN DEFAULT 0,
758
        user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
759
    )
760
SQL;
761
762
        $queryList[] =
763
<<< 'SQL'
764
    CREATE TABLE IF NOT EXISTS totp_log (
765
        totp_key VARCHAR(255) NOT NULL,
766
        time_unix INTEGER NOT NULL,
767
        user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
768
        UNIQUE (user_id, totp_key)
769
    )
770
SQL;
771
772
        $queryList[] =
773
<<< 'SQL'
774
    CREATE TABLE IF NOT EXISTS connection_log (
775
        user_id VARCHAR(255) NOT NULL,
776
        common_name VARCHAR(255) NOT NULL,
777
        profile_id VARCHAR(255) NOT NULL,
778
        ip4 VARCHAR(255) NOT NULL,
779
        ip6 VARCHAR(255) NOT NULL,
780
        connected_at INTEGER NOT NULL,
781
        disconnected_at INTEGER DEFAULT NULL,
782
        bytes_transferred INTEGER DEFAULT NULL                
783
    )
784
SQL;
785
786
        $queryList[] =
787
<<< 'SQL'
788
    CREATE TABLE IF NOT EXISTS motd (
789
        motd_message TINYTEXT NOT NULL
790
    )
791
SQL;
792
793
        foreach ($queryList as $query) {
794
            $this->db->query($query);
795
        }
796
    }
797
}
798