You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
685 lines
24 KiB
685 lines
24 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* @copyright Copyright (c) 2021, Watcha <contact@watcha.fr>
|
|
*
|
|
* @author Charlie Calendre <c-cal@watcha.fr>
|
|
*
|
|
* @license GNU AGPL version 3 or any later version
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
namespace OCA\Watcha\Controller;
|
|
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
use OCA\DAV\CalDAV\CalDavBackend;
|
|
use OCP\AppFramework\Controller;
|
|
use OCP\AppFramework\Http;
|
|
use OCP\AppFramework\Http\JSONResponse;
|
|
use OCP\IConfig;
|
|
use OCP\IDBConnection;
|
|
use OCP\IGroup;
|
|
use OCP\IGroupManager;
|
|
use OCP\IRequest;
|
|
use OCP\IUserManager;
|
|
use OCP\Util;
|
|
use Sabre\DAV\Exception\NotFound;
|
|
use Sabre\Uri;
|
|
|
|
use OCA\Watcha\Dav;
|
|
use OCA\Watcha\Exception\GenericException;
|
|
|
|
const CALENDAR_ORDER_KEY = "{http://apple.com/ns/ical/}calendar-order";
|
|
const DISPLAYNAME_KEY = "{DAV:}displayname";
|
|
const OWNER_PRINCIPAL_KEY = "{" . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . "}owner-principal";
|
|
const SUPPORTED_CALENDAR_COMPONENT_SET_KEY = "{" . \OCA\DAV\CalDAV\Plugin::NS_CALDAV . "}supported-calendar-component-set";
|
|
|
|
class CalendarController extends Controller {
|
|
/** @var string */
|
|
private $userId;
|
|
|
|
/** @var LoggerInterface */
|
|
private $logger;
|
|
|
|
/** @var CalDavBackend */
|
|
private $caldav;
|
|
|
|
/** @var IDBConnection */
|
|
private $connection;
|
|
|
|
/** @var IUserManager */
|
|
private $userManager;
|
|
|
|
/** @var IGroupManager */
|
|
private $groupManager;
|
|
|
|
/** @var IConfig */
|
|
private $config;
|
|
|
|
public function __construct(
|
|
string $AppName,
|
|
string $UserId,
|
|
IRequest $request,
|
|
LoggerInterface $logger,
|
|
CalDavBackend $caldav,
|
|
IDBConnection $connection,
|
|
IUserManager $userManager,
|
|
IGroupManager $groupManager,
|
|
IConfig $config
|
|
) {
|
|
parent::__construct($AppName, $request);
|
|
$this->userId = $UserId;
|
|
$this->logger = $logger;
|
|
$this->caldav = $caldav;
|
|
$this->connection = $connection;
|
|
$this->userManager = $userManager;
|
|
$this->groupManager = $groupManager;
|
|
$this->config = $config;
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $userId
|
|
* @return JSONResponse
|
|
*/
|
|
public function list(string $userId) {
|
|
$principalUri = "principals/users/$userId";
|
|
$calendars = $this->caldav->getUsersOwnCalendars($principalUri);
|
|
$fmtCalendars = [];
|
|
foreach ($calendars as $calendar) {
|
|
$fmtCalendars[] = [
|
|
"id" => (int) $calendar["id"],
|
|
"displayname" => $calendar[DISPLAYNAME_KEY],
|
|
"components" => $calendar[SUPPORTED_CALENDAR_COMPONENT_SET_KEY]->getValue()
|
|
];
|
|
}
|
|
usort($fmtCalendars, function (array $a, array $b) {
|
|
return strcmp(strtolower($a['displayname']), strtolower($b['displayname']));
|
|
});
|
|
return new JSONResponse($fmtCalendars);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $userId
|
|
* @param int $calendarId
|
|
* @return JSONResponse
|
|
*/
|
|
public function get(string $userId, int $calendarId) {
|
|
$calendar = $this->getFormatedCalendar($calendarId);
|
|
try {
|
|
$displayName = $this->getDisplayName($userId, $calendarId);
|
|
} catch (GenericException $e) {
|
|
return new JSONResponse(["message" => $e->getMessage()], $e->getHTTPCode());
|
|
}
|
|
$calendar["displayname"] = $displayName;
|
|
return new JSONResponse($calendar);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $userId
|
|
* @param int $calendarId
|
|
* @return JSONResponse
|
|
*/
|
|
public function reorder(string $userId, int $calendarId) {
|
|
$calendar = $this->caldav->getCalendarById($calendarId);
|
|
if (is_null($calendar)) {
|
|
$this->logger->warning("calendar $calendarId no found, can't reorder it for user $userId");
|
|
return;
|
|
}
|
|
$components = $calendar[SUPPORTED_CALENDAR_COMPONENT_SET_KEY]->getValue();
|
|
if (in_array("VTODO", $components)) {
|
|
list(, $ownerId) = Uri\split($calendar["principaluri"]);
|
|
$calendarUri = $ownerId === $userId ? $calendar["uri"] : $this->computeUriForSharedCalendar($calendar["uri"], $ownerId);
|
|
$value = "/calendars/$calendarUri";
|
|
$this->config->setUserValue($userId, "tasks", "various_initialRoute", $value);
|
|
$this->logger->info("todo list with URI $calendarUri defined as initial route for user $userId");
|
|
}
|
|
|
|
$query = $this->connection->getQueryBuilder();
|
|
$fields = ["propertypath", "propertyvalue"];
|
|
$query->select($fields)
|
|
->from("properties")
|
|
->where($query->expr()->eq("userid", $query->createNamedParameter($userId)))
|
|
->andWhere($query->expr()->eq("propertyname", $query->createNamedParameter(CALENDAR_ORDER_KEY)))
|
|
->orderBy("propertyvalue", "ASC");
|
|
|
|
$cursor = $query->execute();
|
|
|
|
$ocProperties = array();
|
|
|
|
while ($row = $cursor->fetch()) {
|
|
$order = (int) $row["propertyvalue"];
|
|
$path = (string) $row["propertypath"];
|
|
$ocProperties[$path] = [
|
|
"order" => $order
|
|
];
|
|
}
|
|
|
|
$cursor->closeCursor();
|
|
|
|
$principalUri = "principals/users/$userId";
|
|
$calendars = $this->caldav->getCalendarsForUser($principalUri);
|
|
$orderedCalendars = array();
|
|
|
|
foreach ($calendars as $calendar) {
|
|
$owner = $calendar[OWNER_PRINCIPAL_KEY];
|
|
$uri = $calendar["uri"];
|
|
$path = "calendars/$userId/$uri";
|
|
if ($owner !== $principalUri and array_key_exists($path, $ocProperties)) {
|
|
$ocProperties[$path]["calendar"] = $calendar;
|
|
} else {
|
|
$orderedCalendars[] = $calendar;
|
|
}
|
|
}
|
|
|
|
foreach ($ocProperties as $propertie) {
|
|
$order = $propertie["order"];
|
|
$calendar = $propertie["calendar"];
|
|
array_splice($orderedCalendars, $order, 0, array($calendar));
|
|
}
|
|
|
|
$user = $this->userManager->get($userId);
|
|
$server = Dav::getServerInstance($this->connection, $user);
|
|
|
|
$i = 1;
|
|
foreach ($orderedCalendars as $calendar) {
|
|
$uri = $calendar["uri"];
|
|
$path = "calendars/$userId/$uri";
|
|
$order = (int) $calendar["id"] === $calendarId ? 0 : $i++;
|
|
$properties = [CALENDAR_ORDER_KEY => $order];
|
|
$server->updateProperties($path, $properties);
|
|
}
|
|
$this->logger->info("calendar $calendarId moved to top of list for user $userId");
|
|
return new JSONResponse((object)[]);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $mxRoomId
|
|
* @param string $displayName
|
|
* @param string[] $userIds (optional)
|
|
* @return JSONResponse
|
|
*/
|
|
public function createAndShare(string $mxRoomId, string $displayName, array $userIds = []) {
|
|
$userId = $this->userId;
|
|
$calendarUri = $this->computeIdFromMxRoomId($mxRoomId);
|
|
$calendarId = $this->create($userId, $calendarUri, $displayName);
|
|
$userIds[] = $this->userId;
|
|
return $this->share($userId, $calendarId, $mxRoomId, $displayName, $userIds);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $userId
|
|
* @param int $calendarId
|
|
* @param string $mxRoomId
|
|
* @param string $displayName
|
|
* @param string[] $userIds (optional)
|
|
* @return JSONResponse
|
|
*/
|
|
public function share(string $userId, int $calendarId, string $mxRoomId, string $displayName, array $userIds = []) {
|
|
$ownerId = $this->getUserIdFromCalendarId($calendarId);
|
|
if (is_null($ownerId)) {
|
|
$message = "calendar $calendarId not found, can't share it";
|
|
$this->logger->warning($message);
|
|
return new JSONResponse(["message" => $message], Http::STATUS_NOT_FOUND);
|
|
}
|
|
if ($ownerId !== $userId) {
|
|
$message = "calendar $calendarId is not owned by $userId, can't share it";
|
|
$this->logger->warning($message);
|
|
return new JSONResponse(["message" => $message], Http::STATUS_FORBIDDEN);
|
|
}
|
|
$groupId = $this->computeIdFromMxRoomId($mxRoomId);
|
|
try {
|
|
$this->createGroup($groupId, $displayName);
|
|
} catch (GenericException $e) {
|
|
return new JSONResponse(["message" => $e->getMessage()], $e->getHTTPCode());
|
|
}
|
|
# workaround for an upstream bug: users must be added to the group before
|
|
# sharing the calendar to avoid it appearing empty when its members are listed later
|
|
$this->addUsersToGroup($groupId, $userIds, $ownerId);
|
|
$add = [
|
|
array(
|
|
"href" => "principal:principals/groups/$groupId",
|
|
"commonName" => null,
|
|
"summary" => null,
|
|
"readOnly" => false,
|
|
)
|
|
];
|
|
try {
|
|
$this->updateShares($calendarId, $add);
|
|
} catch (GenericException | NotFound $e) {
|
|
return new JSONResponse(["message" => $e->getMessage()], $e->getHTTPCode());
|
|
}
|
|
$this->renameForGroupMembers($groupId, $calendarId, $displayName);
|
|
$calendar = $this->getFormatedCalendar($calendarId);
|
|
return new JSONResponse($calendar);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param int[] $calendarIds
|
|
* @param string $mxRoomId
|
|
* @param bool $deleteGroup (optional)
|
|
* @return JSONResponse
|
|
*/
|
|
public function unShare(array $calendarIds, string $mxRoomId, bool $deleteGroup = False) {
|
|
$groupId = $this->computeIdFromMxRoomId($mxRoomId);
|
|
foreach ($calendarIds as $calendarId) {
|
|
if ($this->getUserIdFromCalendarId($calendarId) === $this->userId) {
|
|
$this->delete($calendarId);
|
|
} else {
|
|
$remove = ["principal:principals/groups/$groupId"];
|
|
$this->updateShares($calendarId, [], $remove);
|
|
}
|
|
}
|
|
if ($deleteGroup) {
|
|
try {
|
|
$this->deleteGroup($groupId);
|
|
} catch (GenericException $e) {
|
|
return new JSONResponse(["message" => $e->getMessage()], $e->getHTTPCode());
|
|
}
|
|
}
|
|
return new JSONResponse((object)[]);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $userId
|
|
* @param string $mxRoomId
|
|
* @param int[] $calendarIds
|
|
* @param string $displayName
|
|
* @return JSONResponse
|
|
*/
|
|
public function addUser(string $userId, string $mxRoomId, array $calendarIds, string $displayName) {
|
|
$groupId = $this->computeIdFromMxRoomId($mxRoomId);
|
|
foreach ($calendarIds as $calendarId) {
|
|
$ownerId = $this->getUserIdFromCalendarId($calendarId);
|
|
$this->addUsersToGroup($groupId, [$userId], $ownerId);
|
|
try {
|
|
$this->renameForUser($userId, $calendarId, $displayName);
|
|
} catch (NotFound $e) {
|
|
$this->logger->warning($e->getMessage());
|
|
}
|
|
}
|
|
return new JSONResponse((object)[]);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $userId
|
|
* @param string $mxRoomId
|
|
* @return JSONResponse
|
|
*/
|
|
public function removeUser(string $userId, string $mxRoomId) {
|
|
$groupId = $this->computeIdFromMxRoomId($mxRoomId);
|
|
$this->removeUserFromGroup($groupId, $userId);
|
|
return new JSONResponse((object)[]);
|
|
}
|
|
|
|
/**
|
|
* @NoAdminRequired
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param int[] $calendarIds
|
|
* @param string $mxRoomId
|
|
* @param string $displayName
|
|
* @return JSONResponse
|
|
*/
|
|
public function rename(array $calendarIds, string $mxRoomId, string $displayName) {
|
|
$groupId = $this->computeIdFromMxRoomId($mxRoomId);
|
|
$this->renameGroup($groupId, $displayName);
|
|
foreach ($calendarIds as $calendarId) {
|
|
$this->renameForGroupMembers($groupId, $calendarId, $displayName);
|
|
}
|
|
return new JSONResponse((object)[]);
|
|
}
|
|
|
|
/**
|
|
* @param int $calendarId
|
|
* @return array
|
|
*/
|
|
private function getFormatedCalendar(int $calendarId) {
|
|
$calendar = $this->caldav->getCalendarById($calendarId);
|
|
return [
|
|
"id" => (int) $calendar["id"],
|
|
"components" => $calendar[SUPPORTED_CALENDAR_COMPONENT_SET_KEY]->getValue(),
|
|
"is_personal" => $this->getUserIdFromCalendarId($calendarId) !== $this->userId
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param string $userId
|
|
* @param int $calendarId
|
|
* @return JSONResponse
|
|
*/
|
|
private function getDisplayName(string $userId, int $calendarId) {
|
|
$user = $this->userManager->get($userId);
|
|
$server = Dav::getServerInstance($this->connection, $user);
|
|
$propertyNames = [DISPLAYNAME_KEY];
|
|
$principalUri = "principals/users/$userId";
|
|
$calendars = $this->caldav->getCalendarsForUser($principalUri);
|
|
foreach ($calendars as $calendar) {
|
|
if ((int) $calendar["id"] !== $calendarId) {
|
|
continue;
|
|
}
|
|
$uri = $calendar["uri"];
|
|
$path = "calendars/$userId/$uri";
|
|
$properties = $server->getProperties($path, $propertyNames);
|
|
return $properties[DISPLAYNAME_KEY];
|
|
}
|
|
$message = "calendar $calendarId not available for user $userId, can't get displayname";
|
|
$this->logger->warning($message);
|
|
throw new GenericException($message, Http::STATUS_FORBIDDEN);
|
|
}
|
|
|
|
/**
|
|
* @param string $userId
|
|
* @param string $calendarUri
|
|
* @param string $displayName
|
|
* @return int
|
|
*/
|
|
private function create(string $userId, string $calendarUri, string $displayName) {
|
|
$server = Dav::getServerInstance();
|
|
$path = "calendars/$userId/$calendarUri";
|
|
if ($server->tree->nodeExists($path)) {
|
|
$this->logger->warning("calendar $path already exists");
|
|
return $this->getCalendarIdFromUri($userId, $calendarUri);
|
|
}
|
|
$principalUri = "principals/users/$userId";
|
|
$properties = [DISPLAYNAME_KEY => $displayName];
|
|
$calendarId = $this->caldav->createCalendar($principalUri, $calendarUri, $properties);
|
|
$this->logger->info("calendar $calendarId ($displayName) created");
|
|
return $calendarId;
|
|
}
|
|
|
|
/**
|
|
* @param int $calendarId
|
|
* @return void
|
|
*/
|
|
private function delete(int $calendarId) {
|
|
if (is_null($this->caldav->getCalendarById($calendarId))) {
|
|
$this->logger->warning("calendar $calendarId no found, can't delete it");
|
|
return;
|
|
}
|
|
list($major,) = Util::getVersion();
|
|
if ($major > 21) {
|
|
$this->caldav->deleteCalendar($calendarId, true);
|
|
} else {
|
|
$this->caldav->deleteCalendar($calendarId);
|
|
}
|
|
$this->logger->info("calendar $calendarId deleted");
|
|
}
|
|
|
|
/**
|
|
* @param int $calendarId
|
|
* @param array $add
|
|
* @param array $remove
|
|
* @return void
|
|
* @throws GenericException
|
|
* @throws Sabre\DAV\Exception\NotFound
|
|
*/
|
|
private function updateShares(int $calendarId, array $add = [], array $remove = []) {
|
|
$server = Dav::getServerInstance();
|
|
$userId = $this->getUserIdFromCalendarId($calendarId);
|
|
if (is_null($userId)) {
|
|
if ($add) {
|
|
$exception = new GenericException("no calendar $calendarId to add a share to");
|
|
$this->logger->error($exception->getMessage(), ["exception" => $exception]);
|
|
throw $exception;
|
|
}
|
|
$this->logger->warning("no calendar $calendarId to remove a share to");
|
|
return;
|
|
}
|
|
$calendar = $this->caldav->getCalendarById($calendarId);
|
|
$uri = $calendar["uri"];
|
|
$path = "calendars/$userId/$uri";
|
|
$node = $server->tree->getNodeForPath($path);
|
|
$node->updateShares($add, $remove);
|
|
$this->logger->info("share(s) for calendar $calendarId updated (add: {add} | remove: {remove})", [
|
|
"add" => json_encode($add, JSON_UNESCAPED_SLASHES), "remove" => json_encode($remove, JSON_UNESCAPED_SLASHES)
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
* @param string $displayName
|
|
* @return void
|
|
* @throws GenericException
|
|
*/
|
|
private function createGroup(string $groupId, string $displayName) {
|
|
if ($this->groupManager->groupExists($groupId)) {
|
|
$this->logger->warning("group $groupId already exists");
|
|
return;
|
|
}
|
|
$group = $this->groupManager->createGroup($groupId);
|
|
if (!$group instanceof IGroup) {
|
|
$exception = new GenericException("can't create $groupId");
|
|
$this->logger->error($exception->getMessage(), ["exception" => $exception]);
|
|
throw $exception;
|
|
}
|
|
$group->setDisplayName($displayName);
|
|
$this->logger->info("group $groupId ($displayName) created");
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
* @return void
|
|
*/
|
|
private function deleteGroup(string $groupId) {
|
|
$group = $this->groupManager->get($groupId);
|
|
if (is_null($group)) {
|
|
$this->logger->warning("group $groupId no found, can't delete it");
|
|
return;
|
|
}
|
|
if (!$group->delete()) {
|
|
$exception = new GenericException("can't delete group $groupId");
|
|
$this->logger->error($exception->getMessage(), ["exception" => $exception]);
|
|
throw $exception;
|
|
}
|
|
$this->logger->info("group $groupId deleted");
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
* @param string $displayName
|
|
* @return void
|
|
*/
|
|
private function renameGroup(string $groupId, string $displayName) {
|
|
$group = $this->groupManager->get($groupId);
|
|
if (is_null($group)) {
|
|
$this->logger->warning("group $groupId no found, can't rename it");
|
|
return;
|
|
}
|
|
$group->setDisplayName($displayName);
|
|
$this->logger->info("group $groupId renamed to $displayName");
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
* @param string[] $userIds
|
|
* @param string $ownerId
|
|
* @return void
|
|
*/
|
|
private function addUsersToGroup(string $groupId, array $userIds, string $ownerId) {
|
|
$group = $this->groupManager->get($groupId);
|
|
if (is_null($group)) {
|
|
$this->logger->warning("group $groupId no found, can't add users");
|
|
return;
|
|
}
|
|
foreach ($userIds as $userId) {
|
|
# never add calendar owner other than the service account to group
|
|
if ($userId === $ownerId and $ownerId !== $this->userId) {
|
|
$this->logger->info("user $userId is the calendar owner, addition to group $groupId skipped");
|
|
continue;
|
|
}
|
|
$user = $this->userManager->get($userId);
|
|
if (is_null($user)) {
|
|
$this->logger->warning("user $userId no found, can't add it to group $groupId");
|
|
continue;
|
|
}
|
|
$group->addUser($user);
|
|
$this->logger->info("user $userId added to group $groupId");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
* @param string $userId
|
|
* @return void
|
|
*/
|
|
private function removeUserFromGroup(string $groupId, string $userId) {
|
|
$group = $this->groupManager->get($groupId);
|
|
if (is_null($group)) {
|
|
$this->logger->warning("group $groupId no found, can't remove user");
|
|
return;
|
|
}
|
|
$user = $this->userManager->get($userId);
|
|
if (is_null($user)) {
|
|
$this->logger->warning("user $userId no found, can't remove it from group $groupId");
|
|
return;
|
|
}
|
|
$group->removeUser($user);
|
|
$this->logger->info("user $userId remove from group $groupId");
|
|
}
|
|
|
|
/**
|
|
* @param string $groupId
|
|
* @param int $calendarId
|
|
* @param string $displayName
|
|
* @return void
|
|
*/
|
|
private function renameForGroupMembers(string $groupId, int $calendarId, string $displayName) {
|
|
$group = $this->groupManager->get($groupId);
|
|
if (is_null($group)) {
|
|
$this->logger->warning("group $groupId no found, can't rename calendar $calendarId for its members");
|
|
return;
|
|
}
|
|
$users = $group->getUsers();
|
|
foreach ($users as $user) {
|
|
$userId = $user->getUID();
|
|
try {
|
|
$this->renameForUser($userId, $calendarId, $displayName);
|
|
} catch (NotFound $e) {
|
|
$this->logger->warning($e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $userId
|
|
* @param int $calendarId
|
|
* @param string $displayName
|
|
* @return void
|
|
* @throws GenericException
|
|
*/
|
|
private function renameForUser(string $userId, int $calendarId, string $displayName) {
|
|
$user = $this->userManager->get($userId);
|
|
if (is_null($user)) {
|
|
$this->logger->warning("user $userId no found, can't rename calendar $calendarId for them");
|
|
return;
|
|
}
|
|
$server = Dav::getServerInstance($this->connection, $user);
|
|
$calendar = $this->caldav->getCalendarById($calendarId);
|
|
if (is_null($calendar)) {
|
|
$this->logger->warning("calendar $calendarId no found, can't rename it for user $userId");
|
|
return;
|
|
}
|
|
list(, $ownerId) = Uri\split($calendar["principaluri"]);
|
|
# never rename a personal calendar other than those of the service account
|
|
if ($ownerId === $userId and $ownerId !== $this->userId) {
|
|
return;
|
|
}
|
|
$calendarUri = $ownerId === $userId ? $calendar["uri"] : $this->computeUriForSharedCalendar($calendar["uri"], $ownerId);
|
|
$path = "calendars/$userId/$calendarUri";
|
|
$properties = [DISPLAYNAME_KEY => $displayName];
|
|
$result = $server->updateProperties($path, $properties);
|
|
if (!in_array($result[DISPLAYNAME_KEY], [200, 204])) {
|
|
$exception = new GenericException("can't rename calendar with URI $calendarUri for user $userId");
|
|
$this->logger->error($exception->getMessage(), ["exception" => $exception]);
|
|
throw $exception;
|
|
}
|
|
$this->logger->info("calendar $calendarId renamed to $displayName for user $userId");
|
|
}
|
|
|
|
/**
|
|
* @param int $calendarId
|
|
* @return string|null
|
|
*/
|
|
private function getUserIdFromCalendarId(int $calendarId) {
|
|
$calendar = $this->caldav->getCalendarById($calendarId);
|
|
if (is_null($calendar)) {
|
|
$this->logger->warning("calendar $calendarId no found, can't parse user ID");
|
|
return;
|
|
}
|
|
$principalUri = $calendar["principaluri"];
|
|
list(, $userId) = Uri\split($principalUri);
|
|
return $userId;
|
|
}
|
|
|
|
/**
|
|
* @param string $userId
|
|
* @param string $calendarUri
|
|
* @return int|null
|
|
*/
|
|
private function getCalendarIdFromUri(string $userId, string $calendarUri) {
|
|
$principalUri = "principals/users/$userId";
|
|
$calendar = $this->caldav->getCalendarByUri($principalUri, $calendarUri);
|
|
if (is_null($calendar)) {
|
|
$this->logger->warning("calendar $calendarUri owned by $userId no found, can't get ID");
|
|
return;
|
|
}
|
|
return (int) $calendar["id"];
|
|
}
|
|
|
|
/**
|
|
* @param string $calendarUri
|
|
* @param string $ownerId
|
|
* @return string
|
|
*/
|
|
private function computeUriForSharedCalendar(string $calendarUri, string $ownerId) {
|
|
return $calendarUri . "_shared_by_" . $ownerId;
|
|
}
|
|
|
|
/**
|
|
* @param string $mxRoomId
|
|
* @return string
|
|
*/
|
|
private function computeIdFromMxRoomId(string $mxRoomId) {
|
|
return hash("sha256", $mxRoomId);
|
|
}
|
|
}
|
|
|