mirror of
https://github.com/nextcloud/richdocuments.git
synced 2025-12-17 21:12:14 +01:00
fix(settings): generate user config per userId & handle guest users
Signed-off-by: codewithvk <vivek.javiya@collabora.com>
This commit is contained in:
parent
5defde2c0b
commit
969a4f90a8
5 changed files with 66 additions and 23 deletions
|
|
@ -38,7 +38,7 @@ return [
|
|||
['name' => 'settings#uploadFontFile', 'url' => 'settings/fonts', 'verb' => 'POST'],
|
||||
[
|
||||
'name' => 'settings#getSettingsFile',
|
||||
'url' => 'settings/{type}/{category}/{name}',
|
||||
'url' => 'settings/{type}/{token}/{category}/{name}',
|
||||
'verb' => 'GET',
|
||||
'requirements' => [
|
||||
'type' => '[a-zA-Z0-9_\-]+',
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace OCA\Richdocuments\Controller;
|
|||
|
||||
use OCA\Richdocuments\AppConfig;
|
||||
use OCA\Richdocuments\Capabilities;
|
||||
use OCA\Richdocuments\Db\WopiMapper;
|
||||
use OCA\Richdocuments\Service\CapabilitiesService;
|
||||
use OCA\Richdocuments\Service\ConnectivityService;
|
||||
use OCA\Richdocuments\Service\DemoService;
|
||||
|
|
@ -58,6 +59,7 @@ class SettingsController extends Controller {
|
|||
private SettingsService $settingsService,
|
||||
private LoggerInterface $logger,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private WopiMapper $wopiMapper,
|
||||
private ?string $userId,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
|
|
@ -484,8 +486,13 @@ class SettingsController extends Controller {
|
|||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
**/
|
||||
public function getSettingsFile(string $type, string $category, string $name) {
|
||||
public function getSettingsFile(string $type, string $token, string $category, string $name) {
|
||||
try {
|
||||
$wopi = $this->wopiMapper->getWopiForToken($token);
|
||||
if ($type === 'userconfig') {
|
||||
$userId = $wopi->getEditorUid() ?: $wopi->getOwnerUid();
|
||||
$type = $type . '/' . $userId;
|
||||
}
|
||||
$systemFile = $this->settingsService->getSettingsFile($type, $category, $name);
|
||||
return new DataDisplayResponse(
|
||||
$systemFile->getContent(),
|
||||
|
|
|
|||
|
|
@ -139,7 +139,9 @@ class WopiController extends Controller {
|
|||
|
||||
$userId = !$isPublic ? $wopi->getEditorUid() : $guestUserId;
|
||||
|
||||
$userSettings = $this->generateSettings($userId, 'userconfig');
|
||||
if (!$isPublic) {
|
||||
$userSettings = $this->generateSettings($userId, 'userconfig');
|
||||
}
|
||||
$sharedSettings = $this->generateSettings($userId, 'systemconfig');
|
||||
|
||||
$response = [
|
||||
|
|
@ -174,10 +176,13 @@ class WopiController extends Controller {
|
|||
'EnableRemoteAIContent' => $isTaskProcessingEnabled,
|
||||
'HasContentRange' => true,
|
||||
'ServerPrivateInfo' => [],
|
||||
'UserSettings' => $userSettings,
|
||||
'SharedSettings' => $sharedSettings,
|
||||
];
|
||||
|
||||
if (!$isPublic) {
|
||||
$response['UserSettings'] = $userSettings;
|
||||
}
|
||||
|
||||
$enableZotero = $this->config->getAppValue(Application::APPNAME, 'zoteroEnabled', 'yes') === 'yes';
|
||||
if (!$isPublic && $enableZotero) {
|
||||
$zoteroAPIKey = $this->config->getUserValue($wopi->getEditorUid(), 'richdocuments', 'zoteroAPIKey', '');
|
||||
|
|
@ -406,13 +411,12 @@ class WopiController extends Controller {
|
|||
if ($wopi->getTokenType() !== Wopi::TOKEN_TYPE_SETTING_AUTH) {
|
||||
return new JSONResponse(['error' => 'Invalid token type'], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$isPublic = empty($wopi->getEditorUid());
|
||||
$guestUserId = 'Guest-' . \OC::$server->getSecureRandom()->generate(8);
|
||||
$userId = !$isPublic ? $wopi->getEditorUid() : $guestUserId;
|
||||
|
||||
$user = $this->userManager->get($wopi->getOwnerUid());
|
||||
if (!$user || !$this->groupManager->isAdmin($user->getUID())) {
|
||||
return new JSONResponse(['error' => 'Access denied'], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$userConfig = $this->settingsService->generateSettingsConfig($type);
|
||||
$userConfig = $this->settingsService->generateSettingsConfig($type, $userId);
|
||||
return new JSONResponse($userConfig, Http::STATUS_OK);
|
||||
} catch (UnknownTokenException|ExpiredTokenException $e) {
|
||||
$this->logger->debug($e->getMessage(), ['exception' => $e]);
|
||||
|
|
@ -431,6 +435,7 @@ class WopiController extends Controller {
|
|||
try {
|
||||
$wopi = $this->wopiMapper->getWopiForToken($access_token);
|
||||
|
||||
$userId = $wopi->getEditorUid();
|
||||
// TODO: auth - for admin??
|
||||
$content = fopen('php://input', 'rb');
|
||||
if (!$content) {
|
||||
|
|
@ -442,7 +447,7 @@ class WopiController extends Controller {
|
|||
|
||||
// Use the fileId as a file path URL (e.g., "/settings/systemconfig/wordbook/en_US%20(1).dic")
|
||||
$settingsUrl = new SettingsUrl($fileId);
|
||||
$result = $this->settingsService->uploadFile($settingsUrl, $fileContent);
|
||||
$result = $this->settingsService->uploadFile($settingsUrl, $fileContent, $userId);
|
||||
|
||||
return new JSONResponse([
|
||||
'status' => 'success',
|
||||
|
|
@ -475,8 +480,9 @@ class WopiController extends Controller {
|
|||
$type = $settingsUrl->getType();
|
||||
$category = $settingsUrl->getCategory();
|
||||
$fileName = $settingsUrl->getFileName();
|
||||
$userId = $wopi->getEditorUid();
|
||||
|
||||
$this->settingsService->deleteSettingsFile($type, $category, $fileName);
|
||||
$this->settingsService->deleteSettingsFile($type, $category, $fileName, $userId);
|
||||
|
||||
return new JSONResponse([
|
||||
'status' => 'success',
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class WopiMapper extends QBMapper {
|
|||
$wopi = Wopi::fromParams([
|
||||
'fileid' => $fileId,
|
||||
'ownerUid' => $userId,
|
||||
'editorUid' => $userId,
|
||||
'version' => $version,
|
||||
'canwrite' => true,
|
||||
'serverHost' => $serverHost,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class SettingsService {
|
|||
* @return ISimpleFolder
|
||||
*/
|
||||
|
||||
public function ensureDirectory(SettingsUrl $settingsUrl): ISimpleFolder {
|
||||
public function ensureDirectory(SettingsUrl $settingsUrl, string $userId): ISimpleFolder {
|
||||
$type = $settingsUrl->getType();
|
||||
$category = $settingsUrl->getCategory();
|
||||
|
||||
|
|
@ -68,6 +68,14 @@ class SettingsService {
|
|||
$baseFolder = $this->appData->newFolder($type);
|
||||
}
|
||||
|
||||
if ($type === 'userconfig') {
|
||||
try {
|
||||
$baseFolder = $baseFolder->getFolder($userId);
|
||||
} catch (NotFoundException $e) {
|
||||
$baseFolder = $baseFolder->newFolder($userId);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$categoryFolder = $baseFolder->getFolder($category);
|
||||
} catch (NotFoundException $e) {
|
||||
|
|
@ -86,11 +94,11 @@ class SettingsService {
|
|||
* @return array ['stamp' => string, 'uri' => string]
|
||||
*/
|
||||
|
||||
public function uploadFile(SettingsUrl $settingsUrl, string $fileData): array {
|
||||
$categoryFolder = $this->ensureDirectory($settingsUrl);
|
||||
public function uploadFile(SettingsUrl $settingsUrl, string $fileData, string $userId): array {
|
||||
$categoryFolder = $this->ensureDirectory($settingsUrl, $userId);
|
||||
$fileName = $settingsUrl->getFileName();
|
||||
$newFile = $categoryFolder->newFile($fileName, $fileData);
|
||||
$fileUri = $this->generateFileUri($settingsUrl->getType(), $settingsUrl->getCategory(), $fileName);
|
||||
$fileUri = $this->generateFileUri($settingsUrl->getType(), $settingsUrl->getCategory(), $fileName, $userId);
|
||||
|
||||
return [
|
||||
'stamp' => $newFile->getETag(),
|
||||
|
|
@ -105,7 +113,7 @@ class SettingsService {
|
|||
* @param string $category
|
||||
* @return array Each item has 'stamp' and 'uri'.
|
||||
*/
|
||||
public function getCategoryFileList(string $type, string $category): array {
|
||||
public function getCategoryFileList(string $type, string $category, string $userId): array {
|
||||
try {
|
||||
$categoryFolder = $this->appData->getFolder($type . '/' . $category);
|
||||
} catch (NotFoundException $e) {
|
||||
|
|
@ -114,10 +122,10 @@ class SettingsService {
|
|||
|
||||
$files = $categoryFolder->getDirectoryListing();
|
||||
|
||||
return array_map(function (ISimpleFile $file) use ($type, $category) {
|
||||
return array_map(function (ISimpleFile $file) use ($type, $category, $userId) {
|
||||
return [
|
||||
'stamp' => $file->getETag(),
|
||||
'uri' => $this->generateFileUri($type, $category, $file->getName()),
|
||||
'uri' => $this->generateFileUri($type, $category, $file->getName(), $userId),
|
||||
];
|
||||
}, $files);
|
||||
}
|
||||
|
|
@ -155,17 +163,21 @@ class SettingsService {
|
|||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public function generateSettingsConfig(string $type): array {
|
||||
public function generateSettingsConfig(string $type, string $userId): array {
|
||||
$kind = $type === 'userconfig' ? 'user' : 'shared';
|
||||
|
||||
$config = [
|
||||
'kind' => $kind,
|
||||
];
|
||||
|
||||
if ($type === 'userconfig') {
|
||||
$type = $type . '/' . $userId;
|
||||
}
|
||||
|
||||
$categories = $this->getAllCategories($type);
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$files = $this->getCategoryFileList($type, $category);
|
||||
$files = $this->getCategoryFileList($type, $category, $userId);
|
||||
$config[$category] = $files;
|
||||
}
|
||||
|
||||
|
|
@ -220,11 +232,20 @@ class SettingsService {
|
|||
* @param string $fileName
|
||||
* @return string
|
||||
*/
|
||||
private function generateFileUri(string $type, string $category, string $fileName): string {
|
||||
private function generateFileUri(string $type, string $category, string $fileName, string $userId): string {
|
||||
|
||||
// Passing userId is dangerous so we have to trim from url...
|
||||
if (strpos($type, '/') !== false) {
|
||||
$type = explode('/', $type)[0];
|
||||
}
|
||||
|
||||
$token = $this->generateIframeToken($type, $userId);
|
||||
|
||||
return $this->urlGenerator->linkToRouteAbsolute(
|
||||
'richdocuments.settings.getSettingsFile',
|
||||
[
|
||||
'type' => $type,
|
||||
'token' => $token['token'],
|
||||
'category' => $category,
|
||||
'name' => $fileName,
|
||||
]
|
||||
|
|
@ -266,12 +287,20 @@ class SettingsService {
|
|||
* @param string $category
|
||||
* @param string $name
|
||||
*/
|
||||
public function deleteSettingsFile(string $type, string $category, string $name): void {
|
||||
public function deleteSettingsFile(string $type, string $category, string $name, string $userId): void {
|
||||
try {
|
||||
$baseFolder = $this->appData->getFolder($type);
|
||||
} catch (NotFoundException $e) {
|
||||
throw new NotFoundException("Type folder '{$type}' not found.");
|
||||
}
|
||||
|
||||
if ($type === 'userconfig') {
|
||||
try {
|
||||
$baseFolder = $baseFolder->getFolder($userId);
|
||||
} catch (NotFoundException $e) {
|
||||
throw new NotFoundException("User folder '{$userId}' not found.");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$categoryFolder = $baseFolder->getFolder($category);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue