Registration::main()   B
last analyzed

Complexity

Conditions 8
Paths 24

Size

Total Lines 66
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 8
eloc 44
c 7
b 0
f 0
nc 24
nop 1
dl 0
loc 66
rs 7.9715

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\webauthn\Controller;
6
7
use Exception;
8
use SimpleSAML\Auth;
9
use SimpleSAML\Configuration;
10
use SimpleSAML\HTTP\RunnableResponse;
11
use SimpleSAML\Logger;
12
use SimpleSAML\Metadata\MetaDataStorageHandler;
13
use SimpleSAML\Module\webauthn\Store;
14
use SimpleSAML\Module\webauthn\WebAuthn\StateData;
15
use SimpleSAML\Module\webauthn\WebAuthn\StaticProcessHelper;
16
use SimpleSAML\Module\webauthn\WebAuthn\WebAuthnRegistrationEvent;
17
use SimpleSAML\Session;
18
use SimpleSAML\Utils;
19
use Symfony\Component\HttpFoundation\Request;
20
21
/**
22
 * Controller class for the webauthn module.
23
 *
24
 * This class serves the different views available in the module.
25
 *
26
 * @package SimpleSAML\Module\webauthn
27
 */
28
class Registration
29
{
30
    /** @var \SimpleSAML\Auth\State|string */
31
    protected $authState = Auth\State::class;
32
33
    /** @var \SimpleSAML\Auth\Simple|string */
34
    protected $authSimple = Auth\Simple::class;
35
36
    /** @var \SimpleSAML\Logger|string */
37
    protected $logger = Logger::class;
38
39
40
    /**
41
     * Controller constructor.
42
     *
43
     * It initializes the global configuration and session for the controllers implemented here.
44
     *
45
     * @param \SimpleSAML\Configuration              $config The configuration to use by the controllers.
46
     * @param \SimpleSAML\Session                    $session The session to use by the controllers.
47
     *
48
     * @throws \Exception
49
     */
50
    public function __construct(
51
        protected Configuration $config,
52
        protected Session $session,
53
    ) {
54
    }
55
56
57
    /**
58
     * Inject the \SimpleSAML\Auth\State dependency.
59
     *
60
     * @param \SimpleSAML\Auth\State $authState
61
     */
62
    public function setAuthState(Auth\State $authState): void
63
    {
64
        $this->authState = $authState;
65
    }
66
67
68
    /**
69
     * Inject the \SimpleSAML\Auth\Simple dependency.
70
     *
71
     * @param \SimpleSAML\Auth\Simple $authSimple
72
     */
73
    public function setAuthSimple(Auth\Simple $authSimple): void
74
    {
75
        $this->authSimple = $authSimple;
76
    }
77
78
79
    /**
80
     * Inject the \SimpleSAML\Logger dependency.
81
     *
82
     * @param \SimpleSAML\Logger $logger
83
     */
84
    public function setLogger(Logger $logger): void
85
    {
86
        $this->logger = $logger;
87
    }
88
89
90
    /**
91
     * @param \Symfony\Component\HttpFoundation\Request $request
92
     * @return \SimpleSAML\HTTP\RunnableResponse  A Symfony Response-object.
93
     */
94
    public function main(/** @scrutinizer ignore-unused */ Request $request): RunnableResponse
95
    {
96
        $moduleConfig = Configuration::getOptionalConfig('module_webauthn.php');
97
        $registrationConfig = $moduleConfig->getArray('registration');
98
        $registrationAuthSource = $registrationConfig['auth_source'] ?? 'default-sp';
99
100
        $state = [];
101
        $state['SPMetadata']['entityid'] = "WEBAUTHN-SP-REGISTRATION";
102
103
        $authSimple = $this->authSimple;
104
        $as = new $authSimple($registrationAuthSource);
105
        $as->requireAuth();
106
        $attrs = $as->getAttributes();
107
108
        $state['Attributes'] = $attrs;
109
110
        $stateData = new StateData();
111
        // phpcs:disable Generic.Files.LineLength.TooLong
112
        $stateData->requestTokenModel = ($registrationConfig['policy_2fa']['minimum_certification_level'] == WebAuthnRegistrationEvent::CERTIFICATION_NOT_REQUIRED ? false : true);
113
        $stateData->minCertLevel2FA = $registrationConfig['policy_2fa']['minimum_certification_level'];
114
        $stateData->aaguidWhitelist2FA = $registrationConfig['policy_2fa']['aaguid_whitelist'] ?? [];
115
        $stateData->attFmtWhitelist2FA = $registrationConfig['policy_2fa']['attestation_format_whitelist'] ?? [];
116
        $stateData->minCertLevelPasswordless = $registrationConfig['policy_passwordless']['minimum_certification_level'];
117
        $stateData->aaguidWhitelistPasswordless = $registrationConfig['policy_passwordless']['aaguid_whitelist'] ?? [];
118
        $stateData->attFmtWhitelistPasswordless = $registrationConfig['policy_passwordless']['attestation_format_whitelist'] ?? [];
119
        // phpcs:enable Generic.Files.LineLength.TooLong
120
121
        try {
122
            $stateData->store = Store::parseStoreConfig($moduleConfig->getArray('store'));
123
        } catch (Exception $e) {
124
            $this->logger::error(
125
                'webauthn: Could not create storage: ' . $e->getMessage(),
126
            );
127
        }
128
129
        $stateData->scope = $moduleConfig->getOptionalString('scope', null);
130
        $httpUtils = new Utils\HTTP();
131
        $baseurl = $httpUtils->getSelfHost();
132
        $hostname = parse_url($baseurl, PHP_URL_HOST);
133
        if ($hostname !== null) {
134
            $stateData->derivedScope = $hostname;
135
        }
136
        $stateData->usernameAttrib = $moduleConfig->getString('identifyingAttribute');
137
        $stateData->displaynameAttrib = $moduleConfig->getString('attrib_displayname');
138
139
        StaticProcessHelper::prepareState($stateData, $state);
140
141
        $metadataHandler = MetaDataStorageHandler::getMetadataHandler();
142
        $metadata = $metadataHandler->getMetaDataCurrent('saml20-idp-hosted');
143
        $state['Source'] = $metadata;
144
        $state['IdPMetadata'] = $metadata;
145
        // inflow users are not allowed to enter the Registration page. If they
146
        // did, kill the session
147
        $moduleConfig = Configuration::getOptionalConfig('module_webauthn.php')->toArray();
148
149
        if ($moduleConfig['registration']['use_inflow_registration']) {
150
            throw new Exception("Attempt to access the stand-alone registration page in inflow mode!");
151
        }
152
153
        $state['Registration'] = true;
154
        $state['FIDO2WantsRegister'] = true;
155
        if (isset($state['Attributes']['FIDO2AuthSuccessful']) && is_array($state['Attributes']['FIDO2AuthSuccessful']) && count($state['Attributes']['FIDO2AuthSuccessful']) > 0) {
156
            $state['FIDO2AuthSuccessful'] = $state['Attributes']['FIDO2AuthSuccessful'][0];
157
        }
158
        
159
        return new RunnableResponse([StaticProcessHelper::class, 'saveStateAndRedirect'], [&$state]);
160
    }
161
}
162