Passed
Pull Request — master (#22)
by Simon
01:54
created

BootstrapMFAAuthenticator::validateBackupCode()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 4
nop 3
dl 0
loc 26
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
namespace Firesphere\BootstrapMFA\Authenticators;
4
5
use Firesphere\BootstrapMFA\Handlers\BootstrapMFALoginHandler;
6
use Firesphere\BootstrapMFA\Providers\BootstrapMFAProvider;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Core\Injector\Injector;
9
use SilverStripe\ORM\ValidationException;
10
use SilverStripe\ORM\ValidationResult;
11
use SilverStripe\Security\Authenticator;
12
use SilverStripe\Security\Member;
13
use SilverStripe\Security\MemberAuthenticator\MemberAuthenticator;
14
use SilverStripe\Security\PasswordEncryptor_NotFoundException;
15
16
/**
17
 * Class BootstrapMFAAuthenticator
18
 * It needs to be instantiable, therefore it can't be an Abstract.
19
 *
20
 * @package Firesphere\BootstrapMFA\Authenticators
21
 * @method string getTokenField() Stub for child implementations
22
 */
23
class BootstrapMFAAuthenticator extends MemberAuthenticator
24
{
25
    /**
26
     * Key for array to be stored in between steps in the session
27
     */
28
    const SESSION_KEY = 'MFALogin';
29
30
    /**
31
     * @return int
32
     */
33
    public function supportedServices()
34
    {
35
        // Bitwise-OR of all the supported services in this Authenticator, to make a bitmask
36
        return Authenticator::LOGIN | Authenticator::LOGOUT | Authenticator::CHANGE_PASSWORD
37
            | Authenticator::RESET_PASSWORD | Authenticator::CHECK_PASSWORD;
38
    }
39
40
    /**
41
     * @param Member $member
42
     * @param string $token
43
     * @param ValidationResult|null $result
44
     * @return bool|Member
45
     * @throws ValidationException
46
     * @throws PasswordEncryptor_NotFoundException
47
     */
48
    public function validateBackupCode($member, $token, &$result = null)
49
    {
50
        if (!$result) {
51
            $result = new ValidationResult();
52
        }
53
        $token = $member->encryptWithUserSettings($token);
54
55
        /** @var BootstrapMFAProvider $provider */
56
        $provider = Injector::inst()->get(BootstrapMFAProvider::class);
57
        $provider->setMember($member);
58
59
        $backupCode = $provider->fetchToken($token);
60
61
        if ($backupCode && $backupCode->exists()) {
62
            $backupCode->expire();
63
            // Reset the subclass authenticator results
64
            $result = Injector::inst()->get(ValidationResult::class, false);
65
66
            /** @var Member $member */
67
            return $member;
68
        }
69
70
        $member->registerFailedLogin();
71
        $result->addError(_t(self::class . '.INVALIDTOKEN', 'Invalid token'));
72
73
        return false;
74
    }
75
76
    /**
77
     * @param string $link
78
     * @return BootstrapMFALoginHandler|static
79
     */
80
    public function getLoginHandler($link)
81
    {
82
        return BootstrapMFALoginHandler::create($link, $this);
83
    }
84
85
    /**
86
     * This implementation should be on the subclass
87
     *
88
     * @param array $data
89
     * @param HTTPRequest $request
90
     * @param string $token
91
     * @param ValidationResult $result
92
     * @throws \LogicException
93
     */
94
    public function verifyMFA($data, $request, $token, &$result)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

94
    public function verifyMFA(/** @scrutinizer ignore-unused */ $data, $request, $token, &$result)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

94
    public function verifyMFA($data, /** @scrutinizer ignore-unused */ $request, $token, &$result)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $result is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

94
    public function verifyMFA($data, $request, $token, /** @scrutinizer ignore-unused */ &$result)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $token is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

94
    public function verifyMFA($data, $request, /** @scrutinizer ignore-unused */ $token, &$result)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
95
    {
96
        throw new \LogicException('No token verification implemented');
97
    }
98
99
    /**
100
     * This implementation should be on the subclass
101
     *
102
     * @param BootstrapMFALoginHandler $controller
103
     * @param string $name
104
     */
105
    public function getMFAForm($controller, $name)
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

105
    public function getMFAForm($controller, /** @scrutinizer ignore-unused */ $name)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $controller is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

105
    public function getMFAForm(/** @scrutinizer ignore-unused */ $controller, $name)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
106
    {
107
        throw new \LogicException('No MFA Form implementation found');
108
    }
109
}
110