Skip to content

Commit a3f7ed0

Browse files
committed
test(files_external); Ensure Home folder permissions are correct
Signed-off-by: Louis Chemineau <[email protected]>
1 parent 38cde59 commit a3f7ed0

3 files changed

Lines changed: 99 additions & 32 deletions

File tree

cypress/dockerNode.ts

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,37 @@ const SERVER_IMAGE = 'ghcr.io/nextcloud/continuous-integration-shallow-server'
2626
export const startNextcloud = async function(branch: string = getCurrentGitBranch()): Promise<any> {
2727

2828
try {
29-
try {
30-
// Pulling images
31-
console.log('\nPulling images... ⏳')
32-
await new Promise((resolve, reject): any => docker.pull(SERVER_IMAGE, (err, stream) => {
33-
if (err) {
34-
reject(err)
35-
}
36-
if (stream === null) {
37-
reject(new Error('Could not connect to docker, ensure docker is running.'))
38-
return
39-
}
40-
41-
// https://github.com/apocas/dockerode/issues/357
42-
docker.modem.followProgress(stream, onFinished)
43-
44-
function onFinished(err) {
45-
if (!err) {
46-
resolve(true)
47-
return
48-
}
49-
reject(err)
50-
}
51-
}))
52-
53-
const digest = await (await docker.getImage(SERVER_IMAGE).inspect()).RepoDigests.at(0)
54-
const sha = digest?.split('@').at(1)
55-
console.log('├─ Using image ' + sha)
56-
console.log('└─ Done')
57-
} catch (e) {
58-
console.log('└─ Failed to pull images')
59-
throw e
60-
}
29+
// try {
30+
// // Pulling images
31+
// console.log('\nPulling images... ⏳')
32+
// await new Promise((resolve, reject): any => docker.pull(SERVER_IMAGE, (err, stream) => {
33+
// if (err) {
34+
// reject(err)
35+
// }
36+
// if (stream === null) {
37+
// reject(new Error('Could not connect to docker, ensure docker is running.'))
38+
// return
39+
// }
40+
41+
// // https://github.com/apocas/dockerode/issues/357
42+
// docker.modem.followProgress(stream, onFinished)
43+
44+
// function onFinished(err) {
45+
// if (!err) {
46+
// resolve(true)
47+
// return
48+
// }
49+
// reject(err)
50+
// }
51+
// }))
52+
53+
// const digest = await (await docker.getImage(SERVER_IMAGE).inspect()).RepoDigests.at(0)
54+
// const sha = digest?.split('@').at(1)
55+
// console.log('├─ Using image ' + sha)
56+
// console.log('└─ Done')
57+
// } catch (e) {
58+
// console.log('└─ Failed to pull images')
59+
// }
6160

6261
// Remove old container if exists
6362
console.log('\nChecking running containers... 🔍')

cypress/e2e/files_external/StorageUtils.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ export type StorageConfig = {
99
[key: string]: string
1010
}
1111

12+
export type StorageMountOption = {
13+
readonly: boolean
14+
}
15+
1216
export enum StorageBackend {
1317
DAV = 'dav',
1418
SMB = 'smb',
1519
SFTP = 'sftp',
20+
LOCAL = 'local',
1621
}
1722

1823
export enum AuthBackend {
@@ -22,6 +27,7 @@ export enum AuthBackend {
2227
SessionCredentials = 'password::sessioncredentials',
2328
UserGlobalAuth = 'password::global::user',
2429
UserProvided = 'password::userprovided',
30+
Null = 'null::null',
2531
}
2632

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

3642
cy.log(`Creating storage with command: ${command}`)
3743
return cy.runOccCommand(command)
44+
.then(({ stdout }) => {
45+
return stdout.replace('Storage created with id ', '')
46+
})
47+
}
48+
49+
export function setStorageMountOptions(mountId: string, options: StorageMountOption) {
50+
for (const [key, value] of Object.entries(options)) {
51+
cy.runOccCommand(`files_external:option ${mountId} ${key} ${value}`)
52+
}
53+
}
54+
55+
export function deleteAllExternalStorages() {
56+
cy.runOccCommand('files_external:list --all --output=json').then(({ stdout }) => {
57+
const list = JSON.parse(stdout)
58+
list.forEach((storage) => cy.runOccCommand(`files_external:delete --yes ${storage.mount_id}`), { failOnNonZeroExit: false })
59+
})
3860
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { User } from '@nextcloud/cypress'
7+
import { AuthBackend, createStorageWithConfig, deleteAllExternalStorages, setStorageMountOptions, StorageBackend } from './StorageUtils'
8+
9+
describe('Home folder root mount permissions', { testIsolation: true }, () => {
10+
let user1: User
11+
12+
before(() => {
13+
cy.runOccCommand('app:enable files_external')
14+
cy.createRandomUser().then((user) => { user1 = user })
15+
})
16+
17+
after(() => {
18+
deleteAllExternalStorages()
19+
cy.runOccCommand('app:disable files_external')
20+
})
21+
22+
it('Does not show write actions on read-only storage mounted at the root of the user\'s home folder', () => {
23+
cy.login(user1)
24+
cy.visit('/apps/files/')
25+
cy.runOccCommand('config:app:get files overwrites_home_folders')
26+
.then(({ stdout }) => assert.equal(stdout.trim(), '[]'))
27+
cy.get('[data-cy-upload-picker=""]').should('exist')
28+
29+
30+
createStorageWithConfig('/', StorageBackend.LOCAL, AuthBackend.Null, { datadir: '/tmp' })
31+
.then((id) => setStorageMountOptions(id, { readonly: true }))
32+
// HACK: somehow, we need to create an external folder targeting a subpath for the previous one to show.
33+
createStorageWithConfig('/a', StorageBackend.LOCAL, AuthBackend.Null, { datadir: '/tmp' })
34+
cy.visit('/apps/files/')
35+
cy.visit('/apps/files/')
36+
cy.runOccCommand('config:app:get files overwrites_home_folders')
37+
.then(({ stdout }) => assert.equal(stdout.trim(), '["files_external"]'))
38+
cy.get('[data-cy-upload-picker=""]').should('not.exist')
39+
40+
deleteAllExternalStorages()
41+
cy.visit('/apps/files/')
42+
cy.runOccCommand('config:app:get files overwrites_home_folders')
43+
.then(({ stdout }) => assert.equal(stdout.trim(), '[]'))
44+
cy.get('[data-cy-upload-picker=""]').should('exist')
45+
})
46+
})

0 commit comments

Comments
 (0)