aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Controller/OutOfOfficeController.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib/Controller/OutOfOfficeController.php')
-rw-r--r--apps/dav/lib/Controller/OutOfOfficeController.php189
1 files changed, 189 insertions, 0 deletions
diff --git a/apps/dav/lib/Controller/OutOfOfficeController.php b/apps/dav/lib/Controller/OutOfOfficeController.php
new file mode 100644
index 00000000000..d3516d092e8
--- /dev/null
+++ b/apps/dav/lib/Controller/OutOfOfficeController.php
@@ -0,0 +1,189 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\DAV\Controller;
+
+use DateTimeImmutable;
+use OCA\DAV\ResponseDefinitions;
+use OCA\DAV\Service\AbsenceService;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCSController;
+use OCP\IRequest;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\User\IAvailabilityCoordinator;
+use function mb_strlen;
+
+/**
+ * @psalm-import-type DAVOutOfOfficeData from ResponseDefinitions
+ * @psalm-import-type DAVCurrentOutOfOfficeData from ResponseDefinitions
+ */
+class OutOfOfficeController extends OCSController {
+
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private IUserManager $userManager,
+ private ?IUserSession $userSession,
+ private AbsenceService $absenceService,
+ private IAvailabilityCoordinator $coordinator,
+ ) {
+ parent::__construct($appName, $request);
+ }
+
+ /**
+ * Get the currently configured out-of-office data of a user
+ *
+ * @param string $userId The user id to get out-of-office data for.
+ * @return DataResponse<Http::STATUS_OK, DAVCurrentOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
+ *
+ * 200: Out-of-office data
+ * 404: No out-of-office data was found
+ */
+ #[NoAdminRequired]
+ public function getCurrentOutOfOfficeData(string $userId): DataResponse {
+ $user = $this->userManager->get($userId);
+ if ($user === null) {
+ return new DataResponse(null, Http::STATUS_NOT_FOUND);
+ }
+ try {
+ $data = $this->absenceService->getCurrentAbsence($user);
+ if ($data === null) {
+ return new DataResponse(null, Http::STATUS_NOT_FOUND);
+ }
+ } catch (DoesNotExistException) {
+ return new DataResponse(null, Http::STATUS_NOT_FOUND);
+ }
+
+ return new DataResponse($data->jsonSerialize());
+ }
+
+ /**
+ * Get the configured out-of-office data of a user.
+ *
+ * @param string $userId The user id to get out-of-office data for.
+ * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
+ *
+ * 200: Out-of-office data
+ * 404: No out-of-office data was found
+ */
+ #[NoAdminRequired]
+ public function getOutOfOffice(string $userId): DataResponse {
+ try {
+ $data = $this->absenceService->getAbsence($userId);
+ if ($data === null) {
+ return new DataResponse(null, Http::STATUS_NOT_FOUND);
+ }
+ } catch (DoesNotExistException) {
+ return new DataResponse(null, Http::STATUS_NOT_FOUND);
+ }
+
+ return new DataResponse([
+ 'id' => $data->getId(),
+ 'userId' => $data->getUserId(),
+ 'firstDay' => $data->getFirstDay(),
+ 'lastDay' => $data->getLastDay(),
+ 'status' => $data->getStatus(),
+ 'message' => $data->getMessage(),
+ 'replacementUserId' => $data->getReplacementUserId(),
+ 'replacementUserDisplayName' => $data->getReplacementUserDisplayName(),
+ ]);
+ }
+
+ /**
+ * Set out-of-office absence
+ *
+ * @param string $firstDay First day of the absence in format `YYYY-MM-DD`
+ * @param string $lastDay Last day of the absence in format `YYYY-MM-DD`
+ * @param string $status Short text that is set as user status during the absence
+ * @param string $message Longer multiline message that is shown to others during the absence
+ * @param ?string $replacementUserId User id of the replacement user
+ * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'firstDay'|'statusLength'}, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, null, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
+ *
+ * 200: Absence data
+ * 400: When validation fails, e.g. data range error or the first day is not before the last day
+ * 401: When the user is not logged in
+ * 404: When the replacementUserId was provided but replacement user was not found
+ */
+ #[NoAdminRequired]
+ public function setOutOfOffice(
+ string $firstDay,
+ string $lastDay,
+ string $status,
+ string $message,
+ ?string $replacementUserId,
+ ): DataResponse {
+ $user = $this->userSession?->getUser();
+ if ($user === null) {
+ return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
+ }
+ if (mb_strlen($status) > 100) {
+ return new DataResponse(['error' => 'statusLength'], Http::STATUS_BAD_REQUEST);
+ }
+
+ $replacementUser = null;
+ if ($replacementUserId !== null) {
+ $replacementUser = $this->userManager->get($replacementUserId);
+ if ($replacementUser === null) {
+ return new DataResponse(null, Http::STATUS_NOT_FOUND);
+ }
+ }
+
+ $parsedFirstDay = new DateTimeImmutable($firstDay);
+ $parsedLastDay = new DateTimeImmutable($lastDay);
+ if ($parsedFirstDay->getTimestamp() > $parsedLastDay->getTimestamp()) {
+ return new DataResponse(['error' => 'firstDay'], Http::STATUS_BAD_REQUEST);
+ }
+
+ $data = $this->absenceService->createOrUpdateAbsence(
+ $user,
+ $firstDay,
+ $lastDay,
+ $status,
+ $message,
+ $replacementUserId,
+ $replacementUser?->getDisplayName()
+ );
+ $this->coordinator->clearCache($user->getUID());
+
+ return new DataResponse([
+ 'id' => $data->getId(),
+ 'userId' => $data->getUserId(),
+ 'firstDay' => $data->getFirstDay(),
+ 'lastDay' => $data->getLastDay(),
+ 'status' => $data->getStatus(),
+ 'message' => $data->getMessage(),
+ 'replacementUserId' => $data->getReplacementUserId(),
+ 'replacementUserDisplayName' => $data->getReplacementUserDisplayName(),
+ ]);
+ }
+
+ /**
+ * Clear the out-of-office
+ *
+ * @return DataResponse<Http::STATUS_OK|Http::STATUS_UNAUTHORIZED, null, array{}>
+ *
+ * 200: When the absence was cleared successfully
+ * 401: When the user is not logged in
+ */
+ #[NoAdminRequired]
+ public function clearOutOfOffice(): DataResponse {
+ $user = $this->userSession?->getUser();
+ if ($user === null) {
+ return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
+ }
+
+ $this->absenceService->clearAbsence($user);
+ $this->coordinator->clearCache($user->getUID());
+ return new DataResponse(null);
+ }
+}