Skip to content

Commit

Permalink
Adding dynamic share providers.
Browse files Browse the repository at this point in the history
Signed-off-by: Michiel de Jong <michiel@unhosted.org>
  • Loading branch information
ylebre authored and michielbdejong committed Apr 19, 2022
1 parent 13dbad0 commit f927a1c
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 25 deletions.
105 changes: 80 additions & 25 deletions apps/files_sharing/lib/Controller/ShareAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class ShareAPIController extends OCSController {
/** @var IPreview */
private $previewManager;

private $dynamicShareTypes;

/**
* Share20OCS constructor.
*
Expand Down Expand Up @@ -161,6 +163,33 @@ public function __construct(
$this->serverContainer = $serverContainer;
$this->userStatusManager = $userStatusManager;
$this->previewManager = $previewManager;
$this->dynamicShareTypes = [];
// FIXME: Move this line into the sciencemesh app:
$this->registerHelper(IShare::TYPE_SCIENCEMESH, 'sciencemesh', '\OCA\ScienceMesh\ShareProvider\ShareAPIHelper');
}

public function registerHelper($shareType, $identifier, $helperClassName) {
$this->dynamicShareTypes[$shareType] = [
"identifier" => $identifier,
"helperClass" => $helperClassName
];
}

private function haveHelperFor($shareType) {
return isset($this->dynamicShareTypes[$shareType]);
}

private function getIdentifierFor($shareType) {
return $this->dynamicShareTypes[$shareType]["identifier"];
}

private function getHelperFor($shareType) {
$identifier = $this->getIdentifierFor($shareType);
if (!$this->appManager->isEnabledForUser($identifier)) {
throw new QueryException();
}

return $this->serverContainer->get($this->dynamicShareTypes[$shareType]["helperClass"]);
}

/**
Expand Down Expand Up @@ -318,6 +347,14 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array
$result = array_merge($result, $this->getDeckShareHelper()->formatShare($share));
} catch (QueryException $e) {
}
} elseif ($this->haveHelperFor($share->getShareType())) {
$result['share_with'] = $share->getSharedWith();
$result['share_with_displayname'] = '';

try {
$result = array_merge($result, $this->getHelperFor($share->getShareType())->formatShare($share));
} catch (QueryException $e) {
}
}


Expand Down Expand Up @@ -663,6 +700,12 @@ public function createShare(
} catch (QueryException $e) {
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$node->getPath()]));
}
} elseif ($this->haveHelperFor($shareType)) {
try {
$this->getHelperFor($shareType)->createShare($share, $shareWith, $permissions, $expireDate);
} catch (QueryException $e) {
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support this type of shares', [$node->getPath()]));
}
} else {
throw new OCSBadRequestException($this->l->t('Unknown share type'));
}
Expand Down Expand Up @@ -1568,6 +1611,17 @@ private function getShareById(string $id): IShare {
// Do nothing, just try the other share type
}

foreach ($this->dynamicShareTypes as $shareType => $details) {
try {
if ($this->shareManager->shareProviderExists($shareType)) {
$share = $this->shareManager->getShareById($details["identifier"] . ":" . $id, $this->currentUser);
return $share;
}
} catch (ShareNotFound $e) {
// Do nothing, just try the other share type
}
}

if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
throw new ShareNotFound();
}
Expand Down Expand Up @@ -1631,6 +1685,20 @@ private function getDeckShareHelper() {
return $this->serverContainer->get('\OCA\Deck\Sharing\ShareAPIHelper');
}

private function getProvidersExceptOutgoing() {
// FIXME: load this list dynamically
return [
IShare::TYPE_USER,
IShare::TYPE_GROUP,
IShare::TYPE_LINK,
IShare::TYPE_EMAIL,
IShare::TYPE_CIRCLE,
IShare::TYPE_ROOM,
IShare::TYPE_DECK,
IShare::TYPE_SCIENCEMESH
];
}

/**
* @param string $viewer
* @param Node $node
Expand All @@ -1639,15 +1707,7 @@ private function getDeckShareHelper() {
* @return IShare[]
*/
private function getSharesFromNode(string $viewer, $node, bool $reShares): array {
$providers = [
IShare::TYPE_USER,
IShare::TYPE_GROUP,
IShare::TYPE_LINK,
IShare::TYPE_EMAIL,
IShare::TYPE_CIRCLE,
IShare::TYPE_ROOM,
IShare::TYPE_DECK
];
$providers = $this->getProviders(false);

// Should we assume that the (currentUser) viewer is the owner of the node !?
$shares = [];
Expand Down Expand Up @@ -1785,21 +1845,16 @@ private function shareProviderResharingRights(string $userId, IShare $share, $no
* @return IShare[]
*/
private function getAllShares(?Node $path = null, bool $reshares = false) {
// Get all shares
$userShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_USER, $path, $reshares, -1, 0);
$groupShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_GROUP, $path, $reshares, -1, 0);
$linkShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_LINK, $path, $reshares, -1, 0);

// EMAIL SHARES
$mailShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_EMAIL, $path, $reshares, -1, 0);

// CIRCLE SHARES
$circleShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_CIRCLE, $path, $reshares, -1, 0);

// TALK SHARES
$roomShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_ROOM, $path, $reshares, -1, 0);

$deckShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_DECK, $path, $reshares, -1, 0);
$providers = $this->getProvidersExceptOutgoing();
$shares = [];
foreach ($providers as $provider) {
if (!$this->shareManager->shareProviderExists($provider)) {
continue;
}
$providerShares =
$this->shareManager->getSharesBy($this->currentUser, $provider, $path, $reshares, -1, 0);
$shares = array_merge($shares, $providerShares);
}

// FEDERATION
if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
Expand All @@ -1813,7 +1868,7 @@ private function getAllShares(?Node $path = null, bool $reshares = false) {
$federatedGroupShares = [];
}

return array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares, $deckShares, $federatedShares, $federatedGroupShares);
return array_merge($shares, $federatedShares, $federatedGroupShares);
}


Expand Down
1 change: 1 addition & 0 deletions lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ protected function generalCreateChecks(IShare $share) {
}
} elseif ($share->getShareType() === IShare::TYPE_ROOM) {
} elseif ($share->getShareType() === IShare::TYPE_DECK) {
} else if ($this->factory->getProviderForType($share->getShareType())) {
} else {
// We cannot handle other types yet
throw new \InvalidArgumentException('unknown share type');
Expand Down
14 changes: 14 additions & 0 deletions lib/private/Share20/ProviderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,20 @@ public function getProviderForType($shareType) {
$provider = $this->getRoomShareProvider();
} elseif ($shareType === IShare::TYPE_DECK) {
$provider = $this->getProvider('deck');
} else {
// try to autodetect in the registered providers;
foreach ($this->registeredShareProviders as $shareProvider) {
/** @var IShareProvider $instance */
$instance = $this->serverContainer->get($shareProvider);

// not all instances will have the isShareTypeSupported function;
if (method_exists($instance, "isShareTypeSupported")) {
if ($instance->isShareTypeSupported($shareType)) {
$provider = $this->getProvider($instance->identifier());
break;
}
}
}
}


Expand Down
5 changes: 5 additions & 0 deletions lib/public/Share/IShare.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ interface IShare {
*/
public const TYPE_DECK_USER = 13;

/**
* @since ?
*/
public const TYPE_SCIENCEMESH = 1000;

/**
* @since 18.0.0
*/
Expand Down

0 comments on commit f927a1c

Please sign in to comment.