Passed
Push — master ( c4afc2...9cde23 )
by Pieter van der
27:49 queued 12:42
created

SamlController::consumeAssertionAction()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 63
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 6
eloc 36
nc 9
nop 1
dl 0
loc 63
rs 8.7217
c 5
b 0
f 0

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
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupSelfService\SelfServiceBundle\Controller;
20
21
use Exception;
22
use Surfnet\SamlBundle\Http\XMLResponse;
23
use Surfnet\SamlBundle\SAML2\Response\Assertion\InResponseTo;
24
use Surfnet\StepupBundle\Value\Loa;
25
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenState;
26
use Surfnet\StepupSelfService\SelfServiceBundle\Value\SelfVetRequestId;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
29
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
30
use Symfony\Component\Security\Core\Exception\AuthenticationException;
31
32
class SamlController extends Controller
33
{
34
    /**
35
     * A SelfService user is able to test it's token in this endpoint
36
     *
37
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
38
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
39
     * @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException
40
     */
41
    public function testSecondFactorAction()
42
    {
43
        $logger = $this->get('logger');
44
        $logger->notice('Starting second factor test');
45
46
        $secondFactorService = $this->get('surfnet_stepup_self_service_self_service.service.second_factor');
47
        $loaResolutionService = $this->get('surfnet_stepup.service.loa_resolution');
48
        $identity = $this->getIdentity();
49
50
        $vettedSecondFactors = $secondFactorService->findVettedByIdentity($identity->id);
51
        if (!$vettedSecondFactors || $vettedSecondFactors->getTotalItems() === 0) {
52
            $logger->error(
53
                sprintf(
54
                    'Identity "%s" tried to test a second factor, but does not own a suitable vetted token.',
55
                    $identity->id
56
                )
57
            );
58
59
            throw new NotFoundHttpException();
60
        }
61
62
        $authenticationRequestFactory = $this->get('self_service.test_second_factor_authentication_request_factory');
63
64
        // By requesting LoA 1.5 any relevant token can be tested (LoA 2 and 3)
65
        $authenticationRequest = $authenticationRequestFactory->createSecondFactorTestRequest(
66
            $identity->nameId,
67
            $loaResolutionService->getLoaByLevel(Loa::LOA_SELF_VETTED)
68
        );
69
70
        $this->get('session')->set('second_factor_test_request_id', $authenticationRequest->getRequestId());
71
72
        $samlLogger = $this->get('surfnet_saml.logger')->forAuthentication($authenticationRequest->getRequestId());
73
        $samlLogger->notice('Sending authentication request to the second factor test IDP');
74
75
        return $this->get('surfnet_saml.http.redirect_binding')->createRedirectResponseFor($authenticationRequest);
76
    }
77
78
    public function consumeAssertionAction(Request $httpRequest)
79
    {
80
        $logger = $this->get('logger');
81
82
        $session = $this->get('session');
83
        switch (true) {
84
            case ($session->has(SelfVetController::SELF_VET_SESSION_ID)):
85
                // The test authentication IdP is also used for self vetting, a different session id is
86
                // used to mark a self vet command
87
                /** @var SelfVetRequestId $selfVetRequestId */
88
                $selfVetRequestId = $session->get(SelfVetController::SELF_VET_SESSION_ID);
89
                $secondFactorId = $selfVetRequestId->vettingSecondFactorId();
90
                return $this->forward(
91
                    'SurfnetStepupSelfServiceSelfServiceBundle:SelfVet:consumeSelfVetAssertion',
92
                    ['secondFactorId' => $secondFactorId]
93
                );
94
            case ($session->has(RecoveryTokenState::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER)):
95
                // The test authentication IdP is also used for self-asserted recovery token
96
                // verification a different session id is used to mark the authentication.
97
                return $this->forward('SurfnetStepupSelfServiceSelfServiceBundle:RecoveryToken:stepUpConsumeAssertion');
98
            default:
99
                if (!$session->has('second_factor_test_request_id')) {
100
                    $logger->error(
101
                        'Received an authentication response for testing a second factor, but no second factor test response was expected'
102
                    );
103
104
                    throw new AccessDeniedHttpException('Did not expect an authentication response');
105
                }
106
107
                $logger->notice('Received an authentication response for testing a second factor');
108
109
                $initiatedRequestId = $session->get('second_factor_test_request_id');
110
111
                $samlLogger = $this->get('surfnet_saml.logger')->forAuthentication($initiatedRequestId);
112
113
                $session->remove('second_factor_test_request_id');
114
115
                $postBinding = $this->get('surfnet_saml.http.post_binding');
116
117
                try {
118
                    $assertion = $postBinding->processResponse(
119
                        $httpRequest,
120
                        $this->get('self_service.second_factor_test_idp'),
121
                        $this->get('surfnet_saml.hosted.service_provider')
122
                    );
123
124
                    if (!InResponseTo::assertEquals($assertion, $initiatedRequestId)) {
125
                        $samlLogger->error(
126
                            sprintf(
127
                                'Expected a response to the request with ID "%s", but the SAMLResponse was a response to a different request',
128
                                $initiatedRequestId
129
                            )
130
                        );
131
132
                        throw new AuthenticationException('Unexpected InResponseTo in SAMLResponse');
133
                    }
134
135
                    $session->getFlashBag()->add('success', 'ss.test_second_factor.verification_successful');
136
                } catch (Exception $exception) {
137
                    $session->getFlashBag()->add('error', 'ss.test_second_factor.verification_failed');
138
                }
139
140
                return $this->redirectToRoute('ss_second_factor_list');
141
        }
142
    }
143
144
    public function metadataAction()
145
    {
146
        /** @var \Surfnet\SamlBundle\Metadata\MetadataFactory $metadataFactory */
147
        $metadataFactory = $this->get('surfnet_saml.metadata_factory');
148
149
        return new XMLResponse($metadataFactory->generate());
150
    }
151
}
152