Completed
Push — bugfix/fix-auth-filter ( b7b604...49ed0d )
by
unknown
05:20 queued 02:38
created

applySecondFactorVettedEvent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
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\StepupMiddleware\ApiBundle\Identity\Projector;
20
21
use Broadway\ReadModel\Projector;
22
use Surfnet\Stepup\Configuration\Event\InstitutionConfigurationRemovedEvent;
23
use Surfnet\Stepup\Configuration\Event\SelectRaaOptionChangedEvent;
24
use Surfnet\Stepup\Configuration\Event\SraaUpdatedEvent;
25
use Surfnet\Stepup\Identity\Collection\InstitutionCollection;
26
use Surfnet\Stepup\Identity\Event\IdentityAccreditedAsRaaForInstitutionEvent;
27
use Surfnet\Stepup\Identity\Event\IdentityAccreditedAsRaForInstitutionEvent;
28
use Surfnet\Stepup\Identity\Event\RegistrationAuthorityRetractedForInstitutionEvent;
29
use Surfnet\Stepup\Identity\Value\CommonName;
30
use Surfnet\Stepup\Identity\Value\Email;
31
use Surfnet\Stepup\Identity\Value\IdentityId;
32
use Surfnet\Stepup\Identity\Value\Institution;
33
use Surfnet\Stepup\Configuration\Value\Institution as ConfigurationInstitution;
34
use Surfnet\Stepup\Identity\Event\CompliedWithVettedSecondFactorRevocationEvent;
35
use Surfnet\Stepup\Identity\Event\IdentityAccreditedAsRaaEvent;
36
use Surfnet\Stepup\Identity\Event\IdentityAccreditedAsRaEvent;
37
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
38
use Surfnet\Stepup\Identity\Event\RegistrationAuthorityRetractedEvent;
39
use Surfnet\Stepup\Identity\Event\SecondFactorVettedEvent;
40
use Surfnet\Stepup\Identity\Event\VettedSecondFactorRevokedEvent;
41
use Surfnet\Stepup\Identity\Event\YubikeySecondFactorBootstrappedEvent;
42
use Surfnet\Stepup\Identity\Value\NameId;
43
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Repository\InstitutionAuthorizationRepository;
44
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaCandidate;
45
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\IdentityRepository;
46
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\RaCandidateRepository;
47
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\RaListingRepository;
48
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\RaSecondFactorRepository;
49
50
/**
51
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
52
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
53
 */
54
class RaCandidateProjector extends Projector
55
{
56
    /**
57
     * @var RaCandidateRepository
58
     */
59
    private $raCandidateRepository;
60
61
    /**
62
     * @var RaListingRepository
63
     */
64
    private $raListingRepository;
65
66
    /**
67
     * @var institutionAuthorizationRepository
68
     */
69
    private $institutionAuthorizationRepository;
70
    /**
71
     * @var IdentityRepository
72
     */
73
    private $identityRepository;
74
    /**
75
     * @var RaSecondFactorRepository
76
     */
77
    private $raSecondFactorRepository;
78
79
    public function __construct(
80
        RaCandidateRepository $raCandidateRepository,
81
        RaListingRepository $raListingRepository,
82
        InstitutionAuthorizationRepository $institutionAuthorizationRepository,
83
        IdentityRepository $identityRepository,
84
        RaSecondFactorRepository $raSecondFactorRepository
85
    ) {
86
        $this->raCandidateRepository = $raCandidateRepository;
87
        $this->raListingRepository = $raListingRepository;
88
        $this->institutionAuthorizationRepository = $institutionAuthorizationRepository;
0 ignored issues
show
Documentation Bug introduced by
It seems like $institutionAuthorizationRepository of type object<Surfnet\StepupMid...uthorizationRepository> is incompatible with the declared type object<Surfnet\StepupMid...uthorizationRepository> of property $institutionAuthorizationRepository.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
89
        $this->identityRepository = $identityRepository;
90
        $this->raSecondFactorRepository = $raSecondFactorRepository;
91
    }
92
93
    /**
94
     * @param SecondFactorVettedEvent $event
95
     * @return void
96
     * @throws \Doctrine\ORM\NonUniqueResultException
97
     */
98
    public function applySecondFactorVettedEvent(SecondFactorVettedEvent $event)
99
    {
100
        $this->addCandidateToProjection(
101
            $event->identityInstitution,
102
            $event->identityId,
103
            $event->nameId,
104
            $event->commonName,
105
            $event->email
106
        );
107
    }
108
109
    /**
110
     * @param YubikeySecondFactorBootstrappedEvent $event
111
     * @return void
112
     * @throws \Doctrine\ORM\NonUniqueResultException
113
     */
114
    public function applyYubikeySecondFactorBootstrappedEvent(YubikeySecondFactorBootstrappedEvent $event)
115
    {
116
        $this->addCandidateToProjection(
117
            $event->identityInstitution,
118
            $event->identityId,
119
            $event->nameId,
120
            $event->commonName,
121
            $event->email
122
        );
123
    }
124
125
    /**
126
     * @param VettedSecondFactorRevokedEvent $event
127
     * @return void
128
     */
129
    public function applyVettedSecondFactorRevokedEvent(VettedSecondFactorRevokedEvent $event)
130
    {
131
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
132
    }
133
134
    /**
135
     * @param CompliedWithVettedSecondFactorRevocationEvent $event
136
     * @return void
137
     */
138
    public function applyCompliedWithVettedSecondFactorRevocationEvent(
139
        CompliedWithVettedSecondFactorRevocationEvent $event
140
    ) {
141
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
142
    }
143
144
    /**
145
     * @param SraaUpdatedEvent $event
146
     *
147
     * Removes all RaCandidates that have a nameId matching an SRAA, as they cannot be made RA(A) as they
148
     * already are SRAA.
149
     */
150
    public function applySraaUpdatedEvent(SraaUpdatedEvent $event)
151
    {
152
        $this->raCandidateRepository->removeByNameIds($event->sraaList);
153
    }
154
155
    /**
156
     * @param IdentityAccreditedAsRaForInstitutionEvent $event
157
     * @return void
158
     */
159
    public function applyIdentityAccreditedAsRaForInstitutionEvent(IdentityAccreditedAsRaForInstitutionEvent $event)
160
    {
161
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->raInstitution);
162
    }
163
164
    /**
165
     * @param IdentityAccreditedAsRaaForInstitutionEvent $event
166
     * @return void
167
     */
168
    public function applyIdentityAccreditedAsRaaForInstitutionEvent(IdentityAccreditedAsRaaForInstitutionEvent $event)
169
    {
170
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->raInstitution);
171
    }
172
173
    /**
174
     * @param RegistrationAuthorityRetractedForInstitutionEvent $event
175
     * @return void
176
     */
177
    public function applyRegistrationAuthorityRetractedForInstitutionEvent(RegistrationAuthorityRetractedForInstitutionEvent $event)
178
    {
179
        $this->addCandidateToProjection(
180
            $event->identityInstitution,
181
            $event->identityId,
182
            $event->nameId,
183
            $event->commonName,
184
            $event->email
185
        );
186
    }
187
188
    protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event)
189
    {
190
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
191
    }
192
193
    protected function applySelectRaaOptionChangedEvent(SelectRaaOptionChangedEvent $event)
194
    {
195
        $authorizedInstitutions = $event->selectRaaOption->getInstitutions($event->institution);
196
        $this->updateInstitutionCandidatesFromCollection(new Institution($event->institution->getInstitution()), $authorizedInstitutions);
197
    }
198
199
    protected function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurationRemovedEvent $event)
200
    {
201
        $this->raCandidateRepository->removeByRaInstitution(new Institution($event->institution->getInstitution()));
202
    }
203
204
    /**
205
     * This method is kept to be backwards compatible for changes before FGA
206
     *
207
     * @param IdentityAccreditedAsRaEvent $event
208
     * @return void
209
     */
210
    public function applyIdentityAccreditedAsRaEvent(IdentityAccreditedAsRaEvent $event)
211
    {
212
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->identityInstitution);
213
    }
214
215
    /**
216
     * This method is kept to be backwards compatible for changes before FGA
217
     *
218
     * @param IdentityAccreditedAsRaaEvent $event
219
     * @return void
220
     */
221
    public function applyIdentityAccreditedAsRaaEvent(IdentityAccreditedAsRaaEvent $event)
222
    {
223
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->identityInstitution);
224
    }
225
226
    /**
227
     * This method is kept to be backwards compatible for changes before FGA
228
     *
229
     * @param RegistrationAuthorityRetractedEvent $event
230
     * @return void
231
     */
232
    public function applyRegistrationAuthorityRetractedEvent(RegistrationAuthorityRetractedEvent $event)
233
    {
234
        $candidate = RaCandidate::nominate(
235
            $event->identityId,
236
            $event->identityInstitution,
237
            $event->nameId,
238
            $event->commonName,
239
            $event->email,
240
            $event->identityInstitution
241
        );
242
243
        $this->raCandidateRepository->merge($candidate);
244
    }
245
246
    /**
247
     * @param Institution $institution
248
     * @param ConfigurationInstitution[] $authorizedInstitutions
249
     * @throws \Doctrine\ORM\NonUniqueResultException
250
     */
251
    private function updateInstitutionCandidatesFromCollection(Institution $institution, array $authorizedInstitutions)
252
    {
253
        // convert configuration to value institutions
254
        $raInstitutions = new InstitutionCollection();
255
        foreach ($authorizedInstitutions as $authorizedInstitution) {
256
            $raInstitutions->add(new Institution($authorizedInstitution->getInstitution()));
257
        }
258
259
        // Remove candidates from removed institutions
260
        $this->raCandidateRepository->removeInstitutionsNotInList($institution, $raInstitutions);
261
262
        // loop through authorized institutions
263
        foreach ($raInstitutions as $raInstitution) {
264
            // add new identities
265
            $raSecondFactors = $this->raSecondFactorRepository->findByInstitution($raInstitution->getInstitution());
266
            foreach ($raSecondFactors as $raSecondFactor) {
267
                $identity = $this->identityRepository->find($raSecondFactor->identityId);
268
                $identityId = new IdentityId($identity->id);
269
270
                // check if persistent in ra listing
271
                if ($this->raListingRepository->findByIdentityIdAndRaInstitution($identityId, $institution)) {
272
                    continue;
273
                }
274
275
                // create candidate if not exists
276
                $candidate = $this->raCandidateRepository->findByIdentityIdAndRaInstitution($identityId, $institution);
277
                if (!$candidate) {
278
                    $candidate = RaCandidate::nominate(
279
                        $identityId,
280
                        $identity->institution,
281
                        $identity->nameId,
282
                        $identity->commonName,
283
                        $identity->email,
284
                        $institution
285
                    );
286
                }
287
288
                // store
289
                $this->raCandidateRepository->merge($candidate);
290
            }
291
        }
292
    }
293
294
    /**
295
     * @param Institution $identityInstitution
296
     * @param IdentityId $identityId
297
     * @param NameId $identityNameId
298
     * @param CommonName $identityCommonName
299
     * @param Email $identityEmail
300
     * @throws \Doctrine\ORM\NonUniqueResultException
301
     */
302
    private function addCandidateToProjection(
303
        Institution $identityInstitution,
304
        IdentityId $identityId,
305
        NameId $identityNameId,
306
        CommonName $identityCommonName,
307
        Email $identityEmail
308
    ) {
309
        $institutionAuthorizations = $this->institutionAuthorizationRepository
310
            ->findAuthorizationOptionsForInstitution(new ConfigurationInstitution($identityInstitution->getInstitution()));
311
312
        $institutions = [];
313
        foreach ($institutionAuthorizations as $authorization) {
314
            $raInstitutionName = $authorization->institutionRelation->getInstitution();
315
            $institutions[$raInstitutionName] = new Institution($raInstitutionName);
316
        }
317
318
        foreach ($institutions as $institution) {
319
            if ($this->raListingRepository->findByIdentityIdAndInstitution($identityId, $institution)) {
320
                continue;
321
            }
322
323
            // create candidate if not exists
324
            $candidate = $this->raCandidateRepository->findByIdentityIdAndRaInstitution($identityId, $institution);
325
            if (!$candidate) {
326
                $candidate = RaCandidate::nominate(
327
                    $identityId,
328
                    $identityInstitution,
329
                    $identityNameId,
330
                    $identityCommonName,
331
                    $identityEmail,
332
                    $institution
333
                );
334
            }
335
336
            $this->raCandidateRepository->merge($candidate);
337
        }
338
    }
339
}
340