Browse Source
Merge pull request #15952 from nextcloud/feature/noid/inherited-shares
Merge pull request #15952 from nextcloud/feature/noid/inherited-shares
Inherited Sharespull/18209/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 814 additions and 178 deletions
-
5apps/files_sharing/appinfo/routes.php
-
1apps/files_sharing/composer/composer/autoload_classmap.php
-
1apps/files_sharing/composer/composer/autoload_static.php
-
4apps/files_sharing/js/dist/additionalScripts.js
-
2apps/files_sharing/js/dist/additionalScripts.js.map
-
2apps/files_sharing/js/dist/collaboration.js
-
2apps/files_sharing/js/dist/collaboration.js.map
-
2apps/files_sharing/js/dist/files_sharing.js
-
2apps/files_sharing/js/dist/files_sharing.js.map
-
210apps/files_sharing/js/dist/files_sharing_tab.js
-
2apps/files_sharing/js/dist/files_sharing_tab.js.map
-
2apps/files_sharing/js/dist/main.js
-
2apps/files_sharing/js/dist/main.js.map
-
335apps/files_sharing/lib/Controller/ShareAPIController.php
-
40apps/files_sharing/lib/Exceptions/SharingRightsException.php
-
2apps/files_sharing/src/components/SharingEntry.vue
-
112apps/files_sharing/src/components/SharingEntryInherited.vue
-
164apps/files_sharing/src/views/SharingInherited.vue
-
11apps/files_sharing/src/views/SharingTab.vue
-
11apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
-
80build/integration/sharing_features/sharing-v1.feature
4
apps/files_sharing/js/dist/additionalScripts.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
apps/files_sharing/js/dist/additionalScripts.js.map
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,2 +1,2 @@ |
|||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/js/",t(t.s=65)}({65:function(e,n,r){r.p=OC.linkTo("files_sharing","js/dist/"),r.nc=btoa(OC.requestToken),window.OCP.Collaboration.registerType("file",{action:function(){return new Promise((function(e,n){OC.dialogs.filepicker(t("files_sharing","Link to a file"),(function(t){OC.Files.getClient().getFileInfo(t).then((function(n,t){e(t.id)})).fail((function(){n(new Error("Cannot get fileinfo"))}))}),!1,null,!1,OC.dialogs.FILEPICKER_TYPE_CHOOSE,"",{allowDirectoryChooser:!0})}))},typeString:t("files_sharing","Link to a file"),typeIconClass:"icon-files-dark"})}}); |
|||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/js/",t(t.s=68)}({68:function(e,n,r){r.p=OC.linkTo("files_sharing","js/dist/"),r.nc=btoa(OC.requestToken),window.OCP.Collaboration.registerType("file",{action:function(){return new Promise((function(e,n){OC.dialogs.filepicker(t("files_sharing","Link to a file"),(function(t){OC.Files.getClient().getFileInfo(t).then((function(n,t){e(t.id)})).fail((function(){n(new Error("Cannot get fileinfo"))}))}),!1,null,!1,OC.dialogs.FILEPICKER_TYPE_CHOOSE,"",{allowDirectoryChooser:!0})}))},typeString:t("files_sharing","Link to a file"),typeIconClass:"icon-files-dark"})}}); |
|||
//# sourceMappingURL=collaboration.js.map
|
|||
2
apps/files_sharing/js/dist/collaboration.js.map
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
apps/files_sharing/js/dist/files_sharing.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
apps/files_sharing/js/dist/files_sharing.js.map
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
210
apps/files_sharing/js/dist/files_sharing_tab.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
apps/files_sharing/js/dist/files_sharing_tab.js.map
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2
apps/files_sharing/js/dist/main.js.map
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,40 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* @copyright Copyright (c) 2019, Maxence Lange <maxence@artificial-owl.com> |
|||
* |
|||
* @author Maxence Lange <maxence@artificial-owl.com> |
|||
* |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Files_Sharing\Exceptions; |
|||
|
|||
use Exception; |
|||
|
|||
|
|||
/** |
|||
* Sharing and Resharing rights. |
|||
* |
|||
* Class SharingRightsException |
|||
* |
|||
* @package OCA\Files_Sharing\Exceptions |
|||
*/ |
|||
class SharingRightsException extends Exception { |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,112 @@ |
|||
<!-- |
|||
- @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com> |
|||
- |
|||
- @author John Molakvoæ <skjnldsv@protonmail.com> |
|||
- |
|||
- @license GNU AGPL version 3 or any later version |
|||
- |
|||
- This program is free software: you can redistribute it and/or modify |
|||
- it under the terms of the GNU Affero General Public License as |
|||
- published by the Free Software Foundation, either version 3 of the |
|||
- License, or (at your option) any later version. |
|||
- |
|||
- This program is distributed in the hope that it will be useful, |
|||
- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
- GNU Affero General Public License for more details. |
|||
- |
|||
- You should have received a copy of the GNU Affero General Public License |
|||
- along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
- |
|||
--> |
|||
|
|||
<template> |
|||
<SharingEntrySimple |
|||
:key="share.id" |
|||
class="sharing-entry__inherited" |
|||
:title="share.shareWithDisplayName"> |
|||
<template #avatar> |
|||
<Avatar |
|||
:user="share.shareWith" |
|||
:display-name="share.shareWithDisplayName" |
|||
class="sharing-entry__avatar" |
|||
tooltip-message="" /> |
|||
</template> |
|||
<ActionText icon="icon-user"> |
|||
{{ t('files_sharing', 'Invited by {initiator}', { initiator: share.ownerDisplayName }) }} |
|||
</ActionText> |
|||
<ActionLink v-if="share.fileSource" |
|||
icon="icon-folder" |
|||
:href="fileTargetUrl"> |
|||
{{ t('files_sharing', 'Open folder') }} |
|||
</ActionLink> |
|||
<ActionButton v-if="share.canDelete" |
|||
icon="icon-delete" |
|||
@click.prevent="onDelete"> |
|||
{{ t('files_sharing', 'Delete share') }} |
|||
</actionbutton> |
|||
</SharingEntrySimple> |
|||
</template> |
|||
|
|||
<script> |
|||
import { generateUrl } from '@nextcloud/router' |
|||
import Avatar from 'nextcloud-vue/dist/Components/Avatar' |
|||
import ActionButton from 'nextcloud-vue/dist/Components/ActionButton' |
|||
import ActionLink from 'nextcloud-vue/dist/Components/ActionLink' |
|||
import ActionText from 'nextcloud-vue/dist/Components/ActionText' |
|||
|
|||
// eslint-disable-next-line no-unused-vars |
|||
import Share from '../models/Share' |
|||
import SharesMixin from '../mixins/SharesMixin' |
|||
import SharingEntrySimple from '../components/SharingEntrySimple' |
|||
|
|||
export default { |
|||
name: 'SharingEntryInherited', |
|||
|
|||
components: { |
|||
ActionButton, |
|||
ActionLink, |
|||
ActionText, |
|||
Avatar, |
|||
SharingEntrySimple |
|||
}, |
|||
|
|||
mixins: [SharesMixin], |
|||
|
|||
props: { |
|||
share: { |
|||
type: Share, |
|||
required: true |
|||
} |
|||
}, |
|||
|
|||
computed: { |
|||
fileTargetUrl() { |
|||
return generateUrl('/f/{fileid}', { |
|||
fileid: this.share.fileSource |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.sharing-entry { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 44px; |
|||
&__desc { |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
padding: 8px; |
|||
line-height: 1.2em; |
|||
p { |
|||
color: var(--color-text-maxcontrast); |
|||
} |
|||
} |
|||
&__actions { |
|||
margin-left: auto; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,164 @@ |
|||
<!-- |
|||
- @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com> |
|||
- |
|||
- @author John Molakvoæ <skjnldsv@protonmail.com> |
|||
- |
|||
- @license GNU AGPL version 3 or any later version |
|||
- |
|||
- This program is free software: you can redistribute it and/or modify |
|||
- it under the terms of the GNU Affero General Public License as |
|||
- published by the Free Software Foundation, either version 3 of the |
|||
- License, or (at your option) any later version. |
|||
- |
|||
- This program is distributed in the hope that it will be useful, |
|||
- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
- GNU Affero General Public License for more details. |
|||
- |
|||
- You should have received a copy of the GNU Affero General Public License |
|||
- along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
- |
|||
--> |
|||
|
|||
<template> |
|||
<ul id="sharing-inherited-shares"> |
|||
<!-- Main collapsible entry --> |
|||
<SharingEntrySimple |
|||
class="sharing-entry__inherited" |
|||
:title="mainTitle"> |
|||
<template #avatar> |
|||
<div class="avatar-shared icon-more-white" /> |
|||
</template> |
|||
<ActionButton :icon="showInheritedSharesIcon" @click.prevent.stop="toggleInheritedShares"> |
|||
{{ toggleTooltip }} |
|||
</ActionButton> |
|||
</SharingEntrySimple> |
|||
|
|||
<!-- Inherited shares list --> |
|||
<SharingEntryInherited v-for="share in shares" |
|||
:key="share.id" |
|||
:share="share" /> |
|||
</ul> |
|||
</template> |
|||
|
|||
<script> |
|||
import { generateOcsUrl } from '@nextcloud/router' |
|||
import ActionButton from 'nextcloud-vue/dist/Components/ActionButton' |
|||
import axios from '@nextcloud/axios' |
|||
|
|||
import Share from '../models/Share' |
|||
import SharingEntryInherited from '../components/SharingEntryInherited' |
|||
import SharingEntrySimple from '../components/SharingEntrySimple' |
|||
|
|||
export default { |
|||
name: 'SharingInherited', |
|||
|
|||
components: { |
|||
ActionButton, |
|||
SharingEntryInherited, |
|||
SharingEntrySimple |
|||
}, |
|||
|
|||
props: { |
|||
fileInfo: { |
|||
type: Object, |
|||
default: () => {}, |
|||
required: true |
|||
} |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
loaded: false, |
|||
loading: false, |
|||
showInheritedShares: false, |
|||
shares: [] |
|||
} |
|||
}, |
|||
computed: { |
|||
showInheritedSharesIcon() { |
|||
if (this.loading) { |
|||
return 'icon-loading-small' |
|||
} |
|||
if (this.showInheritedShares) { |
|||
return 'icon-triangle-n' |
|||
} |
|||
return 'icon-triangle-s' |
|||
}, |
|||
mainTitle() { |
|||
return t('files_sharing', 'Others with access {count}', { |
|||
count: this.loaded ? `: ${this.shares.length}` : '' |
|||
}) |
|||
}, |
|||
toggleTooltip() { |
|||
return this.fileInfo.type === 'dir' |
|||
? t('files_sharing', 'Toggle list of others with access to this directory') |
|||
: t('files_sharing', 'Toggle list of others with access to this file') |
|||
}, |
|||
fullPath() { |
|||
const path = `${this.fileInfo.path}/${this.fileInfo.name}` |
|||
return path.replace('//', '/') |
|||
} |
|||
}, |
|||
watch: { |
|||
fileInfo() { |
|||
this.resetState() |
|||
} |
|||
}, |
|||
methods: { |
|||
/** |
|||
* Toggle the list view and fetch/reset the state |
|||
*/ |
|||
toggleInheritedShares() { |
|||
this.showInheritedShares = !this.showInheritedShares |
|||
if (this.showInheritedShares) { |
|||
this.fetchInheritedShares() |
|||
} else { |
|||
this.resetState() |
|||
} |
|||
}, |
|||
/** |
|||
* Fetch the Inherited Shares array |
|||
*/ |
|||
async fetchInheritedShares() { |
|||
this.loading = true |
|||
try { |
|||
const url = generateOcsUrl(`apps/files_sharing/api/v1/shares/inherited?format=json&path=${this.fullPath}`, 2) |
|||
const shares = await axios.get(url.replace(/\/$/, '')) |
|||
this.shares = shares.data.ocs.data |
|||
.map(share => new Share(share)) |
|||
.sort((a, b) => b.createdTime - a.createdTime) |
|||
console.info(this.shares) |
|||
this.loaded = true |
|||
} catch (error) { |
|||
OC.Notification.showTemporary(t('files_sharing', 'Unable to fetch inherited shares'), { type: 'error' }) |
|||
} finally { |
|||
this.loading = false |
|||
} |
|||
}, |
|||
/** |
|||
* Reset current component state |
|||
*/ |
|||
resetState() { |
|||
this.loaded = false |
|||
this.loading = false |
|||
this.showInheritedShares = false |
|||
this.shares = [] |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.sharing-entry__inherited { |
|||
.avatar-shared { |
|||
width: 32px; |
|||
height: 32px; |
|||
line-height: 32px; |
|||
font-size: 18px; |
|||
background-color: var(--color-text-maxcontrast); |
|||
border-radius: 50%; |
|||
flex-shrink: 0; |
|||
} |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue