Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nmc 434-changed the process of sharing #28832

Closed
wants to merge 8 commits into from
29 changes: 28 additions & 1 deletion apps/files_sharing/lib/Controller/ShareAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ public function deleteShare(string $id): DataResponse {
* @param string $sendPasswordByTalk
* @param string $expireDate
* @param string $label
* @param string $hideDownload
*
* @return DataResponse
* @throws NotFoundException
Expand All @@ -449,7 +450,8 @@ public function createShare(
string $password = '',
string $sendPasswordByTalk = null,
string $expireDate = '',
string $label = ''
string $label = '',
string $hideDownload = null
): DataResponse {
$share = $this->shareManager->newShare();

Expand Down Expand Up @@ -506,6 +508,15 @@ public function createShare(
}
$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_GROUP) {
if (!$this->shareManager->allowGroupSharing()) {
throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
Expand All @@ -517,6 +528,15 @@ public function createShare(
}
$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_LINK
|| $shareType === IShare::TYPE_EMAIL) {

Expand Down Expand Up @@ -544,6 +564,13 @@ public function createShare(
$permissions = Constants::PERMISSION_READ;
}

// Update hide download state
if ($hideDownload === 'true') {
$share->setHideDownload(true);
} elseif ($hideDownload === 'false') {
$share->setHideDownload(false);
}

// TODO: It might make sense to have a dedicated setting to allow/deny converting link shares into federated ones
if (($permissions & Constants::PERMISSION_READ) && $this->shareManager->outgoingServer2ServerSharesAllowed()) {
$permissions |= Constants::PERMISSION_SHARE;
Expand Down
240 changes: 80 additions & 160 deletions apps/files_sharing/src/components/SharingEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,106 +38,49 @@
<span>{{ share.status.icon || '' }}</span>
<span>{{ share.status.message || '' }}</span>
</p>

<template v-if="share.canEdit">
<!-- folder -->
<template v-if="isFolder && fileHasCreatePermission && config.isPublicUploadEnabled">
<select
:name="randomId"
@change="togglePermissions">
<option :value="publicUploadRValue" :selected="sharePermissions === publicUploadRValue">{{ t('files_sharing', 'Read only') }}</option>
<option :value="publicUploadRWValue" :selected="sharePermissions === publicUploadRWValue">{{ t('files_sharing', 'Read, write and upload') }}</option>
</select>
</template>
<!-- files -->
<template v-else>
<select
:name="randomId"
@change="togglePermissions">
<option :value="publicUploadRValue" :selected="sharePermissions === publicUploadRValue">{{ t('files_sharing', 'Read only') }}</option>
<option :value="publicUploadEValue" :selected="sharePermissions === publicUploadEValue">{{ t('files_sharing', 'Read and write') }}</option>
</select>
</template>
</template>
</component>
<Actions
<Actions v-if="open === false"
menu-align="right"
class="sharing-entry__actions"
@close="onMenuClose">
<template v-if="share.canEdit">
<!-- edit permission -->
<ActionCheckbox
ref="canEdit"
:checked.sync="canEdit"
:value="permissionsEdit"
:disabled="saving || !canSetEdit">
{{ t('files_sharing', 'Allow editing') }}
</ActionCheckbox>

<!-- create permission -->
<ActionCheckbox
v-if="isFolder"
ref="canCreate"
:checked.sync="canCreate"
:value="permissionsCreate"
:disabled="saving || !canSetCreate">
{{ t('files_sharing', 'Allow creating') }}
</ActionCheckbox>

<!-- delete permission -->
<ActionCheckbox
v-if="isFolder"
ref="canDelete"
:checked.sync="canDelete"
:value="permissionsDelete"
:disabled="saving || !canSetDelete">
{{ t('files_sharing', 'Allow deleting') }}
</ActionCheckbox>

<!-- reshare permission -->
<ActionCheckbox
v-if="config.isResharingAllowed"
ref="canReshare"
:checked.sync="canReshare"
:value="permissionsShare"
:disabled="saving || !canSetReshare">
{{ t('files_sharing', 'Allow resharing') }}
</ActionCheckbox>

<!-- expiration date -->
<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="hasExpirationDate"
ref="expireDate"
v-tooltip.auto="{
content: errors.expireDate,
show: errors.expireDate,
trigger: 'manual'
}"
:class="{ error: errors.expireDate}"
:disabled="saving"
:first-day-of-week="firstDay"
:lang="lang"
:value="share.expireDate"
value-type="format"
icon="icon-calendar-dark"
type="date"
:disabled-date="disabledDate"
@update:value="onExpirationChange">
{{ t('files_sharing', 'Enter a date') }}
</ActionInput>

<!-- note -->
<template v-if="canHaveNote">
<ActionCheckbox
:checked.sync="hasNote"
:disabled="saving"
@uncheck="queueUpdate('note')">
{{ t('files_sharing', 'Note to recipient') }}
</ActionCheckbox>
<ActionTextEditable v-if="hasNote"
ref="note"
v-tooltip.auto="{
content: errors.note,
show: errors.note,
trigger: 'manual'
}"
:class="{ error: errors.note}"
:disabled="saving"
:value="share.newNote || share.note"
icon="icon-edit"
@update:value="onNoteChange"
@submit="onNoteSubmit" />
</template>
</template>

<ActionButton v-if="share.canEdit"
icon="icon-settings"
:disabled="saving || !canSetEdit"
:share="share"
@click.prevent="editPermissions">
{{ t('files_sharing', 'Advanced permission') }}
</ActionButton>
<ActionButton v-if="share.canEdit"
icon="icon-mail"
:disabled="saving || !canSetEdit"
:share="share"
@click.prevent="editNotes">
{{ t('files_sharing', 'Send new mail') }}
</ActionButton>
<ActionButton v-if="share.canDelete"
icon="icon-close"
:disabled="saving"
:disabled="saving || !canSetEdit"
@click.prevent="onDelete">
{{ t('files_sharing', 'Unshare') }}
</ActionButton>
Expand Down Expand Up @@ -181,10 +124,33 @@ export default {
permissionsDelete: OC.PERMISSION_DELETE,
permissionsRead: OC.PERMISSION_READ,
permissionsShare: OC.PERMISSION_SHARE,

publicUploadRWValue: OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE,
publicUploadRValue: OC.PERMISSION_READ,
publicUploadWValue: OC.PERMISSION_CREATE,
publicUploadEValue: OC.PERMISSION_UPDATE | OC.PERMISSION_READ,
}
},

computed: {
/**
* Return the current share permissions
* We always ignore the SHARE permission as this is used for the
* federated sharing.
* @returns {number}
*/
sharePermissions() {
return this.share.permissions & ~OC.PERMISSION_SHARE
},

/**
* Generate a unique random id for this SharingEntry only
* @returns {string}
*/
randomId() {
return Math.random().toString(27).substr(2)
},

title() {
let title = this.share.shareWithDisplayName
if (this.share.type === this.SHARE_TYPES.SHARE_TYPE_GROUP) {
Expand Down Expand Up @@ -221,10 +187,6 @@ export default {
return null
},

canHaveNote() {
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 All @@ -242,42 +204,6 @@ export default {
return (this.fileInfo.sharePermissions & OC.PERMISSION_UPDATE) || this.canEdit
},

/**
* Can the sharer set whether the sharee can create the file ?
*
* @returns {boolean}
*/
canSetCreate() {
// If the owner revoked the permission after the resharer granted it
// the share still has the permission, and the resharer is still
// allowed to revoke it too (but not to grant it again).
return (this.fileInfo.sharePermissions & OC.PERMISSION_CREATE) || this.canCreate
},

/**
* Can the sharer set whether the sharee can delete the file ?
*
* @returns {boolean}
*/
canSetDelete() {
// If the owner revoked the permission after the resharer granted it
// the share still has the permission, and the resharer is still
// allowed to revoke it too (but not to grant it again).
return (this.fileInfo.sharePermissions & OC.PERMISSION_DELETE) || this.canDelete
},

/**
* Can the sharer set whether the sharee can reshare the file ?
*
* @returns {boolean}
*/
canSetReshare() {
// If the owner revoked the permission after the resharer granted it
// the share still has the permission, and the resharer is still
// allowed to revoke it too (but not to grant it again).
return (this.fileInfo.sharePermissions & OC.PERMISSION_SHARE) || this.canReshare
},

/**
* Can the sharee edit the shared file ?
*/
Expand Down Expand Up @@ -337,38 +263,20 @@ export default {
},

/**
* Is the current share a folder ?
* Does the current file/folder have create permissions
* TODO: move to a proper FileInfo model?
* @returns {boolean}
*/
isFolder() {
return this.fileInfo.type === 'dir'
fileHasCreatePermission() {
return !!(this.fileInfo.permissions & OC.PERMISSION_CREATE)
},

/**
* Does the current share have an expiration date
* Is the current share a folder ?
* @returns {boolean}
*/
hasExpirationDate: {
get() {
return this.config.isDefaultInternalExpireDateEnforced || !!this.share.expireDate
},
set(enabled) {
this.share.expireDate = enabled
? this.config.defaultInternalExpirationDateString !== ''
? this.config.defaultInternalExpirationDateString
: moment().format('YYYY-MM-DD')
: ''
},
},

dateMaxEnforced() {
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')
}
isFolder() {
return this.fileInfo.type === 'dir'
},

/**
Expand Down Expand Up @@ -404,6 +312,18 @@ export default {
onMenuClose() {
this.onNoteSubmit()
},

editPermissions() {
this.$store.commit('addFromInput', false)
this.$store.commit('addShare', this.share)
this.$store.commit('addCurrentTab', 'permissions')
},

editNotes() {
this.$store.commit('addFromInput', false)
this.$store.commit('addShare', this.share)
this.$store.commit('addCurrentTab', 'notes')
},
},
}
</script>
Expand All @@ -412,7 +332,7 @@ export default {
.sharing-entry {
display: flex;
align-items: center;
height: 44px;
min-height: 44px;
&__desc {
display: flex;
flex-direction: column;
Expand Down
Loading