Browse Source

Implement creating room shares

In order to keep the share manager as isolated as possible from room
share specifics the validity checks are done in RoomShareManager.

Getting room shares by path was also implemented, as it is needed to
prevent creating again a share for the same path and room.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
pull/1050/head
Daniel Calviño Sánchez 7 years ago
committed by Joas Schilling
parent
commit
1634f2c61e
No known key found for this signature in database GPG Key ID: 7076EA9751AACDDA
  1. 211
      lib/Share/RoomShareProvider.php

211
lib/Share/RoomShareProvider.php

@ -24,10 +24,18 @@ declare(strict_types=1);
namespace OCA\Spreed\Share;
use OCA\Spreed\Exceptions\ParticipantNotFoundException;
use OCA\Spreed\Exceptions\RoomNotFoundException;
use OCA\Spreed\Manager;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IUserManager;
use OCP\Share\Exceptions\GenericShareException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager as IShareManager;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
@ -43,6 +51,50 @@ use OCP\Share\IShareProvider;
*/
class RoomShareProvider implements IShareProvider {
/** @var IDBConnection */
private $dbConnection;
/** @var IUserManager */
private $userManager;
/** @var IShareManager */
private $shareManager;
/** @var IRootFolder */
private $rootFolder;
/** @var IL10N */
private $l;
/** @var Manager */
private $manager;
/**
* RoomShareProvider constructor.
*
* @param IDBConnection $connection
* @param IUserManager $userManager
* @param IShareManager $shareManager
* @param IRootFolder $rootFolder
* @param IL10N $l10n
* @param Manager $manager
*/
public function __construct(
IDBConnection $connection,
IUserManager $userManager,
IShareManager $shareManager,
IRootFolder $rootFolder,
IL10N $l,
Manager $manager
) {
$this->dbConnection = $connection;
$this->userManager = $userManager;
$this->shareManager = $shareManager;
$this->rootFolder = $rootFolder;
$this->l = $l;
$this->manager = $manager;
}
/**
* Return the identifier of this provider.
*
@ -57,9 +109,150 @@ class RoomShareProvider implements IShareProvider {
*
* @param IShare $share
* @return IShare The share object
* @throws GenericShareException
*/
public function create(IShare $share) {
throw new \Exception("Not implemented");
try {
$room = $this->manager->getRoomByToken($share->getSharedWith());
} catch (RoomNotFoundException $e) {
throw new GenericShareException("Room not found", $this->l->t('Conversation not found'), 404);
}
try {
$room->getParticipant($share->getSharedBy());
} catch (ParticipantNotFoundException $e) {
// If the sharer is not a participant of the room even if the room
// exists the error is still "Room not found".
throw new GenericShareException("Room not found", $this->l->t('Conversation not found'), 404);
}
$existingShares = $this->getSharesByPath($share->getNode());
foreach ($existingShares as $existingShare) {
if ($existingShare->getSharedWith() === $share->getSharedWith()) {
throw new GenericShareException("Already shared", $this->l->t('Path is already shared with this room'), 403);
}
}
$shareId = $this->addShareToDB(
$share->getSharedWith(),
$share->getSharedBy(),
$share->getShareOwner(),
$share->getNodeType(),
$share->getNodeId(),
$share->getTarget(),
$share->getPermissions(),
$share->getExpirationDate()
);
$data = $this->getRawShare($shareId);
return $this->createShareObject($data);
}
/**
* Add share to the database and return the ID
*
* @param string $shareWith
* @param string $sharedBy
* @param string $shareOwner
* @param string $itemType
* @param int $itemSource
* @param string $target
* @param int $permissions
* @param \DateTime|null $expirationDate
* @return int
*/
private function addShareToDB(
string $shareWith,
string $sharedBy,
string $shareOwner,
string $itemType,
int $itemSource,
string $target,
int $permissions,
\DateTime $expirationDate = null
): int {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert('share')
->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))
->setValue('share_with', $qb->createNamedParameter($shareWith))
->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
->setValue('uid_owner', $qb->createNamedParameter($shareOwner))
->setValue('item_type', $qb->createNamedParameter($itemType))
->setValue('item_source', $qb->createNamedParameter($itemSource))
->setValue('file_source', $qb->createNamedParameter($itemSource))
->setValue('file_target', $qb->createNamedParameter($target))
->setValue('permissions', $qb->createNamedParameter($permissions))
->setValue('stime', $qb->createNamedParameter(time()));
if ($expirationDate !== null) {
$qb->setValue('expiration', $qb->createNamedParameter($expirationDate, 'datetime'));
}
$qb->execute();
$id = $qb->getLastInsertId();
return (int)$id;
}
/**
* Get database row of the given share
*
* @param int $id
* @return array
* @throws ShareNotFound
*/
private function getRawShare(int $id) {
$qb = $this->dbConnection->getQueryBuilder();
$qb->select('*')
->from('share')
->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new ShareNotFound();
}
return $data;
}
/**
* Create a share object from a database row
*
* @param array $data
* @return IShare
*/
private function createShareObject($data) {
$share = $this->shareManager->newShare();
$share->setId((int)$data['id'])
->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions'])
->setTarget($data['file_target']);
$shareTime = new \DateTime();
$shareTime->setTimestamp((int)$data['stime']);
$share->setShareTime($shareTime);
$share->setSharedWith($data['share_with']);
$share->setSharedBy($data['uid_initiator']);
$share->setShareOwner($data['uid_owner']);
if ($data['expiration'] !== null) {
$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
if ($expiration !== false) {
$share->setExpirationDate($expiration);
}
}
$share->setNodeId((int)$data['file_source']);
$share->setNodeType($data['item_type']);
$share->setProviderId($this->identifier());
return $share;
}
/**
@ -167,7 +360,21 @@ class RoomShareProvider implements IShareProvider {
* @return IShare[]
*/
public function getSharesByPath(Node $path) {
throw new \Exception("Not implemented");
$qb = $this->dbConnection->getQueryBuilder();
$cursor = $qb->select('*')
->from('share')
->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM)))
->execute();
$shares = [];
while ($data = $cursor->fetch()) {
$shares[] = $this->createShareObject($data);
}
$cursor->closeCursor();
return $shares;
}
/**

Loading…
Cancel
Save