Completed
Pull Request — feature/fine-grained-authoriza... (#247)
by
unknown
07:05 queued 52s
created

updateInstitutionCandidatesFromCollection()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
c 0
b 0
f 0
rs 8.6257
cc 6
nc 10
nop 2
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\IdentityId;
30
use Surfnet\Stepup\Identity\Value\Institution;
31
use Surfnet\Stepup\Configuration\Value\Institution as ConfigurationInstitution;
32
use Surfnet\Stepup\Identity\Event\CompliedWithVettedSecondFactorRevocationEvent;
33
use Surfnet\Stepup\Identity\Event\IdentityAccreditedAsRaaEvent;
34
use Surfnet\Stepup\Identity\Event\IdentityAccreditedAsRaEvent;
35
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
36
use Surfnet\Stepup\Identity\Event\RegistrationAuthorityRetractedEvent;
37
use Surfnet\Stepup\Identity\Event\SecondFactorVettedEvent;
38
use Surfnet\Stepup\Identity\Event\VettedSecondFactorRevokedEvent;
39
use Surfnet\Stepup\Identity\Event\YubikeySecondFactorBootstrappedEvent;
40
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Repository\InstitutionAuthorizationRepository;
41
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaCandidate;
42
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\IdentityRepository;
43
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\RaCandidateRepository;
44
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\RaListingRepository;
45
46
/**
47
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
48
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
49
 */
50
class RaCandidateProjector extends Projector
51
{
52
    /**
53
     * @var RaCandidateRepository
54
     */
55
    private $raCandidateRepository;
56
57
    /**
58
     * @var RaListingRepository
59
     */
60
    private $raListingRepository;
61
62
    /**
63
     * @var institutionAuthorizationRepository
64
     */
65
    private $institutionAuthorizationRepository;
66
    /**
67
     * @var IdentityRepository
68
     */
69
    private $identityRepository;
70
71
    public function __construct(
72
        RaCandidateRepository $raCandidateRepository,
73
        RaListingRepository $raListingRepository,
74
        InstitutionAuthorizationRepository $institutionAuthorizationRepository,
75
        IdentityRepository $identityRepository
76
    ) {
77
        $this->raCandidateRepository = $raCandidateRepository;
78
        $this->raListingRepository = $raListingRepository;
79
        $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...
80
        $this->identityRepository = $identityRepository;
81
    }
82
83
    /**
84
     * @param SecondFactorVettedEvent $event
85
     * @return void
86
     */
87
    public function applySecondFactorVettedEvent(SecondFactorVettedEvent $event)
88
    {
89
        $institutionAuthorizations = $this->institutionAuthorizationRepository
90
            ->findAuthorizationOptionsForInstitution(new ConfigurationInstitution($event->identityInstitution->getInstitution()));
91
92
        $institutions = [];
93
        foreach ($institutionAuthorizations as $authorization) {
94
            $institutions[$authorization->institution->getInstitution()] = new Institution($authorization->institution->getInstitution());
95
        }
96
97
        foreach ($institutions as $institution) {
98
            if ($this->raListingRepository->findByIdentityIdAndInstitution($event->identityId, $institution)) {
99
                continue;
100
            }
101
102
            // create candidate if not exists
103
            $candidate = $this->raCandidateRepository->findByIdentityIdAndRaInstitution($event->identityId, $institution);
104
            if (!$candidate) {
105
                $candidate = RaCandidate::nominate(
106
                    $event->identityId,
107
                    $event->identityInstitution,
108
                    $event->nameId,
109
                    $event->commonName,
110
                    $event->email,
111
                    $institution
112
                );
113
            }
114
115
            $this->raCandidateRepository->merge($candidate);
116
        }
117
    }
118
119
    /**
120
     * @param YubikeySecondFactorBootstrappedEvent $event
121
     * @return void
122
     */
123
    public function applyYubikeySecondFactorBootstrappedEvent(YubikeySecondFactorBootstrappedEvent $event)
124
    {
125
        $institutionAuthorizations = $this->institutionAuthorizationRepository
126
            ->findAuthorizationOptionsForInstitution(new ConfigurationInstitution($event->identityInstitution->getInstitution()));
127
128
        $institutions = [];
129
        foreach ($institutionAuthorizations as $authorization) {
130
            $institutions[$authorization->institution->getInstitution()] = new Institution($authorization->institution->getInstitution());
131
        }
132
133
        foreach ($institutions as $institution) {
134
135
            $institution = new Institution($institution->getInstitution());
136
137
            $candidate = RaCandidate::nominate(
138
                $event->identityId,
139
                $event->identityInstitution,
140
                $event->nameId,
141
                $event->commonName,
142
                $event->email,
143
                $institution
144
            );
145
146
            $this->raCandidateRepository->merge($candidate);
147
        }
148
    }
149
150
    /**
151
     * @param VettedSecondFactorRevokedEvent $event
152
     * @return void
153
     */
154
    public function applyVettedSecondFactorRevokedEvent(VettedSecondFactorRevokedEvent $event)
155
    {
156
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
157
    }
158
159
    /**
160
     * @param CompliedWithVettedSecondFactorRevocationEvent $event
161
     * @return void
162
     */
163
    public function applyCompliedWithVettedSecondFactorRevocationEvent(
164
        CompliedWithVettedSecondFactorRevocationEvent $event
165
    ) {
166
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
167
    }
168
169
    /**
170
     * @param SraaUpdatedEvent $event
171
     *
172
     * Removes all RaCandidates that have a nameId matching an SRAA, as they cannot be made RA(A) as they
173
     * already are SRAA.
174
     */
175
    public function applySraaUpdatedEvent(SraaUpdatedEvent $event)
176
    {
177
        $this->raCandidateRepository->removeByNameIds($event->sraaList);
178
    }
179
180
    /**
181
     * @param IdentityAccreditedAsRaForInstitutionEvent $event
182
     * @return void
183
     */
184
    public function applyIdentityAccreditedAsRaForInstitutionEvent(IdentityAccreditedAsRaForInstitutionEvent $event)
185
    {
186
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->raInstitution);
187
    }
188
189
    /**
190
     * @param IdentityAccreditedAsRaaForInstitutionEvent $event
191
     * @return void
192
     */
193
    public function applyIdentityAccreditedAsRaaForInstitutionEvent(IdentityAccreditedAsRaaForInstitutionEvent $event)
194
    {
195
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->raInstitution);
196
    }
197
198
    /**
199
     * @param RegistrationAuthorityRetractedForInstitutionEvent $event
200
     * @return void
201
     */
202 View Code Duplication
    public function applyRegistrationAuthorityRetractedForInstitutionEvent(RegistrationAuthorityRetractedForInstitutionEvent $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
203
    {
204
        $candidate = RaCandidate::nominate(
205
            $event->identityId,
206
            $event->identityInstitution,
207
            $event->nameId,
208
            $event->commonName,
209
            $event->email,
210
            $event->raInstitution
211
        );
212
213
        $this->raCandidateRepository->merge($candidate);
214
    }
215
216
    protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event)
217
    {
218
        $this->raCandidateRepository->removeByIdentityId($event->identityId);
219
    }
220
221
    protected function applySelectRaaOptionChangedEvent(SelectRaaOptionChangedEvent $event)
222
    {
223
        $authorizedInstitutions = $event->selectRaaOption->getInstitutions($event->institution);
224
        $this->updateInstitutionCandidatesFromCollection(new Institution($event->institution->getInstitution()), $authorizedInstitutions);
225
    }
226
227
    protected function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurationRemovedEvent $event)
228
    {
229
        $this->raCandidateRepository->removeByRaInstitution(new Institution($event->institution->getInstitution()));
230
    }
231
232
    /**
233
     * This method is kept to be backwards compatible for changes before FGA
234
     *
235
     * @param IdentityAccreditedAsRaEvent $event
236
     * @return void
237
     */
238
    public function applyIdentityAccreditedAsRaEvent(IdentityAccreditedAsRaEvent $event)
239
    {
240
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->identityInstitution);
241
    }
242
243
    /**
244
     * This method is kept to be backwards compatible for changes before FGA
245
     *
246
     * @param IdentityAccreditedAsRaaEvent $event
247
     * @return void
248
     */
249
    public function applyIdentityAccreditedAsRaaEvent(IdentityAccreditedAsRaaEvent $event)
250
    {
251
        $this->raCandidateRepository->removeByIdentityIdAndRaInstitution($event->identityId, $event->identityInstitution);
252
    }
253
254
    /**
255
     * This method is kept to be backwards compatible for changes before FGA
256
     *
257
     * @param RegistrationAuthorityRetractedEvent $event
258
     * @return void
259
     */
260 View Code Duplication
    public function applyRegistrationAuthorityRetractedEvent(RegistrationAuthorityRetractedEvent $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
    {
262
        $candidate = RaCandidate::nominate(
263
            $event->identityId,
264
            $event->identityInstitution,
265
            $event->nameId,
266
            $event->commonName,
267
            $event->email,
268
            $event->identityInstitution
269
        );
270
271
        $this->raCandidateRepository->merge($candidate);
272
    }
273
274
    /**
275
     * @param Institution $institution
276
     * @param ConfigurationInstitution[] $authorizedInstitutions
277
     * @throws \Doctrine\ORM\NonUniqueResultException
278
     */
279
    private function updateInstitutionCandidatesFromCollection(Institution $institution, array $authorizedInstitutions)
280
    {
281
        // convert configuration to value institutions
282
        $raInstitutions = new InstitutionCollection();
283
        foreach ($authorizedInstitutions as $authorizedInstitution) {
284
            $raInstitutions->add(new Institution($authorizedInstitution->getInstitution()));
285
        }
286
287
        // Remove candidates from removed institutions
288
        $this->raCandidateRepository->removeInstitutionsNotInList($institution, $raInstitutions);
289
290
        // loop through authorized institutions
291
        foreach ($raInstitutions as $raInstitution) {
292
293
            // add new identities
294
            $identities = $this->identityRepository->findByInstitution($raInstitution);
295
            foreach ($identities as $identity) {
296
                $identityId = new IdentityId($identity->id);
297
298
                // check if persistent in ra listing
299
                if ($this->raListingRepository->findByIdentityIdAndInstitution($identityId, $raInstitution)) {
300
                    continue;
301
                }
302
303
                // create candidate if not exists
304
                $candidate = $this->raCandidateRepository->findByIdentityIdAndRaInstitution($identityId, $raInstitution);
305
                if (!$candidate) {
306
                    $candidate = RaCandidate::nominate(
307
                        $identityId,
308
                        $identity->institution,
309
                        $identity->nameId,
310
                        $identity->commonName,
311
                        $identity->email,
312
                        $raInstitution
313
                    );
314
                }
315
316
                // store
317
                $this->raCandidateRepository->merge($candidate);
318
            }
319
        }
320
    }
321
}
322