feat: switched to actor and actorId for replication

This commit is contained in:
=
2024-05-14 16:31:53 +05:30
parent d5229a27b2
commit 346dbee96a
7 changed files with 54 additions and 41 deletions

View File

@@ -484,13 +484,14 @@ export const secretApprovalRequestServiceFactory = ({
});
await snapshotService.performSnapshot(folderId);
const [folder] = await folderDAL.findSecretPathByFolderIds(projectId, [folderId]);
// TODO(akhilmhdh-pg): change query to do secret path from folder
if (!folder) throw new BadRequestError({ message: "Folder not found" });
await secretQueueService.syncSecrets({
projectId,
secretPath: folder.path,
environmentSlug: folder.environmentSlug,
folderId: folder.id,
membershipId: membership.id,
actorId,
actor,
environmentId: folder.envId,
secrets: mergeStatus.secrets.created
.map(({ id, version }) => ({

View File

@@ -679,7 +679,8 @@ export const registerRoutes = async (
secretApprovalRequestDAL,
secretApprovalRequestSecretDAL,
secretQueueService,
snapshotService
snapshotService,
projectMembershipDAL
});
const secretRotationQueue = secretRotationQueueFactory({
telemetryService,

View File

@@ -56,7 +56,7 @@ export const secretImportServiceFactory = ({
isReplication,
path
}: TCreateSecretImportDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -111,7 +111,7 @@ export const secretImportServiceFactory = ({
);
});
if (secImport.isReplication && sourceFolder && membership) {
if (secImport.isReplication && sourceFolder) {
const importedSecrets = await secretDAL.find({ folderId: sourceFolder?.id });
await secretQueueService.replicateSecrets({
secretPath: secImport.importPath,
@@ -120,8 +120,8 @@ export const secretImportServiceFactory = ({
pickOnlyImportIds: [secImport.id],
folderId: sourceFolder.id,
secrets: importedSecrets.map(({ id, version }) => ({ operation: SecretOperations.Create, version, id })),
// TODO(akhilmhdh): approval based replication this will fail for identity
membershipId: membership.id,
actorId,
actor,
environmentId: importEnv.id
});
} else {
@@ -310,8 +310,8 @@ export const secretImportServiceFactory = ({
pickOnlyImportIds: [secretImportDoc.id],
folderId: sourceFolder.id,
secrets: importedSecrets.map(({ id, version }) => ({ operation: SecretOperations.Create, version, id })),
// TODO(akhilmhdh): approval based replication this will fail for identity
membershipId: membership.id,
actorId,
actor,
environmentId: secretImportDoc.importEnv.id
});
}

View File

@@ -9,6 +9,8 @@ import { logger } from "@app/lib/logger";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
import { ActorType } from "../auth/auth-type";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { TSecretDALFactory } from "../secret/secret-dal";
import { fnSecretBulkInsert, fnSecretBulkUpdate } from "../secret/secret-fns";
import { TSecretQueueFactory } from "../secret/secret-queue";
@@ -36,6 +38,7 @@ type TSecretReplicationServiceFactoryDep = {
secretBlindIndexDAL: Pick<TSecretBlindIndexDALFactory, "findOne">;
secretTagDAL: Pick<TSecretTagDALFactory, "findManyTagsById" | "saveTagsToSecret" | "deleteTagsManySecret" | "find">;
secretApprovalRequestDAL: Pick<TSecretApprovalRequestDALFactory, "create" | "transaction">;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findOne">;
secretApprovalRequestSecretDAL: Pick<
TSecretApprovalRequestSecretDALFactory,
"insertMany" | "insertApprovalSecretTags"
@@ -60,11 +63,12 @@ export const secretReplicationServiceFactory = ({
secretApprovalRequestSecretDAL,
secretApprovalRequestDAL,
secretQueueService,
snapshotService
snapshotService,
projectMembershipDAL
}: TSecretReplicationServiceFactoryDep) => {
queueService.start(QueueName.SecretReplication, async (job) => {
logger.info(job.data, "Replication started");
const { secrets, folderId, secretPath, environmentId, projectId, membershipId, pickOnlyImportIds } = job.data;
const { secrets, folderId, secretPath, environmentId, projectId, actorId, actor, pickOnlyImportIds } = job.data;
let secretImports = await secretImportDAL.find({
importPath: secretPath,
importEnv: environmentId,
@@ -140,7 +144,13 @@ export const secretReplicationServiceFactory = ({
importedFolder.path
);
// this means it should be a approval request rather than direct replication
if (policy) {
if (policy && actor === ActorType.USER) {
const membership = await projectMembershipDAL.findOne({ projectId, userId: actorId });
if (!membership) {
logger.error("Project membership not found in %s for user %s", projectId, actorId);
return;
}
const localSecretsLatestVersions = localSecrets.map(({ id }) => id);
const latestSecretVersions = await secretVersionDAL.findLatestVersionMany(
importFolderId,
@@ -154,7 +164,7 @@ export const secretReplicationServiceFactory = ({
policyId: policy.id,
status: "open",
hasMerged: false,
committerId: membershipId,
committerId: membership.id,
isReplicated: true
},
tx
@@ -294,7 +304,8 @@ export const secretReplicationServiceFactory = ({
secrets: nestedImportSecrets,
secretPath: importedFolder.path,
environmentId: importedFolder.envId,
membershipId
actorId,
actor
});
const folderLock = await keyStore
.acquireLock([`secret-replication-${importFolderId}`], 5000)

View File

@@ -354,7 +354,8 @@ export const secretQueueFactory = ({
secrets,
folderId,
excludeReplication,
membershipId
actorId,
actor
} = job.data;
await queueService.queue(
QueueName.SecretWebhook,
@@ -380,7 +381,8 @@ export const secretQueueFactory = ({
secretPath,
folderId,
secrets,
membershipId,
actorId,
actor,
excludeReplication,
environmentSlug: environment
});

View File

@@ -149,7 +149,7 @@ export const secretServiceFactory = ({
projectId,
...inputSecret
}: TCreateSecretDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -238,9 +238,9 @@ export const secretServiceFactory = ({
await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({
secretPath: path,
// if secret service reached means there was no secret policy
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
membershipId: membership?.id as string,
folderId: folder.id,
actorId,
actor,
projectId,
environmentSlug: folder.environment.slug,
environmentId: folder.envId,
@@ -265,7 +265,7 @@ export const secretServiceFactory = ({
projectId,
...inputSecret
}: TUpdateSecretDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -381,9 +381,8 @@ export const secretServiceFactory = ({
await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({
// if secret service reached means there was no secret policy
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
membershipId: membership?.id as string,
actor,
actorId,
secretPath: path,
folderId: folder.id,
projectId,
@@ -410,7 +409,7 @@ export const secretServiceFactory = ({
projectId,
...inputSecret
}: TDeleteSecretDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -466,9 +465,8 @@ export const secretServiceFactory = ({
await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({
// if secret service reached means there was no secret policy
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
membershipId: membership?.id as string,
actor,
actorId,
secretPath: path,
folderId: folder.id,
projectId,
@@ -703,7 +701,7 @@ export const secretServiceFactory = ({
projectId,
secrets: inputSecrets
}: TCreateBulkSecretDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -768,9 +766,8 @@ export const secretServiceFactory = ({
await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({
// if secret service reached means there was no secret policy
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
membershipId: membership?.id as string,
actor,
actorId,
secretPath: path,
folderId: folder.id,
projectId,
@@ -792,7 +789,7 @@ export const secretServiceFactory = ({
projectId,
secrets: inputSecrets
}: TUpdateBulkSecretDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -878,9 +875,8 @@ export const secretServiceFactory = ({
await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({
// if secret service reached means there was no secret policy
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
membershipId: membership?.id as string,
actor,
actorId,
secretPath: path,
folderId: folder.id,
projectId,
@@ -902,7 +898,7 @@ export const secretServiceFactory = ({
actorAuthMethod,
actorOrgId
}: TDeleteBulkSecretDTO) => {
const { permission, membership } = await permissionService.getProjectPermission(
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
@@ -952,9 +948,8 @@ export const secretServiceFactory = ({
await snapshotService.performSnapshot(folderId);
await secretQueueService.syncSecrets({
// if secret service reached means there was no secret policy
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
membershipId: membership?.id as string,
actor,
actorId,
secretPath: path,
folderId: folder.id,
projectId,

View File

@@ -11,6 +11,8 @@ import { TSecretBlindIndexDALFactory } from "@app/services/secret-blind-index/se
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-dal";
import { ActorType } from "../auth/auth-type";
type TPartialSecret = Pick<TSecrets, "id" | "secretReminderRepeatDays" | "secretReminderNote">;
type TPartialInputSecret = Pick<TSecrets, "type" | "secretReminderNote" | "secretReminderRepeatDays" | "id">;
@@ -388,7 +390,8 @@ export type TSyncSecretsDTO<T extends boolean = false> = {
: {
environmentId: string;
folderId: string;
membershipId: string;
actor: ActorType;
actorId: string;
// used for import creation to trigger replication
pickOnlyImportIds?: string[];
secrets: {