mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
fix(files): actions permissions requirements
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
This commit is contained in:
parent
6f54f72bb4
commit
a9f7e66d3d
8 changed files with 59 additions and 16 deletions
|
|
@ -22,7 +22,7 @@
|
|||
import * as favoriteAction from './favoriteAction'
|
||||
import { action } from './favoriteAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File, Folder, Permission } from '@nextcloud/files'
|
||||
import { File, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import * as eventBus from '@nextcloud/event-bus'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
|
@ -120,6 +120,7 @@ describe('Favorite action enabled tests', () => {
|
|||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.ALL,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
|
|
|
|||
|
|
@ -20,13 +20,15 @@
|
|||
*
|
||||
*/
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { Permission, type Node } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import axios from '@nextcloud/axios'
|
||||
import StarSvg from '@mdi/svg/svg/star.svg?raw'
|
||||
import StarOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import Vue from 'vue'
|
||||
|
||||
import StarOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
|
||||
import StarSvg from '@mdi/svg/svg/star.svg?raw'
|
||||
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
|
|
@ -54,7 +56,7 @@ export const favoriteNode = async (node: Node, view: Navigation, willFavorite: b
|
|||
}
|
||||
|
||||
// Update the node webdav attribute
|
||||
node.attributes.favorite = willFavorite ? 1 : 0
|
||||
Vue.set(node.attributes, 'favorite', willFavorite ? 1 : 0)
|
||||
|
||||
// Dispatch event to whoever is interested
|
||||
if (willFavorite) {
|
||||
|
|
@ -85,8 +87,9 @@ export const action = new FileAction({
|
|||
},
|
||||
|
||||
enabled(nodes: Node[]) {
|
||||
// We can only favorite nodes within files
|
||||
// We can only favorite nodes within files and with permissions
|
||||
return !nodes.some(node => !node.root?.startsWith?.('/files'))
|
||||
&& nodes.every(node => node.permissions !== Permission.NONE)
|
||||
},
|
||||
|
||||
async exec(node: Node, view: Navigation) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
import { action } from './sidebarAction'
|
||||
import { expect } from '@jest/globals'
|
||||
import { File } from '@nextcloud/files'
|
||||
import { File, Permission } from '@nextcloud/files'
|
||||
import { FileAction } from '../services/FileAction'
|
||||
import type { Navigation } from '../services/Navigation'
|
||||
import logger from '../logger'
|
||||
|
|
@ -51,12 +51,29 @@ describe('Open sidebar action enabled tests', () => {
|
|||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.ALL,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(true)
|
||||
})
|
||||
|
||||
test('Disabled without permissions', () => {
|
||||
window.OCA = { Files: { Sidebar: {} } }
|
||||
|
||||
const file = new File({
|
||||
id: 1,
|
||||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.NONE,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
expect(action.enabled!([file], view)).toBe(false)
|
||||
|
||||
})
|
||||
|
||||
test('Disabled if more than one node', () => {
|
||||
window.OCA = { Files: { Sidebar: {} } }
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
*/
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import InformationSvg from '@mdi/svg/svg/information-variant.svg?raw'
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import { Permission, type Node } from '@nextcloud/files'
|
||||
|
||||
import { registerFileAction, FileAction, DefaultType } from '../services/FileAction'
|
||||
import { registerFileAction, FileAction } from '../services/FileAction'
|
||||
import logger from '../logger.js'
|
||||
|
||||
export const ACTION_DETAILS = 'details'
|
||||
|
|
@ -45,7 +45,7 @@ export const action = new FileAction({
|
|||
return false
|
||||
}
|
||||
|
||||
return nodes[0].root?.startsWith('/files/') ?? false
|
||||
return (nodes[0].root?.startsWith('/files/') && nodes[0].permissions !== Permission.NONE) ?? false
|
||||
},
|
||||
|
||||
async exec(node: Node) {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ describe('View in folder action enabled tests', () => {
|
|||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.ALL,
|
||||
})
|
||||
|
||||
expect(action.enabled).toBeDefined()
|
||||
|
|
@ -107,13 +108,14 @@ describe('View in folder action execute tests', () => {
|
|||
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
// Silent action
|
||||
expect(exec).toBe(null)
|
||||
expect(goToRouteMock).toBeCalledTimes(1)
|
||||
expect(goToRouteMock).toBeCalledWith(null, { view: 'files' }, { dir: '/' })
|
||||
expect(goToRouteMock).toBeCalledWith(null, { fileid: 1, view: 'files' }, { fileid: 1, dir: '/' })
|
||||
})
|
||||
|
||||
test('View in (sub) folder', async () => {
|
||||
|
|
@ -126,13 +128,14 @@ describe('View in folder action execute tests', () => {
|
|||
root: '/files/admin',
|
||||
owner: 'admin',
|
||||
mime: 'text/plain',
|
||||
permissions: Permission.READ,
|
||||
})
|
||||
|
||||
const exec = await action.exec(file, view, '/')
|
||||
// Silent action
|
||||
expect(exec).toBe(null)
|
||||
expect(goToRouteMock).toBeCalledTimes(1)
|
||||
expect(goToRouteMock).toBeCalledWith(null, { view: 'files' }, { dir: '/Foo/Bar' })
|
||||
expect(goToRouteMock).toBeCalledWith(null, { fileid: 1, view: 'files' }, { fileid: 1, dir: '/Foo/Bar' })
|
||||
})
|
||||
|
||||
test('View in folder fails without node', async () => {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { Node, FileType } from '@nextcloud/files'
|
||||
import { Node, FileType, Permission } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import FolderMoveSvg from '@mdi/svg/svg/folder-move.svg?raw'
|
||||
|
||||
|
|
@ -46,6 +46,10 @@ export const action = new FileAction({
|
|||
return false
|
||||
}
|
||||
|
||||
if (node.permissions === Permission.NONE) {
|
||||
return false
|
||||
}
|
||||
|
||||
return node.type === FileType.File
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export const useFilesStore = function(...args) {
|
|||
// Update the store all at once
|
||||
const files = nodes.reduce((acc, node) => {
|
||||
if (!node.fileid) {
|
||||
logger.warn('Trying to update/set a node without fileid', node)
|
||||
logger.error('Trying to update/set a node without fileid', node)
|
||||
return acc
|
||||
}
|
||||
acc[node.fileid] = node
|
||||
|
|
|
|||
|
|
@ -129,9 +129,16 @@ export default () => {
|
|||
// Add a folder to the favorites paths array and update the views
|
||||
const addPathToFavorites = function(path: string) {
|
||||
const view = generateFolderView(path)
|
||||
|
||||
// Skip if already exists
|
||||
if (favoriteFolders.find(folder => folder === path)) {
|
||||
return
|
||||
}
|
||||
|
||||
// Update arrays
|
||||
favoriteFolders.push(path)
|
||||
favoriteFoldersViews.push(view)
|
||||
|
||||
// Update and sort views
|
||||
updateAndSortViews()
|
||||
Navigation.register(view)
|
||||
|
|
@ -140,10 +147,18 @@ export default () => {
|
|||
// Remove a folder from the favorites paths array and update the views
|
||||
const removePathFromFavorites = function(path: string) {
|
||||
const id = generateIdFromPath(path)
|
||||
const index = favoriteFolders.findIndex(f => f === path)
|
||||
const index = favoriteFolders.findIndex(folder => folder === path)
|
||||
|
||||
// Skip if not exists
|
||||
if (index === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
// Update arrays
|
||||
favoriteFolders.splice(index, 1)
|
||||
favoriteFoldersViews.splice(index, 1)
|
||||
|
||||
// Update and sort views
|
||||
Navigation.remove(id)
|
||||
updateAndSortViews()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue