Passed
Pull Request — master (#127)
by Garion
02:33
created

MemberResetExtension   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 3
eloc 21
dl 0
loc 53
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A generateAccountResetTokenAndStoreHash() 0 18 2
A getMemberByAccountResetToken() 0 11 1
1
<?php
2
3
namespace SilverStripe\MFA\Extension;
4
5
use SilverStripe\ORM\DataExtension;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\ORM\FieldType\DBDatetime;
8
use SilverStripe\ORM\ValidationException;
9
use SilverStripe\Security\Member;
10
use SilverStripe\Security\PasswordEncryptor_NotFoundException;
11
use SilverStripe\Security\RandomGenerator;
12
13
/**
14
 * Provides DB columns / methods for account resets on Members
15
 *
16
 * @package SilverStripe\MFA\Extension
17
 * @property Member owner
18
 */
19
class MemberResetExtension extends DataExtension
20
{
21
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
22
        'AccountResetHash' => 'Varchar(160)',
23
        'AccountResetExpired' => 'Datetime',
24
    ];
25
26
    /**
27
     * Mirrors the implementation in Member::generateAutologinTokenAndStoreHash(),
28
     * but against the AccountReset fields.
29
     *
30
     * @return string
31
     * @throws PasswordEncryptor_NotFoundException
32
     * @throws ValidationException
33
     */
34
    public function generateAccountResetTokenAndStoreHash(): string
35
    {
36
        $lifetime = $this->owner->config()->auto_login_token_lifetime;
37
38
        do {
39
            $generator = new RandomGenerator();
40
            $token = $generator->randomToken();
41
            $hash = $this->owner->encryptWithUserSettings($token);
42
        } while (DataObject::get_one(Member::class, [
43
            '"Member"."AccountResetHash"' => $hash,
44
        ]));
45
46
        $this->owner->AccountResetHash = $hash;
47
        $this->owner->AccountResetExpired = date('Y-m-d H:i:s', time() + $lifetime);
48
49
        $this->owner->write();
50
51
        return $token;
52
    }
53
54
    /**
55
     * Based on Member::validateAutoLoginToken() and Member::member_from_autologinhash().
56
     *
57
     * @param string $token
58
     * @return Member
59
     * @throws PasswordEncryptor_NotFoundException
60
     */
61
    public function getMemberByAccountResetToken(string $token): ?Member
62
    {
63
        $hash = $this->owner->encryptWithUserSettings($token);
64
65
        /** @var Member $member */
66
        $member = Member::get()->filter([
67
            'AutoLoginHash' => $hash,
68
            'AutoLoginExpired:GreaterThan' => DBDatetime::now()->getValue(),
69
        ])->first();
70
71
        return $member;
72
    }
73
}
74