Completed
Push — feature/fine-grained-authoriza... ( 048037...d683d5 )
by Michiel
10s
created

getInstitutionConfigurationOptionsService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
nc 1
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\StepupRa\RaBundle\Controller;
20
21
use Surfnet\StepupMiddlewareClient\Identity\Dto\RaListingSearchQuery;
22
use Surfnet\StepupRa\RaBundle\Command\AccreditCandidateCommand;
23
use Surfnet\StepupRa\RaBundle\Command\AmendRegistrationAuthorityInformationCommand;
24
use Surfnet\StepupRa\RaBundle\Command\ChangeRaManagementInstitutionCommand;
25
use Surfnet\StepupRa\RaBundle\Command\ChangeRaRoleCommand;
26
use Surfnet\StepupRa\RaBundle\Command\RetractRegistrationAuthorityCommand;
27
use Surfnet\StepupRa\RaBundle\Command\SearchRaCandidatesCommand;
28
use Surfnet\StepupRa\RaBundle\Form\Type\AmendRegistrationAuthorityInformationType;
29
use Surfnet\StepupRa\RaBundle\Form\Type\ChangeRaManagementInstitutionType;
30
use Surfnet\StepupRa\RaBundle\Form\Type\ChangeRaRoleType;
31
use Surfnet\StepupRa\RaBundle\Form\Type\CreateRaType;
32
use Surfnet\StepupRa\RaBundle\Form\Type\RetractRegistrationAuthorityType;
33
use Surfnet\StepupRa\RaBundle\Form\Type\SearchRaCandidatesType;
34
use Surfnet\StepupRa\RaBundle\Security\Authentication\Token\SamlToken;
35
use Surfnet\StepupRa\RaBundle\Service\InstitutionConfigurationOptionsService;
36
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
37
use Symfony\Component\HttpFoundation\Request;
38
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
39
40
/**
41
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
42
 */
43
class RaManagementController extends Controller
44
{
45
    /**
46
     * @param Request $request
47
     * @return \Symfony\Component\HttpFoundation\Response
48
     */
49
    public function manageAction(Request $request)
50
    {
51
        $this->denyAccessUnlessGranted(['ROLE_RAA', 'ROLE_SRAA']);
52
53
        $logger = $this->get('logger');
54
        $institution = $this->getUser()->institution;
55
56
        /**
57
         * @var SamlToken $token
58
         */
59
        $token  = $this->get('security.token_storage')->getToken();
60
        $logger->notice(sprintf('Loading overview of RA(A)s for institution "%s"', $institution));
61
62
        $raaSwitcherOptions = $this
63
            ->getInstitutionConfigurationOptionsService()
64
            ->getSelectRaaOptionsFor($institution);
65
66
        $raaSwitcherCommand = new ChangeRaManagementInstitutionCommand();
67
        $raaSwitcherCommand->raaManagementInstitution = $token->getRaManagementInstitution();
68
        $raaSwitcherCommand->availableInstitutions = $raaSwitcherOptions;
69
70
        $form = $this->createForm(ChangeRaManagementInstitutionType::class, $raaSwitcherCommand);
71
        $form->handleRequest($request);
72
73
        if ($form->isSubmitted()) {
74
            $token->changeRaaInstitutionScope($raaSwitcherCommand->raaManagementInstitution);
75
76
            $flashMessage = $this->get('translator')
77
                ->trans('ra.raa.changed_institution', ['%institution%' => $raaSwitcherCommand->raaManagementInstitution]);
78
            $this->get('session')->getFlashBag()->add('success', $flashMessage);
79
80
            $logger->notice(sprintf(
81
                'RAA "%s" successfully switched to institution "%s"',
82
                $this->getUser()->id,
83
                $raaSwitcherCommand->raaManagementInstitution
84
            ));
85
        }
86
87
        $searchQuery = (new RaListingSearchQuery($this->getUser()->institution, 1))
88
            ->setOrderBy($request->get('orderBy', 'commonName'))
89
            ->setOrderDirection($request->get('orderDirection', 'asc'));
90
91
        $service = $this->getRaListingService();
92
        $raList = $service->search($searchQuery);
93
94
        $pagination = $this->getPaginator()->paginate(
95
            $raList->getTotalItems() > 0 ? array_fill(0, $raList->getTotalItems(), 1) : [],
96
            $raList->getCurrentPage(),
97
            $raList->getItemsPerPage()
98
        );
99
100
        $logger->notice(sprintf(
101
            'Created overview of "%d" RA(A)s for institution "%s"',
102
            $raList->getTotalItems(),
103
            $institution
104
        ));
105
106
        /** @var \Surfnet\StepupMiddlewareClientBundle\Identity\Dto\RaListing[] $raListings */
107
        $raListings = $raList->getElements();
108
109
        return $this->render(
110
            'SurfnetStepupRaRaBundle:RaManagement:manage.html.twig',
111
            [
112
                'raInstitutionSwitcher' => $form->createView(),
113
                'raList' => $raListings,
114
                'pagination' => $pagination,
115
            ]
116
        );
117
    }
118
119
    /**
120
     * @param Request $request
121
     * @return \Symfony\Component\HttpFoundation\Response
122
     */
123
    public function raCandidateSearchAction(Request $request)
124
    {
125
        $this->denyAccessUnlessGranted(['ROLE_RAA', 'ROLE_SRAA']);
126
127
        $logger = $this->get('logger');
128
        $institution = $this->getUser()->institution;
129
130
        $logger->notice(sprintf('Searching for RaCandidates within institution "%s"', $institution));
131
132
        $command                   = new SearchRaCandidatesCommand();
133
        $command->actorInstitution = $institution;
134
        $command->pageNumber       = (int) $request->get('p', 1);
135
        $command->orderBy          = $request->get('orderBy');
136
        $command->orderDirection   = $request->get('orderDirection');
137
138
        $form = $this->createForm(SearchRaCandidatesType::class, $command, ['method' => 'get']);
139
        $form->handleRequest($request);
140
141
        $service = $this->getRaCandidateService();
142
        $raCandidateList = $service->search($command);
143
144
        $pagination = $this->getPaginator()->paginate(
145
            $raCandidateList->getTotalItems() > 0 ? array_fill(4, $raCandidateList->getTotalItems(), 1) : [],
146
            $raCandidateList->getCurrentPage(),
147
            $raCandidateList->getItemsPerPage()
148
        );
149
150
        $logger->notice(sprintf(
151
            'Searching for RaCandidates within institution "%s" yielded "%s" results',
152
            $institution,
153
            $raCandidateList->getTotalItems()
154
        ));
155
156
        return $this->render(
157
            'SurfnetStepupRaRaBundle:RaManagement:raCandidateOverview.html.twig',
158
            [
159
                'form'         => $form->createView(),
160
                'raCandidates' => $raCandidateList,
161
                'pagination'   => $pagination
162
            ]
163
        );
164
    }
165
166
    /**
167
     * @param Request $request
168
     * @return \Symfony\Component\HttpFoundation\Response
169
     */
170
    public function createRaAction(Request $request)
171
    {
172
        $this->denyAccessUnlessGranted(['ROLE_RAA', 'ROLE_SRAA']);
173
        $logger = $this->get('logger');
174
175
        $logger->notice('Page for Accreditation of Identity to Ra or Raa requested');
176
        $identityId = $request->get('identityId');
177
        $raCandidate = $this->getRaCandidateService()->getRaCandidate($identityId, $this->getUser()->institution);
178
179
        if (!$raCandidate) {
180
            $logger->warning(sprintf('RaCandidate based on identity "%s" not found', $identityId));
181
            throw new NotFoundHttpException();
182
        }
183
184
        $command                   = new AccreditCandidateCommand();
185
        $command->actorInstitution = $this->getUser()->institution;
186
        $command->identityId       = $identityId;
187
        $command->institution      = $raCandidate->institution;
188
189
        // todo: make choicelist configurable
190
        $form = $this->createForm(CreateRaType::class, $command)->handleRequest($request);
191 View Code Duplication
        if ($form->isSubmitted() && $form->isValid()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
192
            $logger->debug('Accreditation form submitted, start processing command');
193
194
            $success = $this->getRaCandidateService()->accreditCandidate($command);
195
196
            if ($success) {
197
                $this->addFlash(
198
                    'success',
199
                    $this->get('translator')->trans('ra.management.create_ra.identity_accredited')
200
                );
201
202
                $logger->debug('Identity Accredited, redirecting to candidate overview');
203
                return $this->redirectToRoute('ra_management_ra_candidate_search');
204
            }
205
206
            $logger->debug('Identity Accreditation failed, adding error to form');
207
            $this->addFlash('error', 'ra.management.create_ra.error.middleware_command_failed');
208
        }
209
210
        return $this->render('SurfnetStepupRaRaBundle:RaManagement:createRa.html.twig', [
211
            'raCandidate' => $raCandidate,
212
            'form'        => $form->createView()
213
        ]);
214
    }
215
216
    /**
217
     * @param Request $request
218
     * @param         $identityId
219
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
220
     */
221 View Code Duplication
    public function amendRaInformationAction(Request $request, $identityId)
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...
222
    {
223
        $this->denyAccessUnlessGranted(['ROLE_RAA', 'ROLE_SRAA']);
224
225
        $logger = $this->get('logger');
226
        $logger->notice(sprintf("Loading information amendment form for RA(A) '%s'", $identityId));
227
228
        $raListing = $this->getRaListingService()->get($identityId, $this->getUser()->institution);
229
230
        if (!$raListing) {
231
            $logger->warning(sprintf("RA listing for identity ID '%s' not found", $identityId));
232
            throw new NotFoundHttpException(sprintf("RA listing for identity ID '%s' not found", $identityId));
233
        }
234
235
        $command = new AmendRegistrationAuthorityInformationCommand();
236
        $command->identityId = $raListing->identityId;
237
        $command->location = $this->getUser()->institution;
238
        $command->contactInformation = $raListing->contactInformation;
239
240
        $form = $this->createForm(AmendRegistrationAuthorityInformationType::class, $command)->handleRequest($request);
241
        if ($form->isSubmitted() && $form->isValid()) {
242
            $logger->notice(sprintf("RA(A) '%s' information amendment form submitted, processing", $identityId));
243
244
            if ($this->get('ra.service.ra')->amendRegistrationAuthorityInformation($command)) {
245
                $this->addFlash('success', $this->get('translator')->trans('ra.management.amend_ra_info.info_amended'));
246
247
                $logger->notice(sprintf("RA(A) '%s' information successfully amended", $identityId));
248
                return $this->redirectToRoute('ra_management_manage');
249
            }
250
251
            $logger->notice(sprintf("Information of RA(A) '%s' failed to be amended, informing user", $identityId));
252
            $this->addFlash('error', 'ra.management.amend_ra_info.error.middleware_command_failed');
253
        }
254
255
        return $this->render('SurfnetStepupRaRaBundle:RaManagement:amendRaInformation.html.twig', [
256
            'raListing' => $raListing,
257
            'form' => $form->createView(),
258
        ]);
259
    }
260
261
    /**
262
     * @param Request $request
263
     * @param         $identityId
264
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
265
     */
266 View Code Duplication
    public function changeRaRoleAction(Request $request, $identityId)
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...
267
    {
268
        $this->denyAccessUnlessGranted(['ROLE_RAA', 'ROLE_SRAA']);
269
        $logger = $this->get('logger');
270
271
        $logger->notice(sprintf("Loading change Ra Role form for RA(A) '%s'", $identityId));
272
273
        $raListing = $this->getRaListingService()->get($identityId, $this->getUser()->institution);
274
        if (!$raListing) {
275
            $logger->warning(sprintf("RA listing for identity ID '%s' not found", $identityId));
276
            throw new NotFoundHttpException(sprintf("RA listing for identity ID '%s' not found", $identityId));
277
        }
278
279
        $command              = new ChangeRaRoleCommand();
280
        $command->identityId  = $raListing->identityId;
281
        $command->institution = $this->getUser()->institution;
282
        $command->role        = $raListing->role;
283
284
        $form = $this->createForm(ChangeRaRoleType::class, $command)->handleRequest($request);
285
        if ($form->isSubmitted() && $form->isValid()) {
286
            $logger->notice(sprintf('RA(A) "%s" Change Role form submitted, processing', $identityId));
287
288
            if ($this->get('ra.service.ra')->changeRegistrationAuthorityRole($command)) {
289
                $logger->notice('Role successfully changed');
290
291
                $this->addFlash('success', $this->get('translator')->trans('ra.management.change_ra_role_changed'));
292
                return $this->redirectToRoute('ra_management_manage');
293
            }
294
295
            $logger->notice(sprintf('Role of RA(A) "%s" could not be changed, informing user', $identityId));
296
            $this->addFlash('error', 'ra.management.change_ra_role.middleware_command_failed');
297
        }
298
299
        return $this->render('SurfnetStepupRaRaBundle:RaManagement:changeRaRole.html.twig', [
300
            'raListing' => $raListing,
301
            'form'      => $form->createView()
302
        ]);
303
    }
304
305
    /**
306
     * @param Request $request
307
     * @param         $identityId
308
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
309
     */
310
    public function retractRegistrationAuthorityAction(Request $request, $identityId)
311
    {
312
        $this->denyAccessUnlessGranted(['ROLE_RAA', 'ROLE_SRAA']);
313
        $logger = $this->get('logger');
314
315
        $logger->notice(sprintf("Loading retract registration authority form for RA(A) '%s'", $identityId));
316
317
        $raListing = $this->getRaListingService()->get($identityId, $this->getUser()->institution);
318
        if (!$raListing) {
319
            $logger->warning(sprintf("RA listing for identity ID '%s' not found", $identityId));
320
            throw new NotFoundHttpException(sprintf("RA listing for identity ID '%s' not found", $identityId));
321
        }
322
323
        $command = new RetractRegistrationAuthorityCommand();
324
        $command->identityId = $identityId;
325
326
        $form = $this->createForm(RetractRegistrationAuthorityType::class, $command)->handleRequest($request);
327
        if ($form->isSubmitted() && $form->isValid()) {
328
            if ($form->get('cancel')->isClicked()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Form\FormInterface as the method isClicked() does only exist in the following implementations of said interface: Symfony\Component\Form\SubmitButton.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
329
                $logger->notice('Retraction of registration authority cancelled');
330
                return $this->redirectToRoute('ra_management_manage');
331
            }
332
333
            $logger->notice(sprintf('Confirmed retraction of RA credentials for identity "%s"', $identityId));
334
335
            if ($this->get('ra.service.ra')->retractRegistrationAuthority($command)) {
336
                $logger->notice(sprintf('Registration authority for identity "%s" retracted', $identityId));
337
338
                $this->addFlash('success', $this->get('translator')->trans('ra.management.retract_ra.success'));
339
                return $this->redirectToRoute('ra_management_manage');
340
            }
341
342
            $logger->notice(sprintf(
343
                'Could not retract Registration Authority credentials for identity "%s"',
344
                $identityId
345
            ));
346
            $this->addFlash('error', 'ra.management.retract_ra.middleware_command_failed');
347
        }
348
349
        return $this->render('SurfnetStepupRaRaBundle:RaManagement:confirmRetractRa.html.twig', [
350
            'raListing' => $raListing,
351
            'form'      => $form->createView()
352
        ]);
353
    }
354
355
    /**
356
     * @return \Surfnet\StepupMiddlewareClientBundle\Identity\Service\RaListingService
357
     */
358
    private function getRaListingService()
359
    {
360
        return $this->get('surfnet_stepup_middleware_client.identity.service.ra_listing');
361
    }
362
363
    /**
364
     * @return \Surfnet\StepupRa\RaBundle\Service\RaCandidateService
365
     */
366
    private function getRaCandidateService()
367
    {
368
        return $this->get('ra.service.ra_candidate');
369
    }
370
371
    /**
372
     * @return InstitutionConfigurationOptionsService
373
     */
374
    private function getInstitutionConfigurationOptionsService()
375
    {
376
        return $this->get('ra.service.institution_configuration_options');
377
    }
378
379
    /**
380
     * @return \Knp\Component\Pager\Paginator
381
     */
382
    private function getPaginator()
383
    {
384
        return $this->get('knp_paginator');
385
    }
386
}
387