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 ( 428068...2536bf )
by François
02:04
created

Storage::setVootToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 18
Ratio 100 %

Importance

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