🔢 Shared with me filters (#79)
✨ feat: shared with me filters 🐛 Fix try to access the service with init 🌐 feat: shared with me i18n 🌐russian translation --------- Co-authored-by: Anton SHEPILOV <ashepilov@linagora.com>
This commit is contained in:
@@ -1,88 +0,0 @@
|
||||
import yargs from "yargs";
|
||||
import ora from "ora";
|
||||
import tdrive from "../../../tdrive";
|
||||
import Table from "cli-table";
|
||||
import { exit } from "process";
|
||||
import gr from "../../../services/global-resolver";
|
||||
|
||||
/**
|
||||
* Merge command parameters. Check the builder definition below for more details.
|
||||
*/
|
||||
type CLIArgs = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
const services = [
|
||||
"storage",
|
||||
"counter",
|
||||
"message-queue",
|
||||
"platform-services",
|
||||
"user",
|
||||
"search",
|
||||
"database",
|
||||
"webserver",
|
||||
"statistics",
|
||||
"applications",
|
||||
"auth",
|
||||
"realtime",
|
||||
"websocket",
|
||||
];
|
||||
|
||||
const command: yargs.CommandModule<unknown, CLIArgs> = {
|
||||
command: "remove",
|
||||
describe: "command that allow you to remove one user",
|
||||
builder: {
|
||||
id: {
|
||||
default: "",
|
||||
type: "string",
|
||||
description: "User ID",
|
||||
},
|
||||
},
|
||||
handler: async argv => {
|
||||
const tableBefore = new Table({
|
||||
head: ["User ID", "Username", "Deleted"],
|
||||
colWidths: [40, 40, 10],
|
||||
});
|
||||
const tableAfter = new Table({
|
||||
head: ["User ID", "Username", "Deleted"],
|
||||
colWidths: [40, 40, 10],
|
||||
});
|
||||
const spinner = ora({ text: "Retrieving user" }).start();
|
||||
|
||||
const platform = await tdrive.run(services);
|
||||
await gr.doInit(platform);
|
||||
|
||||
const user = await gr.services.users.get({ id: argv.id });
|
||||
|
||||
if (!user) {
|
||||
console.error("Error: You need to provide User ID");
|
||||
spinner.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (user) {
|
||||
// Table before
|
||||
tableBefore.push([user.id, user.username_canonical, user.deleted]);
|
||||
|
||||
await gr.services.users.anonymizeAndDelete(
|
||||
{ id: user.id },
|
||||
{
|
||||
user: { id: user.id, server_request: true },
|
||||
},
|
||||
);
|
||||
|
||||
const finalUser = await gr.services.users.get({ id: argv.id });
|
||||
|
||||
// Table after
|
||||
tableAfter.push([finalUser.id, finalUser.username_canonical, finalUser.deleted]);
|
||||
|
||||
spinner.stop();
|
||||
}
|
||||
|
||||
exit();
|
||||
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
export default command;
|
||||
@@ -85,7 +85,7 @@ export type AccessInformation = {
|
||||
entities: AuthEntity[];
|
||||
};
|
||||
|
||||
type AuthEntity = {
|
||||
export type AuthEntity = {
|
||||
type: "user" | "channel" | "company" | "folder";
|
||||
id: string | "parent";
|
||||
level: publicAccessLevel | DriveFileAccessLevel;
|
||||
|
||||
@@ -3,7 +3,7 @@ import _ from "lodash";
|
||||
import { logger } from "../../../core/platform/framework";
|
||||
import Repository from "../../../core/platform/services/database/services/orm/repository/repository";
|
||||
import globalResolver from "../../global-resolver";
|
||||
import { AccessInformation, DriveFile } from "../entities/drive-file";
|
||||
import { AccessInformation, AuthEntity, DriveFile } from "../entities/drive-file";
|
||||
import { CompanyExecutionContext, DriveFileAccessLevel } from "../types";
|
||||
|
||||
/**
|
||||
@@ -341,11 +341,20 @@ export const getSharedByUser = (
|
||||
for (const idx in accessInfo?.entities) {
|
||||
const entity = accessInfo.entities[idx];
|
||||
if (entity.type === "user" && entity.id === context.user?.id) {
|
||||
return entity.grantor;
|
||||
return getGrantorAndThrowIfEmpty(entity);
|
||||
}
|
||||
if (entity.type === "company" && entity.id === context.company.id) {
|
||||
return entity.grantor;
|
||||
if (entity.type === "company" && entity.id === context.company.id && entity.level != "none") {
|
||||
console.log("company", entity);
|
||||
return getGrantorAndThrowIfEmpty(entity);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const getGrantorAndThrowIfEmpty = (entity: AuthEntity) => {
|
||||
if (!entity.grantor) {
|
||||
logger.warn(`For the file permissions ${entity.id} grantor is not defined`);
|
||||
// throw CrudException.badGateway(`For the file permissions ${entity.id} grantor is not defined`);
|
||||
}
|
||||
return entity.grantor;
|
||||
};
|
||||
|
||||
+13
-13
@@ -1,17 +1,19 @@
|
||||
import { DriveFile } from "../../entities/drive-file";
|
||||
import { DriveFileDTO } from "./drive-file-dto";
|
||||
import { DriveFile } from "../entities/drive-file";
|
||||
import { DriveFileDTO } from "../web/dto/drive-file-dto";
|
||||
import {
|
||||
ListResult,
|
||||
Paginable,
|
||||
Pagination,
|
||||
} from "../../../../core/platform/framework/api/crud-service";
|
||||
} from "../../../core/platform/framework/api/crud-service";
|
||||
import _ from "lodash";
|
||||
import { CompanyExecutionContext } from "../../types";
|
||||
import globalResolver from "../../../../services/global-resolver";
|
||||
import User from "../../../../services/user/entities/user";
|
||||
import { getSharedByUser } from "../../services/access-check";
|
||||
import { CompanyExecutionContext } from "../types";
|
||||
import User from "../../user/entities/user";
|
||||
import { getSharedByUser } from "./access-check";
|
||||
import globalResolver from "../../../services/global-resolver";
|
||||
|
||||
export class DriveFileDTOBuilder {
|
||||
static VIEW_SHARED_WITH_ME = "shared_with_me";
|
||||
|
||||
private views: Map<string, string[]> = new Map([
|
||||
[
|
||||
"default",
|
||||
@@ -35,7 +37,7 @@ export class DriveFileDTOBuilder {
|
||||
],
|
||||
],
|
||||
[
|
||||
"shared_with_me",
|
||||
DriveFileDTOBuilder.VIEW_SHARED_WITH_ME,
|
||||
[
|
||||
"id",
|
||||
"name",
|
||||
@@ -51,7 +53,6 @@ export class DriveFileDTOBuilder {
|
||||
],
|
||||
],
|
||||
]);
|
||||
usersService = globalResolver.services?.users;
|
||||
|
||||
public async build(
|
||||
files: ListResult<DriveFile>,
|
||||
@@ -59,8 +60,6 @@ export class DriveFileDTOBuilder {
|
||||
fields?: string[],
|
||||
view?: string,
|
||||
): Promise<ListResult<DriveFileDTO>> {
|
||||
const file = new DriveFile();
|
||||
file.id = "1";
|
||||
if (view) {
|
||||
fields = this.views.get(view);
|
||||
}
|
||||
@@ -110,9 +109,10 @@ export class DriveFileDTOBuilder {
|
||||
});
|
||||
}
|
||||
|
||||
private async fetchUsers(ids: string[]) {
|
||||
async fetchUsers(ids: string[]) {
|
||||
ids.filter(id => id != null);
|
||||
return (
|
||||
await this.usersService.list(
|
||||
await globalResolver.services.users.list(
|
||||
{
|
||||
limitStr: ids.length.toString(),
|
||||
} as Pagination,
|
||||
@@ -783,9 +783,7 @@ export class DocumentsService {
|
||||
limitStr: "100",
|
||||
},
|
||||
$in: [
|
||||
...(options.onlyDirectlyShared
|
||||
? [["access_entities", [context.user.id, context.company.id]] as inType]
|
||||
: []),
|
||||
...(options.onlyDirectlyShared ? [["access_entities", [context.user.id]] as inType] : []),
|
||||
...(options.company_id ? [["company_id", [options.company_id]] as inType] : []),
|
||||
...(options.creator ? [["creator", [options.creator]] as inType] : []),
|
||||
...(options.mime_type
|
||||
@@ -834,9 +832,17 @@ export class DocumentsService {
|
||||
});
|
||||
|
||||
return new ListResult(result.type, filteredResult, result.nextPage);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (options.onlyUploadedNotByMe) {
|
||||
const filteredResult = await this.filter(result.getEntities(), async item => {
|
||||
return item.creator != context.user.id;
|
||||
});
|
||||
|
||||
return new ListResult(result.type, filteredResult, result.nextPage);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
private async filter(arr, callback) {
|
||||
|
||||
@@ -48,6 +48,7 @@ export type SearchDocumentsOptions = {
|
||||
view?: string;
|
||||
fields?: string[];
|
||||
onlyDirectlyShared?: boolean;
|
||||
onlyUploadedNotByMe?: boolean;
|
||||
};
|
||||
|
||||
export type SearchDocumentsBody = {
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
SearchDocumentsOptions,
|
||||
} from "../../types";
|
||||
import { DriveFileDTO } from "../dto/drive-file-dto";
|
||||
import { DriveFileDTOBuilder } from "../dto/drive-file-dto-builder";
|
||||
import { DriveFileDTOBuilder } from "../../services/drive-file-dto-builder";
|
||||
|
||||
export class DocumentsController {
|
||||
private driveFileDTOBuilder = new DriveFileDTOBuilder();
|
||||
@@ -154,7 +154,9 @@ export class DocumentsController {
|
||||
const options: SearchDocumentsOptions = {
|
||||
...request.body,
|
||||
company_id: request.body.company_id || context.company.id,
|
||||
view: DriveFileDTOBuilder.VIEW_SHARED_WITH_ME,
|
||||
onlyDirectlyShared: true,
|
||||
onlyUploadedNotByMe: true,
|
||||
};
|
||||
|
||||
if (!Object.keys(options).length) {
|
||||
|
||||
Reference in New Issue
Block a user