]> source.dussan.org Git - nextcloud-server.git/commitdiff
feat(out-of-office): Add OCS endpoint to set and clear absence
authorJoas Schilling <coding@schilljs.com>
Fri, 1 Dec 2023 08:15:18 +0000 (09:15 +0100)
committerJoas Schilling <coding@schilljs.com>
Fri, 1 Dec 2023 08:15:18 +0000 (09:15 +0100)
Signed-off-by: Joas Schilling <coding@schilljs.com>
apps/dav/appinfo/routes.php
apps/dav/lib/Controller/OutOfOfficeController.php
apps/dav/openapi.json

index 1b2fa0094bfd58c7c1b097b54d5f73fd762569c4..d4a9f4cbeeb499416ebe8b151c83026b8b1a1fc8 100644 (file)
@@ -36,5 +36,7 @@ return [
        'ocs' => [
                ['name' => 'direct#getUrl', 'url' => '/api/v1/direct', 'verb' => 'POST'],
                ['name' => 'out_of_office#getCurrentOutOfOfficeData', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'GET'],
+               ['name' => 'out_of_office#setOutOfOffice', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'POST'],
+               ['name' => 'out_of_office#clearOutOfOffice', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'DELETE'],
        ],
 ];
index e86f116c3b1028435b9c2680e2591d649a50c74e..ffac1247a6ceceeb175eafbe71bedaba4e1405e8 100644 (file)
@@ -26,14 +26,18 @@ declare(strict_types=1);
 
 namespace OCA\DAV\Controller;
 
+use DateTimeImmutable;
 use OCA\DAV\Db\AbsenceMapper;
 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\IUserSession;
+use OCP\User\IAvailabilityCoordinator;
 
 /**
  * @psalm-import-type DAVOutOfOfficeData from ResponseDefinitions
@@ -44,6 +48,9 @@ class OutOfOfficeController extends OCSController {
                string $appName,
                IRequest $request,
                private AbsenceMapper $absenceMapper,
+               private ?IUserSession $userSession,
+               private AbsenceService $absenceService,
+               private IAvailabilityCoordinator $coordinator,
        ) {
                parent::__construct($appName, $request);
        }
@@ -74,4 +81,74 @@ class OutOfOfficeController extends OCSController {
                        'message' => $data->getMessage(),
                ]);
        }
+
+       /**
+        * 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
+        * @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'firstDay'}, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, null, array{}>
+        *
+        * 200: Absence data
+        * 400: When the first day is not before the last day
+        * 401: When the user is not logged in
+        */
+       #[NoAdminRequired]
+       public function setOutOfOffice(
+               string $firstDay,
+               string $lastDay,
+               string $status,
+               string $message,
+       ): DataResponse {
+               $user = $this->userSession?->getUser();
+               if ($user === null) {
+                       return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
+               }
+
+               $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,
+               );
+               $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(),
+               ]);
+       }
+
+       /**
+        * 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);
+       }
 }
index c8ae5a9620648790a821be487a24538e3288ac3a..a235e3bff1d6b54b8ba5853671671190eb316188 100644 (file)
                         }
                     }
                 }
+            },
+            "post": {
+                "operationId": "out_of_office-set-out-of-office",
+                "summary": "Set out-of-office absence",
+                "tags": [
+                    "out_of_office"
+                ],
+                "security": [
+                    {
+                        "bearer_auth": []
+                    },
+                    {
+                        "basic_auth": []
+                    }
+                ],
+                "parameters": [
+                    {
+                        "name": "firstDay",
+                        "in": "query",
+                        "description": "First day of the absence in format `YYYY-MM-DD`",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    },
+                    {
+                        "name": "lastDay",
+                        "in": "query",
+                        "description": "Last day of the absence in format `YYYY-MM-DD`",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    },
+                    {
+                        "name": "status",
+                        "in": "query",
+                        "description": "Short text that is set as user status during the absence",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    },
+                    {
+                        "name": "message",
+                        "in": "query",
+                        "description": "Longer multiline message that is shown to others during the absence",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    },
+                    {
+                        "name": "userId",
+                        "in": "path",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    },
+                    {
+                        "name": "OCS-APIRequest",
+                        "in": "header",
+                        "description": "Required to be true for the API request to pass",
+                        "required": true,
+                        "schema": {
+                            "type": "boolean",
+                            "default": true
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Absence data",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "object",
+                                    "required": [
+                                        "ocs"
+                                    ],
+                                    "properties": {
+                                        "ocs": {
+                                            "type": "object",
+                                            "required": [
+                                                "meta",
+                                                "data"
+                                            ],
+                                            "properties": {
+                                                "meta": {
+                                                    "$ref": "#/components/schemas/OCSMeta"
+                                                },
+                                                "data": {
+                                                    "$ref": "#/components/schemas/OutOfOfficeData"
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "400": {
+                        "description": "When the first day is not before the last day",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "object",
+                                    "required": [
+                                        "ocs"
+                                    ],
+                                    "properties": {
+                                        "ocs": {
+                                            "type": "object",
+                                            "required": [
+                                                "meta",
+                                                "data"
+                                            ],
+                                            "properties": {
+                                                "meta": {
+                                                    "$ref": "#/components/schemas/OCSMeta"
+                                                },
+                                                "data": {
+                                                    "type": "object",
+                                                    "required": [
+                                                        "error"
+                                                    ],
+                                                    "properties": {
+                                                        "error": {
+                                                            "type": "string",
+                                                            "enum": [
+                                                                "firstDay"
+                                                            ]
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "401": {
+                        "description": "When the user is not logged in",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "object",
+                                    "required": [
+                                        "ocs"
+                                    ],
+                                    "properties": {
+                                        "ocs": {
+                                            "type": "object",
+                                            "required": [
+                                                "meta",
+                                                "data"
+                                            ],
+                                            "properties": {
+                                                "meta": {
+                                                    "$ref": "#/components/schemas/OCSMeta"
+                                                },
+                                                "data": {
+                                                    "nullable": true
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            "delete": {
+                "operationId": "out_of_office-clear-out-of-office",
+                "summary": "Clear the out-of-office",
+                "tags": [
+                    "out_of_office"
+                ],
+                "security": [
+                    {
+                        "bearer_auth": []
+                    },
+                    {
+                        "basic_auth": []
+                    }
+                ],
+                "parameters": [
+                    {
+                        "name": "userId",
+                        "in": "path",
+                        "required": true,
+                        "schema": {
+                            "type": "string"
+                        }
+                    },
+                    {
+                        "name": "OCS-APIRequest",
+                        "in": "header",
+                        "description": "Required to be true for the API request to pass",
+                        "required": true,
+                        "schema": {
+                            "type": "boolean",
+                            "default": true
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "When the absence was cleared successfully",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "object",
+                                    "required": [
+                                        "ocs"
+                                    ],
+                                    "properties": {
+                                        "ocs": {
+                                            "type": "object",
+                                            "required": [
+                                                "meta",
+                                                "data"
+                                            ],
+                                            "properties": {
+                                                "meta": {
+                                                    "$ref": "#/components/schemas/OCSMeta"
+                                                },
+                                                "data": {
+                                                    "nullable": true
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "401": {
+                        "description": "When the user is not logged in",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "object",
+                                    "required": [
+                                        "ocs"
+                                    ],
+                                    "properties": {
+                                        "ocs": {
+                                            "type": "object",
+                                            "required": [
+                                                "meta",
+                                                "data"
+                                            ],
+                                            "properties": {
+                                                "meta": {
+                                                    "$ref": "#/components/schemas/OCSMeta"
+                                                },
+                                                "data": {
+                                                    "nullable": true
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
             }
         }
     },