Completed
Push — master ( bf1ac1...6eab0c )
by Guy
21s
created

completeRegistrationRequest()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 32
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 32
rs 9.7333
c 0
b 0
f 0
cc 4
nc 4
nop 3
1
<?php
2
3
namespace SilverStripe\MFA\RequestHandler;
4
5
use Exception;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Control\HTTPResponse;
8
use SilverStripe\MFA\Method\MethodInterface;
9
use SilverStripe\MFA\Service\RegisteredMethodManager;
10
use SilverStripe\MFA\State\Result;
11
use SilverStripe\MFA\Store\StoreInterface;
12
use SilverStripe\ORM\ValidationResult;
13
14
/**
15
 * This trait encapsulates logic that can be added to a `RequestHandler` to work with registering MFA authenticators
16
 * using the MFA front-end app. It provides two main methods; @see createStartRegistrationResponse - creates a response
17
 * that can be easily consumed by the MFA app to start the registration process for a method, and
18
 * @see completeRegistrationRequest - used to complete the registration flow for a method using details sent back by the
19
 * MFA app.
20
 */
21
trait RegistrationHandlerTrait
22
{
23
    public function createStartRegistrationResponse(StoreInterface $store, MethodInterface $method): HTTPResponse
24
    {
25
        $member = $store->getMember();
26
27
        // Sanity check that the method hasn't already been registered
28
        $existingRegisteredMethod = RegisteredMethodManager::singleton()->getFromMember($member, $method);
29
30
        $response = HTTPResponse::create()
31
            ->addHeader('Content-Type', 'application/json');
32
33
        if ($existingRegisteredMethod) {
34
            return $response->setBody(json_encode(['errors' => [_t(
35
                __CLASS__ . '.METHOD_ALREADY_REGISTERED',
36
                'That method has already been registered against this Member'
37
            )]]))->setStatusCode(400);
38
        }
39
40
        // Mark the given method as started within the session
41
        $store->setMethod($method->getURLSegment());
42
        // Allow the registration handler to begin the process and generate some data to pass through to the front-end
43
        $data = $method->getRegisterHandler()->start($store);
44
45
        return $response->setBody(json_encode($data));
46
    }
47
48
    public function completeRegistrationRequest(
49
        StoreInterface $store,
50
        MethodInterface $method,
51
        HTTPRequest $request
52
    ): Result {
53
        $storedMethodName = $store->getMethod();
54
55
        // If a registration process hasn't been initiated in a previous request, calling this method is invalid
56
        if (!$storedMethodName) {
57
            return Result::create(false, _t(__CLASS__ . '.NO_REGISTRATION_IN_PROGRESS', 'No registration in progress'));
58
        }
59
60
        // Assert the method in progress matches the request for completion
61
        if ($storedMethodName !== $method->getURLSegment()) {
62
            return Result::create(
63
                false,
64
                _t(__CLASS__ . '.METHOD_MISMATCH', 'Method does not match registration in progress')
65
            );
66
        }
67
68
        $registrationHandler = $method->getRegisterHandler();
69
        $result = $registrationHandler->register($request, $store);
70
71
        $member = $store->getMember();
72
        if ($result->isSuccessful()) {
73
            RegisteredMethodManager::singleton()
74
                ->registerForMember($member, $method, $result->getContext());
75
        } else {
76
            $this->extend('onRegisterMethodFailure', $member, $method);
0 ignored issues
show
Bug introduced by
It seems like extend() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

76
            $this->/** @scrutinizer ignore-call */ 
77
                   extend('onRegisterMethodFailure', $member, $method);
Loading history...
77
        }
78
79
        return $result;
80
    }
81
}
82