Completed
Pull Request — develop (#261)
by
unknown
02:58
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
49
/**
50
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
51
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
52
 */
53
class RaCandidateProjector extends Projector
54
{
55
    /**
56
     * @var RaCandidateRepository
57
     */
58
    private $raCandidateRepository;
59
60
    /**
61
     * @var RaListingRepository
62
     */
63
    private $raListingRepository;
64
65
    /**
66
     * @var institutionAuthorizationRepository
67
     */
68
    private $institutionAuthorizationRepository;
69
    /**
70
     * @var IdentityRepository
71
     */
72
    private $identityRepository;
73
74
    public function __construct(
75
        RaCandidateRepository $raCandidateRepository,
76
        RaListingRepository $raListingRepository,
77
        InstitutionAuthorizationRepository $institutionAuthorizationRepository,
78
        IdentityRepository $identityRepository
79
    ) {
80
        $this->raCandidateRepository = $raCandidateRepository;
81
        $this->raListingRepository = $raListingRepository;
82
        $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...
83
        $this->identityRepository = $identityRepository;
84
    }
85
86
    /**
87
     * @param VettedSecondFactorRevokedEvent $event
88
     * @return void
89
     */
90
    public function applyVettedSecondFactorRevokedEvent(VettedSecondFactorRevokedEvent $event)
91
    {
92
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
93
    }
94
95
    /**
96
     * @param CompliedWithVettedSecondFactorRevocationEvent $event
97
     * @return void
98
     */
99
    public function applyCompliedWithVettedSecondFactorRevocationEvent(
100
        CompliedWithVettedSecondFactorRevocationEvent $event
101
    ) {
102
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
103
    }
104
105
    /**
106
     * @param SraaUpdatedEvent $event
107
     *
108
     * Removes all RaCandidates that have a nameId matching an SRAA, as they cannot be made RA(A) as they
109
     * already are SRAA.
110
     */
111
    public function applySraaUpdatedEvent(SraaUpdatedEvent $event)
112
    {
113
        $this->raCandidateRepository->removeByNameIds($event->sraaList);
114
    }
115
116
    /**
117
     * @param IdentityAccreditedAsRaForInstitutionEvent $event
118
     * @return void
119
     */
120
    public function applyIdentityAccreditedAsRaForInstitutionEvent(IdentityAccreditedAsRaForInstitutionEvent $event)
121
    {
122
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->raInstitution);
123
    }
124
125
    /**
126
     * @param IdentityAccreditedAsRaaForInstitutionEvent $event
127
     * @return void
128
     */
129
    public function applyIdentityAccreditedAsRaaForInstitutionEvent(IdentityAccreditedAsRaaForInstitutionEvent $event)
130
    {
131
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->raInstitution);
132
    }
133
134
    /**
135
     * @param RegistrationAuthorityRetractedForInstitutionEvent $event
136
     * @return void
137
     */
138
    public function applyRegistrationAuthorityRetractedForInstitutionEvent(RegistrationAuthorityRetractedForInstitutionEvent $event)
139
    {
140
        $this->addCandidateToProjection(
141
            $event->identityInstitution,
142
            $event->identityId,
143
            $event->nameId,
144
            $event->commonName,
145
            $event->email
146
        );
147
    }
148
149
    protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event)
150
    {
151
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
152
    }
153
154
    protected function applySelectRaaOptionChangedEvent(SelectRaaOptionChangedEvent $event)
155
    {
156
        $authorizedInstitutions = $event->selectRaaOption->getInstitutions($event->institution);
157
        $this->updateInstitutionCandidatesFromCollection(new Institution($event->institution->getInstitution()), $authorizedInstitutions);
158
    }
159
160
    protected function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurationRemovedEvent $event)
161
    {
162
        $this->raCandidateRepository->removeByRaInstitution(new Institution($event->institution->getInstitution()));
163
    }
164
165
    /**
166
     * This method is kept to be backwards compatible for changes before FGA
167
     *
168
     * @param IdentityAccreditedAsRaEvent $event
169
     * @return void
170
     */
171
    public function applyIdentityAccreditedAsRaEvent(IdentityAccreditedAsRaEvent $event)
172
    {
173
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->identityInstitution);
174
    }
175
176
    /**
177
     * This method is kept to be backwards compatible for changes before FGA
178
     *
179
     * @param IdentityAccreditedAsRaaEvent $event
180
     * @return void
181
     */
182
    public function applyIdentityAccreditedAsRaaEvent(IdentityAccreditedAsRaaEvent $event)
183
    {
184
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->identityInstitution);
185
    }
186
187
    /**
188
     * This method is kept to be backwards compatible for changes before FGA
189
     *
190
     * @param RegistrationAuthorityRetractedEvent $event
191
     * @return void
192
     */
193
    public function applyRegistrationAuthorityRetractedEvent(RegistrationAuthorityRetractedEvent $event)
194
    {
195
        $candidate = RaCandidate::nominate(
196
            $event->identityId,
197
            $event->identityInstitution,
198
            $event->nameId,
199
            $event->commonName,
200
            $event->email,
201
            $event->identityInstitution
202
        );
203
204
        $this->raCandidateRepository->merge($candidate);
205
    }
206
207
    /**
208
     * @param Institution $institution
209
     * @param ConfigurationInstitution[] $authorizedInstitutions
210
     * @throws \Doctrine\ORM\NonUniqueResultException
211
     */
212
    private function updateInstitutionCandidatesFromCollection(Institution $institution, array $authorizedInstitutions)
213
    {
214
        // convert configuration to value institutions
215
        $raInstitutions = new InstitutionCollection();
216
        foreach ($authorizedInstitutions as $authorizedInstitution) {
217
            $raInstitutions->add(new Institution($authorizedInstitution->getInstitution()));
218
        }
219
220
        // Remove candidates from removed institutions
221
        $this->raCandidateRepository->removeInstitutionsNotInList($institution, $raInstitutions);
222
223
        // loop through authorized institutions
224
        foreach ($raInstitutions as $raInstitution) {
225
            // add new identities
226
            $identities = $this->identityRepository->findByInstitution($raInstitution);
227
            foreach ($identities as $identity) {
228
                $identityId = new IdentityId($identity->id);
229
230
                // check if persistent in ra listing
231
                if ($this->raListingRepository->findByIdentityIdAndRaInstitution($identityId, $institution)) {
232
                    continue;
233
                }
234
235
                // create candidate if not exists
236
                $candidate = $this->raCandidateRepository->findByIdentityIdAndRaInstitution($identityId, $institution);
237
                if (!$candidate) {
238
                    $candidate = RaCandidate::nominate(
239
                        $identityId,
240
                        $identity->institution,
241
                        $identity->nameId,
242
                        $identity->commonName,
243
                        $identity->email,
244
                        $institution
245
                    );
246
                }
247
248
                // store
249
                $this->raCandidateRepository->merge($candidate);
250
            }
251
        }
252
    }
253
254
    /**
255
     * @param Institution $identityInstitution
256
     * @param IdentityId $identityId
257
     * @param NameId $identityNameId
258
     * @param CommonName $identityCommonName
259
     * @param Email $identityEmail
260
     * @throws \Doctrine\ORM\NonUniqueResultException
261
     */
262
    private function addCandidateToProjection(
263
        Institution $identityInstitution,
264
        IdentityId $identityId,
265
        NameId $identityNameId,
266
        CommonName $identityCommonName,
267
        Email $identityEmail
268
    ) {
269
        $institutionAuthorizations = $this->institutionAuthorizationRepository
270
            ->findAuthorizationOptionsForInstitution(new ConfigurationInstitution($identityInstitution->getInstitution()));
271
272
        $institutions = [];
273
        foreach ($institutionAuthorizations as $authorization) {
274
            $raInstitutionName = $authorization->institutionRelation->getInstitution();
275
            $institutions[$raInstitutionName] = new Institution($raInstitutionName);
276
        }
277
278
        foreach ($institutions as $institution) {
279
            if ($this->raListingRepository->findByIdentityIdAndInstitution($identityId, $institution)) {
280
                continue;
281
            }
282
283
            // create candidate if not exists
284
            $candidate = $this->raCandidateRepository->findByIdentityIdAndRaInstitution($identityId, $institution);
285
            if (!$candidate) {
286
                $candidate = RaCandidate::nominate(
287
                    $identityId,
288
                    $identityInstitution,
289
                    $identityNameId,
290
                    $identityCommonName,
291
                    $identityEmail,
292
                    $institution
293
                );
294
            }
295
296
            $this->raCandidateRepository->merge($candidate);
297
        }
298
    }
299
}
300