OutOfOfficeController.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2023 Richard Steinmetz <richard@steinmetz.cloud>
  5. *
  6. * @author Richard Steinmetz <richard@steinmetz.cloud>
  7. *
  8. * @license AGPL-3.0-or-later
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. namespace OCA\DAV\Controller;
  25. use DateTimeImmutable;
  26. use OCA\DAV\ResponseDefinitions;
  27. use OCA\DAV\Service\AbsenceService;
  28. use OCP\AppFramework\Db\DoesNotExistException;
  29. use OCP\AppFramework\Http;
  30. use OCP\AppFramework\Http\Attribute\NoAdminRequired;
  31. use OCP\AppFramework\Http\DataResponse;
  32. use OCP\AppFramework\OCSController;
  33. use OCP\IRequest;
  34. use OCP\IUserManager;
  35. use OCP\IUserSession;
  36. use OCP\User\IAvailabilityCoordinator;
  37. /**
  38. * @psalm-import-type DAVOutOfOfficeData from ResponseDefinitions
  39. * @psalm-import-type DAVCurrentOutOfOfficeData from ResponseDefinitions
  40. */
  41. class OutOfOfficeController extends OCSController {
  42. public function __construct(
  43. string $appName,
  44. IRequest $request,
  45. private IUserManager $userManager,
  46. private ?IUserSession $userSession,
  47. private AbsenceService $absenceService,
  48. private IAvailabilityCoordinator $coordinator,
  49. ) {
  50. parent::__construct($appName, $request);
  51. }
  52. /**
  53. * Get the currently configured out-of-office data of a user
  54. *
  55. * @param string $userId The user id to get out-of-office data for.
  56. * @return DataResponse<Http::STATUS_OK, DAVCurrentOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
  57. *
  58. * 200: Out-of-office data
  59. * 404: No out-of-office data was found
  60. */
  61. #[NoAdminRequired]
  62. public function getCurrentOutOfOfficeData(string $userId): DataResponse {
  63. $user = $this->userManager->get($userId);
  64. if ($user === null) {
  65. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  66. }
  67. try {
  68. $data = $this->absenceService->getCurrentAbsence($user);
  69. if ($data === null) {
  70. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  71. }
  72. } catch (DoesNotExistException) {
  73. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  74. }
  75. return new DataResponse($data->jsonSerialize());
  76. }
  77. /**
  78. * Get the configured out-of-office data of a user.
  79. *
  80. * @param string $userId The user id to get out-of-office data for.
  81. * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
  82. *
  83. * 200: Out-of-office data
  84. * 404: No out-of-office data was found
  85. */
  86. #[NoAdminRequired]
  87. public function getOutOfOffice(string $userId): DataResponse {
  88. try {
  89. $data = $this->absenceService->getAbsence($userId);
  90. if ($data === null) {
  91. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  92. }
  93. } catch (DoesNotExistException) {
  94. return new DataResponse(null, Http::STATUS_NOT_FOUND);
  95. }
  96. return new DataResponse([
  97. 'id' => $data->getId(),
  98. 'userId' => $data->getUserId(),
  99. 'firstDay' => $data->getFirstDay(),
  100. 'lastDay' => $data->getLastDay(),
  101. 'status' => $data->getStatus(),
  102. 'message' => $data->getMessage(),
  103. ]);
  104. }
  105. /**
  106. * Set out-of-office absence
  107. *
  108. * @param string $firstDay First day of the absence in format `YYYY-MM-DD`
  109. * @param string $lastDay Last day of the absence in format `YYYY-MM-DD`
  110. * @param string $status Short text that is set as user status during the absence
  111. * @param string $message Longer multiline message that is shown to others during the absence
  112. * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'firstDay'}, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, null, array{}>
  113. *
  114. * 200: Absence data
  115. * 400: When the first day is not before the last day
  116. * 401: When the user is not logged in
  117. */
  118. #[NoAdminRequired]
  119. public function setOutOfOffice(
  120. string $firstDay,
  121. string $lastDay,
  122. string $status,
  123. string $message,
  124. ): DataResponse {
  125. $user = $this->userSession?->getUser();
  126. if ($user === null) {
  127. return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
  128. }
  129. $parsedFirstDay = new DateTimeImmutable($firstDay);
  130. $parsedLastDay = new DateTimeImmutable($lastDay);
  131. if ($parsedFirstDay->getTimestamp() > $parsedLastDay->getTimestamp()) {
  132. return new DataResponse(['error' => 'firstDay'], Http::STATUS_BAD_REQUEST);
  133. }
  134. $data = $this->absenceService->createOrUpdateAbsence(
  135. $user,
  136. $firstDay,
  137. $lastDay,
  138. $status,
  139. $message,
  140. );
  141. $this->coordinator->clearCache($user->getUID());
  142. return new DataResponse([
  143. 'id' => $data->getId(),
  144. 'userId' => $data->getUserId(),
  145. 'firstDay' => $data->getFirstDay(),
  146. 'lastDay' => $data->getLastDay(),
  147. 'status' => $data->getStatus(),
  148. 'message' => $data->getMessage(),
  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. }