aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2023-12-01 10:46:16 +0100
committerChristoph Wurst <christoph@winzerhof-wurst.at>2023-12-05 08:36:50 +0100
commit9a206c6282a55c9fdeb99abe8684199c0f934d7f (patch)
treeafbcabe90d48f80bf26284651bbbfceba806bb4e
parente27e2e43955bc09bbce86b4cfe458a2af2f66724 (diff)
downloadnextcloud-server-9a206c6282a55c9fdeb99abe8684199c0f934d7f.tar.gz
nextcloud-server-9a206c6282a55c9fdeb99abe8684199c0f934d7f.zip
fix(dav): Make current ooo info time-dependent
* 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>
-rw-r--r--apps/dav/appinfo/routes.php3
-rw-r--r--apps/dav/lib/Controller/OutOfOfficeController.php39
-rw-r--r--apps/dav/lib/ResponseDefinitions.php17
-rw-r--r--apps/dav/lib/Service/AbsenceService.php16
-rw-r--r--apps/dav/openapi.json182
-rw-r--r--lib/private/User/OutOfOfficeData.php11
-rw-r--r--lib/public/User/IOutOfOfficeData.php19
7 files changed, 260 insertions, 27 deletions
diff --git a/apps/dav/appinfo/routes.php b/apps/dav/appinfo/routes.php
index a6874aeb57d..529bd0781fa 100644
--- a/apps/dav/appinfo/routes.php
+++ b/apps/dav/appinfo/routes.php
@@ -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'],
],
diff --git a/apps/dav/lib/Controller/OutOfOfficeController.php b/apps/dav/lib/Controller/OutOfOfficeController.php
index ffac1247a6c..a2e7378f32d 100644
--- a/apps/dav/lib/Controller/OutOfOfficeController.php
+++ b/apps/dav/lib/Controller/OutOfOfficeController.php
@@ -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);
}
diff --git a/apps/dav/lib/ResponseDefinitions.php b/apps/dav/lib/ResponseDefinitions.php
index 97bd8e9efe9..e6de3d5a65c 100644
--- a/apps/dav/lib/ResponseDefinitions.php
+++ b/apps/dav/lib/ResponseDefinitions.php
@@ -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 {
diff --git a/apps/dav/lib/Service/AbsenceService.php b/apps/dav/lib/Service/AbsenceService.php
index 7c0d6eec082..3e2a218d52b 100644
--- a/apps/dav/lib/Service/AbsenceService.php
+++ b/apps/dav/lib/Service/AbsenceService.php
@@ -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;
diff --git a/apps/dav/openapi.json b/apps/dav/openapi.json
index a235e3bff1d..a0df1cedd16 100644
--- a/apps/dav/openapi.json
+++ b/apps/dav/openapi.json
@@ -42,6 +42,38 @@
}
}
},
+ "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": [
@@ -67,32 +99,46 @@
}
},
"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"
}
@@ -219,7 +265,7 @@
}
}
},
- "/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.",
@@ -277,6 +323,106 @@
"$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",
+ "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"
}
}
diff --git a/lib/private/User/OutOfOfficeData.php b/lib/private/User/OutOfOfficeData.php
index 12b7e03a0ae..72e42afab6a 100644
--- a/lib/private/User/OutOfOfficeData.php
+++ b/lib/private/User/OutOfOfficeData.php
@@ -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(),
+ ];
+ }
}
diff --git a/lib/public/User/IOutOfOfficeData.php b/lib/public/User/IOutOfOfficeData.php
index 03444449d58..31281104382 100644
--- a/lib/public/User/IOutOfOfficeData.php
+++ b/lib/public/User/IOutOfOfficeData.php
@@ -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;
}