Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
test(files_external): Ensure Home folder permissions are correct
Signed-off-by: Louis Chemineau <[email protected]>
  • Loading branch information
artonge committed Sep 29, 2025
commit 1ab6dba24220677ce0426af8041b0ec4e2b2f0f2
22 changes: 22 additions & 0 deletions cypress/e2e/files_external/StorageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ export type StorageConfig = {
[key: string]: string
}

export type StorageMountOption = {
readonly: boolean
}

export enum StorageBackend {
DAV = 'dav',
SMB = 'smb',
SFTP = 'sftp',
LOCAL = 'local',
}

export enum AuthBackend {
Expand All @@ -22,6 +27,7 @@ export enum AuthBackend {
SessionCredentials = 'password::sessioncredentials',
UserGlobalAuth = 'password::global::user',
UserProvided = 'password::userprovided',
Null = 'null::null',
}

/**
Expand All @@ -35,4 +41,20 @@ export function createStorageWithConfig(mountPoint: string, storageBackend: Stor

cy.log(`Creating storage with command: ${command}`)
return cy.runOccCommand(command)
.then(({ stdout }) => {
return stdout.replace('Storage created with id ', '')
})
}

export function setStorageMountOptions(mountId: string, options: StorageMountOption) {
for (const [key, value] of Object.entries(options)) {
cy.runOccCommand(`files_external:option ${mountId} ${key} ${value}`)
}
}

export function deleteAllExternalStorages() {
cy.runOccCommand('files_external:list --all --output=json').then(({ stdout }) => {
const list = JSON.parse(stdout)
list.forEach((storage) => cy.runOccCommand(`files_external:delete --yes ${storage.mount_id}`), { failOnNonZeroExit: false })
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { User } from '@nextcloud/cypress'
import { AuthBackend, createStorageWithConfig, deleteAllExternalStorages, setStorageMountOptions, StorageBackend } from './StorageUtils'

describe('Home folder root mount permissions', { testIsolation: true }, () => {
let user1: User

before(() => {
cy.runOccCommand('app:enable files_external')
cy.createRandomUser().then((user) => { user1 = user })
})

after(() => {
deleteAllExternalStorages()
cy.runOccCommand('app:disable files_external')
})

it('Does not show write actions on read-only storage mounted at the root of the user\'s home folder', () => {
cy.login(user1)
cy.visit('/apps/files/')
cy.runOccCommand('config:app:get files overwrites_home_folders --default-value=[]')
.then(({ stdout }) => assert.equal(stdout.trim(), '[]'))

cy.get('[data-cy-upload-picker=""]').should('exist')

createStorageWithConfig('/', StorageBackend.LOCAL, AuthBackend.Null, { datadir: '/tmp' })
.then((id) => setStorageMountOptions(id, { readonly: true }))
// HACK: somehow, we need to create an external folder targeting a subpath for the previous one to show.
createStorageWithConfig('/a', StorageBackend.LOCAL, AuthBackend.Null, { datadir: '/tmp' })
cy.visit('/apps/files/')
cy.visit('/apps/files/')
cy.runOccCommand('config:app:get files overwrites_home_folders')
.then(({ stdout }) => assert.equal(stdout.trim(), '["files_external"]'))
cy.get('[data-cy-upload-picker=""]').should('not.exist')

deleteAllExternalStorages()
cy.visit('/apps/files/')
cy.runOccCommand('config:app:get files overwrites_home_folders')
.then(({ stdout }) => assert.equal(stdout.trim(), '[]'))
cy.get('[data-cy-upload-picker=""]').should('exist')
})
})
Loading