Test Failed
Pull Request — master (#3)
by Florian
03:40
created

CakeLegacyPasswordHasher::setSalt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
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
namespace Phauthentic\PasswordHasher;
16
17
use Cake\Core\Configure;
18
use Cake\Error\Debugger;
19
use Cake\Utility\Security;
20
use RuntimeException;
21
22
/**
23
 * Password hashing class that use weak hashing algorithms. This class is
24
 * intended only to be used with legacy databases where passwords have
25
 * not been migrated to a stronger algorithm yet.
26
 */
27
class CakeLegacyPasswordHasher extends AbstractPasswordHasher
28
{
29
30
    /**
31
     * Hash type
32
     *
33
     * @var string
34
     */
35
    protected $hashType = 'sha1';
36
37
    /**
38
     * @var bool
39
     */
40 4
    protected $cakeIsPresent = false;
41
42 4
    /**
43
     * @var string
44
     */
45 4
    protected $salt;
46
47
    /**
48 4
     * {@inheritDoc}
49
     */
50
    public function __construct($useFallback = false)
51
    {
52
        if (class_exists(Security::class) && $useFallback === false) {
53
            $this->cakeIsPresent = true;
54
            if (Configure::read('debug')) {
55
                Debugger::checkSecurityKeys();
56 1
            }
57
        }
58 1
    }
59
60 1
    /**
61
     * Sets the hash type
62
     *
63
     * @param string $type Hashing algo to use. Valid values are those supported by `$algo` argument of `password_hash()`. Defaults to `PASSWORD_DEFAULT`
64
     * @return $this
65
     */
66
    public function setHashType(string $type): self
67
    {
68
        $this->hashType = $type;
69 4
70
        return $this;
71 4
    }
72
73
    /**
74
     * Sets the salt
75
     *
76
     * @param string $salt Salt
77
     * @return $this
78
     */
79
    public function setSalt(string $salt)
80
    {
81 2
        $this->salt = $salt;
82
83 2
        return $this;
84
    }
85
86
    /**
87
     * Generates password hash.
88
     *
89
     * @param string $password Plain text password to hash.
90
     * @return string Password hash
91
     */
92
    public function hash(string $password): string {
93
        if ($this->cakeIsPresent) {
94
            return Security::hash($password, $this->hashType, true);
95
        }
96
97
        return $this->fallbackHash($password);
98
    }
99
100
    /**
101
     * Basically a copy of Cakes Security::hash() method
102
     *
103
     * @param string $password
104
     * @return string
105
     */
106
    protected function fallbackHash(string $password)
107
    {
108
        if (empty($this->hashType)) {
109
            throw new RuntimeException('You must specify a hash type');
110
        }
111
112
        $algorithm = strtolower($this->hashType);
113
114
        $availableAlgorithms = hash_algos();
115
        if (!in_array($algorithm, $availableAlgorithms)) {
116
            throw new RuntimeException(sprintf(
117
                'The hash type `%s` was not found. Available algorithms are: %s',
118
                $algorithm,
119
                implode(', ', $availableAlgorithms)
120
            ));
121
        }
122
123
        if ($this->salt) {
124
            if (!is_string($this->salt)) {
0 ignored issues
show
introduced by
The condition is_string($this->salt) is always true.
Loading history...
125
                throw new RuntimeException('No salt present');
126
            }
127
            $string = $this->salt . $password;
0 ignored issues
show
Unused Code introduced by
The assignment to $string is dead and can be removed.
Loading history...
128
        }
129
130
        return hash($algorithm, $password);
131
    }
132
133
    /**
134
     * Check hash. Generate hash for user provided password and check against existing hash.
135
     *
136
     * @param string $password Plain text password to hash.
137
     * @param string $hashedPassword Existing hashed password.
138
     * @return bool True if hashes match else false.
139
     */
140
    public function check(string $password, string $hashedPassword): bool
141
    {
142
        return $hashedPassword === $this->hash($password);
143
    }
144
}
145