Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
Password
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
6 / 6
10
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 fromConfig
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 strongEnough
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 valid
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasArgon2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Util;
6
7use Cosray\Config;
8
9class Password
10{
11    public const DEFAULT_PASSWORD_ENTROPY = 40.0;
12
13    public function __construct(
14        protected string|int|null $algo = null,
15        protected float $entropy = self::DEFAULT_PASSWORD_ENTROPY,
16    ) {
17        if ($this->algo === null) {
18            $this->algo = self::hasArgon2() ? PASSWORD_ARGON2ID : PASSWORD_BCRYPT;
19        }
20    }
21
22    public static function fromConfig(Config $config): self
23    {
24        $entropy = $config->password->entropy;
25        $defaultAlgo = self::hasArgon2() ? PASSWORD_ARGON2ID : PASSWORD_BCRYPT;
26        $algo = $config->password->algorithm ?? $defaultAlgo;
27
28        return new self($algo, $entropy);
29    }
30
31    public function strongEnough(#[\SensitiveParameter] string $password): bool
32    {
33        if (Strings::entropy($password) < $this->entropy) {
34            return false;
35        }
36
37        return true;
38    }
39
40    public function valid(#[\SensitiveParameter] string $password, string $hash): bool
41    {
42        return password_verify($password, $hash);
43    }
44
45    public function hash(#[\SensitiveParameter] string $password): string
46    {
47        return password_hash($password, $this->algo);
48    }
49
50    public static function hasArgon2(): bool
51    {
52        return in_array('argon2id', password_algos(), true);
53    }
54}