Skip to content

Commit

Permalink
Separate settings for remote share expiration
Browse files Browse the repository at this point in the history
Added separate settings for default and enforced expiration date for
remote shares.

Signed-off-by: Vincent Petry <vincent@nextcloud.com>
  • Loading branch information
PVince81 committed Mar 26, 2021
1 parent eafedaa commit 553afe1
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 86 deletions.
6 changes: 3 additions & 3 deletions apps/files_sharing/js/dist/files_sharing_tab.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/files_sharing/js/dist/files_sharing_tab.js.map

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions apps/files_sharing/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ public function getCapabilities() {
$public['expire_date_internal']['enforced'] = $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
}

$public['expire_date_remote'] = [];
$public['expire_date_remote']['enabled'] = $this->config->getAppValue('core', 'shareapi_default_remote_expire_date', 'no') === 'yes';
if ($public['expire_date_remote']['enabled']) {
$public['expire_date_remote']['days'] = $this->config->getAppValue('core', 'shareapi_remote_expire_after_n_days', '7');
$public['expire_date_remote']['enforced'] = $this->config->getAppValue('core', 'shareapi_enforce_remote_expire_date', 'no') === 'yes';
}

$public['send_mail'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no') === 'yes';
$public['upload'] = $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
$public['upload_files_drop'] = $public['upload'];
Expand Down
17 changes: 13 additions & 4 deletions apps/files_sharing/src/components/SharingEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,12 @@ export default {
},
canHaveNote() {
return this.share.type !== this.SHARE_TYPES.SHARE_TYPE_REMOTE
&& this.share.type !== this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP
return !this.isRemote
},
isRemote() {
return this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE
|| this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP
},
/**
Expand Down Expand Up @@ -348,8 +352,13 @@ export default {
},
dateMaxEnforced() {
return this.config.isDefaultInternalExpireDateEnforced
&& moment().add(1 + this.config.defaultInternalExpireDate, 'days')
if (!this.isRemote) {
return this.config.isDefaultInternalExpireDateEnforced
&& moment().add(1 + this.config.defaultInternalExpireDate, 'days')
} else {
return this.config.isDefaultRemoteExpireDateEnforced
&& moment().add(1 + this.config.defaultRemoteExpireDate, 'days')
}
},
/**
Expand Down
40 changes: 40 additions & 0 deletions apps/files_sharing/src/services/ConfigService.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ export default class Config {
return expireDateString
}

/**
* Get the default remote expiration date as string
*
* @returns {string}
* @readonly
* @memberof Config
*/
get defaultRemoteExpirationDateString() {
let expireDateString = ''
if (this.isDefaultRemoteExpireDateEnabled) {
const date = window.moment.utc()
const expireAfterDays = this.defaultRemoteExpireDate
date.add(expireAfterDays, 'days')
expireDateString = date.format('YYYY-MM-DD')
}
return expireDateString
}

/**
* Are link shares password-enforced ?
*
Expand Down Expand Up @@ -148,6 +166,17 @@ export default class Config {
return OC.appConfig.core.defaultInternalExpireDateEnforced === true
}

/**
* Is remote shares expiration enforced ?
*
* @returns {boolean}
* @readonly
* @memberof Config
*/
get isDefaultRemoteExpireDateEnforced() {
return OC.appConfig.core.defaultRemoteExpireDateEnforced === true
}

/**
* Is there a default expiration date for new internal shares ?
*
Expand Down Expand Up @@ -207,6 +236,17 @@ export default class Config {
return OC.appConfig.core.defaultInternalExpireDate
}

/**
* Get the default days to remote shares expiration
*
* @returns {int}
* @readonly
* @memberof Config
*/
get defaultRemoteExpireDate() {
return OC.appConfig.core.defaultRemoteExpireDate
}

/**
* Is resharing allowed ?
*
Expand Down
4 changes: 4 additions & 0 deletions apps/settings/js/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ window.addEventListener('DOMContentLoaded', function(){
$("#setDefaultInternalExpireDate").toggleClass('hidden', !this.checked);
});

$('#shareapiDefaultRemoteExpireDate').change(function() {
$("#setDefaultRemoteExpireDate").toggleClass('hidden', !this.checked);
});

$('#publicShareDisclaimer').change(function() {
$("#publicShareDisclaimerText").toggleClass('hidden', !this.checked);
if(!this.checked) {
Expand Down
3 changes: 3 additions & 0 deletions apps/settings/lib/Settings/Admin/Sharing.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public function getForm() {
'shareDefaultInternalExpireDateSet' => $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no'),
'shareInternalExpireAfterNDays' => $this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7'),
'shareInternalEnforceExpireDate' => $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no'),
'shareDefaultRemoteExpireDateSet' => $this->config->getAppValue('core', 'shareapi_default_remote_expire_date', 'no'),
'shareRemoteExpireAfterNDays' => $this->config->getAppValue('core', 'shareapi_remote_expire_after_n_days', '7'),
'shareRemoteEnforceExpireDate' => $this->config->getAppValue('core', 'shareapi_enforce_remote_expire_date', 'no'),
];

return new TemplateResponse('settings', 'settings/admin/sharing', $parameters, '');
Expand Down
23 changes: 23 additions & 0 deletions apps/settings/templates/settings/admin/sharing.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,29 @@
<label for="shareapiInternalEnforceExpireDate"><?php p($l->t('Enforce expiration date'));?></label><br/>
</p>

<p id="remoteShareSettings" class="indent <?php if ($_['shareAPIEnabled'] === 'no') {
p('hidden');
} ?>">
<input type="checkbox" name="shareapi_default_remote_expire_date" id="shareapiDefaultRemoteExpireDate" class="checkbox"
value="1" <?php if ($_['shareDefaultRemoteExpireDateSet'] === 'yes') {
print_unescaped('checked="checked"');
} ?> />
<label for="shareapiDefaultRemoteExpireDate"><?php p($l->t('Set default expiration date for shares to other servers'));?></label><br/>
</p>
<p id="setDefaultRemoteExpireDate" class="double-indent <?php if ($_['shareDefaultRemoteExpireDateSet'] === 'no' || $_['shareAPIEnabled'] === 'no') {
p('hidden');
}?>">
<?php p($l->t('Expire after ')); ?>
<input type="text" name='shareapi_remote_expire_after_n_days' id="shareapiRemoteExpireAfterNDays" placeholder="<?php p('7')?>"
value='<?php p($_['shareRemoteExpireAfterNDays']) ?>' />
<?php p($l->t('days')); ?>
<input type="checkbox" name="shareapi_enforce_remote_expire_date" id="shareapiRemoteEnforceExpireDate" class="checkbox"
value="1" <?php if ($_['shareRemoteEnforceExpireDate'] === 'yes') {
print_unescaped('checked="checked"');
} ?> />
<label for="shareapiRemoteEnforceExpireDate"><?php p($l->t('Enforce expiration date'));?></label><br/>
</p>

<p class="<?php if ($_['shareAPIEnabled'] === 'no') {
p('hidden');
}?>">
Expand Down
12 changes: 12 additions & 0 deletions apps/settings/tests/Settings/Admin/SharingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ public function testGetFormWithoutExcludedGroups() {
['core', 'shareapi_default_internal_expire_date', 'no', 'no'],
['core', 'shareapi_internal_expire_after_n_days', '7', '7'],
['core', 'shareapi_enforce_internal_expire_date', 'no', 'no'],
['core', 'shareapi_default_remote_expire_date', 'no', 'no'],
['core', 'shareapi_remote_expire_after_n_days', '7', '7'],
['core', 'shareapi_enforce_remote_expire_date', 'no', 'no'],
]);

$expected = new TemplateResponse(
Expand Down Expand Up @@ -115,6 +118,9 @@ public function testGetFormWithoutExcludedGroups() {
'shareDefaultInternalExpireDateSet' => 'no',
'shareInternalExpireAfterNDays' => '7',
'shareInternalEnforceExpireDate' => 'no',
'shareDefaultRemoteExpireDateSet' => 'no',
'shareRemoteExpireAfterNDays' => '7',
'shareRemoteEnforceExpireDate' => 'no',
],
''
);
Expand Down Expand Up @@ -146,6 +152,9 @@ public function testGetFormWithExcludedGroups() {
['core', 'shareapi_default_internal_expire_date', 'no', 'no'],
['core', 'shareapi_internal_expire_after_n_days', '7', '7'],
['core', 'shareapi_enforce_internal_expire_date', 'no', 'no'],
['core', 'shareapi_default_remote_expire_date', 'no', 'no'],
['core', 'shareapi_remote_expire_after_n_days', '7', '7'],
['core', 'shareapi_enforce_remote_expire_date', 'no', 'no'],
]);

$expected = new TemplateResponse(
Expand Down Expand Up @@ -175,6 +184,9 @@ public function testGetFormWithExcludedGroups() {
'shareDefaultInternalExpireDateSet' => 'no',
'shareInternalExpireAfterNDays' => '7',
'shareInternalEnforceExpireDate' => 'no',
'shareDefaultRemoteExpireDateSet' => 'no',
'shareRemoteExpireAfterNDays' => '7',
'shareRemoteEnforceExpireDate' => 'no',
],
''
);
Expand Down
55 changes: 47 additions & 8 deletions lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ protected function generalCreateChecks(IShare $share) {
* @throws \Exception
*/
protected function validateExpirationDateInternal(IShare $share) {
$isRemote = $share->getShareType() === IShare::TYPE_REMOTE || $share->getShareType() === IShare::TYPE_REMOTE_GROUP;

$expirationDate = $share->getExpirationDate();

if ($expirationDate !== null) {
Expand All @@ -407,28 +409,39 @@ protected function validateExpirationDateInternal(IShare $share) {
// This is a new share
}

if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
if ($isRemote) {
$defaultExpireDate = $this->shareApiRemoteDefaultExpireDate();
$defaultExpireDays = $this->shareApiRemoteDefaultExpireDays();
$configProp = 'remote_defaultExpDays';
$isEnforced = $this->shareApiRemoteDefaultExpireDateEnforced();
} else {
$defaultExpireDate = $this->shareApiInternalDefaultExpireDate();
$defaultExpireDays = $this->shareApiInternalDefaultExpireDays();
$configProp = 'internal_defaultExpDays';
$isEnforced = $this->shareApiInternalDefaultExpireDateEnforced();
}
if ($fullId === null && $expirationDate === null && $defaultExpireDate) {
$expirationDate = new \DateTime();
$expirationDate->setTime(0,0,0);

$days = (int)$this->config->getAppValue('core', 'internal_defaultExpDays', (string)$this->shareApiInternalDefaultExpireDays());
if ($days > $this->shareApiInternalDefaultExpireDays()) {
$days = $this->shareApiInternalDefaultExpireDays();
$days = (int)$this->config->getAppValue('core', $configProp, (string)$defaultExpireDays);
if ($days > $defaultExpireDays) {
$days = $defaultExpireDays;
}
$expirationDate->add(new \DateInterval('P'.$days.'D'));
}

// If we enforce the expiration date check that is does not exceed
if ($this->shareApiInternalDefaultExpireDateEnforced()) {
if ($isEnforced) {
if ($expirationDate === null) {
throw new \InvalidArgumentException('Expiration date is enforced');
}

$date = new \DateTime();
$date->setTime(0, 0, 0);
$date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
$date->add(new \DateInterval('P' . $defaultExpireDays . 'D'));
if ($date < $expirationDate) {
$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$defaultExpireDays]);
throw new GenericShareException($message, $message, 404);
}
}
Expand Down Expand Up @@ -1792,16 +1805,34 @@ public function shareApiInternalDefaultExpireDate(): bool {
return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
}

/**
* Is default remote expire date enabled
*
* @return bool
*/
public function shareApiRemoteDefaultExpireDate(): bool {
return $this->config->getAppValue('core', 'shareapi_default_remote_expire_date', 'no') === 'yes';
}

/**
* Is default expire date enforced
*`
*
* @return bool
*/
public function shareApiInternalDefaultExpireDateEnforced(): bool {
return $this->shareApiInternalDefaultExpireDate() &&
$this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
}

/**
* Is default expire date enforced for remote shares
*
* @return bool
*/
public function shareApiRemoteDefaultExpireDateEnforced(): bool {
return $this->shareApiRemoteDefaultExpireDate() &&
$this->config->getAppValue('core', 'shareapi_enforce_remote_expire_date', 'no') === 'yes';
}

/**
* Number of default expire days
Expand All @@ -1811,6 +1842,14 @@ public function shareApiInternalDefaultExpireDays(): int {
return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
}

/**
* Number of default expire days for remote shares
* @return int
*/
public function shareApiRemoteDefaultExpireDays(): int {
return (int)$this->config->getAppValue('core', 'shareapi_remote_expire_after_n_days', '7');
}

/**
* Allow public upload on link shares
*
Expand Down
10 changes: 10 additions & 0 deletions lib/private/Template/JSConfigHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ public function getConfig() {
$defaultInternalExpireDateEnforced = $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
}

$defaultRemoteExpireDateEnabled = $this->config->getAppValue('core', 'shareapi_default_remote_expire_date', 'no') === 'yes';
$defaultRemoteExpireDate = $defaultRemoteExpireDateEnforced = null;
if ($defaultRemoteExpireDateEnabled) {
$defaultRemoteExpireDate = (int)$this->config->getAppValue('core', 'shareapi_remote_expire_after_n_days', '7');
$defaultRemoteExpireDateEnforced = $this->config->getAppValue('core', 'shareapi_enforce_remote_expire_date', 'no') === 'yes';
}

$countOfDataLocation = 0;
$dataLocation = str_replace(\OC::$SERVERROOT . '/', '', $this->config->getSystemValue('datadirectory', ''), $countOfDataLocation);
if ($countOfDataLocation !== 1 || $uid === null || !$this->groupManager->isAdmin($uid)) {
Expand Down Expand Up @@ -278,6 +285,9 @@ public function getConfig() {
'defaultInternalExpireDateEnabled' => $defaultInternalExpireDateEnabled,
'defaultInternalExpireDate' => $defaultInternalExpireDate,
'defaultInternalExpireDateEnforced' => $defaultInternalExpireDateEnforced,
'defaultRemoteExpireDateEnabled' => $defaultRemoteExpireDateEnabled,
'defaultRemoteExpireDate' => $defaultRemoteExpireDate,
'defaultRemoteExpireDateEnforced' => $defaultRemoteExpireDateEnforced,
]
]),
"_theme" => json_encode([
Expand Down
Loading

0 comments on commit 553afe1

Please sign in to comment.