Implement expiration date for federated shares

Add expiration date field in UI.
Save expiration date when creating or updating federated share.
Read expiration date from DB in federated share provider.
Applies to both federated user and group shares.

Signed-off-by: Vincent Petry <vincent@nextcloud.com>
This commit is contained in:
Vincent Petry 2021-01-25 15:26:16 +01:00
parent 8ef920fdf9
commit 8680bafc5c
No known key found for this signature in database
GPG Key ID: E055D6A4D513575C
4 changed files with 51 additions and 18 deletions

View File

@ -173,6 +173,7 @@ class FederatedShareProvider implements IShareProvider {
$permissions = $share->getPermissions();
$sharedBy = $share->getSharedBy();
$shareType = $share->getShareType();
$expirationDate = $share->getExpirationDate();
if ($shareType === IShare::TYPE_REMOTE_GROUP &&
!$this->isOutgoingServer2serverGroupShareEnabled()
@ -219,7 +220,7 @@ class FederatedShareProvider implements IShareProvider {
if ($remoteShare) {
try {
$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType);
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType, $expirationDate);
$share->setId($shareId);
[$token, $remoteId] = $this->askOwnerToReShare($shareWith, $share, $shareId);
// remote share was create successfully if we get a valid token as return
@ -264,7 +265,8 @@ class FederatedShareProvider implements IShareProvider {
$share->getShareOwner(),
$share->getPermissions(),
$token,
$share->getShareType()
$share->getShareType(),
$share->getExpirationDate()
);
$failure = false;
@ -370,9 +372,10 @@ class FederatedShareProvider implements IShareProvider {
* @param int $permissions
* @param string $token
* @param int $shareType
* @param \DateTime $expirationDate
* @return int
*/
private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $shareType) {
private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $shareType, $expirationDate) {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert('share')
->setValue('share_type', $qb->createNamedParameter($shareType))
@ -383,6 +386,7 @@ class FederatedShareProvider implements IShareProvider {
->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
->setValue('permissions', $qb->createNamedParameter($permissions))
->setValue('expiration', $qb->createNamedParameter($expirationDate, IQueryBuilder::PARAM_DATE))
->setValue('token', $qb->createNamedParameter($token))
->setValue('stime', $qb->createNamedParameter(time()));
@ -412,6 +416,7 @@ class FederatedShareProvider implements IShareProvider {
->set('permissions', $qb->createNamedParameter($share->getPermissions()))
->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
->execute();
// send the updated permission to the owner/initiator, if they are not the same
@ -910,6 +915,11 @@ class FederatedShareProvider implements IShareProvider {
$share->setProviderId($this->identifier());
if ($data['expiration'] !== null) {
$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
$share->setExpirationDate($expiration);
}
return $share;
}

View File

@ -587,15 +587,39 @@ class ShareAPIController extends OCSController {
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
}
if ($shareWith === null) {
throw new OCSNotFoundException($this->l->t('Please specify a valid federated user id'));
}
$share->setSharedWith($shareWith);
$share->setPermissions($permissions);
if ($expireDate !== '') {
try {
$expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate);
} catch (\Exception $e) {
throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
}
}
} elseif ($shareType === IShare::TYPE_REMOTE_GROUP) {
if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
}
if ($shareWith === null) {
throw new OCSNotFoundException($this->l->t('Please specify a valid federated group id'));
}
$share->setSharedWith($shareWith);
$share->setPermissions($permissions);
if ($expireDate !== '') {
try {
$expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate);
} catch (\Exception $e) {
throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
}
}
} elseif ($shareType === IShare::TYPE_CIRCLE) {
if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));

View File

@ -84,16 +84,14 @@
</ActionCheckbox>
<!-- expiration date -->
<ActionCheckbox
v-if="canHaveExpirationDate"
:checked.sync="hasExpirationDate"
<ActionCheckbox :checked.sync="hasExpirationDate"
:disabled="config.isDefaultInternalExpireDateEnforced || saving"
@uncheck="onExpirationDisable">
{{ config.isDefaultInternalExpireDateEnforced
? t('files_sharing', 'Expiration date enforced')
: t('files_sharing', 'Set expiration date') }}
</ActionCheckbox>
<ActionInput v-if="canHaveExpirationDate && hasExpirationDate"
<ActionInput v-if="hasExpirationDate"
ref="expireDate"
v-tooltip.auto="{
content: errors.expireDate,
@ -224,16 +222,8 @@ export default {
},
canHaveNote() {
return !this.isRemoteShare
},
canHaveExpirationDate() {
return !this.isRemoteShare
},
isRemoteShare() {
return this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE
|| this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP
return this.share.type !== this.SHARE_TYPES.SHARE_TYPE_REMOTE
&& this.share.type !== this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP
},
/**

View File

@ -751,6 +751,9 @@ class Manager implements IManager {
// Verify the expiration date
$share = $this->validateExpirationDateInternal($share);
} elseif ($share->getShareType() === IShare::TYPE_REMOTE || $share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
//Verify the expiration date
$share = $this->validateExpirationDateInternal($share);
} elseif ($share->getShareType() === IShare::TYPE_LINK
|| $share->getShareType() === IShare::TYPE_EMAIL) {
$this->linkCreateChecks($share);
@ -999,7 +1002,7 @@ class Manager implements IManager {
if (empty($plainTextPassword) && $share->getSendPasswordByTalk()) {
throw new \InvalidArgumentException('Cant enable sending the password by Talk with an empty password');
}
/**
* If we're in a mail share, we need to force a password change
* as either the user is not aware of the password or is already (received by mail)
@ -1019,6 +1022,12 @@ class Manager implements IManager {
$this->validateExpirationDateLink($share);
$expirationDateUpdated = true;
}
} elseif ($share->getShareType() === IShare::TYPE_REMOTE || $share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
//Verify the expiration date
$this->validateExpirationDateInternal($share);
$expirationDateUpdated = true;
}
}
$this->pathCreateChecks($share->getNode());