OutOfOfficeController.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\DAV\Controller;
  8. use DateTimeImmutable;
  9. use OCA\DAV\ResponseDefinitions;
  10. use OCA\DAV\Service\AbsenceService;
  11. use OCP\AppFramework\Db\DoesNotExistException;
  12. use OCP\AppFramework\Http;
  13. use OCP\AppFramework\Http\Attribute\NoAdminRequired;
  14. use OCP\AppFramework\Http\DataResponse;
  15. use OCP\AppFramework\OCSController;
  16. use OCP\IRequest;
  17. use OCP\IUserManager;
  18. use OCP\IUserSession;
  19. use OCP\User\IAvailabilityCoordinator;
  20. /**
  21. * @psalm-import-type DAVOutOfOfficeData from ResponseDefinitions
  22. * @psalm-import-type DAVCurrentOutOfOfficeData from ResponseDefinitions
  23. */
  24. class OutOfOfficeController extends OCSController {
  25. public function __construct(
  26. string $appName,
  27. IRequest $request,
  28. private IUserManager $userManager,
  29. private ?IUserSession $userSession,
  30. private AbsenceService $absenceService,
  31. private IAvailabilityCoordinator $coordinator,
  32. ) {
  33. parent::__construct($appName, $request);
  34. }
  35. /**
  36. * Get the currently configured out-of-office data of a user
  37. *
  38. * @param string $userId The user id to get out-of-office data for.
  39. * @return DataResponse<Http::STATUS_OK, DAVCurrentOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
  40. *
  41. * 200: Out-of-office data
  42. * 404: No out-of-office data was found
  43. */
  44. #[NoAdminRequired]
  45. public function getCurrentOutOfOfficeData(string $userId): DataResponse {
  46. $user = $this->userManager->get($userId);
  47. if ($user === null) {
  48. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  49. }
  50. try {
  51. $data = $this->absenceService->getCurrentAbsence($user);
  52. if ($data === null) {
  53. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  54. }
  55. } catch (DoesNotExistException) {
  56. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  57. }
  58. return new DataResponse($data->jsonSerialize());
  59. }
  60. /**
  61. * Get the configured out-of-office data of a user.
  62. *
  63. * @param string $userId The user id to get out-of-office data for.
  64. * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
  65. *
  66. * 200: Out-of-office data
  67. * 404: No out-of-office data was found
  68. */
  69. #[NoAdminRequired]
  70. public function getOutOfOffice(string $userId): DataResponse {
  71. try {
  72. $data = $this->absenceService->getAbsence($userId);
  73. if ($data === null) {
  74. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  75. }
  76. } catch (DoesNotExistException) {
  77. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  78. }
  79. return new DataResponse([
  80. 'id' => $data->getId(),
  81. 'userId' => $data->getUserId(),
  82. 'firstDay' => $data->getFirstDay(),
  83. 'lastDay' => $data->getLastDay(),
  84. 'status' => $data->getStatus(),
  85. 'message' => $data->getMessage(),
  86. 'replacementUserId' => $data->getReplacementUserId(),
  87. 'replacementUserDisplayName' => $data->getReplacementUserDisplayName(),
  88. ]);
  89. }
  90. /**
  91. * Set out-of-office absence
  92. *
  93. * @param string $firstDay First day of the absence in format `YYYY-MM-DD`
  94. * @param string $lastDay Last day of the absence in format `YYYY-MM-DD`
  95. * @param string $status Short text that is set as user status during the absence
  96. * @param string $message Longer multiline message that is shown to others during the absence
  97. * @param ?string $replacementUserId User id of the replacement user
  98. * @param ?string $replacementUserDisplayName Display name of the replacement user
  99. * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'firstDay'}, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, null, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
  100. *
  101. * 200: Absence data
  102. * 400: When the first day is not before the last day
  103. * 401: When the user is not logged in
  104. * 404: When the replacementUserId was provided but replacement user was not found
  105. */
  106. #[NoAdminRequired]
  107. public function setOutOfOffice(
  108. string $firstDay,
  109. string $lastDay,
  110. string $status,
  111. string $message,
  112. ?string $replacementUserId,
  113. ?string $replacementUserDisplayName,
  114. ): DataResponse {
  115. $user = $this->userSession?->getUser();
  116. if ($user === null) {
  117. return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
  118. }
  119. if ($replacementUserId !== null) {
  120. $replacementUser = $this->userManager->get($replacementUserId);
  121. if ($replacementUser === null) {
  122. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  123. }
  124. }
  125. $parsedFirstDay = new DateTimeImmutable($firstDay);
  126. $parsedLastDay = new DateTimeImmutable($lastDay);
  127. if ($parsedFirstDay->getTimestamp() > $parsedLastDay->getTimestamp()) {
  128. return new DataResponse(['error' => 'firstDay'], Http::STATUS_BAD_REQUEST);
  129. }
  130. $data = $this->absenceService->createOrUpdateAbsence(
  131. $user,
  132. $firstDay,
  133. $lastDay,
  134. $status,
  135. $message,
  136. $replacementUserId,
  137. $replacementUserDisplayName
  138. );
  139. $this->coordinator->clearCache($user->getUID());
  140. return new DataResponse([
  141. 'id' => $data->getId(),
  142. 'userId' => $data->getUserId(),
  143. 'firstDay' => $data->getFirstDay(),
  144. 'lastDay' => $data->getLastDay(),
  145. 'status' => $data->getStatus(),
  146. 'message' => $data->getMessage(),
  147. 'replacementUserId' => $data->getReplacementUserId(),
  148. 'replacementUserDisplayName' => $data->getReplacementUserDisplayName(),
  149. ]);
  150. }
  151. /**
  152. * Clear the out-of-office
  153. *
  154. * @return DataResponse<Http::STATUS_OK|Http::STATUS_UNAUTHORIZED, null, array{}>
  155. *
  156. * 200: When the absence was cleared successfully
  157. * 401: When the user is not logged in
  158. */
  159. #[NoAdminRequired]
  160. public function clearOutOfOffice(): DataResponse {
  161. $user = $this->userSession?->getUser();
  162. if ($user === null) {
  163. return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
  164. }
  165. $this->absenceService->clearAbsence($user);
  166. $this->coordinator->clearCache($user->getUID());
  167. return new DataResponse(null);
  168. }
  169. }