Passed
Push — master ( 46e795...e02900 )
by Florian
03:56 queued 02:04
created

CakeLegacyPasswordHasher::hash()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 3
c 2
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
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
    protected $cakeIsPresent = false;
41
42
    /**
43
     * @var string
44
     */
45
    protected $salt;
46
47
    /**
48
     * {@inheritDoc}
49
     */
50 7
    public function __construct($useFallback = false)
51
    {
52 7
        if (class_exists(Security::class) && $useFallback === false) {
53 6
            $this->cakeIsPresent = true;
54 6
            if (Configure::read('debug')) {
55
                Debugger::checkSecurityKeys();
56
            }
57
        }
58 7
    }
59
60
    /**
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 2
    public function setHashType(string $type): self
67
    {
68 2
        $this->hashType = $type;
69
70 2
        return $this;
71
    }
72
73
    /**
74
     * Generates password hash.
75
     *
76
     * @param string $password Plain text password to hash.
77
     * @return string Password hash
78
     */
79 6
    public function hash(string $password): string {
80 6
        if ($this->cakeIsPresent) {
81 5
            return Security::hash($password, $this->hashType, true);
82
        }
83
84 1
        return $this->fallbackHash($password);
85
    }
86
87
    /**
88
     * Basically a copy of Cakes Security::hash() method
89
     *
90
     * @param string $password
91
     * @return string
92
     */
93 1
    protected function fallbackHash(string $password)
94
    {
95 1
        if (empty($this->hashType)) {
96
            throw new RuntimeException('You must specify a hash type');
97
        }
98
99 1
        $algorithm = strtolower($this->hashType);
100
101 1
        $availableAlgorithms = hash_algos();
102 1
        if (!in_array($algorithm, $availableAlgorithms)) {
103
            throw new RuntimeException(sprintf(
104
                'The hash type `%s` was not found. Available algorithms are: %s',
105
                $algorithm,
106
                implode(', ', $availableAlgorithms)
107
            ));
108
        }
109
110 1
        if ($this->salt) {
111 1
            if (!is_string($this->salt)) {
0 ignored issues
show
introduced by
The condition is_string($this->salt) is always true.
Loading history...
112
                throw new RuntimeException('No salt present');
113
            }
114 1
            $password = $this->salt . $password;
115
        }
116
117 1
        return hash($algorithm, $password);
118
    }
119
120
    /**
121
     * Check hash. Generate hash for user provided password and check against existing hash.
122
     *
123
     * @param string $password Plain text password to hash.
124
     * @param string $hashedPassword Existing hashed password.
125
     * @return bool True if hashes match else false.
126
     */
127 4
    public function check(string $password, string $hashedPassword): bool
128
    {
129 4
        return $hashedPassword === $this->hash($password);
130
    }
131
}
132