Skip to content

Commit 866411a

Browse files
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 <[email protected]>
1 parent 782160a commit 866411a

File tree

7 files changed

+260
-27
lines changed

7 files changed

+260
-27
lines changed

apps/dav/appinfo/routes.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
],
3434
'ocs' => [
3535
['name' => 'direct#getUrl', 'url' => '/api/v1/direct', 'verb' => 'POST'],
36-
['name' => 'out_of_office#getCurrentOutOfOfficeData', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'GET'],
36+
['name' => 'out_of_office#getCurrentOutOfOfficeData', 'url' => '/api/v1/outOfOffice/{userId}/now', 'verb' => 'GET'],
37+
['name' => 'out_of_office#getOutOfOffice', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'GET'],
3738
['name' => 'out_of_office#setOutOfOffice', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'POST'],
3839
['name' => 'out_of_office#clearOutOfOffice', 'url' => '/api/v1/outOfOffice/{userId}', 'verb' => 'DELETE'],
3940
],

apps/dav/lib/Controller/OutOfOfficeController.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
namespace OCA\DAV\Controller;
2828

2929
use DateTimeImmutable;
30-
use OCA\DAV\Db\AbsenceMapper;
3130
use OCA\DAV\ResponseDefinitions;
3231
use OCA\DAV\Service\AbsenceService;
3332
use OCP\AppFramework\Db\DoesNotExistException;
@@ -36,18 +35,20 @@
3635
use OCP\AppFramework\Http\DataResponse;
3736
use OCP\AppFramework\OCSController;
3837
use OCP\IRequest;
38+
use OCP\IUserManager;
3939
use OCP\IUserSession;
4040
use OCP\User\IAvailabilityCoordinator;
4141

4242
/**
4343
* @psalm-import-type DAVOutOfOfficeData from ResponseDefinitions
44+
* @psalm-import-type DAVCurrentOutOfOfficeData from ResponseDefinitions
4445
*/
4546
class OutOfOfficeController extends OCSController {
4647

4748
public function __construct(
4849
string $appName,
4950
IRequest $request,
50-
private AbsenceMapper $absenceMapper,
51+
private IUserManager $userManager,
5152
private ?IUserSession $userSession,
5253
private AbsenceService $absenceService,
5354
private IAvailabilityCoordinator $coordinator,
@@ -59,15 +60,45 @@ public function __construct(
5960
* Get the currently configured out-of-office data of a user.
6061
*
6162
* @param string $userId The user id to get out-of-office data for.
62-
* @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
63+
* @return DataResponse<Http::STATUS_OK, DAVCurrentOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
6364
*
6465
* 200: Out-of-office data
6566
* 404: No out-of-office data was found
6667
*/
6768
#[NoAdminRequired]
6869
public function getCurrentOutOfOfficeData(string $userId): DataResponse {
70+
$user = $this->userManager->get($userId);
71+
if ($user === null) {
72+
return new DataResponse(null, Http::STATUS_NOT_FOUND);
73+
}
74+
try {
75+
$data = $this->absenceService->getCurrentAbsence($user);
76+
if ($data === null) {
77+
return new DataResponse(null, Http::STATUS_NOT_FOUND);
78+
}
79+
} catch (DoesNotExistException) {
80+
return new DataResponse(null, Http::STATUS_NOT_FOUND);
81+
}
82+
83+
return new DataResponse($data->jsonSerialize());
84+
}
85+
86+
/**
87+
* Get the configured out-of-office data of a user.
88+
*
89+
* @param string $userId The user id to get out-of-office data for.
90+
* @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
91+
*
92+
* 200: Out-of-office data
93+
* 404: No out-of-office data was found
94+
*/
95+
#[NoAdminRequired]
96+
public function getOutOfOffice(string $userId): DataResponse {
6997
try {
70-
$data = $this->absenceMapper->findByUserId($userId);
98+
$data = $this->absenceService->getAbsence($userId);
99+
if ($data === null) {
100+
return new DataResponse(null, Http::STATUS_NOT_FOUND);
101+
}
71102
} catch (DoesNotExistException) {
72103
return new DataResponse(null, Http::STATUS_NOT_FOUND);
73104
}

apps/dav/lib/ResponseDefinitions.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,24 @@
2727
namespace OCA\DAV;
2828

2929
/**
30-
* @psalm-type DAVOutOfOfficeData = array{
30+
* @psalm-type DAVOutOfOfficeDataCommon = array{
31+
* userId: string,
32+
* message: string,
33+
* }
34+
*
35+
* @psalm-type DAVOutOfOfficeData = DAVOutOfOfficeDataCommon&array{
3136
* id: int,
32-
* userId: string,
3337
* firstDay: string,
3438
* lastDay: string,
3539
* status: string,
36-
* message: string,
40+
* }
41+
*
42+
* @todo this is a copy of \OCP\User\IOutOfOfficeData
43+
* @psalm-type DAVCurrentOutOfOfficeData = DAVOutOfOfficeDataCommon&array{
44+
* id: string,
45+
* startDate: int,
46+
* endDate: int,
47+
* shortMessage: string,
3748
* }
3849
*/
3950
class ResponseDefinitions {

apps/dav/lib/Service/AbsenceService.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ public function getAbsence(string $userId): ?Absence {
145145
}
146146
}
147147

148+
public function getCurrentAbsence(IUser $user): ?IOutOfOfficeData {
149+
try {
150+
$absence = $this->absenceMapper->findByUserId($user->getUID());
151+
$oooData = $absence->toOutOufOfficeData(
152+
$user,
153+
$this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(),
154+
);
155+
if ($this->isInEffect($oooData)) {
156+
return $oooData;
157+
}
158+
} catch (DoesNotExistException) {
159+
// Nothing there to process
160+
}
161+
return null;
162+
}
163+
148164
public function isInEffect(IOutOfOfficeData $absence): bool {
149165
$now = $this->timeFactory->getTime();
150166
return $absence->getStartDate() <= $now && $absence->getEndDate() >= $now;

apps/dav/openapi.json

Lines changed: 164 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,38 @@
4242
}
4343
}
4444
},
45+
"CurrentOutOfOfficeData": {
46+
"allOf": [
47+
{
48+
"$ref": "#/components/schemas/OutOfOfficeDataCommon"
49+
},
50+
{
51+
"type": "object",
52+
"required": [
53+
"id",
54+
"startDate",
55+
"endDate",
56+
"shortMessage"
57+
],
58+
"properties": {
59+
"id": {
60+
"type": "string"
61+
},
62+
"startDate": {
63+
"type": "integer",
64+
"format": "int64"
65+
},
66+
"endDate": {
67+
"type": "integer",
68+
"format": "int64"
69+
},
70+
"shortMessage": {
71+
"type": "string"
72+
}
73+
}
74+
}
75+
]
76+
},
4577
"OCSMeta": {
4678
"type": "object",
4779
"required": [
@@ -67,32 +99,46 @@
6799
}
68100
},
69101
"OutOfOfficeData": {
102+
"allOf": [
103+
{
104+
"$ref": "#/components/schemas/OutOfOfficeDataCommon"
105+
},
106+
{
107+
"type": "object",
108+
"required": [
109+
"id",
110+
"firstDay",
111+
"lastDay",
112+
"status"
113+
],
114+
"properties": {
115+
"id": {
116+
"type": "integer",
117+
"format": "int64"
118+
},
119+
"firstDay": {
120+
"type": "string"
121+
},
122+
"lastDay": {
123+
"type": "string"
124+
},
125+
"status": {
126+
"type": "string"
127+
}
128+
}
129+
}
130+
]
131+
},
132+
"OutOfOfficeDataCommon": {
70133
"type": "object",
71134
"required": [
72-
"id",
73135
"userId",
74-
"firstDay",
75-
"lastDay",
76-
"status",
77136
"message"
78137
],
79138
"properties": {
80-
"id": {
81-
"type": "integer",
82-
"format": "int64"
83-
},
84139
"userId": {
85140
"type": "string"
86141
},
87-
"firstDay": {
88-
"type": "string"
89-
},
90-
"lastDay": {
91-
"type": "string"
92-
},
93-
"status": {
94-
"type": "string"
95-
},
96142
"message": {
97143
"type": "string"
98144
}
@@ -219,7 +265,7 @@
219265
}
220266
}
221267
},
222-
"/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}": {
268+
"/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}/now": {
223269
"get": {
224270
"operationId": "out_of_office-get-current-out-of-office-data",
225271
"summary": "Get the currently configured out-of-office data of a user.",
@@ -255,6 +301,106 @@
255301
}
256302
}
257303
],
304+
"responses": {
305+
"200": {
306+
"description": "Out-of-office data",
307+
"content": {
308+
"application/json": {
309+
"schema": {
310+
"type": "object",
311+
"required": [
312+
"ocs"
313+
],
314+
"properties": {
315+
"ocs": {
316+
"type": "object",
317+
"required": [
318+
"meta",
319+
"data"
320+
],
321+
"properties": {
322+
"meta": {
323+
"$ref": "#/components/schemas/OCSMeta"
324+
},
325+
"data": {
326+
"$ref": "#/components/schemas/CurrentOutOfOfficeData"
327+
}
328+
}
329+
}
330+
}
331+
}
332+
}
333+
}
334+
},
335+
"404": {
336+
"description": "No out-of-office data was found",
337+
"content": {
338+
"application/json": {
339+
"schema": {
340+
"type": "object",
341+
"required": [
342+
"ocs"
343+
],
344+
"properties": {
345+
"ocs": {
346+
"type": "object",
347+
"required": [
348+
"meta",
349+
"data"
350+
],
351+
"properties": {
352+
"meta": {
353+
"$ref": "#/components/schemas/OCSMeta"
354+
},
355+
"data": {
356+
"nullable": true
357+
}
358+
}
359+
}
360+
}
361+
}
362+
}
363+
}
364+
}
365+
}
366+
}
367+
},
368+
"/ocs/v2.php/apps/dav/api/v1/outOfOffice/{userId}": {
369+
"get": {
370+
"operationId": "out_of_office-get-out-of-office",
371+
"summary": "Get the configured out-of-office data of a user.",
372+
"tags": [
373+
"out_of_office"
374+
],
375+
"security": [
376+
{
377+
"bearer_auth": []
378+
},
379+
{
380+
"basic_auth": []
381+
}
382+
],
383+
"parameters": [
384+
{
385+
"name": "userId",
386+
"in": "path",
387+
"description": "The user id to get out-of-office data for.",
388+
"required": true,
389+
"schema": {
390+
"type": "string"
391+
}
392+
},
393+
{
394+
"name": "OCS-APIRequest",
395+
"in": "header",
396+
"description": "Required to be true for the API request to pass",
397+
"required": true,
398+
"schema": {
399+
"type": "boolean",
400+
"default": true
401+
}
402+
}
403+
],
258404
"responses": {
259405
"200": {
260406
"description": "Out-of-office data",

lib/private/User/OutOfOfficeData.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,15 @@ public function getShortMessage(): string {
6060
public function getMessage(): string {
6161
return $this->message;
6262
}
63+
64+
public function jsonSerialize(): array {
65+
return [
66+
'id' => $this->getId(),
67+
'userId' => $this->getUser()->getUID(),
68+
'startDate' => $this->getStartDate(),
69+
'endDate' => $this->getEndDate(),
70+
'shortMessage' => $this->getShortMessage(),
71+
'message' => $this->getMessage(),
72+
];
73+
}
6374
}

0 commit comments

Comments
 (0)