Completed
Push — feature/upgrade-remote-vetting ( 883904 )
by
unknown
65:35
created

SamlCalloutHelper   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 3
lcom 1
cbo 5
dl 0
loc 100
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
A createAuthnRequest() 0 25 1
A handleResponse() 0 27 1
1
<?php
2
/**
3
 * Copyright 2010 SURFnet B.V.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace Surfnet\StepupSelfService\SelfServiceBundle\Service\RemoteVetting;
19
20
use Psr\Log\LoggerInterface;
21
use SAML2\Constants;
22
use SAML2\XML\saml\SubjectConfirmation;
23
use Surfnet\SamlBundle\Entity\ServiceProvider;
24
use Surfnet\SamlBundle\Http\PostBinding;
25
use Surfnet\SamlBundle\SAML2\AuthnRequestFactory;
26
use Surfnet\StepupSelfService\SelfServiceBundle\Service\RemoteVetting\Dto\AttributeListDto;
27
use Surfnet\StepupSelfService\SelfServiceBundle\Service\RemoteVetting\Value\ProcessId;
28
use Surfnet\StepupSelfService\SelfServiceBundle\Service\RemoteVettingService;
29
use Symfony\Component\HttpFoundation\Request;
30
31
class SamlCalloutHelper
32
{
33
    /**
34
     * @var IdentityProviderFactory
35
     */
36
    private $identityProviderFactory;
37
    /**
38
     * @var PostBinding
39
     */
40
    private $postBinding;
41
    /**
42
     * @var RemoteVettingService
43
     */
44
    private $remoteVettingService;
45
    /**
46
     * @var LoggerInterface
47
     */
48
    private $logger;
49
    /**
50
     * @var ServiceProvider
51
     */
52
    private $serviceProvider;
53
54
    public function __construct(
55
        IdentityProviderFactory $identityProviderFactory,
56
        ServiceProviderFactory $serviceProviderFactory,
57
        PostBinding $postBinding,
58
        RemoteVettingService $remoteVettingService,
59
        LoggerInterface $logger
60
    ) {
61
        $this->identityProviderFactory = $identityProviderFactory;
62
        $this->serviceProvider = $serviceProviderFactory->create();
63
        $this->postBinding = $postBinding;
64
        $this->remoteVettingService = $remoteVettingService;
65
        $this->logger = $logger;
66
    }
67
68
    /**
69
     * @param string $identityProviderSlug
70
     * @return string
71
     */
72
    public function createAuthnRequest($identityProviderSlug)
73
    {
74
        $this->logger->info(sprintf('Creating a SAML2 AuthnRequest to send to the %s remote vetting IdP', $identityProviderSlug));
75
76
        $identityProvider = $this->identityProviderFactory->create($identityProviderSlug);
77
        $authnRequest = AuthnRequestFactory::createNewRequest($this->serviceProvider, $identityProvider);
78
79
        // Set NameId
80
        $authnRequest->setSubject('', Constants::NAMEID_UNSPECIFIED);
81
82
        // Set AuthnContextClassRef
83
        $authnRequest->setAuthenticationContextClassRef(Constants::AC_UNSPECIFIED);
84
85
        // Handle validating state
86
        $this->remoteVettingService->startValidation(ProcessId::create($authnRequest->getRequestId()));
87
88
        // Create redirect response.
89
        $query = $authnRequest->buildRequestQuery();
90
91
        return sprintf(
92
            '%s?%s',
93
            $identityProvider->getSsoUrl(),
94
            $query
95
        );
96
    }
97
98
    /**
99
     * @param Request $request
100
     * @param string $identityProviderSlug
101
     * @return ProcessId
102
     */
103
    public function handleResponse(Request $request, $identityProviderSlug)
104
    {
105
        $identityProvider = $this->identityProviderFactory->create($identityProviderSlug);
106
107
        $this->logger->info(sprintf('Process the SAML Respons received from the %s remote vetting IdP', $identityProviderSlug));
108
109
        $assertion = $this->postBinding->processResponse(
110
            $request,
111
            $identityProvider,
112
            $this->serviceProvider
113
        );
114
115
        /** @var SubjectConfirmation $subjectConfirmation */
116
        $subjectConfirmation = $assertion->getSubjectConfirmation()[0];
117
        $requestId = $subjectConfirmation->SubjectConfirmationData->InResponseTo;
118
119
        // Create log DTO in order to store
120
        $attributeLogDto = new AttributeListDto(
121
            $assertion->getAttributes(),
122
            (string)$subjectConfirmation->NameID
123
        );
124
125
        // Handle validated state
126
        $processId = ProcessId::create($requestId);
127
        $this->remoteVettingService->finishValidation($processId, $attributeLogDto);
128
        return $processId;
129
    }
130
}
131