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 |
||
22 | class SessionController extends Controller |
||
23 | { |
||
24 | /** |
||
25 | * @var \eZ\Publish\Core\MVC\Symfony\Security\Authentication\AuthenticatorInterface |
||
26 | */ |
||
27 | private $authenticator; |
||
28 | |||
29 | /** |
||
30 | * @var \Symfony\Component\Security\Csrf\CsrfTokenManager |
||
31 | */ |
||
32 | private $csrfTokenManager; |
||
33 | |||
34 | /** |
||
35 | * @var \Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface |
||
36 | */ |
||
37 | private $csrfTokenStorage; |
||
38 | |||
39 | /** |
||
40 | * @var string |
||
41 | */ |
||
42 | private $csrfTokenIntention; |
||
43 | |||
44 | public function __construct( |
||
55 | |||
56 | /** |
||
57 | * Creates a new session based on the credentials provided as POST parameters. |
||
58 | * |
||
59 | * @throws \eZ\Publish\Core\Base\Exceptions\UnauthorizedException If the login or password are incorrect or invalid CSRF |
||
60 | * |
||
61 | * @return Values\UserSession|Values\Conflict |
||
62 | */ |
||
63 | public function createSessionAction(Request $request) |
||
100 | |||
101 | /** |
||
102 | * Refresh given session. |
||
103 | * |
||
104 | * @param string $sessionId |
||
105 | * |
||
106 | * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException |
||
107 | * |
||
108 | * @return \eZ\Publish\Core\REST\Server\Values\UserSession |
||
109 | */ |
||
110 | public function refreshSessionAction($sessionId, Request $request) |
||
111 | { |
||
112 | $session = $request->getSession(); |
||
113 | |||
114 | View Code Duplication | if ($session === null || !$session->isStarted() || $session->getId() != $sessionId || !$this->hasStoredCsrfToken()) { |
|
115 | $response = $this->authenticator->logout($request); |
||
116 | $response->setStatusCode(404); |
||
117 | |||
118 | return $response; |
||
119 | } |
||
120 | |||
121 | $this->checkCsrfToken($request); |
||
122 | |||
123 | return new Values\UserSession( |
||
124 | $this->repository->getCurrentUser(), |
||
125 | $session->getName(), |
||
126 | $session->getId(), |
||
127 | $request->headers->get('X-CSRF-Token'), |
||
128 | false |
||
129 | ); |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * Deletes given session. |
||
134 | * |
||
135 | * @param string $sessionId |
||
136 | * |
||
137 | * @return Values\DeletedUserSession |
||
138 | * |
||
139 | * @throws NotFoundException |
||
140 | */ |
||
141 | public function deleteSessionAction($sessionId, Request $request) |
||
142 | { |
||
143 | /** @var $session \Symfony\Component\HttpFoundation\Session\Session */ |
||
144 | $session = $request->getSession(); |
||
145 | View Code Duplication | if (!$session->isStarted() || $session->getId() != $sessionId || !$this->hasStoredCsrfToken()) { |
|
146 | $response = $this->authenticator->logout($request); |
||
147 | $response->setStatusCode(404); |
||
148 | |||
149 | return $response; |
||
150 | } |
||
151 | |||
152 | $this->checkCsrfToken($request); |
||
153 | |||
154 | return new Values\DeletedUserSession($this->authenticator->logout($request)); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Tests if a CSRF token is stored. |
||
159 | * |
||
160 | * @return bool |
||
161 | */ |
||
162 | private function hasStoredCsrfToken() |
||
170 | |||
171 | /** |
||
172 | * Checks the presence / validity of the CSRF token. |
||
173 | * |
||
174 | * @param Request $request |
||
175 | * |
||
176 | * @throws UnauthorizedException if the token is missing or invalid. |
||
177 | */ |
||
178 | private function checkCsrfToken(Request $request) |
||
202 | |||
203 | /** |
||
204 | * Returns the csrf token for REST. The token is generated if it doesn't exist. |
||
205 | * |
||
206 | * @return string The csrf token, or an empty string if csrf check is disabled. |
||
207 | */ |
||
208 | private function getCsrfToken() |
||
216 | } |
||
217 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.