Recovery   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 4
eloc 32
c 0
b 0
f 0
dl 0
loc 70
ccs 26
cts 26
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A resetIdentityPassword() 0 12 1
A markForReset() 0 29 2
A __construct() 0 5 1
1
<?php
2
3
namespace Palladium\Service;
4
5
/**
6
 * Application logic for password reset handling
7
 */
8
9
use Palladium\Entity as Entity;
10
use Palladium\Exception\IdentityNotVerified;
11
use Palladium\Repository\Identity as Repository;
12
use Psr\Log\LoggerInterface;
13
14
class Recovery
15
{
16
17
    const DEFAULT_TOKEN_LIFESPAN = 28800; // 8 hours
18
    const DEFAULT_HASH_COST = 12;
19
20
    private $repository;
21
    private $logger;
22
    private $hashCost;
23
24
    /**
25
     * @param Repository $repository Repository for abstracting persistence layer structures
26
     * @param LoggerInterface $logger PSR-3 compatible logger
27
     * @param int $hashCost Cost of the bcrypt hashing function (default: 12)
28
     */
29 10
    public function __construct(Repository $repository, LoggerInterface $logger, $hashCost = Recovery::DEFAULT_HASH_COST)
30
    {
31 10
        $this->repository = $repository;
32 10
        $this->logger = $logger;
33 10
        $this->hashCost = $hashCost;
34 10
    }
35
36
37
    /**
38
     * @throws IdentityNotVerified if attempting to reset password for unverified identity
39
     */
40 5
    public function markForReset(Entity\StandardIdentity $identity, int $tokenLifespan = Recovery::DEFAULT_TOKEN_LIFESPAN): string
41
    {
42 5
        if ($identity->getStatus() === Entity\Identity::STATUS_NEW) {
43 2
            $this->logger->notice('identity not verified', [
44
                'input' => [
45 2
                    'identifier' => $identity->getIdentifier(),
46
                ],
47
                'user' => [
48 2
                    'account' => $identity->getAccountId(),
49 2
                    'identity' => $identity->getId(),
50
                ],
51
            ]);
52
53 2
            throw new IdentityNotVerified;
54
        }
55
56 3
        $identity->generateToken();
57 3
        $identity->setTokenAction(Entity\Identity::ACTION_RESET);
58 3
        $identity->setTokenEndOfLife(time() + $tokenLifespan);
59
60 3
        $this->repository->save($identity);
61
62 3
        $this->logger->info('request password reset', [
63
            'input' => [
64 3
                'identifier' => $identity->getIdentifier(),
65
            ],
66
        ]);
67
68 3
        return $identity->getToken();
69
    }
70
71
72 2
    public function resetIdentityPassword(Entity\StandardIdentity $identity, string $password)
73
    {
74 2
        $token = $identity->getToken();
75
76 2
        $identity->clearToken();
77 2
        $identity->setPassword($password, $this->hashCost);
78
79 2
        $this->repository->save($identity);
80
81 2
        $this->logger->info('password reset successful', [
82
            'input' => [
83 2
                'token' => $token,
84
            ],
85
        ]);
86 2
    }
87
}
88