Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
32 | class SecondFactorOnlyController extends Controller |
||
33 | { |
||
34 | const RESPONSE_CONTEXT_SERVICE_ID = 'second_factor_only.response_context'; |
||
35 | |||
36 | /** |
||
37 | * @param Request $httpRequest |
||
38 | * @return Response |
||
39 | */ |
||
40 | public function ssoAction(Request $httpRequest) |
||
41 | { |
||
42 | $logger = $this->get('logger'); |
||
43 | |||
44 | View Code Duplication | if (!$this->get('service_container')->getParameter('second_factor_only')) { |
|
|
|||
45 | $logger->notice(sprintf( |
||
46 | 'Access to %s denied, second_factor_only parameter set to false.', |
||
47 | __METHOD__ |
||
48 | )); |
||
49 | throw $this->createAccessDeniedException('Second Factor Only feature disabled'); |
||
50 | } |
||
51 | |||
52 | $logger->notice( |
||
53 | 'Received AuthnRequest on second-factor-only endpoint, started processing' |
||
54 | ); |
||
55 | |||
56 | /** @var \Surfnet\SamlBundle\Http\RedirectBinding $redirectBinding */ |
||
57 | $redirectBinding = $this->get('second_factor_only.http.redirect_binding'); |
||
58 | |||
59 | try { |
||
60 | $originalRequest = $redirectBinding->processSignedRequest($httpRequest); |
||
61 | } catch (Exception $e) { |
||
62 | $logger->critical(sprintf('Could not process Request, error: "%s"', $e->getMessage())); |
||
63 | |||
64 | return $this->render( |
||
65 | 'SurfnetStepupGatewayGatewayBundle:Gateway:unrecoverableError.html.twig' |
||
66 | ); |
||
67 | } |
||
68 | |||
69 | $originalRequestId = $originalRequest->getRequestId(); |
||
70 | $logger = $this->get('surfnet_saml.logger')->forAuthentication($originalRequestId); |
||
71 | $logger->notice(sprintf( |
||
72 | 'AuthnRequest processing complete, received AuthnRequest from "%s", request ID: "%s"', |
||
73 | $originalRequest->getServiceProvider(), |
||
74 | $originalRequest->getRequestId() |
||
75 | )); |
||
76 | |||
77 | $stateHandler = $this->get('gateway.proxy.state_handler'); |
||
78 | |||
79 | $stateHandler |
||
80 | ->setRequestId($originalRequestId) |
||
81 | ->setRequestServiceProvider($originalRequest->getServiceProvider()) |
||
82 | ->setRelayState($httpRequest->get(AuthnRequest::PARAMETER_RELAY_STATE, '')) |
||
83 | ->setResponseAction('SurfnetStepupGatewaySecondFactorOnlyBundle:SecondFactorOnly:respond') |
||
84 | ->setResponseContextServiceId(static::RESPONSE_CONTEXT_SERVICE_ID); |
||
85 | |||
86 | // Check if the NameID is provided and we may use it. |
||
87 | $nameId = $originalRequest->getNameId(); |
||
88 | if (!$this->verifyNameId($originalRequest->getServiceProvider(), $nameId, $logger)) { |
||
89 | /** @var \Surfnet\StepupGateway\GatewayBundle\Service\ResponseRenderingService $responseRendering */ |
||
90 | $responseRendering = $this->get('second_factor_only.response_rendering'); |
||
91 | return $responseRendering->renderRequesterFailureResponse( |
||
92 | $this->getResponseContext() |
||
93 | ); |
||
94 | } |
||
95 | $stateHandler->saveIdentityNameId($nameId); |
||
96 | |||
97 | // Check if the requested Loa is provided and supported. |
||
98 | $authnContextClassRef = $originalRequest->getAuthenticationContextClassRef(); |
||
99 | $loaId = $this->verifyAuthnContextClassRef($authnContextClassRef, $logger); |
||
100 | if (!$loaId) { |
||
101 | /** @var \Surfnet\StepupGateway\GatewayBundle\Service\ResponseRenderingService $responseRendering */ |
||
102 | $responseRendering = $this->get('second_factor_only.response_rendering'); |
||
103 | return $responseRendering->renderRequesterFailureResponse( |
||
104 | $this->getResponseContext() |
||
105 | ); |
||
106 | } |
||
107 | $stateHandler->setRequiredLoaIdentifier($loaId); |
||
108 | |||
109 | $logger->notice( |
||
110 | 'Forwarding to second factor controller for loa determination and handling' |
||
111 | ); |
||
112 | return $this->forward( |
||
113 | 'SurfnetStepupGatewayGatewayBundle:SecondFactor:selectSecondFactorForVerification' |
||
114 | ); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * @param string $authnContextClassRef |
||
119 | * @param LoggerInterface $logger |
||
120 | * @return string |
||
121 | */ |
||
122 | private function verifyAuthnContextClassRef( |
||
159 | |||
160 | /** |
||
161 | * @param string $spEntityId |
||
162 | * @param string $nameId |
||
163 | * @param LoggerInterface $logger |
||
164 | * @return bool |
||
165 | */ |
||
166 | private function verifyNameId($spEntityId, $nameId, LoggerInterface $logger) |
||
187 | |||
188 | /** |
||
189 | * @return Response |
||
190 | */ |
||
191 | public function respondAction() |
||
253 | |||
254 | /** |
||
255 | * @return \Surfnet\StepupGateway\GatewayBundle\Saml\ResponseContext |
||
256 | */ |
||
257 | public function getResponseContext() |
||
261 | } |
||
262 |
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.