feat: refactored getPathfromId to folder service

This commit is contained in:
Akhil Mohan
2023-08-08 22:33:59 +05:30
parent 8330890087
commit 91947df5f6
3 changed files with 41 additions and 83 deletions
@@ -1,29 +1,14 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import path from "path";
import { isValidScope, validateMembership } from "../../helpers"; import { isValidScope, validateMembership } from "../../helpers";
import { ServiceTokenData } from "../../models"; import { ServiceTokenData } from "../../models";
import Folder, { TFolderRootSchema } from "../../models/folder"; import Folder from "../../models/folder";
import SecretImport from "../../models/secretImports"; import SecretImport from "../../models/secretImports";
import { searchByFolderIdWithDir } from "../../services/FolderService";
import { getAllImportedSecrets } from "../../services/SecretImportService"; import { getAllImportedSecrets } from "../../services/SecretImportService";
import { getFolderWithPathFromId } from "../../services/FolderService";
import { BadRequestError, ResourceNotFoundError,UnauthorizedRequestError } from "../../utils/errors"; import { BadRequestError, ResourceNotFoundError,UnauthorizedRequestError } from "../../utils/errors";
import { ADMIN, MEMBER } from "../../variables"; import { ADMIN, MEMBER } from "../../variables";
import { EEAuditLogService } from "../../ee/services"; import { EEAuditLogService } from "../../ee/services";
import { EventType } from "../../ee/models"; import { EventType } from "../../ee/models";
import { getFolderPath } from "../../services/FolderService";
const getFolderWithPathFromId = (folders: TFolderRootSchema, parentFolderId: string) => {
const search = searchByFolderIdWithDir(folders.nodes, parentFolderId);
if (!search) {
throw { message: "Folder permission denied" };
}
const { folder, dir } = search;
const folderPath = path.join(
"/",
...dir.filter(({ name }) => name !== "root").map(({ name }) => name)
);
return { folder, folderPath, dir };
};
export const createSecretImport = async (req: Request, res: Response) => { export const createSecretImport = async (req: Request, res: Response) => {
const { workspaceId, environment, folderId, secretImport } = req.body; const { workspaceId, environment, folderId, secretImport } = req.body;
@@ -34,12 +19,14 @@ export const createSecretImport = async (req: Request, res: Response) => {
}).lean(); }).lean();
if (!folders && folderId !== "root") { if (!folders && folderId !== "root") {
throw BadRequestError({ message: "Folder doesn't exist" }); throw ResourceNotFoundError({
message: "Failed to find folder"
});
} }
let secretPath = "/"; let secretPath = "/";
if (folders) { if (folders) {
const { folderPath } = getFolderWithPathFromId(folders, folderId); const { folderPath } = getFolderWithPathFromId(folders.nodes, folderId);
secretPath = folderPath; secretPath = folderPath;
} }
if (req.authData.authPayload instanceof ServiceTokenData) { if (req.authData.authPayload instanceof ServiceTokenData) {
@@ -56,16 +43,7 @@ export const createSecretImport = async (req: Request, res: Response) => {
folderId folderId
}); });
const folders = await Folder.findOne({ const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, folderId).folderPath:"/";
workspace: workspaceId,
environment,
}).lean();
if (!folders) throw ResourceNotFoundError({
message: "Failed to find folder"
});
const importToSecretPath = await getFolderPath(folders, folderId);
if (!importSecDoc) { if (!importSecDoc) {
const doc = new SecretImport({ const doc = new SecretImport({
@@ -154,7 +132,7 @@ export const updateSecretImport = async (req: Request, res: Response) => {
let secretPath = "/"; let secretPath = "/";
if (folders) { if (folders) {
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId); const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
secretPath = folderPath; secretPath = folderPath;
} }
@@ -182,7 +160,7 @@ export const updateSecretImport = async (req: Request, res: Response) => {
message: "Failed to find folder" message: "Failed to find folder"
}); });
const importToSecretPath = await getFolderPath(folders, importSecDoc.folderId); const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/";
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
@@ -227,7 +205,7 @@ export const deleteSecretImport = async (req: Request, res: Response) => {
let secretPath = "/"; let secretPath = "/";
if (folders) { if (folders) {
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId); const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
secretPath = folderPath; secretPath = folderPath;
} }
@@ -255,7 +233,7 @@ export const deleteSecretImport = async (req: Request, res: Response) => {
message: "Failed to find folder" message: "Failed to find folder"
}); });
const importToSecretPath = await getFolderPath(folders, importSecDoc.folderId); const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/";
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
@@ -299,7 +277,7 @@ export const getSecretImports = async (req: Request, res: Response) => {
let secretPath = "/"; let secretPath = "/";
if (folders) { if (folders) {
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId); const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
secretPath = folderPath; secretPath = folderPath;
} }
@@ -341,7 +319,7 @@ export const getAllSecretsFromImport = async (req: Request, res: Response) => {
let secretPath = "/"; let secretPath = "/";
if (folders) { if (folders) {
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId); const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
secretPath = folderPath; secretPath = folderPath;
} }
@@ -1,39 +1,24 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import { Types } from "mongoose"; import { Types } from "mongoose";
import path from "path";
import { EventType, FolderVersion } from "../../ee/models"; import { EventType, FolderVersion } from "../../ee/models";
import { EEAuditLogService, EESecretService } from "../../ee/services"; import { EEAuditLogService, EESecretService } from "../../ee/services";
import { validateMembership } from "../../helpers/membership"; import { validateMembership } from "../../helpers/membership";
import { isValidScope } from "../../helpers/secrets"; import { isValidScope } from "../../helpers/secrets";
import { Secret, ServiceTokenData } from "../../models"; import { Secret, ServiceTokenData } from "../../models";
import Folder, { TFolderRootSchema } from "../../models/folder"; import Folder from "../../models/folder";
import { import {
appendFolder, appendFolder,
deleteFolderById, deleteFolderById,
generateFolderId, generateFolderId,
getAllFolderIds, getAllFolderIds,
getFolderByPath, getFolderByPath,
getFolderPath, getFolderWithPathFromId,
getParentFromFolderId, getParentFromFolderId,
searchByFolderIdWithDir,
validateFolderName validateFolderName
} from "../../services/FolderService"; } from "../../services/FolderService";
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors"; import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
import { ADMIN, MEMBER } from "../../variables"; import { ADMIN, MEMBER } from "../../variables";
const getFolderWithPathFromId = (folders: TFolderRootSchema, parentFolderId: string) => {
const search = searchByFolderIdWithDir(folders.nodes, parentFolderId);
if (!search) {
throw { message: "Folder permission denied" };
}
const { folder, dir } = search;
const folderPath = path.join(
"/",
...dir.filter(({ name }) => name !== "root").map(({ name }) => name)
);
return { folder, folderPath, dir };
};
// verify workspace id/environment // verify workspace id/environment
export const createFolder = async (req: Request, res: Response) => { export const createFolder = async (req: Request, res: Response) => {
const { workspaceId, environment, folderName, parentFolderId } = req.body; const { workspaceId, environment, folderName, parentFolderId } = req.body;
@@ -106,7 +91,7 @@ export const createFolder = async (req: Request, res: Response) => {
await Folder.findByIdAndUpdate(folders._id, folders); await Folder.findByIdAndUpdate(folders._id, folders);
const { folder: parentFolder, folderPath: parentFolderPath } = getFolderWithPathFromId( const { folder: parentFolder, folderPath: parentFolderPath } = getFolderWithPathFromId(
folders, folders.nodes,
parentFolderId || "root" parentFolderId || "root"
); );
@@ -137,7 +122,7 @@ export const createFolder = async (req: Request, res: Response) => {
folderId: parentFolderId folderId: parentFolderId
}); });
const folderPath = await getFolderPath(folders, folder.id); const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id);
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
@@ -192,7 +177,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
} }
if (req.authData.authPayload instanceof ServiceTokenData) { if (req.authData.authPayload instanceof ServiceTokenData) {
const { folderPath: secretPath } = getFolderWithPathFromId(folders, parentFolder.id); const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id);
// root check // root check
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath); const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
if (!isValidScopeAccess) { if (!isValidScopeAccess) {
@@ -200,6 +185,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
} }
} }
const oldFolderName = folder.name;
parentFolder.version += 1; parentFolder.version += 1;
folder.name = name; folder.name = name;
@@ -217,7 +203,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
folderId: parentFolder.id folderId: parentFolder.id
}); });
const folderPath = await getFolderPath(folders, folder.id); const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id);
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
@@ -260,7 +246,7 @@ export const deleteFolder = async (req: Request, res: Response) => {
}); });
} }
const folderPath = await getFolderPath(folders, folderId); const {folderPath} = getFolderWithPathFromId(folders.nodes, folderId);
const delOp = deleteFolderById(folders.nodes, folderId); const delOp = deleteFolderById(folders.nodes, folderId);
if (!delOp) { if (!delOp) {
@@ -269,7 +255,7 @@ export const deleteFolder = async (req: Request, res: Response) => {
const { deletedNode: delFolder, parent: parentFolder } = delOp; const { deletedNode: delFolder, parent: parentFolder } = delOp;
if (req.authData.authPayload instanceof ServiceTokenData) { if (req.authData.authPayload instanceof ServiceTokenData) {
const { folderPath: secretPath } = getFolderWithPathFromId(folders, parentFolder.id); const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id);
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath); const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
if (!isValidScopeAccess) { if (!isValidScopeAccess) {
throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
@@ -384,7 +370,7 @@ export const getFolders = async (req: Request, res: Response) => {
return; return;
} }
const { folder, folderPath, dir } = getFolderWithPathFromId(folders, parentFolderId); const { folder, folderPath, dir } = getFolderWithPathFromId(folders.nodes, parentFolderId);
if (req.authData.authPayload instanceof ServiceTokenData) { if (req.authData.authPayload instanceof ServiceTokenData) {
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, folderPath); const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, folderPath);
if (!isValidScopeAccess) { if (!isValidScopeAccess) {
+18 -24
View File
@@ -1,7 +1,7 @@
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { Types } from "mongoose"; import { Types } from "mongoose";
import Folder, { TFolderRootSchema, TFolderSchema } from "../models/folder"; import Folder, { TFolderSchema } from "../models/folder";
import { ResourceNotFoundError } from "../utils/errors"; import path from "path";
type TAppendFolderDTO = { type TAppendFolderDTO = {
folderName: string; folderName: string;
@@ -59,7 +59,7 @@ const appendChild = (folders: TFolderSchema, folderName: string) => {
id, id,
name: folderName, name: folderName,
children: [], children: [],
version: 1, version: 1
}); });
return { id, name: folderName }; return { id, name: folderName };
}; };
@@ -109,10 +109,7 @@ export const deleteFolderById = (folders: TFolderSchema, folderId: string) => {
}; };
// bfs but return parent of the folderID // bfs but return parent of the folderID
export const getParentFromFolderId = ( export const getParentFromFolderId = (folders: TFolderSchema, folderId: string) => {
folders: TFolderSchema,
folderId: string
) => {
const queue = [folders]; const queue = [folders];
while (queue.length) { while (queue.length) {
const folder = queue.pop() as TFolderSchema; const folder = queue.pop() as TFolderSchema;
@@ -141,10 +138,7 @@ export const getAllFolderIds = (folders: TFolderSchema) => {
// We then record the number of childs of each root node // We then record the number of childs of each root node
// When we reach leaf node or when all childs of a root node are visited // When we reach leaf node or when all childs of a root node are visited
// We remove it from path recorded by using the total child record // We remove it from path recorded by using the total child record
export const searchByFolderIdWithDir = ( export const searchByFolderIdWithDir = (folders: TFolderSchema, folderId: string) => {
folders: TFolderSchema,
folderId: string
) => {
const stack = [folders]; const stack = [folders];
const dir: Array<{ id: string; name: string }> = []; const dir: Array<{ id: string; name: string }> = [];
const hits: Record<string, number> = {}; const hits: Record<string, number> = {};
@@ -173,19 +167,19 @@ export const searchByFolderIdWithDir = (
return; return;
}; };
export const getFolderPath = ( // used for get folder path from id
folders: TFolderRootSchema, export const getFolderWithPathFromId = (folders: TFolderSchema, parentFolderId: string) => {
folderId: string const search = searchByFolderIdWithDir(folders, parentFolderId);
) => { if (!search) {
const folderBySearch = searchByFolderIdWithDir(folders.nodes, folderId); throw { message: "Folder permission denied" };
if (!folderBySearch) throw ResourceNotFoundError({
message: "Failed to find folder"
});
const folderPath = folderBySearch.dir.map((folder) => folder.name).join("/");
return folderPath;
} }
const { folder, dir } = search;
const folderPath = path.join(
"/",
...dir.filter(({ name }) => name !== "root").map(({ name }) => name)
);
return { folder, folderPath, dir };
};
// to get folder of a path given // to get folder of a path given
// Like /frontend/folder#1 // Like /frontend/folder#1
@@ -216,7 +210,7 @@ export const getFolderIdFromServiceToken = async (
) => { ) => {
const folders = await Folder.findOne({ const folders = await Folder.findOne({
workspace: workspaceId, workspace: workspaceId,
environment, environment
}); });
if (!folders) { if (!folders) {