eduVPN /
vpn-server-api
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * eduVPN - End-user friendly VPN. |
||
| 5 | * |
||
| 6 | * Copyright: 2016-2017, The Commons Conservancy eduVPN Programme |
||
| 7 | * SPDX-License-Identifier: AGPL-3.0+ |
||
| 8 | */ |
||
| 9 | |||
| 10 | namespace SURFnet\VPN\Server; |
||
| 11 | |||
| 12 | use DateTime; |
||
| 13 | use fkooman\OAuth\Client\AccessToken; |
||
| 14 | use fkooman\OAuth\Client\TokenStorageInterface; |
||
| 15 | use PDO; |
||
| 16 | use PDOException; |
||
| 17 | |||
| 18 | class Storage implements TokenStorageInterface |
||
| 19 | { |
||
| 20 | /** @var \PDO */ |
||
| 21 | private $db; |
||
| 22 | |||
| 23 | /** @var \DateTime */ |
||
| 24 | private $dateTime; |
||
| 25 | |||
| 26 | public function __construct(PDO $db, DateTime $dateTime) |
||
| 27 | { |
||
| 28 | $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
||
| 29 | if ('sqlite' === $db->getAttribute(PDO::ATTR_DRIVER_NAME)) { |
||
| 30 | $db->query('PRAGMA foreign_keys = ON'); |
||
| 31 | } |
||
| 32 | |||
| 33 | $this->db = $db; |
||
| 34 | $this->dateTime = $dateTime; |
||
| 35 | } |
||
| 36 | |||
| 37 | /** |
||
| 38 | * @return array |
||
| 39 | */ |
||
| 40 | public function getUsers() |
||
| 41 | { |
||
| 42 | $stmt = $this->db->prepare( |
||
| 43 | <<< 'SQL' |
||
| 44 | SELECT |
||
| 45 | user_id, |
||
| 46 | date_time, |
||
| 47 | totp_secret, |
||
| 48 | yubi_key_id, |
||
| 49 | is_disabled |
||
| 50 | FROM |
||
| 51 | users |
||
| 52 | SQL |
||
| 53 | ); |
||
| 54 | $stmt->execute(); |
||
| 55 | |||
| 56 | $userList = []; |
||
| 57 | foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { |
||
| 58 | $userList[] = [ |
||
| 59 | 'user_id' => $row['user_id'], |
||
| 60 | 'is_disabled' => (bool) $row['is_disabled'], |
||
| 61 | 'has_yubi_key_id' => !is_null($row['yubi_key_id']), |
||
| 62 | 'has_totp_secret' => !is_null($row['totp_secret']), |
||
| 63 | ]; |
||
| 64 | } |
||
| 65 | |||
| 66 | return $userList; |
||
| 67 | } |
||
| 68 | |||
| 69 | /** |
||
| 70 | * @return array|false |
||
| 71 | */ |
||
| 72 | View Code Duplication | public function getUserCertificateInfo($commonName) |
|
|
0 ignored issues
–
show
|
|||
| 73 | { |
||
| 74 | $stmt = $this->db->prepare( |
||
| 75 | <<< 'SQL' |
||
| 76 | SELECT |
||
| 77 | u.user_id AS user_id, |
||
| 78 | u.is_disabled AS user_is_disabled, |
||
| 79 | c.display_name AS display_name, |
||
| 80 | c.is_disabled AS certificate_is_disabled |
||
| 81 | FROM |
||
| 82 | users u, certificates c |
||
| 83 | WHERE |
||
| 84 | u.user_id = c.user_id AND |
||
| 85 | c.common_name = :common_name |
||
| 86 | SQL |
||
| 87 | ); |
||
| 88 | |||
| 89 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 90 | $stmt->execute(); |
||
| 91 | |||
| 92 | return $stmt->fetch(PDO::FETCH_ASSOC); |
||
| 93 | } |
||
| 94 | |||
| 95 | /** |
||
| 96 | * @return string|null |
||
| 97 | */ |
||
| 98 | View Code Duplication | public function getVootToken($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 99 | { |
||
| 100 | $this->addUser($userId); |
||
| 101 | $stmt = $this->db->prepare( |
||
| 102 | <<< 'SQL' |
||
| 103 | SELECT |
||
| 104 | voot_token |
||
| 105 | FROM |
||
| 106 | users |
||
| 107 | WHERE |
||
| 108 | user_id = :user_id |
||
| 109 | SQL |
||
| 110 | ); |
||
| 111 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 112 | $stmt->execute(); |
||
| 113 | |||
| 114 | return $stmt->fetchColumn(); |
||
| 115 | } |
||
| 116 | |||
| 117 | public function setVootToken($userId, AccessToken $vootToken) |
||
| 118 | { |
||
| 119 | $this->addUser($userId); |
||
| 120 | $stmt = $this->db->prepare( |
||
| 121 | <<< 'SQL' |
||
| 122 | UPDATE |
||
| 123 | users |
||
| 124 | SET |
||
| 125 | voot_token = :voot_token |
||
| 126 | WHERE |
||
| 127 | user_id = :user_id |
||
| 128 | SQL |
||
| 129 | ); |
||
| 130 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 131 | $stmt->bindValue(':voot_token', $vootToken->toJson(), PDO::PARAM_STR); |
||
| 132 | |||
| 133 | $stmt->execute(); |
||
| 134 | } |
||
| 135 | |||
| 136 | /** |
||
| 137 | * @return bool |
||
| 138 | */ |
||
| 139 | View Code Duplication | public function hasVootToken($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 140 | { |
||
| 141 | $this->addUser($userId); |
||
| 142 | $stmt = $this->db->prepare( |
||
| 143 | <<< 'SQL' |
||
| 144 | SELECT |
||
| 145 | voot_token |
||
| 146 | FROM |
||
| 147 | users |
||
| 148 | WHERE |
||
| 149 | user_id = :user_id |
||
| 150 | SQL |
||
| 151 | ); |
||
| 152 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 153 | $stmt->execute(); |
||
| 154 | |||
| 155 | return !is_null($stmt->fetchColumn()); |
||
| 156 | } |
||
| 157 | |||
| 158 | public function deleteVootToken($userId) |
||
| 159 | { |
||
| 160 | $this->addUser($userId); |
||
| 161 | $stmt = $this->db->prepare( |
||
| 162 | <<< 'SQL' |
||
| 163 | UPDATE |
||
| 164 | users |
||
| 165 | SET |
||
| 166 | voot_token = NULL |
||
| 167 | WHERE |
||
| 168 | user_id = :user_id |
||
| 169 | SQL |
||
| 170 | ); |
||
| 171 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 172 | |||
| 173 | $stmt->execute(); |
||
| 174 | } |
||
| 175 | |||
| 176 | /** |
||
| 177 | * @return bool |
||
| 178 | */ |
||
| 179 | View Code Duplication | public function hasTotpSecret($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 180 | { |
||
| 181 | $this->addUser($userId); |
||
| 182 | $stmt = $this->db->prepare( |
||
| 183 | <<< 'SQL' |
||
| 184 | SELECT |
||
| 185 | totp_secret |
||
| 186 | FROM |
||
| 187 | users |
||
| 188 | WHERE |
||
| 189 | user_id = :user_id |
||
| 190 | SQL |
||
| 191 | ); |
||
| 192 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 193 | $stmt->execute(); |
||
| 194 | |||
| 195 | return !is_null($stmt->fetchColumn()); |
||
| 196 | } |
||
| 197 | |||
| 198 | /** |
||
| 199 | * @return string|null |
||
| 200 | */ |
||
| 201 | View Code Duplication | public function getTotpSecret($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 202 | { |
||
| 203 | $this->addUser($userId); |
||
| 204 | $stmt = $this->db->prepare( |
||
| 205 | <<< 'SQL' |
||
| 206 | SELECT |
||
| 207 | totp_secret |
||
| 208 | FROM |
||
| 209 | users |
||
| 210 | WHERE |
||
| 211 | user_id = :user_id |
||
| 212 | SQL |
||
| 213 | ); |
||
| 214 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 215 | $stmt->execute(); |
||
| 216 | |||
| 217 | return $stmt->fetchColumn(); |
||
| 218 | } |
||
| 219 | |||
| 220 | View Code Duplication | public function setTotpSecret($userId, $totpSecret) |
|
|
0 ignored issues
–
show
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...
|
|||
| 221 | { |
||
| 222 | $this->addUser($userId); |
||
| 223 | $stmt = $this->db->prepare( |
||
| 224 | <<< 'SQL' |
||
| 225 | UPDATE |
||
| 226 | users |
||
| 227 | SET |
||
| 228 | totp_secret = :totp_secret |
||
| 229 | WHERE |
||
| 230 | user_id = :user_id |
||
| 231 | SQL |
||
| 232 | ); |
||
| 233 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 234 | $stmt->bindValue(':totp_secret', $totpSecret, PDO::PARAM_STR); |
||
| 235 | |||
| 236 | $stmt->execute(); |
||
| 237 | } |
||
| 238 | |||
| 239 | View Code Duplication | public function deleteTotpSecret($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 240 | { |
||
| 241 | $this->addUser($userId); |
||
| 242 | $stmt = $this->db->prepare( |
||
| 243 | <<< 'SQL' |
||
| 244 | UPDATE |
||
| 245 | users |
||
| 246 | SET |
||
| 247 | totp_secret = NULL |
||
| 248 | WHERE |
||
| 249 | user_id = :user_id |
||
| 250 | SQL |
||
| 251 | ); |
||
| 252 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 253 | $stmt->execute(); |
||
| 254 | } |
||
| 255 | |||
| 256 | View Code Duplication | public function setYubiKeyId($userId, $yubiKeyId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 257 | { |
||
| 258 | $this->addUser($userId); |
||
| 259 | $stmt = $this->db->prepare( |
||
| 260 | <<< 'SQL' |
||
| 261 | UPDATE |
||
| 262 | users |
||
| 263 | SET |
||
| 264 | yubi_key_id = :yubi_key_id |
||
| 265 | WHERE |
||
| 266 | user_id = :user_id |
||
| 267 | SQL |
||
| 268 | ); |
||
| 269 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 270 | $stmt->bindValue(':yubi_key_id', $yubiKeyId, PDO::PARAM_STR); |
||
| 271 | |||
| 272 | $stmt->execute(); |
||
| 273 | } |
||
| 274 | |||
| 275 | /** |
||
| 276 | * @return bool |
||
| 277 | */ |
||
| 278 | View Code Duplication | public function hasYubiKeyId($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 279 | { |
||
| 280 | $this->addUser($userId); |
||
| 281 | $stmt = $this->db->prepare( |
||
| 282 | <<< 'SQL' |
||
| 283 | SELECT |
||
| 284 | yubi_key_id |
||
| 285 | FROM |
||
| 286 | users |
||
| 287 | WHERE |
||
| 288 | user_id = :user_id |
||
| 289 | SQL |
||
| 290 | ); |
||
| 291 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 292 | $stmt->execute(); |
||
| 293 | |||
| 294 | return !is_null($stmt->fetchColumn()); |
||
| 295 | } |
||
| 296 | |||
| 297 | /** |
||
| 298 | * @return string|null |
||
| 299 | */ |
||
| 300 | View Code Duplication | public function getYubiKeyId($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 301 | { |
||
| 302 | $this->addUser($userId); |
||
| 303 | $stmt = $this->db->prepare( |
||
| 304 | <<< 'SQL' |
||
| 305 | SELECT |
||
| 306 | yubi_key_id |
||
| 307 | FROM |
||
| 308 | users |
||
| 309 | WHERE |
||
| 310 | user_id = :user_id |
||
| 311 | SQL |
||
| 312 | ); |
||
| 313 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 314 | $stmt->execute(); |
||
| 315 | |||
| 316 | return $stmt->fetchColumn(); |
||
| 317 | } |
||
| 318 | |||
| 319 | View Code Duplication | public function deleteYubiKeyId($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 320 | { |
||
| 321 | $this->addUser($userId); |
||
| 322 | $stmt = $this->db->prepare( |
||
| 323 | <<< 'SQL' |
||
| 324 | UPDATE |
||
| 325 | users |
||
| 326 | SET |
||
| 327 | yubi_key_id = NULL |
||
| 328 | WHERE |
||
| 329 | user_id = :user_id |
||
| 330 | SQL |
||
| 331 | ); |
||
| 332 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 333 | $stmt->execute(); |
||
| 334 | } |
||
| 335 | |||
| 336 | View Code Duplication | public function deleteUser($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 337 | { |
||
| 338 | $this->addUser($userId); |
||
| 339 | $stmt = $this->db->prepare( |
||
| 340 | <<< 'SQL' |
||
| 341 | DELETE FROM |
||
| 342 | users |
||
| 343 | WHERE |
||
| 344 | user_id = :user_id |
||
| 345 | SQL |
||
| 346 | ); |
||
| 347 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 348 | $stmt->execute(); |
||
| 349 | } |
||
| 350 | |||
| 351 | View Code Duplication | public function addCertificate($userId, $commonName, $displayName, DateTime $validFrom, DateTime $validTo) |
|
|
0 ignored issues
–
show
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...
|
|||
| 352 | { |
||
| 353 | $this->addUser($userId); |
||
| 354 | $stmt = $this->db->prepare( |
||
| 355 | <<< 'SQL' |
||
| 356 | INSERT INTO certificates |
||
| 357 | (common_name, user_id, display_name, valid_from, valid_to) |
||
| 358 | VALUES |
||
| 359 | (:common_name, :user_id, :display_name, :valid_from, :valid_to) |
||
| 360 | SQL |
||
| 361 | ); |
||
| 362 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 363 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 364 | $stmt->bindValue(':display_name', $displayName, PDO::PARAM_STR); |
||
| 365 | $stmt->bindValue(':valid_from', $validFrom->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 366 | $stmt->bindValue(':valid_to', $validTo->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 367 | $stmt->execute(); |
||
| 368 | } |
||
| 369 | |||
| 370 | /** |
||
| 371 | * @return array |
||
| 372 | */ |
||
| 373 | public function getCertificates($userId) |
||
| 374 | { |
||
| 375 | $this->addUser($userId); |
||
| 376 | $stmt = $this->db->prepare( |
||
| 377 | <<< 'SQL' |
||
| 378 | SELECT |
||
| 379 | common_name, |
||
| 380 | display_name, |
||
| 381 | valid_from, |
||
| 382 | valid_to, |
||
| 383 | is_disabled |
||
| 384 | FROM |
||
| 385 | certificates |
||
| 386 | WHERE |
||
| 387 | user_id = :user_id |
||
| 388 | SQL |
||
| 389 | ); |
||
| 390 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 391 | $stmt->execute(); |
||
| 392 | |||
| 393 | $certificateList = []; |
||
| 394 | foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { |
||
| 395 | $row['is_disabled'] = (bool) $row['is_disabled']; |
||
| 396 | $certificateList[] = $row; |
||
| 397 | } |
||
| 398 | |||
| 399 | return $certificateList; |
||
| 400 | } |
||
| 401 | |||
| 402 | public function disableCertificate($commonName) |
||
| 403 | { |
||
| 404 | $stmt = $this->db->prepare( |
||
| 405 | <<< 'SQL' |
||
| 406 | UPDATE |
||
| 407 | certificates |
||
| 408 | SET |
||
| 409 | is_disabled = 1 |
||
| 410 | WHERE |
||
| 411 | common_name = :common_name |
||
| 412 | SQL |
||
| 413 | ); |
||
| 414 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 415 | $stmt->execute(); |
||
| 416 | } |
||
| 417 | |||
| 418 | public function deleteCertificate($commonName) |
||
| 419 | { |
||
| 420 | $stmt = $this->db->prepare( |
||
| 421 | <<< 'SQL' |
||
| 422 | DELETE FROM |
||
| 423 | certificates |
||
| 424 | WHERE |
||
| 425 | common_name = :common_name |
||
| 426 | SQL |
||
| 427 | ); |
||
| 428 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 429 | $stmt->execute(); |
||
| 430 | } |
||
| 431 | |||
| 432 | public function enableCertificate($commonName) |
||
| 433 | { |
||
| 434 | $stmt = $this->db->prepare( |
||
| 435 | <<< 'SQL' |
||
| 436 | UPDATE |
||
| 437 | certificates |
||
| 438 | SET |
||
| 439 | is_disabled = 0 |
||
| 440 | WHERE |
||
| 441 | common_name = :common_name |
||
| 442 | SQL |
||
| 443 | ); |
||
| 444 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 445 | $stmt->execute(); |
||
| 446 | } |
||
| 447 | |||
| 448 | View Code Duplication | public function disableUser($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 449 | { |
||
| 450 | $this->addUser($userId); |
||
| 451 | $stmt = $this->db->prepare( |
||
| 452 | <<< 'SQL' |
||
| 453 | UPDATE |
||
| 454 | users |
||
| 455 | SET |
||
| 456 | is_disabled = 1 |
||
| 457 | WHERE |
||
| 458 | user_id = :user_id |
||
| 459 | SQL |
||
| 460 | ); |
||
| 461 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 462 | $stmt->execute(); |
||
| 463 | } |
||
| 464 | |||
| 465 | public function enableUser($userId) |
||
| 466 | { |
||
| 467 | $this->addUser($userId); |
||
| 468 | $stmt = $this->db->prepare( |
||
| 469 | <<< 'SQL' |
||
| 470 | UPDATE |
||
| 471 | users |
||
| 472 | SET |
||
| 473 | is_disabled = 0 |
||
| 474 | WHERE |
||
| 475 | user_id = :user_id |
||
| 476 | SQL |
||
| 477 | ); |
||
| 478 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 479 | $stmt->execute(); |
||
| 480 | } |
||
| 481 | |||
| 482 | /** |
||
| 483 | * @return bool |
||
| 484 | */ |
||
| 485 | View Code Duplication | public function isDisabledUser($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 486 | { |
||
| 487 | $this->addUser($userId); |
||
| 488 | $stmt = $this->db->prepare( |
||
| 489 | <<< 'SQL' |
||
| 490 | SELECT |
||
| 491 | is_disabled |
||
| 492 | FROM |
||
| 493 | users |
||
| 494 | WHERE |
||
| 495 | user_id = :user_id |
||
| 496 | SQL |
||
| 497 | ); |
||
| 498 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 499 | $stmt->execute(); |
||
| 500 | |||
| 501 | return (bool) $stmt->fetchColumn(); |
||
| 502 | } |
||
| 503 | |||
| 504 | /** |
||
| 505 | * @return array |
||
| 506 | */ |
||
| 507 | public function getAllLogEntries() |
||
| 508 | { |
||
| 509 | $stmt = $this->db->prepare( |
||
| 510 | <<< 'SQL' |
||
| 511 | SELECT |
||
| 512 | user_id, |
||
| 513 | common_name, |
||
| 514 | connected_at, |
||
| 515 | disconnected_at, |
||
| 516 | bytes_transferred |
||
| 517 | FROM |
||
| 518 | connection_log |
||
| 519 | WHERE |
||
| 520 | disconnected_at IS NOT NULL |
||
| 521 | ORDER BY |
||
| 522 | connected_at |
||
| 523 | SQL |
||
| 524 | ); |
||
| 525 | |||
| 526 | $stmt->execute(); |
||
| 527 | |||
| 528 | return $stmt->fetchAll(PDO::FETCH_ASSOC); |
||
| 529 | } |
||
| 530 | |||
| 531 | View Code Duplication | public function clientConnect($profileId, $commonName, $ip4, $ip6, DateTime $connectedAt) |
|
|
0 ignored issues
–
show
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...
|
|||
| 532 | { |
||
| 533 | // this query is so complex, because we want to store the user_id in the |
||
| 534 | // log as well, not just the common_name... the user may delete the |
||
| 535 | // certificate, or the user account may be deleted... |
||
| 536 | $stmt = $this->db->prepare( |
||
| 537 | <<< 'SQL' |
||
| 538 | INSERT INTO connection_log |
||
| 539 | ( |
||
| 540 | user_id, |
||
| 541 | profile_id, |
||
| 542 | common_name, |
||
| 543 | ip4, |
||
| 544 | ip6, |
||
| 545 | connected_at |
||
| 546 | ) |
||
| 547 | VALUES |
||
| 548 | ( |
||
| 549 | ( |
||
| 550 | SELECT |
||
| 551 | u.user_id |
||
| 552 | FROM |
||
| 553 | users u, certificates c |
||
| 554 | WHERE |
||
| 555 | u.user_id = c.user_id |
||
| 556 | AND |
||
| 557 | c.common_name = :common_name |
||
| 558 | ), |
||
| 559 | :profile_id, |
||
| 560 | :common_name, |
||
| 561 | :ip4, |
||
| 562 | :ip6, |
||
| 563 | :connected_at |
||
| 564 | ) |
||
| 565 | SQL |
||
| 566 | ); |
||
| 567 | |||
| 568 | $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR); |
||
| 569 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 570 | $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR); |
||
| 571 | $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR); |
||
| 572 | $stmt->bindValue(':connected_at', $connectedAt->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 573 | $stmt->execute(); |
||
| 574 | } |
||
| 575 | |||
| 576 | public function clientDisconnect($profileId, $commonName, $ip4, $ip6, DateTime $connectedAt, DateTime $disconnectedAt, $bytesTransferred) |
||
| 577 | { |
||
| 578 | $stmt = $this->db->prepare( |
||
| 579 | <<< 'SQL' |
||
| 580 | UPDATE |
||
| 581 | connection_log |
||
| 582 | SET |
||
| 583 | disconnected_at = :disconnected_at, |
||
| 584 | bytes_transferred = :bytes_transferred |
||
| 585 | WHERE |
||
| 586 | profile_id = :profile_id |
||
| 587 | AND |
||
| 588 | common_name = :common_name |
||
| 589 | AND |
||
| 590 | ip4 = :ip4 |
||
| 591 | AND |
||
| 592 | ip6 = :ip6 |
||
| 593 | AND |
||
| 594 | connected_at = :connected_at |
||
| 595 | SQL |
||
| 596 | ); |
||
| 597 | |||
| 598 | $stmt->bindValue(':profile_id', $profileId, PDO::PARAM_STR); |
||
| 599 | $stmt->bindValue(':common_name', $commonName, PDO::PARAM_STR); |
||
| 600 | $stmt->bindValue(':ip4', $ip4, PDO::PARAM_STR); |
||
| 601 | $stmt->bindValue(':ip6', $ip6, PDO::PARAM_STR); |
||
| 602 | $stmt->bindValue(':connected_at', $connectedAt->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 603 | $stmt->bindValue(':disconnected_at', $disconnectedAt->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 604 | $stmt->bindValue(':bytes_transferred', $bytesTransferred, PDO::PARAM_INT); |
||
| 605 | $stmt->execute(); |
||
| 606 | } |
||
| 607 | |||
| 608 | /** |
||
| 609 | * @return array|false |
||
| 610 | */ |
||
| 611 | View Code Duplication | public function getLogEntry(DateTime $dateTime, $ipAddress) |
|
|
0 ignored issues
–
show
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...
|
|||
| 612 | { |
||
| 613 | $stmt = $this->db->prepare( |
||
| 614 | <<< 'SQL' |
||
| 615 | SELECT |
||
| 616 | user_id, |
||
| 617 | profile_id, |
||
| 618 | common_name, |
||
| 619 | ip4, |
||
| 620 | ip6, |
||
| 621 | connected_at, |
||
| 622 | disconnected_at |
||
| 623 | FROM |
||
| 624 | connection_log |
||
| 625 | WHERE |
||
| 626 | (ip4 = :ip_address OR ip6 = :ip_address) |
||
| 627 | AND |
||
| 628 | connected_at < :date_time |
||
| 629 | AND |
||
| 630 | (disconnected_at > :date_time OR disconnected_at IS NULL) |
||
| 631 | SQL |
||
| 632 | ); |
||
| 633 | $stmt->bindValue(':ip_address', $ipAddress, PDO::PARAM_STR); |
||
| 634 | $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 635 | $stmt->execute(); |
||
| 636 | |||
| 637 | // XXX can this also contain multiple results? I don't think so, but |
||
| 638 | // make sure! |
||
| 639 | return $stmt->fetch(PDO::FETCH_ASSOC); |
||
| 640 | } |
||
| 641 | |||
| 642 | /** |
||
| 643 | * @return int |
||
| 644 | */ |
||
| 645 | View Code Duplication | public function getTotpAttemptCount($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 646 | { |
||
| 647 | $this->addUser($userId); |
||
| 648 | $stmt = $this->db->prepare( |
||
| 649 | <<< 'SQL' |
||
| 650 | SELECT |
||
| 651 | COUNT(*) |
||
| 652 | FROM |
||
| 653 | totp_log |
||
| 654 | WHERE user_id = :user_id |
||
| 655 | SQL |
||
| 656 | ); |
||
| 657 | |||
| 658 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 659 | $stmt->execute(); |
||
| 660 | |||
| 661 | return (int) $stmt->fetchColumn(); |
||
| 662 | } |
||
| 663 | |||
| 664 | /** |
||
| 665 | * @return bool true if recording succeeds, false if it cannot due to replay |
||
| 666 | */ |
||
| 667 | public function recordTotpKey($userId, $totpKey) |
||
| 668 | { |
||
| 669 | $this->addUser($userId); |
||
| 670 | $stmt = $this->db->prepare( |
||
| 671 | <<< 'SQL' |
||
| 672 | INSERT INTO totp_log |
||
| 673 | (user_id, totp_key, date_time) |
||
| 674 | VALUES |
||
| 675 | (:user_id, :totp_key, :date_time) |
||
| 676 | SQL |
||
| 677 | ); |
||
| 678 | |||
| 679 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 680 | $stmt->bindValue(':totp_key', $totpKey, PDO::PARAM_STR); |
||
| 681 | $stmt->bindValue(':date_time', $this->dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 682 | |||
| 683 | try { |
||
| 684 | $stmt->execute(); |
||
| 685 | } catch (PDOException $e) { |
||
| 686 | // unable to record the TOTP, most likely replay |
||
| 687 | return false; |
||
| 688 | } |
||
| 689 | |||
| 690 | return true; |
||
| 691 | } |
||
| 692 | |||
| 693 | View Code Duplication | public function cleanConnectionLog(DateTime $dateTime) |
|
|
0 ignored issues
–
show
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...
|
|||
| 694 | { |
||
| 695 | $stmt = $this->db->prepare( |
||
| 696 | <<< 'SQL' |
||
| 697 | DELETE FROM |
||
| 698 | connection_log |
||
| 699 | WHERE |
||
| 700 | connected_at < :date_time |
||
| 701 | AND |
||
| 702 | disconnected_at IS NOT NULL |
||
| 703 | SQL |
||
| 704 | ); |
||
| 705 | |||
| 706 | $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 707 | |||
| 708 | return $stmt->execute(); |
||
| 709 | } |
||
| 710 | |||
| 711 | View Code Duplication | public function cleanUserMessages(DateTime $dateTime) |
|
|
0 ignored issues
–
show
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...
|
|||
| 712 | { |
||
| 713 | $stmt = $this->db->prepare( |
||
| 714 | <<< 'SQL' |
||
| 715 | DELETE FROM |
||
| 716 | user_messages |
||
| 717 | WHERE |
||
| 718 | date_time < :date_time |
||
| 719 | SQL |
||
| 720 | ); |
||
| 721 | |||
| 722 | $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 723 | |||
| 724 | return $stmt->execute(); |
||
| 725 | } |
||
| 726 | |||
| 727 | View Code Duplication | public function cleanTotpLog(DateTime $dateTime) |
|
|
0 ignored issues
–
show
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...
|
|||
| 728 | { |
||
| 729 | $stmt = $this->db->prepare( |
||
| 730 | <<< 'SQL' |
||
| 731 | DELETE FROM |
||
| 732 | totp_log |
||
| 733 | WHERE |
||
| 734 | date_time < :date_time |
||
| 735 | SQL |
||
| 736 | ); |
||
| 737 | |||
| 738 | $stmt->bindValue(':date_time', $dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 739 | |||
| 740 | return $stmt->execute(); |
||
| 741 | } |
||
| 742 | |||
| 743 | /** |
||
| 744 | * @return array |
||
| 745 | */ |
||
| 746 | View Code Duplication | public function systemMessages($type) |
|
|
0 ignored issues
–
show
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...
|
|||
| 747 | { |
||
| 748 | $stmt = $this->db->prepare( |
||
| 749 | <<< 'SQL' |
||
| 750 | SELECT |
||
| 751 | id, message, date_time |
||
| 752 | FROM |
||
| 753 | system_messages |
||
| 754 | WHERE |
||
| 755 | type = :type |
||
| 756 | SQL |
||
| 757 | ); |
||
| 758 | |||
| 759 | $stmt->bindValue(':type', $type, PDO::PARAM_STR); |
||
| 760 | $stmt->execute(); |
||
| 761 | |||
| 762 | return $stmt->fetchAll(PDO::FETCH_ASSOC); |
||
| 763 | } |
||
| 764 | |||
| 765 | public function addSystemMessage($type, $message) |
||
| 766 | { |
||
| 767 | $stmt = $this->db->prepare( |
||
| 768 | <<< 'SQL' |
||
| 769 | INSERT INTO system_messages |
||
| 770 | (type, message, date_time) |
||
| 771 | VALUES |
||
| 772 | (:type, :message, :date_time) |
||
| 773 | SQL |
||
| 774 | ); |
||
| 775 | |||
| 776 | $stmt->bindValue(':type', $type, PDO::PARAM_STR); |
||
| 777 | $stmt->bindValue(':message', $message, PDO::PARAM_STR); |
||
| 778 | $stmt->bindValue(':date_time', $this->dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 779 | $stmt->execute(); |
||
| 780 | } |
||
| 781 | |||
| 782 | public function deleteSystemMessage($messageId) |
||
| 783 | { |
||
| 784 | $stmt = $this->db->prepare( |
||
| 785 | <<< 'SQL' |
||
| 786 | DELETE FROM |
||
| 787 | system_messages |
||
| 788 | WHERE id = :message_id |
||
| 789 | SQL |
||
| 790 | ); |
||
| 791 | |||
| 792 | $stmt->bindValue(':message_id', $messageId, PDO::PARAM_INT); |
||
| 793 | $stmt->execute(); |
||
| 794 | } |
||
| 795 | |||
| 796 | /** |
||
| 797 | * @return array |
||
| 798 | */ |
||
| 799 | View Code Duplication | public function userMessages($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 800 | { |
||
| 801 | $this->addUser($userId); |
||
| 802 | $stmt = $this->db->prepare( |
||
| 803 | <<< 'SQL' |
||
| 804 | SELECT |
||
| 805 | id, type, message, date_time |
||
| 806 | FROM |
||
| 807 | user_messages |
||
| 808 | WHERE |
||
| 809 | user_id = :user_id |
||
| 810 | ORDER BY |
||
| 811 | date_time DESC |
||
| 812 | SQL |
||
| 813 | ); |
||
| 814 | |||
| 815 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 816 | $stmt->execute(); |
||
| 817 | |||
| 818 | return $stmt->fetchAll(PDO::FETCH_ASSOC); |
||
| 819 | } |
||
| 820 | |||
| 821 | View Code Duplication | public function addUserMessage($userId, $type, $message) |
|
|
0 ignored issues
–
show
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...
|
|||
| 822 | { |
||
| 823 | $this->addUser($userId); |
||
| 824 | $stmt = $this->db->prepare( |
||
| 825 | <<< 'SQL' |
||
| 826 | INSERT INTO user_messages |
||
| 827 | (user_id, type, message, date_time) |
||
| 828 | VALUES |
||
| 829 | (:user_id, :type, :message, :date_time) |
||
| 830 | SQL |
||
| 831 | ); |
||
| 832 | |||
| 833 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 834 | $stmt->bindValue(':type', $type, PDO::PARAM_STR); |
||
| 835 | $stmt->bindValue(':message', $message, PDO::PARAM_STR); |
||
| 836 | $stmt->bindValue(':date_time', $this->dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 837 | $stmt->execute(); |
||
| 838 | } |
||
| 839 | |||
| 840 | // TokenStorageInterface |
||
| 841 | |||
| 842 | /** |
||
| 843 | * @param string $userId |
||
| 844 | * |
||
| 845 | * @return array |
||
| 846 | */ |
||
| 847 | public function getAccessTokenList($userId) |
||
| 848 | { |
||
| 849 | $vootToken = $this->getVootToken($userId); |
||
| 850 | if (is_null($vootToken)) { |
||
| 851 | return []; |
||
| 852 | } |
||
| 853 | |||
| 854 | return [ |
||
| 855 | AccessToken::fromJson($vootToken), |
||
| 856 | ]; |
||
| 857 | } |
||
| 858 | |||
| 859 | /** |
||
| 860 | * @param string $userId |
||
| 861 | * @param AccessToken $accessToken |
||
| 862 | */ |
||
| 863 | public function storeAccessToken($userId, AccessToken $accessToken) |
||
| 864 | { |
||
| 865 | $this->setVootToken($userId, $accessToken); |
||
| 866 | } |
||
| 867 | |||
| 868 | /** |
||
| 869 | * @param string $userId |
||
| 870 | * @param AccessToken $accessToken |
||
| 871 | */ |
||
| 872 | public function deleteAccessToken($userId, AccessToken $accessToken) |
||
| 873 | { |
||
| 874 | $this->deleteVootToken($userId); |
||
| 875 | } |
||
| 876 | |||
| 877 | public function init() |
||
| 878 | { |
||
| 879 | $queryList = []; |
||
| 880 | $queryList[] = |
||
| 881 | <<< 'SQL' |
||
| 882 | CREATE TABLE IF NOT EXISTS users ( |
||
| 883 | user_id VARCHAR(255) NOT NULL PRIMARY KEY UNIQUE, |
||
| 884 | voot_token TEXT DEFAULT NULL, |
||
| 885 | totp_secret VARCHAR(255) DEFAULT NULL, |
||
| 886 | yubi_key_id VARCHAR(255) DEFAULT NULL, |
||
| 887 | date_time DATETIME NOT NULL, |
||
| 888 | is_disabled BOOLEAN DEFAULT 0 NOT NULL |
||
| 889 | ) |
||
| 890 | SQL; |
||
| 891 | |||
| 892 | $queryList[] = |
||
| 893 | <<< 'SQL' |
||
| 894 | CREATE TABLE IF NOT EXISTS certificates ( |
||
| 895 | common_name VARCHAR(255) UNIQUE NOT NULL, |
||
| 896 | display_name VARCHAR(255) NOT NULL, |
||
| 897 | valid_from DATETIME NOT NULL, |
||
| 898 | valid_to DATETIME NOT NULL, |
||
| 899 | is_disabled BOOLEAN DEFAULT 0, |
||
| 900 | user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE |
||
| 901 | ) |
||
| 902 | SQL; |
||
| 903 | |||
| 904 | $queryList[] = |
||
| 905 | <<< 'SQL' |
||
| 906 | CREATE TABLE IF NOT EXISTS totp_log ( |
||
| 907 | totp_key VARCHAR(255) NOT NULL, |
||
| 908 | date_time DATETIME NOT NULL, |
||
| 909 | user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE, |
||
| 910 | UNIQUE (user_id, totp_key) |
||
| 911 | ) |
||
| 912 | SQL; |
||
| 913 | |||
| 914 | $queryList[] = |
||
| 915 | <<< 'SQL' |
||
| 916 | CREATE TABLE IF NOT EXISTS connection_log ( |
||
| 917 | user_id VARCHAR(255) NOT NULL, |
||
| 918 | common_name VARCHAR(255) NOT NULL, |
||
| 919 | profile_id VARCHAR(255) NOT NULL, |
||
| 920 | ip4 VARCHAR(255) NOT NULL, |
||
| 921 | ip6 VARCHAR(255) NOT NULL, |
||
| 922 | connected_at DATETIME NOT NULL, |
||
| 923 | disconnected_at DATETIME DEFAULT NULL, |
||
| 924 | bytes_transferred INTEGER DEFAULT NULL |
||
| 925 | ) |
||
| 926 | SQL; |
||
| 927 | |||
| 928 | $queryList[] = |
||
| 929 | <<< 'SQL' |
||
| 930 | CREATE TABLE IF NOT EXISTS system_messages ( |
||
| 931 | id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, |
||
| 932 | type VARCHAR(255) NOT NULL DEFAULT "notification", |
||
| 933 | message TINYTEXT NOT NULL, |
||
| 934 | date_time DATETIME NOT NULL |
||
| 935 | ) |
||
| 936 | SQL; |
||
| 937 | |||
| 938 | $queryList[] = |
||
| 939 | <<< 'SQL' |
||
| 940 | CREATE TABLE IF NOT EXISTS user_messages ( |
||
| 941 | id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, |
||
| 942 | type VARCHAR(255) NOT NULL DEFAULT "notification", |
||
| 943 | message TINYTEXT NOT NULL, |
||
| 944 | date_time DATETIME NOT NULL, |
||
| 945 | user_id VARCHAR(255) NOT NULL REFERENCES users(user_id) ON DELETE CASCADE |
||
| 946 | ) |
||
| 947 | SQL; |
||
| 948 | |||
| 949 | foreach ($queryList as $query) { |
||
| 950 | if ('sqlite' === $this->db->getAttribute(PDO::ATTR_DRIVER_NAME)) { |
||
| 951 | $query = str_replace('AUTO_INCREMENT', 'AUTOINCREMENT', $query); |
||
| 952 | } |
||
| 953 | $this->db->query($query); |
||
| 954 | } |
||
| 955 | } |
||
| 956 | |||
| 957 | View Code Duplication | private function addUser($userId) |
|
|
0 ignored issues
–
show
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...
|
|||
| 958 | { |
||
| 959 | $stmt = $this->db->prepare( |
||
| 960 | <<< 'SQL' |
||
| 961 | SELECT |
||
| 962 | COUNT(*) |
||
| 963 | FROM |
||
| 964 | users |
||
| 965 | WHERE user_id = :user_id |
||
| 966 | SQL |
||
| 967 | ); |
||
| 968 | |||
| 969 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 970 | $stmt->execute(); |
||
| 971 | |||
| 972 | if (1 !== (int) $stmt->fetchColumn()) { |
||
| 973 | // user does not exist yet |
||
| 974 | $stmt = $this->db->prepare( |
||
| 975 | <<< 'SQL' |
||
| 976 | INSERT INTO |
||
| 977 | users ( |
||
| 978 | user_id, |
||
| 979 | date_time |
||
| 980 | ) |
||
| 981 | VALUES ( |
||
| 982 | :user_id, |
||
| 983 | :date_time |
||
| 984 | ) |
||
| 985 | SQL |
||
| 986 | ); |
||
| 987 | $stmt->bindValue(':user_id', $userId, PDO::PARAM_STR); |
||
| 988 | $stmt->bindValue(':date_time', $this->dateTime->format('Y-m-d H:i:s'), PDO::PARAM_STR); |
||
| 989 | $stmt->execute(); |
||
| 990 | } |
||
| 991 | } |
||
| 992 | } |
||
| 993 |
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.