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 ( 8b1570...06c7af )
by François
01:57
created

Storage::hasTotpSecret()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 18
Ratio 100 %

Importance

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