Completed
Push — release-2.x ( 1c8792...d8830c )
by
unknown
02:25
created

ResponseContext::isSecondFactorVerified()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 0
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\StepupGateway\GatewayBundle\Saml;
20
21
use DateTime;
22
use DateTimeZone;
23
use DOMDocument;
24
use SAML2_Assertion;
25
use Surfnet\SamlBundle\Entity\IdentityProvider;
26
use Surfnet\SamlBundle\Entity\ServiceProvider;
27
use Surfnet\StepupGateway\GatewayBundle\Entity\SecondFactor;
28
use Surfnet\StepupGateway\GatewayBundle\Saml\Proxy\ProxyStateHandler;
29
use Surfnet\StepupGateway\GatewayBundle\Service\SamlEntityService;
30
31
class ResponseContext
32
{
33
    /**
34
     * @var IdentityProvider
35
     */
36
    private $hostedIdentityProvider;
37
38
    /**
39
     * @var \Surfnet\StepupGateway\GatewayBundle\Service\SamlEntityService
40
     */
41
    private $samlEntityService;
42
43
    /**
44
     * @var ProxyStateHandler
45
     */
46
    private $stateHandler;
47
48
    /**
49
     * @var DateTime
50
     */
51
    private $generationTime;
52
53
    /**
54
     * @var IdentityProvider|null
55
     */
56
    private $authenticatingIdp;
57
58
    /**
59
     * @var ServiceProvider
60
     */
61
    private $targetServiceProvider;
62
63
    public function __construct(
64
        IdentityProvider $identityProvider,
65
        SamlEntityService $samlEntityService,
66
        ProxyStateHandler $stateHandler
67
    ) {
68
        $this->hostedIdentityProvider = $identityProvider;
69
        $this->samlEntityService      = $samlEntityService;
70
        $this->stateHandler           = $stateHandler;
71
        $this->generationTime         = new DateTime('now', new DateTimeZone('UTC'));
72
    }
73
74
    /**
75
     * @return string
76
     */
77
    public function getDestination()
78
    {
79
        $serviceProvider = $this->getServiceProvider();
80
81
        if (!$serviceProvider) {
82
            return null;
83
        }
84
85
        return $serviceProvider->getAssertionConsumerUrl();
86
    }
87
88
    /**
89
     * @return null|string
90
     */
91
    public function getIssuer()
92
    {
93
        return $this->hostedIdentityProvider->getEntityId();
94
    }
95
96
    /**
97
     * @return int
98
     */
99
    public function getIssueInstant()
100
    {
101
        return $this->generationTime->getTimestamp();
102
    }
103
104
    /**
105
     * @return null|string
106
     */
107
    public function getInResponseTo()
108
    {
109
        return $this->stateHandler->getRequestId();
110
    }
111
112
    /**
113
     * @return null|string
114
     */
115
    public function getExpectedInResponseTo()
116
    {
117
        return $this->stateHandler->getGatewayRequestId();
118
    }
119
120
    /**
121
     * @return null|string
122
     */
123
    public function getRequiredLoa()
124
    {
125
        return $this->stateHandler->getRequiredLoaIdentifier();
126
    }
127
128
    /**
129
     * @return IdentityProvider
130
     */
131
    public function getIdentityProvider()
132
    {
133
        return $this->hostedIdentityProvider;
134
    }
135
136
    /**
137
     * @return null|ServiceProvider
138
     */
139
    public function getServiceProvider()
140
    {
141
        if (isset($this->targetServiceProvider)) {
142
            return $this->targetServiceProvider;
143
        }
144
145
        $serviceProviderId = $this->stateHandler->getRequestServiceProvider();
146
147
        return $this->targetServiceProvider = $this->samlEntityService->getServiceProvider($serviceProviderId);
148
    }
149
150
    /**
151
     * @return null|string
152
     */
153
    public function getRelayState()
154
    {
155
        return $this->stateHandler->getRelayState();
156
    }
157
158
    /**
159
     * @param SAML2_Assertion $assertion
160
     */
161
    public function saveAssertion(SAML2_Assertion $assertion)
162
    {
163
        // we pluck the NameId to make it easier to access it without having to reconstitute the assertion
164
        $nameId = $assertion->getNameId();
165
        if (!empty($nameId['Value'])) {
166
            $this->stateHandler->saveIdentityNameId($nameId['Value']);
167
        }
168
169
        // same for the entityId of the authenticating Authority
170
        $authenticatingAuthorities = $assertion->getAuthenticatingAuthority();
171
        if (!empty($authenticatingAuthorities)) {
172
            $this->stateHandler->setAuthenticatingIdp(reset($authenticatingAuthorities));
173
        }
174
175
        // And also attempt to save the user's schacHomeOrganization
176
        $attributes = $assertion->getAttributes();
177
        if (!empty($attributes['urn:mace:terena.org:attribute-def:schacHomeOrganization'])) {
178
            $schacHomeOrganization = $attributes['urn:mace:terena.org:attribute-def:schacHomeOrganization'];
179
            $this->stateHandler->setSchacHomeOrganization(reset($schacHomeOrganization));
180
        }
181
182
        $this->stateHandler->saveAssertion($assertion->toXML()->ownerDocument->saveXML());
183
    }
184
185
    /**
186
     * @return SAML2_Assertion
187
     */
188
    public function reconstituteAssertion()
189
    {
190
        $assertionAsXML    = $this->stateHandler->getAssertion();
191
        $assertionDocument = new DOMDocument();
192
        $assertionDocument->loadXML($assertionAsXML);
193
194
        return new SAML2_Assertion($assertionDocument->documentElement);
195
    }
196
197
    /**
198
     * @return null|string
199
     */
200
    public function getIdentityNameId()
201
    {
202
        return $this->stateHandler->getIdentityNameId();
203
    }
204
205
    public function getSchacHomeOrganization()
206
    {
207
        return $this->stateHandler->getSchacHomeOrganization();
208
    }
209
210
    /**
211
     * @return null|IdentityProvider
212
     */
213
    public function getAuthenticatingIdp()
214
    {
215
        $entityId = $this->stateHandler->getAuthenticatingIdp();
216
217
        if (!$entityId) {
218
            return null;
219
        }
220
221
        if (isset($this->authenticatingIdp)) {
222
            return $this->authenticatingIdp;
223
        }
224
225
        $this->authenticatingIdp = $this->samlEntityService->hasIdentityProvider($entityId)
226
            ? $this->samlEntityService->getIdentityProvider($entityId)
227
            : null;
228
229
        return $this->authenticatingIdp;
230
    }
231
232
    /**
233
     * @param SecondFactor $secondFactor
234
     */
235
    public function saveSelectedSecondFactor(SecondFactor $secondFactor)
236
    {
237
        $this->stateHandler->setSelectedSecondFactorId($secondFactor->secondFactorId);
238
        $this->stateHandler->setSecondFactorVerified(false);
239
        $this->stateHandler->setPreferredLocale($secondFactor->displayLocale);
240
    }
241
242
    /**
243
     * @return null|string
244
     */
245
    public function getSelectedSecondFactor()
246
    {
247
        return $this->stateHandler->getSelectedSecondFactorId();
248
    }
249
250
    public function markSecondFactorVerified()
251
    {
252
        $this->stateHandler->setSecondFactorVerified(true);
253
    }
254
255
    /**
256
     * @return bool
257
     */
258
    public function isSecondFactorVerified()
259
    {
260
        return $this->stateHandler->getSelectedSecondFactorId() && $this->stateHandler->isSecondFactorVerified();
261
    }
262
263
    public function getResponseAction()
264
    {
265
        return $this->stateHandler->getResponseAction();
266
    }
267
268
    /**
269
     * Resets some state after the response is sent
270
     * (e.g. resets which second factor was selected and whether it was verified).
271
     */
272
    public function responseSent()
273
    {
274
        $this->stateHandler->setSelectedSecondFactorId(null);
275
        $this->stateHandler->setSecondFactorVerified(false);
276
    }
277
}
278