Completed
Push — master ( f0b03a...fa0cb8 )
by Robbie
27s queued 11s
created

MemberExtension::updateCMSFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace SilverStripe\MFA\Extension\AccountReset;
4
5
use SilverStripe\Forms\FieldList;
6
use SilverStripe\ORM\DataExtension;
7
use SilverStripe\ORM\DataObject;
8
use SilverStripe\ORM\FieldType\DBDatetime;
9
use SilverStripe\Security\Member;
10
use SilverStripe\Security\RandomGenerator;
11
12
/**
13
 * Provides DB columns / methods for account resets on Members
14
 *
15
 * @package SilverStripe\MFA\Extension
16
 * @property Member&MemberExtension owner
17
 * @property string AccountResetHash
18
 * @property DBDatetime AccountResetExpired
19
 */
20
class MemberExtension extends DataExtension
21
{
22
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
23
        'AccountResetHash' => 'Varchar(160)',
24
        'AccountResetExpired' => 'Datetime',
25
    ];
26
27
    public function updateCMSFields(FieldList $fields)
28
    {
29
        $fields->removeByName(['AccountResetHash', 'AccountResetExpired']);
30
31
        return $fields;
32
    }
33
34
    /**
35
     * Mirrors the implementation in Member::generateAutologinTokenAndStoreHash(),
36
     * but against the AccountReset fields.
37
     *
38
     * @return string
39
     */
40
    public function generateAccountResetTokenAndStoreHash(): string
41
    {
42
        $lifetime = $this->owner->config()->auto_login_token_lifetime;
43
        $generator = new RandomGenerator();
44
45
        do {
46
            $token = $generator->randomToken();
47
            $hash = $this->owner->encryptWithUserSettings($token);
48
        } while (DataObject::get_one(Member::class, [
49
            '"Member"."AccountResetHash"' => $hash,
50
        ]));
51
52
        $this->owner->AccountResetHash = $hash;
53
        $this->owner->AccountResetExpired = DBDatetime::create()->setValue(
54
            DBDatetime::now()->getTimestamp() + $lifetime
55
        )->Rfc2822();
56
57
        $this->owner->write();
58
59
        return $token;
60
    }
61
62
    /**
63
     * Based on Member::validateAutoLoginToken() and Member::member_from_autologinhash().
64
     *
65
     * @param string $token
66
     * @return bool
67
     */
68
    public function verifyAccountResetToken(string $token): bool
69
    {
70
        if (!$this->owner->exists()) {
71
            return false;
72
        }
73
74
        $hash = $this->owner->encryptWithUserSettings($token);
75
76
        return (
77
            $this->owner->AccountResetHash === $hash &&
78
            $this->owner->AccountResetExpired >= DBDatetime::now()->getValue()
79
        );
80
    }
81
}
82