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 |
||
28 | final class SecurityAuthenticator implements |
||
29 | SimplePreAuthenticatorInterface, |
||
|
|||
30 | AuthenticationFailureHandlerInterface |
||
31 | { |
||
32 | |||
33 | /** |
||
34 | * Authentication can be required to use any service |
||
35 | * @var bool, |
||
36 | */ |
||
37 | protected $securityRequired; |
||
38 | |||
39 | /** |
||
40 | * Authentication can use a test user if no user found |
||
41 | * @var bool, |
||
42 | */ |
||
43 | protected $securityTestUsername; |
||
44 | |||
45 | /** |
||
46 | * Authentication can allow not identified users to get information |
||
47 | * @var bool, |
||
48 | */ |
||
49 | protected $allowAnonymous; |
||
50 | |||
51 | /** |
||
52 | * @var AuthenticationProvider |
||
53 | */ |
||
54 | protected $userProvider; |
||
55 | |||
56 | /** |
||
57 | * @var StrategyInterface |
||
58 | */ |
||
59 | protected $extractionStrategy; |
||
60 | |||
61 | /** |
||
62 | * @var Logger |
||
63 | */ |
||
64 | protected $logger; |
||
65 | |||
66 | |||
67 | /** |
||
68 | * @param boolean $securityRequired user provider to use |
||
69 | * @param string $securityTestUsername user for testing |
||
70 | * @param boolean $allowAnonymous user provider to use |
||
71 | * @param AuthenticationProvider $userProvider user provider to use |
||
72 | * @param StrategyInterface $extractionStrategy auth strategy to use |
||
73 | * @param Logger $logger logger to user for logging errors |
||
74 | */ |
||
75 | 20 | public function __construct( |
|
92 | |||
93 | /** |
||
94 | * @param Request $request request to authenticate |
||
95 | * @param string $providerKey provider key to auth with |
||
96 | * |
||
97 | * @return SecurityToken |
||
98 | */ |
||
99 | 10 | public function createToken(Request $request, $providerKey) |
|
100 | { |
||
101 | // look for an apikey query parameter |
||
102 | 10 | $apiKey = $this->extractionStrategy->apply($request); |
|
103 | |||
104 | 10 | $token = new SecurityToken( |
|
105 | 10 | 'anon.', |
|
106 | 5 | $apiKey, |
|
107 | 5 | $providerKey, |
|
108 | 10 | $this->extractionStrategy->getRoles() |
|
109 | 5 | ); |
|
110 | |||
111 | 10 | $token->setAttribute('ipAddress', $request->getClientIp()); |
|
112 | |||
113 | 10 | return $token; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * Tries to authenticate the provided token |
||
118 | * |
||
119 | * @param TokenInterface $token token to authenticate |
||
120 | * @param UserProviderInterface $userProvider provider to auth against |
||
121 | * @param string $providerKey key to auth with |
||
122 | * |
||
123 | * @return SecurityToken |
||
124 | */ |
||
125 | 4 | public function authenticateToken( |
|
126 | TokenInterface $token, |
||
127 | UserProviderInterface $userProvider, |
||
128 | $providerKey |
||
129 | ) { |
||
130 | 4 | $username = $token->getCredentials(); |
|
131 | 4 | $securityUser = false; |
|
132 | |||
133 | // If no username in Strategy, check if required. |
||
134 | 4 | if ($this->securityRequired && !$username) { |
|
135 | $this->logger->warning('Authentication key is required.'); |
||
136 | throw new AuthenticationException( |
||
137 | sprintf('Authentication key is required.') |
||
138 | ); |
||
139 | } |
||
140 | |||
141 | /** @var SecurityUser $securityUser */ |
||
142 | 4 | if ($token->hasRole(SecurityUser::ROLE_SUBNET)) { |
|
143 | $this->logger->info('Authentication, loading graviton subnet user IP address: '. $token->getAttribute('ipAddress')); |
||
144 | $securityUser = new SecurityUser(new SubnetUser($username), [SecurityUser::ROLE_SUBNET]); |
||
145 | 4 | View Code Duplication | } elseif ($user = $this->userProvider->loadUserByUsername($username)) { |
146 | 2 | $securityUser = new SecurityUser($user, [SecurityUser::ROLE_USER, SecurityUser::ROLE_CONSULTANT]); |
|
147 | 3 | } elseif ($this->securityTestUsername) { |
|
148 | $this->logger->info('Authentication, loading test user: '.$this->securityTestUsername); |
||
149 | View Code Duplication | if ($user = $this->userProvider->loadUserByUsername($this->securityTestUsername)) { |
|
150 | $securityUser = new SecurityUser($user, [SecurityUser::ROLE_USER]); |
||
151 | } |
||
152 | } |
||
153 | |||
154 | // Check if allow Anonymous |
||
155 | 4 | if (!$securityUser) { |
|
156 | 2 | if ($this->allowAnonymous) { |
|
157 | $this->logger->info('Authentication, loading anonymous user.'); |
||
158 | $securityUser = new SecurityUser(new AnonymousUser(), [SecurityUser::ROLE_ANONYMOUS]); |
||
159 | } else { |
||
160 | 2 | $this->logger->warning(sprintf('Authentication key "%s" could not be resolved.', $username)); |
|
161 | 2 | throw new AuthenticationException( |
|
162 | 2 | sprintf('Authentication key "%s" could not be resolved.', $username) |
|
163 | 1 | ); |
|
164 | } |
||
165 | } |
||
166 | |||
167 | 2 | return new SecurityToken( |
|
168 | 1 | $securityUser, |
|
169 | 1 | $username, |
|
170 | 1 | $providerKey, |
|
171 | 2 | $securityUser->getRoles() |
|
172 | 1 | ); |
|
173 | } |
||
174 | |||
175 | /** |
||
176 | * @param TokenInterface $token token to check |
||
177 | * @param string $providerKey provider to check against |
||
178 | * |
||
179 | * @return bool |
||
180 | */ |
||
181 | 2 | public function supportsToken(TokenInterface $token, $providerKey) |
|
185 | |||
186 | /** |
||
187 | * This is called when an interactive authentication attempt fails. This is |
||
188 | * called by authentication listeners inheriting from |
||
189 | * AbstractAuthenticationListener. |
||
190 | * |
||
191 | * @param Request $request original request |
||
192 | * @param AuthenticationException $exception exception from auth attempt |
||
193 | * |
||
194 | * @return Response|null |
||
195 | */ |
||
196 | 2 | public function onAuthenticationFailure(Request $request, AuthenticationException $exception) |
|
203 | } |
||
204 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.