Completed
Push — master ( fe5c1f...228ee9 )
by Nic
05:10 queued 02:42
created

SamlController::testSecondFactorAction()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 38
rs 8.8571
cc 2
eloc 23
nc 2
nop 1
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\SecondFactorType;
25
use Symfony\Component\HttpFoundation\Request;
26
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
27
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
use Symfony\Component\Security\Core\Exception\AuthenticationException;
29
30
class SamlController extends Controller
31
{
32
    /**
33
     * @param string $secondFactorId
34
     *
35
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
36
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
37
     * @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException
38
     */
39
    public function testSecondFactorAction($secondFactorId)
40
    {
41
        $logger = $this->get('logger');
42
        $logger->notice('Starting second factor test');
43
44
        $secondFactorService = $this->get('surfnet_stepup_self_service_self_service.service.second_factor');
45
        $identity            = $this->getIdentity();
46
47
        if (!$secondFactorService->identityHasSecondFactorOfStateWithId($identity->id, 'vetted', $secondFactorId)) {
48
            $logger->error(
49
                sprintf(
50
                    'Identity "%s" tried to test second factor "%s", but does not own that second factor or it is not vetted',
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
51
                    $identity->id,
52
                    $secondFactorId
53
                )
54
            );
55
56
            throw new NotFoundHttpException();
57
        }
58
59
        $loaResolutionService         = $this->get('surfnet_stepup.service.loa_resolution');
60
        $authenticationRequestFactory = $this->get('self_service.test_second_factor_authentication_request_factory');
61
62
        $secondFactor     = $secondFactorService->findOneVetted($secondFactorId);
63
        $secondFactorType = new SecondFactorType($secondFactor->type);
64
65
        $authenticationRequest = $authenticationRequestFactory->createSecondFactorTestRequest(
66
            $identity->nameId,
67
            $loaResolutionService->getLoaByLevel($secondFactorType->getLevel())
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
        $logger->notice('Received an authentication response for testing a second factor');
83
84
        $session = $this->get('session');
85
86
        if (!$session->has('second_factor_test_request_id')) {
87
            $logger->error(
88
                'Received an authentication response for testing a second factor, but no second factor test response was expected'
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 130 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
89
            );
90
91
            throw new AccessDeniedHttpException('Did not expect an authentication response');
92
        }
93
94
        $initiatedRequestId = $session->get('second_factor_test_request_id');
95
96
        $samlLogger = $this->get('surfnet_saml.logger')->forAuthentication($initiatedRequestId);
97
98
        $session->remove('second_factor_test_request_id');
99
100
        $postBinding = $this->get('surfnet_saml.http.post_binding');
101
102
        try {
103
            $assertion = $postBinding->processResponse(
104
                $httpRequest,
105
                $this->get('self_service.second_factor_test_idp'),
106
                $this->get('surfnet_saml.hosted.service_provider')
107
            );
108
109
            if (!InResponseTo::assertEquals($assertion, $initiatedRequestId)) {
110
                $samlLogger->error(
111
                    sprintf(
112
                        'Expected a response to the request with ID "%s", but the SAMLResponse was a response to a different request',
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 134 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
113
                        $initiatedRequestId
114
                    )
115
                );
116
117
                throw new AuthenticationException('Unexpected InResponseTo in SAMLResponse');
118
            }
119
120
            $session->getFlashBag()->add('success', 'ss.test_second_factor.verification_successful');
121
        } catch (Exception $exception) {
122
            $session->getFlashBag()->add('error', 'ss.test_second_factor.verification_failed');
123
        }
124
125
        return $this->redirectToRoute('ss_second_factor_list');
126
    }
127
128
    public function metadataAction()
129
    {
130
        /** @var \Surfnet\SamlBundle\Metadata\MetadataFactory $metadataFactory */
131
        $metadataFactory = $this->get('surfnet_saml.metadata_factory');
132
133
        return new XMLResponse($metadataFactory->generate());
134
    }
135
}
136