fix(files): actions permissions requirements

Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ 2023-07-06 15:21:07 +02:00
parent 6f54f72bb4
commit a9f7e66d3d
No known key found for this signature in database
GPG key ID: 60C25B8C072916CF
8 changed files with 59 additions and 16 deletions

View file

@ -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()

View file

@ -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) {

View file

@ -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: {} } }

View file

@ -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) {

View file

@ -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 () => {

View file

@ -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
},

View 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

View file

@ -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()
}