Skip to content

Commit

Permalink
Merge pull request #45766 from nextcloud/feat/ooo-replacement
Browse files Browse the repository at this point in the history
Feat: Allow users to select another user as their out-of-office replacement
  • Loading branch information
kesselb authored Jul 1, 2024
2 parents 55f3e53 + a977474 commit 92acbb0
Show file tree
Hide file tree
Showing 17 changed files with 321 additions and 12 deletions.
2 changes: 1 addition & 1 deletion apps/dav/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<name>WebDAV</name>
<summary>WebDAV endpoint</summary>
<description>WebDAV endpoint</description>
<version>1.31.0</version>
<version>1.31.1</version>
<licence>agpl</licence>
<author>owncloud.org</author>
<namespace>DAV</namespace>
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@
'OCA\\DAV\\Migration\\Version1029Date20221114151721' => $baseDir . '/../lib/Migration/Version1029Date20221114151721.php',
'OCA\\DAV\\Migration\\Version1029Date20231004091403' => $baseDir . '/../lib/Migration/Version1029Date20231004091403.php',
'OCA\\DAV\\Migration\\Version1030Date20240205103243' => $baseDir . '/../lib/Migration/Version1030Date20240205103243.php',
'OCA\\DAV\\Migration\\Version1031Date20240610134258' => $baseDir . '/../lib/Migration/Version1031Date20240610134258.php',
'OCA\\DAV\\Profiler\\ProfilerPlugin' => $baseDir . '/../lib/Profiler/ProfilerPlugin.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1029Date20221114151721' => __DIR__ . '/..' . '/../lib/Migration/Version1029Date20221114151721.php',
'OCA\\DAV\\Migration\\Version1029Date20231004091403' => __DIR__ . '/..' . '/../lib/Migration/Version1029Date20231004091403.php',
'OCA\\DAV\\Migration\\Version1030Date20240205103243' => __DIR__ . '/..' . '/../lib/Migration/Version1030Date20240205103243.php',
'OCA\\DAV\\Migration\\Version1031Date20240610134258' => __DIR__ . '/..' . '/../lib/Migration/Version1031Date20240610134258.php',
'OCA\\DAV\\Profiler\\ProfilerPlugin' => __DIR__ . '/..' . '/../lib/Profiler/ProfilerPlugin.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
Expand Down
21 changes: 20 additions & 1 deletion apps/dav/lib/Controller/OutOfOfficeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ public function getOutOfOffice(string $userId): DataResponse {
'lastDay' => $data->getLastDay(),
'status' => $data->getStatus(),
'message' => $data->getMessage(),
'replacementUserId' => $data->getReplacementUserId(),
'replacementUserDisplayName' => $data->getReplacementUserDisplayName(),
]);
}

Expand All @@ -103,24 +105,37 @@ public function getOutOfOffice(string $userId): DataResponse {
* @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{}>
* @param string $replacementUserId User id of the replacement user
* @param string $replacementUserDisplayName Display name of the replacement user
* @return DataResponse<Http::STATUS_OK, DAVOutOfOfficeData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'firstDay'}, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, null, array{}>|DataResponse<Http::STATUS_NOT_FOUND, null, array{}>
*
* 200: Absence data
* 400: When the first day is not before the last day
* 401: When the user is not logged in
* 404: When the replacementUserId was provided but replacement user was not found
*/
#[NoAdminRequired]
public function setOutOfOffice(
string $firstDay,
string $lastDay,
string $status,
string $message,
string $replacementUserId = '',
string $replacementUserDisplayName = ''

): DataResponse {
$user = $this->userSession?->getUser();
if ($user === null) {
return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
}

if ($replacementUserId !== '') {
$replacementUser = $this->userManager->get($replacementUserId);
if ($replacementUser === null) {
return new DataResponse(null, Http::STATUS_NOT_FOUND);
}
}

$parsedFirstDay = new DateTimeImmutable($firstDay);
$parsedLastDay = new DateTimeImmutable($lastDay);
if ($parsedFirstDay->getTimestamp() > $parsedLastDay->getTimestamp()) {
Expand All @@ -133,6 +148,8 @@ public function setOutOfOffice(
$lastDay,
$status,
$message,
$replacementUserId,
$replacementUserDisplayName
);
$this->coordinator->clearCache($user->getUID());

Expand All @@ -143,6 +160,8 @@ public function setOutOfOffice(
'lastDay' => $data->getLastDay(),
'status' => $data->getStatus(),
'message' => $data->getMessage(),
'replacementUserId' => $data->getReplacementUserId(),
'replacementUserDisplayName' => $data->getReplacementUserDisplayName(),
]);
}

Expand Down
14 changes: 14 additions & 0 deletions apps/dav/lib/Db/Absence.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
* @method void setStatus(string $status)
* @method string getMessage()
* @method void setMessage(string $message)
* @method string getReplacementUserId()
* @method void setReplacementUserId(string $replacementUserId)
* @method string getReplacementUserDisplayName()
* @method void setReplacementUserDisplayName(string $replacementUserDisplayName)
*/
class Absence extends Entity implements JsonSerializable {
protected string $userId = '';
Expand All @@ -43,12 +47,18 @@ class Absence extends Entity implements JsonSerializable {

protected string $message = '';

protected string $replacementUserId = '';

protected string $replacementUserDisplayName = '';

public function __construct() {
$this->addType('userId', 'string');
$this->addType('firstDay', 'string');
$this->addType('lastDay', 'string');
$this->addType('status', 'string');
$this->addType('message', 'string');
$this->addType('replacementUserId', 'string');
$this->addType('replacementUserDisplayName', 'string');
}

public function toOutOufOfficeData(IUser $user, string $timezone): IOutOfOfficeData {
Expand All @@ -70,6 +80,8 @@ public function toOutOufOfficeData(IUser $user, string $timezone): IOutOfOfficeD
$endDate->getTimestamp(),
$this->getStatus(),
$this->getMessage(),
$this->getReplacementUserId(),
$this->getReplacementUserDisplayName(),
);
}

Expand All @@ -80,6 +92,8 @@ public function jsonSerialize(): array {
'lastDay' => $this->lastDay,
'status' => $this->status,
'message' => $this->message,
'replacementUserId' => $this->replacementUserId,
'replacementUserDisplayName' => $this->replacementUserDisplayName,
];
}
}
44 changes: 44 additions & 0 deletions apps/dav/lib/Migration/Version1031Date20240610134258.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\DAV\Migration;

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

class Version1031Date20240610134258 extends SimpleMigrationStep {
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

$tableDavAbsence = $schema->getTable('dav_absence');

if (!$tableDavAbsence->hasColumn('replacement_user_id')) {
$tableDavAbsence->addColumn('replacement_user_id', Types::STRING, [
'notnull' => false,
'default' => '',
'length' => 64,
]);
}

if (!$tableDavAbsence->hasColumn('replacement_user_display_name')) {
$tableDavAbsence->addColumn('replacement_user_display_name', Types::STRING, [
'notnull' => false,
'default' => '',
'length' => 64,
]);
}

return $schema;
}

}
2 changes: 2 additions & 0 deletions apps/dav/lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* @psalm-type DAVOutOfOfficeDataCommon = array{
* userId: string,
* message: string,
* replacementUserId: string,
* replacementUserDisplayName: string,
* }
*
* @psalm-type DAVOutOfOfficeData = DAVOutOfOfficeDataCommon&array{
Expand Down
4 changes: 4 additions & 0 deletions apps/dav/lib/Service/AbsenceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public function createOrUpdateAbsence(
string $lastDay,
string $status,
string $message,
?string $replacementUserId = null,
?string $replacementUserDisplayName = null,
): Absence {
try {
$absence = $this->absenceMapper->findByUserId($user->getUID());
Expand All @@ -59,6 +61,8 @@ public function createOrUpdateAbsence(
$absence->setLastDay($lastDay);
$absence->setStatus($status);
$absence->setMessage($message);
$absence->setReplacementUserId($replacementUserId ?? '');
$absence->setReplacementUserDisplayName($replacementUserDisplayName ?? '');

if ($absence->getId() === null) {
$absence = $this->absenceMapper->insert($absence);
Expand Down
58 changes: 57 additions & 1 deletion apps/dav/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,22 @@
"type": "object",
"required": [
"userId",
"message"
"message",
"replacementUserId",
"replacementUserDisplayName"
],
"properties": {
"userId": {
"type": "string"
},
"message": {
"type": "string"
},
"replacementUserId": {
"type": "string"
},
"replacementUserDisplayName": {
"type": "string"
}
}
}
Expand Down Expand Up @@ -570,6 +578,24 @@
"type": "string"
}
},
{
"name": "replacementUserId",
"in": "query",
"description": "User id of the replacement user",
"schema": {
"type": "string",
"default": ""
}
},
{
"name": "replacementUserDisplayName",
"in": "query",
"description": "Display name of the replacement user",
"schema": {
"type": "string",
"default": ""
}
},
{
"name": "userId",
"in": "path",
Expand Down Expand Up @@ -690,6 +716,36 @@
}
}
}
},
"404": {
"description": "When the replacementUserId was provided but replacement user was not 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
}
}
}
}
}
}
}
}
}
},
Expand Down
Loading

0 comments on commit 92acbb0

Please sign in to comment.