Skip to content

Commit

Permalink
Merge pull request #42029 from nextcloud/backport/41962/stable28
Browse files Browse the repository at this point in the history
[stable28] fix(dav): Make current ooo info time-dependent
  • Loading branch information
nickvergessen authored Dec 6, 2023
2 parents 819d474 + df4a76a commit 675d25e
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 27 deletions.
3 changes: 2 additions & 1 deletion apps/dav/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
],
'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'],
],
Expand Down
39 changes: 35 additions & 4 deletions apps/dav/lib/Controller/OutOfOfficeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
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;
Expand All @@ -36,18 +35,20 @@
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,
Expand All @@ -59,15 +60,45 @@ public function __construct(
* 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);
}
Expand Down
17 changes: 14 additions & 3 deletions apps/dav/lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,24 @@
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 {
Expand Down
16 changes: 16 additions & 0 deletions apps/dav/lib/Service/AbsenceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ public function getAbsence(string $userId): ?Absence {
}
}

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;
Expand Down
182 changes: 164 additions & 18 deletions apps/dav/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand All @@ -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"
}
Expand Down Expand Up @@ -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.",
Expand Down Expand Up @@ -255,6 +301,106 @@
}
}
],
"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",
Expand Down
11 changes: 11 additions & 0 deletions lib/private/User/OutOfOfficeData.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,15 @@ public function getShortMessage(): string {
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(),
];
}
}
Loading

0 comments on commit 675d25e

Please sign in to comment.