Completed
Push — feature/authz-service ( 2625fb...8f3145 )
by
unknown
02:12
created

InstitutionConfigurationController   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 23

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 23
dl 0
loc 178
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A showAction() 0 35 2
B reconfigureAction() 0 52 9
A handleCommands() 0 26 4
A getInstitutionConfigurationOptionsService() 0 4 1
A getInstitutionAuthorizationService() 0 4 1
A getAllowedSecondFactorListService() 0 4 1
A getValidator() 0 4 1
A getLogger() 0 4 1
A getPipeline() 0 4 1
A getConnectionHelper() 0 4 1
1
<?php
2
3
/**
4
 * Copyright 2016 SURFnet B.V.
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\ManagementBundle\Controller;
20
21
use DateTime;
22
use Exception;
23
use Liip\FunctionalTestBundle\Validator\DataCollectingValidator;
24
use Rhumsaa\Uuid\Uuid;
25
use Surfnet\Stepup\Configuration\Value\Institution;
26
use Surfnet\Stepup\Configuration\Value\InstitutionAuthorizationOptionMap;
27
use Surfnet\Stepup\Configuration\Value\InstitutionRole;
28
use Surfnet\Stepup\Helper\JsonHelper;
29
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Service\AllowedSecondFactorListService;
30
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Service\InstitutionAuthorizationService;
31
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Service\InstitutionConfigurationOptionsService;
32
use Surfnet\StepupMiddleware\ApiBundle\Exception\BadCommandRequestException;
33
use Surfnet\StepupMiddleware\CommandHandlingBundle\Command\Command;
34
use Surfnet\StepupMiddleware\CommandHandlingBundle\Configuration\Command\ReconfigureInstitutionConfigurationOptionsCommand;
35
use Surfnet\StepupMiddleware\CommandHandlingBundle\Exception\ForbiddenException;
36
use Surfnet\StepupMiddleware\CommandHandlingBundle\Pipeline\Pipeline;
37
use Surfnet\StepupMiddleware\ManagementBundle\Service\DBALConnectionHelper;
38
use Surfnet\StepupMiddleware\ManagementBundle\Validator\Constraints\ValidReconfigureInstitutionsRequest;
39
use Symfony\Bridge\Monolog\Logger;
40
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
41
use Symfony\Component\HttpFoundation\JsonResponse;
42
use Symfony\Component\HttpFoundation\Request;
43
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
44
45
/**
46
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
47
 */
48
final class InstitutionConfigurationController extends Controller
49
{
50
    public function showAction()
51
    {
52
        $this->denyAccessUnlessGranted(['ROLE_MANAGEMENT']);
53
54
        $institutionConfigurationOptions = $this->getInstitutionConfigurationOptionsService()
55
            ->findAllInstitutionConfigurationOptions();
56
57
        $allowedSecondFactorMap = $this->getAllowedSecondFactorListService()->getAllowedSecondFactorMap();
58
59
        $overview = [];
60
        foreach ($institutionConfigurationOptions as $options) {
61
            // Load the numberOfTokensPerIdentity from the institution config options service
62
            $numberOfTokensPerIdentity = $this->getInstitutionConfigurationOptionsService()
63
                ->getMaxNumberOfTokensFor(new Institution($options->institution->getInstitution()));
64
65
            // Get the authorization options for this institution
66
            $institutionConfigurationOptionsMap = $this->getInstitutionAuthorizationService()
67
                ->findAuthorizationsFor($options->institution);
68
69
            $overview[$options->institution->getInstitution()] = [
70
                'use_ra_locations' => $options->useRaLocationsOption,
71
                'show_raa_contact_information' => $options->showRaaContactInformationOption,
72
                'verify_email' => $options->verifyEmailOption,
73
                'number_of_tokens_per_identity' => $numberOfTokensPerIdentity,
74
                'allowed_second_factors' => $allowedSecondFactorMap->getAllowedSecondFactorListFor(
75
                    $options->institution
76
                ),
77
                'use_ra' => $institutionConfigurationOptionsMap->getInstitutionAuthorizationOptionsByRole(InstitutionRole::useRa())->jsonSerialize(),
78
                'use_raa' => $institutionConfigurationOptionsMap->getInstitutionAuthorizationOptionsByRole(InstitutionRole::useRaa())->jsonSerialize(),
79
                'select_raa' => $institutionConfigurationOptionsMap->getInstitutionAuthorizationOptionsByRole(InstitutionRole::selectRaa())->jsonSerialize(),
80
            ];
81
        }
82
83
        return new JsonResponse($overview);
84
    }
85
86
    public function reconfigureAction(Request $request)
87
    {
88
        $this->denyAccessUnlessGranted(['ROLE_MANAGEMENT']);
89
90
        $configuration = JsonHelper::decode($request->getContent());
91
92
        $violations = $this->getValidator()->validate($configuration, new ValidReconfigureInstitutionsRequest());
93
        if ($violations->count() > 0) {
94
            throw BadCommandRequestException::withViolations('Invalid reconfigure institutions request', $violations);
95
        }
96
97
        if (empty($configuration)) {
98
            $this->getLogger()->notice(sprintf('No institutions to reconfigure: empty configuration received'));
99
100
            return new JsonResponse([
101
                'status'       => 'OK',
102
                'processed_by' =>  $request->server->get('SERVER_NAME') ?: $request->server->get('SERVER_ADDR'),
103
                'applied_at'   => (new DateTime())->format(DateTime::ISO8601),
104
            ]);
105
        }
106
107
        $commands = [];
108
        foreach ($configuration as $institution => $options) {
109
            $command                                  = new ReconfigureInstitutionConfigurationOptionsCommand();
110
            $command->UUID                            = (string) Uuid::uuid4();
111
            $command->institution                     = $institution;
0 ignored issues
show
Documentation Bug introduced by
It seems like $institution can also be of type integer. However, the property $institution is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
112
            $command->useRaLocationsOption            = $options['use_ra_locations'];
113
            $command->showRaaContactInformationOption = $options['show_raa_contact_information'];
114
            $command->verifyEmailOption               = $options['verify_email'];
115
            $command->numberOfTokensPerIdentityOption = $options['number_of_tokens_per_identity'];
116
            $command->allowedSecondFactors            = $options['allowed_second_factors'];
117
118
            // The useRa, useRaa and selectRaa options are optional
119
            $command->useRaOption = isset($options['use_ra']) ? $options['use_ra'] : null;
120
            $command->useRaaOption = isset($options['use_raa']) ? $options['use_raa'] : null;
121
            $command->selectRaaOption = isset($options['select_raa']) ? $options['select_raa'] : null;
122
123
            $commands[] = $command;
124
        }
125
126
        $this->getLogger()->notice(
127
            sprintf('Executing %s reconfigure institution configuration options commands', count($commands))
128
        );
129
130
        $this->handleCommands($commands);
131
132
        return new JsonResponse([
133
            'status'       => 'OK',
134
            'processed_by' =>  $request->server->get('SERVER_NAME') ?: $request->server->get('SERVER_ADDR'),
135
            'applied_at'   => (new DateTime())->format(DateTime::ISO8601),
136
        ]);
137
    }
138
139
    /**
140
     * @param Command[] $commands
141
     * @throws Exception
142
     */
143
    private function handleCommands(array $commands)
144
    {
145
        $pipeline         = $this->getPipeline();
146
        $connectionHelper = $this->getConnectionHelper();
147
148
        $connectionHelper->beginTransaction();
149
150
        foreach ($commands as $command) {
151
            try {
152
                $pipeline->process($command);
153
            } catch (ForbiddenException $e) {
154
                $connectionHelper->rollBack();
155
156
                throw new AccessDeniedHttpException(
157
                    sprintf('Processing of command "%s" is forbidden for this client', $command),
158
                    $e
159
                );
160
            } catch (Exception $exception) {
161
                $connectionHelper->rollBack();
162
163
                throw $exception;
164
            }
165
        }
166
167
        $connectionHelper->commit();
168
    }
169
170
    /**
171
     * @return InstitutionConfigurationOptionsService
172
     */
173
    private function getInstitutionConfigurationOptionsService()
174
    {
175
        return $this->get('surfnet_stepup_middleware_api.service.institution_configuration_options');
176
    }
177
178
    /**
179
     * @return InstitutionAuthorizationService
180
     */
181
    private function getInstitutionAuthorizationService()
182
    {
183
        return $this->get('surfnet_stepup_middleware_api.service.institution_authorization');
184
    }
185
186
    /**
187
     * @return AllowedSecondFactorListService
188
     */
189
    private function getAllowedSecondFactorListService()
190
    {
191
        return $this->get('surfnet_stepup_middleware_api.service.allowed_second_factor_list');
192
    }
193
194
    /**
195
     * @return DataCollectingValidator
196
     */
197
    private function getValidator()
198
    {
199
        return $this->get('validator');
200
    }
201
202
    /**
203
     * @return Logger
204
     */
205
    private function getLogger()
206
    {
207
        return $this->get('logger');
208
    }
209
210
    /**
211
     * @return Pipeline
212
     */
213
    private function getPipeline()
214
    {
215
        return $this->get('pipeline');
216
    }
217
218
    /**
219
     * @return DBALConnectionHelper
220
     */
221
    private function getConnectionHelper()
222
    {
223
        return $this->get('surfnet_stepup_middleware_management.dbal_connection_helper');
224
    }
225
}
226