]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix(dav): Make current ooo info time-dependent 41962/head
authorChristoph Wurst <christoph@winzerhof-wurst.at>
Fri, 1 Dec 2023 09:46:16 +0000 (10:46 +0100)
committerChristoph Wurst <christoph@winzerhof-wurst.at>
Tue, 5 Dec 2023 07:36:50 +0000 (08:36 +0100)
* If there is an out of office absence info and it happens now -> return
  data
* Else: return no data

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
apps/dav/appinfo/routes.php
apps/dav/lib/Controller/OutOfOfficeController.php
apps/dav/lib/ResponseDefinitions.php
apps/dav/lib/Service/AbsenceService.php
apps/dav/openapi.json
lib/private/User/OutOfOfficeData.php
lib/public/User/IOutOfOfficeData.php

index a6874aeb57da78d81cea6841841637fd721b9277..529bd0781fa8b5b3e15437c4bdac40e45afa9f8d 100644 (file)
@@ -33,7 +33,8 @@ 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#getCurrentOutOfOfficeData', 'url' => '/api/v1/outOfOffice/{userId}/now', 'verb' => 'GET'],
+               ['name' => 'out_of_office#getOutOfOffice', '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 ffac1247a6ceceeb175eafbe71bedaba4e1405e8..a2e7378f32de1fa2123da306d789da4c37315c68 100644 (file)
@@ -27,7 +27,6 @@ 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;
@@ -36,18 +35,20 @@ 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;
 
 /**
  * @psalm-import-type DAVOutOfOfficeData from ResponseDefinitions
+ * @psalm-import-type DAVCurrentOutOfOfficeData from ResponseDefinitions
  */
 class OutOfOfficeController extends OCSController {
 
        public function __construct(
                string $appName,
                IRequest $request,
-               private AbsenceMapper $absenceMapper,
+               private IUserManager $userManager,
                private ?IUserSession $userSession,
                private AbsenceService $absenceService,
                private IAvailabilityCoordinator $coordinator,
@@ -59,15 +60,45 @@ class OutOfOfficeController extends OCSController {
         * 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, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
+        * @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->absenceMapper->findByUserId($userId);
+                       $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);
                }
index 97bd8e9efe907b0c2d33adcb2149d20374cc35ba..e6de3d5a65cbf5f71404b608e9e579684446c6c0 100644 (file)
@@ -27,13 +27,24 @@ declare(strict_types=1);
 namespace OCA\DAV;
 
 /**
- * @psalm-type DAVOutOfOfficeData = array{
+ * @psalm-type DAVOutOfOfficeDataCommon = array{
+ *      userId: string,
+ *      message: string,
+ *  }
+ *
+ * @psalm-type DAVOutOfOfficeData = DAVOutOfOfficeDataCommon&array{
  *     id: int,
- *     userId: string,
  *     firstDay: string,
  *     lastDay: string,
  *     status: string,
- *     message: string,
+ * }
+ *
+ * @todo this is a copy of \OCP\User\IOutOfOfficeData
+ * @psalm-type DAVCurrentOutOfOfficeData = DAVOutOfOfficeDataCommon&array{
+ *     id: string,
+ *     startDate: int,
+ *     endDate: int,
+ *     shortMessage: string,
  * }
  */
 class ResponseDefinitions {
index 7c0d6eec0824be22ffa17670ba75850e470d61c0..3e2a218d52b478f855dd01062971c4b81ef8ee50 100644 (file)
@@ -145,6 +145,22 @@ class AbsenceService {
                }
        }
 
+       public function getCurrentAbsence(IUser $user): ?IOutOfOfficeData {
+               try {
+                       $absence = $this->absenceMapper->findByUserId($user->getUID());
+                       $oooData = $absence->toOutOufOfficeData(
+                               $user,
+                               $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(),
+                       );
+                       if ($this->isInEffect($oooData)) {
+                               return $oooData;
+                       }
+               } catch (DoesNotExistException) {
+                       // Nothing there to process
+               }
+               return null;
+       }
+
        public function isInEffect(IOutOfOfficeData $absence): bool {
                $now = $this->timeFactory->getTime();
                return $absence->getStartDate() <= $now && $absence->getEndDate() >= $now;
index a235e3bff1d6b54b8ba5853671671190eb316188..a0df1cedd16fd641393eb7ed6c04552c349558fd 100644 (file)
                     }
                 }
             },
+            "CurrentOutOfOfficeData": {
+                "allOf": [
+                    {
+                        "$ref": "#/components/schemas/OutOfOfficeDataCommon"
+                    },
+                    {
+                        "type": "object",
+                        "required": [
+                            "id",
+                            "startDate",
+                            "endDate",
+                            "shortMessage"
+                        ],
+                        "properties": {
+                            "id": {
+                                "type": "string"
+                            },
+                            "startDate": {
+                                "type": "integer",
+                                "format": "int64"
+                            },
+                            "endDate": {
+                                "type": "integer",
+                                "format": "int64"
+                            },
+                            "shortMessage": {
+                                "type": "string"
+                            }
+                        }
+                    }
+                ]
+            },
             "OCSMeta": {
                 "type": "object",
                 "required": [
                 }
             },
             "OutOfOfficeData": {
+                "allOf": [
+                    {
+                        "$ref": "#/components/schemas/OutOfOfficeDataCommon"
+                    },
+                    {
+                        "type": "object",
+                        "required": [
+                            "id",
+                            "firstDay",
+                            "lastDay",
+                            "status"
+                        ],
+                        "properties": {
+                            "id": {
+                                "type": "integer",
+                                "format": "int64"
+                            },
+                            "firstDay": {
+                                "type": "string"
+                            },
+                            "lastDay": {
+                                "type": "string"
+                            },
+                            "status": {
+                                "type": "string"
+                            }
+                        }
+                    }
+                ]
+            },
+            "OutOfOfficeDataCommon": {
                 "type": "object",
                 "required": [
-                    "id",
                     "userId",
-                    "firstDay",
-                    "lastDay",
-                    "status",
                     "message"
                 ],
                 "properties": {
-                    "id": {
-                        "type": "integer",
-                        "format": "int64"
-                    },
                     "userId": {
                         "type": "string"
                     },
-                    "firstDay": {
-                        "type": "string"
-                    },
-                    "lastDay": {
-                        "type": "string"
-                    },
-                    "status": {
-                        "type": "string"
-                    },
                     "message": {
                         "type": "string"
                     }
                 }
             }
         },
-        "/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}": {
+        "/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}/now": {
             "get": {
                 "operationId": "out_of_office-get-current-out-of-office-data",
                 "summary": "Get the currently configured out-of-office data of a user.",
                         }
                     }
                 ],
+                "responses": {
+                    "200": {
+                        "description": "Out-of-office 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/CurrentOutOfOfficeData"
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "404": {
+                        "description": "No out-of-office data was found",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "type": "object",
+                                    "required": [
+                                        "ocs"
+                                    ],
+                                    "properties": {
+                                        "ocs": {
+                                            "type": "object",
+                                            "required": [
+                                                "meta",
+                                                "data"
+                                            ],
+                                            "properties": {
+                                                "meta": {
+                                                    "$ref": "#/components/schemas/OCSMeta"
+                                                },
+                                                "data": {
+                                                    "nullable": true
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        "/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}": {
+            "get": {
+                "operationId": "out_of_office-get-out-of-office",
+                "summary": "Get the configured out-of-office data of a user.",
+                "tags": [
+                    "out_of_office"
+                ],
+                "security": [
+                    {
+                        "bearer_auth": []
+                    },
+                    {
+                        "basic_auth": []
+                    }
+                ],
+                "parameters": [
+                    {
+                        "name": "userId",
+                        "in": "path",
+                        "description": "The user id to get out-of-office data for.",
+                        "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": "Out-of-office data",
index 12b7e03a0ae846464c1b61478dad405d8cc4827d..72e42afab6ae69f8fb4857a5fa99351282ced514 100644 (file)
@@ -60,4 +60,15 @@ class OutOfOfficeData implements IOutOfOfficeData {
        public function getMessage(): string {
                return $this->message;
        }
+
+       public function jsonSerialize(): array {
+               return [
+                       'id' => $this->getId(),
+                       'userId' => $this->getUser()->getUID(),
+                       'startDate' => $this->getStartDate(),
+                       'endDate' => $this->getEndDate(),
+                       'shortMessage' => $this->getShortMessage(),
+                       'message' => $this->getMessage(),
+               ];
+       }
 }
index 03444449d58f918e33d87c081588260115170699..31281104382c21fd85de26ecf4f67546d367c178 100644 (file)
@@ -25,14 +25,24 @@ declare(strict_types=1);
 
 namespace OCP\User;
 
+use JsonSerializable;
 use OCP\IUser;
 
 /**
  * DTO to hold out-of-office information of a user
  *
+ * @psalm-type OutOfOfficeData = array{
+ *      id: string,
+ *      userId: string,
+ *      startDate: int,
+ *      endDate: int,
+ *      shortMessage: string,
+ *      message: string,
+ * }
+ *
  * @since 28.0.0
  */
-interface IOutOfOfficeData {
+interface IOutOfOfficeData extends JsonSerializable {
        /**
         * Get the unique token assigned to the current out-of-office event
         *
@@ -74,4 +84,11 @@ interface IOutOfOfficeData {
         * @since 28.0.0
         */
        public function getMessage(): string;
+
+       /**
+        * @return OutOfOfficeData
+        *
+        * @since 28.0.0
+        */
+       public function jsonSerialize(): array;
 }