CakeLegacyPasswordHasher   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Test Coverage

Coverage 79.31%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 13
eloc 28
c 2
b 0
f 0
dl 0
loc 104
ccs 23
cts 29
cp 0.7931
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A hash() 0 7 2
A fallbackHash() 0 25 5
A __construct() 0 6 4
A check() 0 3 1
A setHashType() 0 5 1
1
<?php
2
3
/**
4
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
5
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
6
 *
7
 * Licensed under The MIT License
8
 * For full copyright and license information, please see the LICENSE.txt
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12
 * @link          http://cakephp.org CakePHP(tm) Project
13
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
14
 */
15
16
declare(strict_types=1);
17
18
namespace Phauthentic\PasswordHasher;
19
20
use Cake\Core\Configure;
21
use Cake\Error\Debugger;
22
use Cake\Utility\Security;
23
use RuntimeException;
24
25
/**
26
 * Password hashing class that use weak hashing algorithms. This class is
27
 * intended only to be used with legacy databases where passwords have
28
 * not been migrated to a stronger algorithm yet.
29
 */
30
class CakeLegacyPasswordHasher extends AbstractPasswordHasher
31
{
32
33
    /**
34
     * Hash type
35
     *
36
     * @var string
37
     */
38
    protected $hashType = 'sha1';
39
40
    /**
41
     * @var bool
42
     */
43
    protected $cakeIsPresent = false;
44
45
    /**
46
     * @var string
47
     */
48
    protected $salt;
49
50
    /**
51
     * {@inheritDoc}
52
     */
53 14
    public function __construct($useFallback = false)
54
    {
55 14
        if (class_exists(Security::class) && $useFallback === false) {
56 12
            $this->cakeIsPresent = true;
57 12
            if (Configure::read('debug')) {
58
                Debugger::checkSecurityKeys();
59
            }
60
        }
61 14
    }
62
63
    /**
64
     * Sets the hash type
65
     *
66
     * @param string $type Hashing algo to use. Valid values are those supported by `$algo` argument of `password_hash()`. Defaults to `PASSWORD_DEFAULT`
67
     * @return $this
68
     */
69 4
    public function setHashType(string $type): self
70
    {
71 4
        $this->hashType = $type;
72
73 4
        return $this;
74
    }
75
76
    /**
77
     * Generates password hash.
78
     *
79
     * @param string $password Plain text password to hash.
80
     * @return string Password hash
81
     */
82 12
    public function hash(string $password): string
83
    {
84 12
        if ($this->cakeIsPresent) {
85 10
            return Security::hash($password, $this->hashType, true);
86
        }
87
88 2
        return $this->fallbackHash($password);
89
    }
90
91
    /**
92
     * Basically a copy of Cakes Security::hash() method
93
     *
94
     * @param string $password
95
     * @return string
96
     */
97 2
    protected function fallbackHash(string $password)
98
    {
99 2
        if (empty($this->hashType)) {
100
            throw new RuntimeException('You must specify a hash type');
101
        }
102
103 2
        $algorithm = strtolower($this->hashType);
104
105 2
        $availableAlgorithms = hash_algos();
106 2
        if (!in_array($algorithm, $availableAlgorithms)) {
107
            throw new RuntimeException(sprintf(
108
                'The hash type `%s` was not found. Available algorithms are: %s',
109
                $algorithm,
110
                implode(', ', $availableAlgorithms)
111
            ));
112
        }
113
114 2
        if ($this->salt) {
115 2
            if (!is_string($this->salt)) {
0 ignored issues
show
introduced by
The condition is_string($this->salt) is always true.
Loading history...
116
                throw new RuntimeException('No salt present');
117
            }
118 2
            $password = $this->salt . $password;
119
        }
120
121 2
        return hash($algorithm, $password);
122
    }
123
124
    /**
125
     * Check hash. Generate hash for user provided password and check against existing hash.
126
     *
127
     * @param string $password Plain text password to hash.
128
     * @param string $hashedPassword Existing hashed password.
129
     * @return bool True if hashes match else false.
130
     */
131 8
    public function check(string $password, string $hashedPassword): bool
132
    {
133 8
        return $hashedPassword === $this->hash($password);
134
    }
135
}
136