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 ( ad44e8...fee13a )
by François
03:34
created

Storage::clientDisconnect()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 35
rs 8.8571
c 1
b 0
f 0
cc 1
eloc 14
nc 1
nop 7
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 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...
673
    {
674
        $stmt = $this->db->prepare(
675
<<< 'SQL'
676
    DELETE FROM 
677
        totp_log
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 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...
689
    {
690
        $stmt = $this->db->prepare(
691
<<< 'SQL'
692
    SELECT
693
        id, message, date_time 
694
    FROM 
695
        system_messages
696
    WHERE
697
        type = :type
698
SQL
699
        );
700
701
        $stmt->bindValue(':type', $type, PDO::PARAM_STR);
702
        $stmt->execute();
703
704
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
705
    }
706
707
    public function addSystemMessage($type, $message, DateTime $dateTime)
708
    {
709
        $stmt = $this->db->prepare(
710
<<< 'SQL'
711
    INSERT INTO system_messages 
712
        (type, message, date_time) 
713
    VALUES
714
        (:type, :message, :date_time)
715
SQL
716
        );
717
718
        $stmt->bindValue(':type', $type, PDO::PARAM_STR);
719
        $stmt->bindValue(':message', $message, PDO::PARAM_STR);
720
        $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR);
721
        $stmt->execute();
722
723
        return 1 === $stmt->rowCount();
724
    }
725
726 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...
727
    {
728
        $stmt = $this->db->prepare(
729
<<< 'SQL'
730
    DELETE FROM 
731
        system_messages
732
    WHERE id = :message_id
733
SQL
734
        );
735
736
        $stmt->bindValue(':message_id', $messageId, PDO::PARAM_INT);
737
        $stmt->execute();
738
739
        return 1 === $stmt->rowCount();
740
    }
741
742
    public function init()
743
    {
744
        $queryList = [];
745
        $queryList[] =
746
<<< 'SQL'
747
    CREATE TABLE IF NOT EXISTS users (
748
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
749
        user_id VARCHAR(255) UNIQUE NOT NULL,
750
        is_disabled BOOLEAN DEFAULT 0
751
    )
752
SQL;
753
754
        $queryList[] =
755
<<< 'SQL'
756
    CREATE TABLE IF NOT EXISTS voot_tokens (
757
        voot_token VARCHAR(255) UNIQUE NOT NULL,
758
        user_id INTEGER UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE
759
    )
760
SQL;
761
762
        $queryList[] =
763
<<< 'SQL'
764
    CREATE TABLE IF NOT EXISTS totp_secrets (
765
        totp_secret VARCHAR(255) UNIQUE NOT NULL,
766
        user_id INTEGER UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE
767
    )
768
SQL;
769
770
        $queryList[] =
771
<<< 'SQL'
772
    CREATE TABLE IF NOT EXISTS certificates (
773
        common_name VARCHAR(255) UNIQUE NOT NULL,
774
        display_name VARCHAR(255) NOT NULL,
775
        valid_from INTEGER NOT NULL,
776
        valid_to INTEGER NOT NULL,
777
        is_disabled BOOLEAN DEFAULT 0,
778
        user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
779
    )
780
SQL;
781
782
        $queryList[] =
783
<<< 'SQL'
784
    CREATE TABLE IF NOT EXISTS totp_log (
785
        totp_key VARCHAR(255) NOT NULL,
786
        date_time DATETIME NOT NULL,
787
        user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
788
        UNIQUE (user_id, totp_key)
789
    )
790
SQL;
791
792
        $queryList[] =
793
<<< 'SQL'
794
    CREATE TABLE IF NOT EXISTS connection_log (
795
        user_id VARCHAR(255) NOT NULL,
796
        common_name VARCHAR(255) NOT NULL,
797
        profile_id VARCHAR(255) NOT NULL,
798
        ip4 VARCHAR(255) NOT NULL,
799
        ip6 VARCHAR(255) NOT NULL,
800
        connected_at INTEGER NOT NULL,
801
        disconnected_at INTEGER DEFAULT NULL,
802
        bytes_transferred INTEGER DEFAULT NULL                
803
    )
804
SQL;
805
806
        $queryList[] =
807
<<< 'SQL'
808
    CREATE TABLE IF NOT EXISTS system_messages (
809
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
810
        type VARCHAR(255) NOT NULL DEFAULT "notification",
811
        message TINYTEXT NOT NULL,
812
        date_time DATETIME NOT NULL
813
    )
814
SQL;
815
816
        foreach ($queryList as $query) {
817
            $this->db->query($query);
818
        }
819
    }
820
}
821