Delete.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OC\Core\Command\User\AuthTokens;
  7. use DateTimeImmutable;
  8. use OC\Authentication\Token\IProvider;
  9. use OC\Core\Command\Base;
  10. use Symfony\Component\Console\Command\Command;
  11. use Symfony\Component\Console\Exception\RuntimeException;
  12. use Symfony\Component\Console\Input\InputArgument;
  13. use Symfony\Component\Console\Input\InputInterface;
  14. use Symfony\Component\Console\Input\InputOption;
  15. use Symfony\Component\Console\Output\OutputInterface;
  16. class Delete extends Base {
  17. public function __construct(
  18. protected IProvider $tokenProvider,
  19. ) {
  20. parent::__construct();
  21. }
  22. protected function configure(): void {
  23. $this
  24. ->setName('user:auth-tokens:delete')
  25. ->setDescription('Deletes an authentication token')
  26. ->addArgument(
  27. 'uid',
  28. InputArgument::REQUIRED,
  29. 'ID of the user to delete tokens for'
  30. )
  31. ->addArgument(
  32. 'id',
  33. InputArgument::OPTIONAL,
  34. 'ID of the auth token to delete'
  35. )
  36. ->addOption(
  37. 'last-used-before',
  38. null,
  39. InputOption::VALUE_REQUIRED,
  40. 'Delete tokens last used before a given date.'
  41. );
  42. }
  43. protected function execute(InputInterface $input, OutputInterface $output): int {
  44. $uid = $input->getArgument('uid');
  45. $id = (int) $input->getArgument('id');
  46. $before = $input->getOption('last-used-before');
  47. if ($before) {
  48. if ($id) {
  49. throw new RuntimeException('Option --last-used-before cannot be used with [<id>]');
  50. }
  51. return $this->deleteLastUsedBefore($uid, $before);
  52. }
  53. if (!$id) {
  54. throw new RuntimeException('Not enough arguments. Specify the token <id> or use the --last-used-before option.');
  55. }
  56. return $this->deleteById($uid, $id);
  57. }
  58. protected function deleteById(string $uid, int $id): int {
  59. $this->tokenProvider->invalidateTokenById($uid, $id);
  60. return Command::SUCCESS;
  61. }
  62. protected function deleteLastUsedBefore(string $uid, string $before): int {
  63. $date = $this->parseDateOption($before);
  64. if (!$date) {
  65. throw new RuntimeException('Invalid date format. Acceptable formats are: ISO8601 (w/o fractions), "YYYY-MM-DD" and Unix time in seconds.');
  66. }
  67. $this->tokenProvider->invalidateLastUsedBefore($uid, $date->getTimestamp());
  68. return Command::SUCCESS;
  69. }
  70. /**
  71. * @return \DateTimeImmutable|false
  72. */
  73. protected function parseDateOption(string $input) {
  74. $date = false;
  75. // Handle Unix timestamp
  76. if (filter_var($input, FILTER_VALIDATE_INT)) {
  77. return new DateTimeImmutable('@' . $input);
  78. }
  79. // ISO8601
  80. $date = DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, $input);
  81. if ($date) {
  82. return $date;
  83. }
  84. // YYYY-MM-DD
  85. return DateTimeImmutable::createFromFormat('!Y-m-d', $input);
  86. }
  87. }