HasPassword   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 8
eloc 27
c 2
b 0
f 0
dl 0
loc 77
rs 10
ccs 20
cts 20
cp 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A isTokenValid() 0 10 2
A revokeToken() 0 4 1
A setPassword() 0 13 2
A getPassword() 0 4 1
A createToken() 0 6 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ecodev\Felix\Model\Traits;
6
7
use Cake\Chronos\Chronos;
8
use Doctrine\ORM\Mapping as ORM;
9
use GraphQL\Doctrine\Attribute as API;
10
11
/**
12
 * Trait for a user with a password and password reset capabilities.
13
 */
14
trait HasPassword
15
{
16
    #[ORM\Column(type: 'string', length: 255, options: ['default' => ''])]
17
    #[API\Exclude]
18
    private string $password = '';
19
20
    #[ORM\Column(type: 'string', length: 32, nullable: true, unique: true)]
21
    #[API\Exclude]
22
    private ?string $token = null;
23
24
    /**
25
     * The time when user asked to reset password.
26
     */
27
    #[ORM\Column(type: 'datetime', nullable: true)]
28
    #[API\Exclude]
29
    private ?Chronos $tokenCreationDate = null;
30
31
    /**
32
     * Hash and change the user password.
33
     */
34 2
    public function setPassword(string $password): void
35
    {
36
        // Ignore empty password that could be sent "by mistake" by the client
37
        // when agreeing to terms
38 2
        if ($password === '') {
39 1
            return;
40
        }
41
42 2
        $this->revokeToken();
43
44 2
        $password = password_hash($password, PASSWORD_DEFAULT);
45
46 2
        $this->password = $password;
47
    }
48
49
    /**
50
     * Returns the hashed password.
51
     */
52 1
    #[API\Exclude]
53
    public function getPassword(): string
54
    {
55 1
        return $this->password;
56
    }
57
58
    /**
59
     * Generate a new random token to reset password.
60
     */
61 1
    public function createToken(bool $mobileToken = false): string
62
    {
63 1
        $this->token = $mobileToken ? str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT) : bin2hex(random_bytes(16));
64 1
        $this->tokenCreationDate = new Chronos();
65
66 1
        return $this->token;
67
    }
68
69
    /**
70
     * Destroy existing token.
71
     */
72 2
    public function revokeToken(): void
73
    {
74 2
        $this->token = null;
75 2
        $this->tokenCreationDate = null;
76
    }
77
78
    /**
79
     * Check if token is valid.
80
     */
81 1
    #[API\Exclude]
82
    public function isTokenValid(): bool
83
    {
84 1
        if (!$this->tokenCreationDate) {
85 1
            return false;
86
        }
87
88 1
        $timeLimit = $this->tokenCreationDate->addMinutes(30);
89
90 1
        return $timeLimit->isFuture();
91
    }
92
}
93