207 lines
5.6 KiB
PHP
207 lines
5.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2017 F7cloud GmbH and F7cloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Activity\Controller;
|
|
|
|
use OCA\Activity\Extension\Files;
|
|
use OCP\Activity\IManager as IActivityManager;
|
|
use OCP\App\IAppManager;
|
|
use OCP\AppFramework\Http;
|
|
use OCP\AppFramework\Http\DataResponse;
|
|
use OCP\AppFramework\OCSController;
|
|
use OCP\Files\InvalidPathException;
|
|
use OCP\Files\IRootFolder;
|
|
use OCP\Files\NotFoundException;
|
|
use OCP\IDBConnection;
|
|
use OCP\IRequest;
|
|
use OCP\IUser;
|
|
use OCP\IUserManager;
|
|
|
|
class RemoteActivityController extends OCSController {
|
|
public function __construct(
|
|
$appName,
|
|
IRequest $request,
|
|
protected IDBConnection $db,
|
|
protected IUserManager $userManager,
|
|
protected IAppManager $appManager,
|
|
protected IRootFolder $rootFolder,
|
|
protected IActivityManager $activityManager,
|
|
) {
|
|
parent::__construct($appName, $request);
|
|
}
|
|
|
|
/**
|
|
* @PublicPage
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $token
|
|
* @param string[] $to
|
|
* @param string[] $actor
|
|
* @param string $type
|
|
* @param string $updated
|
|
* @param string[] $object
|
|
* @param string[] $target
|
|
* @param string[] $origin
|
|
* @return DataResponse
|
|
*/
|
|
public function receiveActivity($token, array $to, array $actor, $type, $updated, array $object = [], array $target = [], array $origin = []) {
|
|
$date = \DateTime::createFromFormat(\DateTime::W3C, $updated);
|
|
if ($date === false) {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
$time = $date->getTimestamp();
|
|
|
|
if (!isset($to['type'], $to['name']) || $to['type'] !== 'Person') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
$user = $this->userManager->get($to['name']);
|
|
if (!$user instanceof IUser) {
|
|
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
|
}
|
|
|
|
if (!isset($actor['type'], $actor['name']) || $actor['type'] !== 'Person') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
if ($user->getCloudId() === $actor['name']) {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
if (!$this->appManager->isInstalled('federatedfilesharing')) {
|
|
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
|
}
|
|
|
|
$query = $this->db->getQueryBuilder();
|
|
$query->select('*')
|
|
->from('share_external')
|
|
->where($query->expr()->eq('share_token', $query->createNamedParameter($token)))
|
|
->andWhere($query->expr()->eq('user', $query->createNamedParameter($user->getUID())));
|
|
|
|
$result = $query->executeQuery();
|
|
$share = $result->fetch();
|
|
$result->closeCursor();
|
|
|
|
if (!is_array($share) || strpos($share['mountpoint'], '{{TemporaryMountPointName#') === 0) {
|
|
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
|
}
|
|
|
|
$internalType = $this->translateType($type);
|
|
if ($internalType === '') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
$path2 = null;
|
|
if ($type === 'Move') {
|
|
if (!isset($target['type'], $target['name']) || $target['type'] !== 'Document') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
if (!isset($origin['type'], $origin['name']) || $origin['type'] !== 'Document') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
$path = $share['mountpoint'] . $target['name'];
|
|
$path2 = $share['mountpoint'] . $origin['name'];
|
|
} else {
|
|
if (!isset($object['type'], $object['name']) || $object['type'] !== 'Document') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
$path = $share['mountpoint'] . $object['name'];
|
|
}
|
|
|
|
$subject = $this->getSubject($type, $path, $path2);
|
|
if ($subject === '') {
|
|
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
|
try {
|
|
$node = $userFolder->get($path);
|
|
$fileId = $node->getId();
|
|
} catch (NotFoundException $e) {
|
|
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
|
} catch (InvalidPathException $e) {
|
|
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
|
}
|
|
|
|
if ($path2 !== null) {
|
|
$secondPath = [$fileId => $path2];
|
|
if ($subject === 'moved_by') {
|
|
try {
|
|
$parent = $node->getParent();
|
|
$secondPath = [$parent->getId() => dirname($path2)];
|
|
} catch (NotFoundException $e) {
|
|
} catch (InvalidPathException $e) {
|
|
}
|
|
}
|
|
$subjectParams = [$secondPath, $actor['name'], [$fileId => $path]];
|
|
} else {
|
|
$subjectParams = [[$fileId => $path], $actor['name']];
|
|
}
|
|
|
|
$event = $this->activityManager->generateEvent();
|
|
try {
|
|
$event->setAffectedUser($user->getUID())
|
|
->setApp('files')
|
|
->setType($internalType)
|
|
->setAuthor($actor['name'])
|
|
->setObject('files', $fileId, $path)
|
|
->setSubject($subject, $subjectParams)
|
|
->setTimestamp($time);
|
|
$this->activityManager->publish($event);
|
|
} catch (\InvalidArgumentException $e) {
|
|
return new DataResponse(['activity'], Http::STATUS_BAD_REQUEST);
|
|
} catch (\BadMethodCallException $e) {
|
|
return new DataResponse(['sending'], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
|
|
return new DataResponse();
|
|
}
|
|
|
|
/**
|
|
* @param null|string $path2
|
|
*/
|
|
protected function getSubject(string $type, string $path, ?string $path2) {
|
|
switch ($type) {
|
|
case 'Create':
|
|
return 'created_by';
|
|
case 'Move':
|
|
if ($path2 === null) {
|
|
return '';
|
|
}
|
|
if (basename($path) === basename($path2)) {
|
|
return 'moved_by';
|
|
}
|
|
return 'renamed_by';
|
|
case 'Update':
|
|
return 'changed_by';
|
|
case 'Delete':
|
|
return 'deleted_by';
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* @param string $type
|
|
* @return string
|
|
*/
|
|
protected function translateType($type) {
|
|
switch ($type) {
|
|
case 'Create':
|
|
return Files::TYPE_SHARE_CREATED;
|
|
case 'Move':
|
|
case 'Update':
|
|
return Files::TYPE_FILE_CHANGED;
|
|
case 'Delete':
|
|
return Files::TYPE_SHARE_DELETED;
|
|
}
|
|
return '';
|
|
}
|
|
}
|