PlaintextPasswordHasher   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 17
c 0
b 0
f 0
dl 0
loc 66
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A needsRehash() 0 3 1
A hash() 0 6 2
A mergePasswordAndSalt() 0 11 4
A info() 0 4 1
A verify() 0 12 2
1
<?php
2
3
/**
4
 * This file is part of web-stack
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Slick\WebStack\Domain\Security\PasswordHasher\Hasher;
13
14
use Slick\WebStack\Domain\Security\Exception\InvalidPasswordException;
15
use Slick\WebStack\Domain\Security\PasswordHasher\LegacyPasswordHasherInterface;
16
use InvalidArgumentException;
17
use SensitiveParameter;
0 ignored issues
show
Bug introduced by
The type SensitiveParameter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
19
/**
20
 * PlaintextPasswordHasher
21
 *
22
 * PlaintextPasswordHasher does not do any hashing but is useful in testing environments.
23
 * As this hasher is not cryptographically secure, usage of it in production environments is discouraged.
24
 *
25
 * @package Slick\WebStack\Domain\Security\PasswordHasher\Hasher
26
 */
27
final class PlaintextPasswordHasher implements LegacyPasswordHasherInterface
28
{
29
    use CheckPasswordLengthTrait;
30
31
    /**
32
     * @inheritDoc
33
     */
34
    public function hash(#[SensitiveParameter] string $plainPassword, ?string $salt = null): string
35
    {
36
        if ($this->isPasswordTooLong($plainPassword)) {
37
            throw new InvalidPasswordException("Password is too long.");
38
        }
39
        return $this->mergePasswordAndSalt($plainPassword, $salt);
40
    }
41
42
    /**
43
     * @inheritDoc
44
     */
45
    public function verify(
46
        string $hashedPassword,
47
        #[SensitiveParameter]
48
        string $plainPassword,
49
        ?string $salt = null
50
    ): bool {
51
        if ($this->isPasswordTooLong($plainPassword)) {
52
            return false;
53
        }
54
55
        $hash = $this->mergePasswordAndSalt($plainPassword, $salt);
56
        return hash_equals($hash, $hashedPassword);
57
    }
58
59
    /**
60
     * @inheritDoc
61
     */
62
    public function needsRehash(string $hashedPassword): bool
63
    {
64
        return false;
65
    }
66
67
    /**
68
     * Merges password and salt and returns the merged string.
69
     *
70
     * @param string $password The password to merge.
71
     * @param string|null $salt The salt to merge.
72
     *
73
     * @return string The merged password and salt.
74
     *
75
     */
76
    private function mergePasswordAndSalt(#[SensitiveParameter] string $password, ?string $salt): string
77
    {
78
        if (empty($salt)) {
79
            return $password;
80
        }
81
82
        if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {
83
            throw new InvalidArgumentException('Cannot use { or } in salt.');
84
        }
85
86
        return $password.'{'.$salt.'}';
87
    }
88
89
    public function info(): array
90
    {
91
        return [
92
            'algorithm' => 'plaintext'
93
        ];
94
    }
95
}
96