mirror of
https://github.com/nextcloud/server.git
synced 2026-06-25 08:31:11 -04:00
Merge pull request #61387 from nextcloud/backport/60151/stable33
[stable33] fix(files_sharing): Hide incompatible actions in shares
This commit is contained in:
commit
2be035be8a
8 changed files with 57 additions and 16 deletions
|
|
@ -36,6 +36,10 @@ export function registerConvertActions() {
|
|||
// cannot create the converted file in a public share if we don't have create permissions
|
||||
return false
|
||||
}
|
||||
// Conversion reads the source file, so it requires read permission
|
||||
if (nodes.some((node) => (node.permissions & Permission.READ) === 0)) {
|
||||
return false
|
||||
}
|
||||
// Check that all nodes have the same mime type
|
||||
return nodes.every((node) => from === node.mime)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -535,6 +535,34 @@ describe('SharingService share to Node mapping', () => {
|
|||
expect(file.attributes.favorite).toBe(0)
|
||||
})
|
||||
|
||||
test('Pending share has no permissions', async () => {
|
||||
axios.get
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
data: { ocs: { data: [shareFile] } },
|
||||
}))
|
||||
.mockReturnValueOnce(Promise.resolve({
|
||||
data: { ocs: { data: [] } },
|
||||
}))
|
||||
|
||||
const shares = await getContents(false, false, true, false)
|
||||
|
||||
expect(axios.get).toHaveBeenCalledTimes(2)
|
||||
expect(shares.contents).toHaveLength(1)
|
||||
expect(shares.contents[0].permissions).toBe(0)
|
||||
})
|
||||
|
||||
test('Deleted share has no permissions', async () => {
|
||||
axios.get.mockReturnValueOnce(Promise.resolve({
|
||||
data: { ocs: { data: [shareFolder] } },
|
||||
}))
|
||||
|
||||
const shares = await getContents(false, false, false, true)
|
||||
|
||||
expect(axios.get).toHaveBeenCalledTimes(1)
|
||||
expect(shares.contents).toHaveLength(1)
|
||||
expect(shares.contents[0].permissions).toBe(0)
|
||||
})
|
||||
|
||||
test('Empty', async () => {
|
||||
vi.spyOn(logger, 'error').mockImplementationOnce(() => {})
|
||||
axios.get.mockReturnValueOnce(Promise.resolve({
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@ const headers = {
|
|||
/**
|
||||
*
|
||||
* @param ocsEntry
|
||||
* @param unmounted whether the share is not mounted into the filesystem (pending or deleted)
|
||||
*/
|
||||
async function ocsEntryToNode(ocsEntry: any): Promise<Folder | File | null> {
|
||||
async function ocsEntryToNode(ocsEntry: any, unmounted = false): Promise<Folder | File | null> {
|
||||
try {
|
||||
// Federated share handling
|
||||
if (ocsEntry?.remote_id !== undefined) {
|
||||
|
|
@ -57,6 +58,13 @@ async function ocsEntryToNode(ocsEntry: any): Promise<Folder | File | null> {
|
|||
ocsEntry.displayname_owner = ocsEntry.owner
|
||||
}
|
||||
|
||||
// Pending and deleted shares are not mounted into the user's filesystem,
|
||||
// so no file operation can act on them until they are accepted or restored.
|
||||
if (unmounted) {
|
||||
ocsEntry.item_permissions = Permission.NONE
|
||||
ocsEntry.permissions = Permission.NONE
|
||||
}
|
||||
|
||||
const isFolder = ocsEntry?.item_type === 'folder'
|
||||
const hasPreview = ocsEntry?.has_preview === true
|
||||
const Node = isFolder ? Folder : File
|
||||
|
|
@ -238,24 +246,25 @@ function groupBy(nodes: (Folder | File)[], key: string) {
|
|||
* @param filterTypes
|
||||
*/
|
||||
export async function getContents(sharedWithYou = true, sharedWithOthers = true, pendingShares = false, deletedshares = false, filterTypes: number[] = []): Promise<ContentsWithRoot> {
|
||||
const promises = [] as AxiosPromise<OCSResponse<any>>[]
|
||||
const requests = [] as { promise: AxiosPromise<OCSResponse<any>>, unmounted: boolean }[]
|
||||
|
||||
if (sharedWithYou) {
|
||||
promises.push(getSharedWithYou(), getRemoteShares())
|
||||
requests.push({ promise: getSharedWithYou(), unmounted: false }, { promise: getRemoteShares(), unmounted: false })
|
||||
}
|
||||
if (sharedWithOthers) {
|
||||
promises.push(getSharedWithOthers())
|
||||
requests.push({ promise: getSharedWithOthers(), unmounted: false })
|
||||
}
|
||||
if (pendingShares) {
|
||||
promises.push(getPendingShares(), getRemotePendingShares())
|
||||
requests.push({ promise: getPendingShares(), unmounted: true }, { promise: getRemotePendingShares(), unmounted: true })
|
||||
}
|
||||
if (deletedshares) {
|
||||
promises.push(getDeletedShares())
|
||||
requests.push({ promise: getDeletedShares(), unmounted: true })
|
||||
}
|
||||
|
||||
const responses = await Promise.all(promises)
|
||||
const data = responses.map((response) => response.data.ocs.data).flat()
|
||||
let contents = (await Promise.all(data.map(ocsEntryToNode)))
|
||||
const responses = await Promise.all(requests.map(({ promise }) => promise))
|
||||
const data = responses.flatMap((response, index) => response.data.ocs.data
|
||||
.map((entry) => ({ entry, unmounted: requests[index].unmounted })))
|
||||
let contents = (await Promise.all(data.map(({ entry, unmounted }) => ocsEntryToNode(entry, unmounted))))
|
||||
.filter((node) => node !== null) as (Folder | File)[]
|
||||
|
||||
if (filterTypes.length > 0) {
|
||||
|
|
|
|||
2
dist/1255-1255.js.map
vendored
2
dist/1255-1255.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files-init.js
vendored
4
dist/files-init.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-init.js.map
vendored
2
dist/files-init.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files_sharing-init.js
vendored
4
dist/files_sharing-init.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_sharing-init.js.map
vendored
2
dist/files_sharing-init.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue