Passed
Push — master ( 23587f...1016f0 )
by Jan
04:38 queued 10s
created

BackupCodeGenerator   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 48
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 15
c 1
b 0
f 1
dl 0
loc 48
rs 10
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A generateCodeSet() 0 8 2
A generateSingleCode() 0 4 1
A __construct() 0 11 3
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
20
 */
21
22
namespace App\Services\TFA;
23
24
/**
25
 * This class generates random backup codes for two factor authentication
26
 * @package App\Services\TFA
27
 */
28
class BackupCodeGenerator
29
{
30
    protected $code_length;
31
    protected $code_count;
32
33
    /**
34
     * BackupCodeGenerator constructor.
35
     * @param  int  $code_length How many characters a single code should have.
36
     * @param  int  $code_count How many codes are generated for a whole backup set.
37
     */
38
    public function __construct(int $code_length, int $code_count)
39
    {
40
        if ($code_length > 32) {
41
            throw new \RuntimeException('Backup code can have maximum 32 digits!');
42
        }
43
        if ($code_length < 6) {
44
            throw new \RuntimeException('Code must have at least 6 digits to ensure security!');
45
        }
46
47
        $this->code_count = $code_count;
48
        $this->code_length = $code_length;
49
    }
50
51
    /**
52
     * Generates a single backup code.
53
     * It is a random hexadecimal value with the digit count configured in constructor
54
     * @return string The generated backup code (e.g. 1f3870be2)
55
     * @throws \Exception If no entropy source is available.
56
     */
57
    public function generateSingleCode() : string
58
    {
59
        $bytes = random_bytes(32);
60
        return substr(md5($bytes), 0, $this->code_length);
61
    }
62
63
64
    /**
65
     * Returns a full backup code set. The code count can be configured in the constructor
66
     * @return string[] An array containing different backup codes.
67
     */
68
    public function generateCodeSet() : array
69
    {
70
        $array = [];
71
        for($n=0; $n<$this->code_count; $n++) {
72
            $array[] = $this->generateSingleCode();
73
        }
74
75
        return $array;
76
    }
77
}