🩹 backend,oo: adding userId override for application updatingEditingSession (#525)

This commit is contained in:
Eric Doughty-Papassideris
2024-09-19 02:50:36 +02:00
parent 5ae1782490
commit c855c29664
5 changed files with 35 additions and 15 deletions
@@ -1075,6 +1075,8 @@ export class DocumentsService {
* @param options Optional upload information from the request * @param options Optional upload information from the request
* @param keepEditing If `true`, the file will be saved as a new version, * @param keepEditing If `true`, the file will be saved as a new version,
* and the DriveFile will keep its editing_session_key. If `true`, a file is required. * and the DriveFile will keep its editing_session_key. If `true`, a file is required.
* @param userId When authentified by the root token of an application, this user
* will override the creator of this version
* @param context * @param context
*/ */
updateEditing = async ( updateEditing = async (
@@ -1082,8 +1084,12 @@ export class DocumentsService {
file: MultipartFile, file: MultipartFile,
options: UploadOptions, options: UploadOptions,
keepEditing: boolean, keepEditing: boolean,
userId: string | null,
context: CompanyExecutionContext, context: CompanyExecutionContext,
) => { ) => {
//TODO rethink the locking stuff shouldn't be just forgotten
//TODO Make this accept even if missing and act ok about it,
// store to dump folder or such
if (!context) { if (!context) {
this.logger.error("invalid execution context"); this.logger.error("invalid execution context");
return null; return null;
@@ -1092,14 +1098,22 @@ export class DocumentsService {
this.logger.error("Invalid editing_session_key: " + JSON.stringify(editing_session_key)); this.logger.error("Invalid editing_session_key: " + JSON.stringify(editing_session_key));
throw new CrudException("Invalid editing_session_key", 400); throw new CrudException("Invalid editing_session_key", 400);
} }
//TODO If the app is the "user" calling, set user to that from the parsed key
try { try {
const parsedKey = EditingSessionKeyFormat.parse(editing_session_key); const parsedKey = EditingSessionKeyFormat.parse(editing_session_key);
context = { context = {
...context, ...context,
company: { id: parsedKey.companyId }, company: { id: parsedKey.companyId },
}; };
if (context.user.id === context.user.application_id && context.user.application_id) {
context = {
...context,
user: {
...context.user,
id: userId || parsedKey.userId,
},
};
}
} catch (e) { } catch (e) {
this.logger.error( this.logger.error(
"Invalid editing_session_key value: " + JSON.stringify(editing_session_key), "Invalid editing_session_key value: " + JSON.stringify(editing_session_key),
@@ -386,6 +386,7 @@ export class DocumentsController {
null, null,
null, null,
false, false,
null,
context, context,
); );
} catch (error) { } catch (error) {
@@ -401,7 +402,7 @@ export class DocumentsController {
updateEditing = async ( updateEditing = async (
request: FastifyRequest<{ request: FastifyRequest<{
Params: ItemRequestByEditingSessionKeyParams; Params: ItemRequestByEditingSessionKeyParams;
Querystring: { keepEditing?: string }; Querystring: { keepEditing?: string; userId?: string };
Body: { Body: {
item: Partial<DriveFile>; item: Partial<DriveFile>;
version: Partial<FileVersion>; version: Partial<FileVersion>;
@@ -430,6 +431,7 @@ export class DocumentsController {
file, file,
options, options,
request.query.keepEditing == "true", request.query.keepEditing == "true",
request.query.userId,
context, context,
); );
} else { } else {
@@ -438,6 +440,7 @@ export class DocumentsController {
null, null,
null, null,
true, true,
request.query.userId,
context, context,
); );
} }
@@ -409,17 +409,21 @@ export default class UserApi {
}); });
} }
async endEditingDocument( async updateEditingDocument(
editingSessionKey: string editingSessionKey: string,
keepEditing: boolean = false,
userId: string | null = null,
): Promise<Response> { ): Promise<Response> {
const fullPath = `${__dirname}/assets/${UserApi.ALL_FILES[0]}`; const fullPath = `${__dirname}/assets/${UserApi.ALL_FILES[0]}`;
const readable= Readable.from(fs.createReadStream(fullPath)); const readable= Readable.from(fs.createReadStream(fullPath));
const form = formAutoContent({ file: readable }); const form = formAutoContent({ file: readable });
form.headers["authorization"] = `Bearer ${this.jwt}`; form.headers["authorization"] = `Bearer ${this.jwt}`;
let queryString = keepEditing ? "keepEditing=true" : "";
if (userId)
queryString += `${queryString.length ? "&" : ""}userId=${encodeURIComponent(userId)}`;
return await this.platform.app.inject({ return await this.platform.app.inject({
method: "POST", method: "POST",
url: `${UserApi.DOC_URL}/editing_session/${editingSessionKey}`, url: `${UserApi.DOC_URL}/editing_session/${encodeURIComponent(editingSessionKey)}${queryString ? "?" : ""}${queryString}`,
headers: { headers: {
authorization: `Bearer ${this.jwt}` authorization: `Bearer ${this.jwt}`
}, },
@@ -4,7 +4,6 @@ import { init, TestPlatform } from "../setup";
import UserApi from "../common/user-api"; import UserApi from "../common/user-api";
import { DriveFile, TYPE as DriveFileType } from "../../../src/services/documents/entities/drive-file"; import { DriveFile, TYPE as DriveFileType } from "../../../src/services/documents/entities/drive-file";
import exp = require("node:constants");
import ApplicationsApiService, { ApplicationEditingKeyStatus } from "../../../src/services/applications-api"; import ApplicationsApiService, { ApplicationEditingKeyStatus } from "../../../src/services/applications-api";
import { afterEach } from "node:test"; import { afterEach } from "node:test";
import Application from "../../../src/services/applications/entities/application"; import Application from "../../../src/services/applications/entities/application";
@@ -135,7 +134,7 @@ describe("the Drive's documents' editing session kind-of-lock", () => {
//given //given
const editingSessionKey = await currentUser.beginEditingDocumentExpectOk(temporaryDocument.id, 'e2e_testing'); const editingSessionKey = await currentUser.beginEditingDocumentExpectOk(temporaryDocument.id, 'e2e_testing');
//when //when
const response = await currentUser.endEditingDocument(editingSessionKey); const response = await currentUser.updateEditingDocument(editingSessionKey);
//then //then
expect(response.statusCode).toBe(200); expect(response.statusCode).toBe(200);
@@ -93,15 +93,15 @@ class DriveService implements IDriveService {
} }
} }
public async addEditingSessionVersion(editing_session_key: string, url: string, user_token?: string) { public async addEditingSessionVersion(editing_session_key: string, url: string, userId?: string) {
return this.updateEditing(editing_session_key, url, true, user_token); return this.updateEditing(editing_session_key, url, true, userId);
} }
public async endEditing(editing_session_key: string, url: string, user_token?: string) { public async endEditing(editing_session_key: string, url: string, userId?: string) {
return this.updateEditing(editing_session_key, url, false, user_token); return this.updateEditing(editing_session_key, url, false, userId);
} }
private async updateEditing(editing_session_key: string, url: string, keepEditing: boolean, user_token?: string) { private async updateEditing(editing_session_key: string, url: string, keepEditing: boolean, userId?: string) {
try { try {
if (!url) { if (!url) {
throw Error('no url found'); throw Error('no url found');
@@ -121,9 +121,9 @@ class DriveService implements IDriveService {
await apiService.post({ await apiService.post({
url: makeEditingSessionItemUrl(editing_session_key, { url: makeEditingSessionItemUrl(editing_session_key, {
keepEditing: keepEditing ? 'true' : null, keepEditing: keepEditing ? 'true' : null,
userId,
}), }),
payload: form, payload: form,
token: user_token,
headers: form.getHeaders(), headers: form.getHeaders(),
}); });
} catch (error) { } catch (error) {