Skip to content

Commit

Permalink
fix: Allow to mount the collectives user folder into a subfolder
Browse files Browse the repository at this point in the history
Fixes: #514

Signed-off-by: Jonas <jonas@freesources.org>
  • Loading branch information
mejo- committed Sep 25, 2024
1 parent ffa54c8 commit 6c2741e
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 24 deletions.
4 changes: 2 additions & 2 deletions lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ private function validateSetUserSetting(string $setting, ?string $value): void {
}

if ($setting === 'user_folder') {
// No root folder, has to start with `/`, no subfolder
// No root folder, has to start with `/`, not allowed to end with `/`
if ($value === '/'
|| !(str_starts_with($value, '/'))
|| str_contains(substr($value, 1), '/')) {
|| str_ends_with($value, '/')) {
throw new InvalidArgumentException('Invalid collectives folder path');
}

Expand Down
11 changes: 8 additions & 3 deletions lib/Mount/MountProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,15 @@ public function getFoldersForUser(IUser $user): array {
return $folders;
}

$userFolderSetting = $this->userFolderHelper->getUserFolderSetting($user->getUID());
$internalPathPrefix = 'files';
$userFolderPath = substr($userFolder->getInternalPath(), 0, strlen($internalPathPrefix)) == $internalPathPrefix
? substr($userFolder->getInternalPath(), strlen('files')) . '/'
: $userFolder->getName() . '/';
$mountPointPath = ($userFolderSetting === '/')
? ''
: $userFolderPath;
foreach ($collectives as $c) {
$mountPointPath = ($this->userFolderHelper->getUserFolderSetting($user->getUID()) === '/')
? ''
: $userFolder->getName() . '/';
$mountPointName = $c->getName();
try {
$cacheEntry = $this->collectiveFolderManager->getFolderFileCache($c->getId(), $mountPointName);
Expand Down
4 changes: 2 additions & 2 deletions src/components/Nav/CollectivesGlobalSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export default {
.build()
picker.pick()
.then((path) => {
// No root folder, has to start with `/`, no subfolder
// No root folder, has to start with `/`, not allowed to end with `/`
if (path === '/'
|| !path.startsWith('/')
|| path.includes('/', 1)) {
|| path.endsWith('/')) {
const error = t('collectives', 'Invalid path selected. Only folders on first level are supported.')
showError(error)
throw new Error(error)
Expand Down
32 changes: 17 additions & 15 deletions tests/Integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class FeatureContext implements Context {
private array $cookieJars = [];
private array $requestTokens = [];
private array $store = [];
private bool $setXdebugSession = false;

private const CIRCLE_MEMBER_LEVEL = [
1 => 'Member',
Expand Down Expand Up @@ -586,14 +587,18 @@ public function userSetsPageSubpageOrder(string $user, string $page, string $sub
*
* @throws GuzzleException
*/
public function userGetsSetting(string $user, string $key, string $value): void {
public function userGetsSetting(string $user, string $key, ?string $value = null): string {
$this->setCurrentUser($user);

$this->sendOcsRequest('GET', '/apps/collectives/api/v1.0/settings/user/' . $key);
$this->assertStatusCode(200);

$jsonBody = $this->getJson();
Assert::assertEquals($value, $jsonBody['ocs']['data']);
if ($value) {
Assert::assertEquals($value, $jsonBody['ocs']['data']);
}

return $jsonBody['ocs']['data'];
}

/**
Expand Down Expand Up @@ -1301,13 +1306,8 @@ public function anonymousSeesPageShareAttachments(string $name, string $mimetype
}

private function getUserCollectivesPath(string $user): string {
// Dirty hack to not break it on local dev setup
$lang = $this->getUserLanguage($user);
if ($lang === 'de') {
return 'Kollektive';
}

return 'Collectives';
$this->setCurrentUser($user);
return $this->userGetsSetting($user, 'user_folder');
}

/**
Expand All @@ -1330,7 +1330,7 @@ public function hasWebdavAccess(string $collective, string $user, string $permis
$body = $dom->saveXML();
$userCollectivesPath = $this->getUserCollectivesPath($user);

$this->sendRemoteRequest('PROPFIND', '/dav/files/' . $user . '/' . $userCollectivesPath . '/' . urlencode($collective) . '/', $body, null, $headers);
$this->sendRemoteRequest('PROPFIND', '/dav/files/' . $user . $userCollectivesPath . '/' . urlencode($collective) . '/', $body, null, $headers);
$this->assertStatusCode(207);

// simplexml_load_string() would be better than preg_replace
Expand Down Expand Up @@ -1732,11 +1732,13 @@ private function sendRequestBase(string $verb,
}

// Add Xdebug trigger variable as GET parameter
$xdebugSession = 'XDEBUG_SESSION=PHPSTORM';
if (str_contains($url, '?')) {
$url .= '&' . $xdebugSession;
} else {
$url .= '?' . $xdebugSession;
if ($this->setXdebugSession) {
$xdebugSession = 'XDEBUG_SESSION=PHPSTORM';
if (str_contains($url, '?')) {
$url .= '&' . $xdebugSession;
} else {
$url .= '?' . $xdebugSession;
}
}

// clear the cached json response
Expand Down
8 changes: 8 additions & 0 deletions tests/Integration/features/mountpoint.feature
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ Feature: mountpoint
And user "alice" has webdav access to "BehatMountPoint" with permissions "RMG"
And user "bob" has webdav access to "BehatMountPoint" with permissions "MG"

Scenario: Change collectives user folder for user
When user "bob" sets setting "user_folder" to value "/some/folder"
Then user "jane" has webdav access to "BehatMountPoint" with permissions "RMGDNVCK"
And user "john" has webdav access to "BehatMountPoint" with permissions "RMGDNVCK"
And user "alice" has webdav access to "BehatMountPoint" with permissions "RMG"
And user "bob" has webdav access to "BehatMountPoint" with permissions "MG"
Then user "bob" sets setting "user_folder" to value "/Collectives"

Scenario: Trash page via webdav
When user "bob" fails to trash page "firstpage" via webdav in "BehatMountPoint"
And user "jane" trashes page "firstpage" via webdav in "BehatMountPoint"
Expand Down
10 changes: 8 additions & 2 deletions tests/Unit/Controller/SettingsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,28 @@ public function testSetUserSettingsEmptyString(): void {
public function testSetUserSettingsNoSlashStart(): void {
$response = new DataResponse('Invalid collectives folder path', Http::STATUS_BAD_REQUEST);
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', 'test'));
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', '/test/'));
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', 'test/'));
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', 'test/abc'));
}

public function testSetUserSettingsRootFolder(): void {
$response = new DataResponse('Invalid collectives folder path', Http::STATUS_BAD_REQUEST);
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', '/'));
}

public function testSetUserSettingsMultipleSlashes(): void {
public function testSetUserSettingsSlashEnd(): void {
$response = new DataResponse('Invalid collectives folder path', Http::STATUS_BAD_REQUEST);
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', '/test/'));
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', '/test/abc/'));
}

public function testSetUserSettings(): void {
$response = new DataResponse('/test', Http::STATUS_OK);
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', '/test'));
}

public function testSetUserSettingsSubfolder(): void {
$response = new DataResponse('/test/abc', Http::STATUS_OK);
self::assertEquals($response, $this->settingsController->setUserSetting('user_folder', '/test/abc'));
}
}

0 comments on commit 6c2741e

Please sign in to comment.