mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: switched to actor and actorId for replication
This commit is contained in:
@@ -484,13 +484,14 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
});
|
});
|
||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
const [folder] = await folderDAL.findSecretPathByFolderIds(projectId, [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({
|
await secretQueueService.syncSecrets({
|
||||||
projectId,
|
projectId,
|
||||||
secretPath: folder.path,
|
secretPath: folder.path,
|
||||||
environmentSlug: folder.environmentSlug,
|
environmentSlug: folder.environmentSlug,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
membershipId: membership.id,
|
actorId,
|
||||||
|
actor,
|
||||||
environmentId: folder.envId,
|
environmentId: folder.envId,
|
||||||
secrets: mergeStatus.secrets.created
|
secrets: mergeStatus.secrets.created
|
||||||
.map(({ id, version }) => ({
|
.map(({ id, version }) => ({
|
||||||
|
|||||||
@@ -679,7 +679,8 @@ export const registerRoutes = async (
|
|||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
secretApprovalRequestSecretDAL,
|
secretApprovalRequestSecretDAL,
|
||||||
secretQueueService,
|
secretQueueService,
|
||||||
snapshotService
|
snapshotService,
|
||||||
|
projectMembershipDAL
|
||||||
});
|
});
|
||||||
const secretRotationQueue = secretRotationQueueFactory({
|
const secretRotationQueue = secretRotationQueueFactory({
|
||||||
telemetryService,
|
telemetryService,
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export const secretImportServiceFactory = ({
|
|||||||
isReplication,
|
isReplication,
|
||||||
path
|
path
|
||||||
}: TCreateSecretImportDTO) => {
|
}: TCreateSecretImportDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
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 });
|
const importedSecrets = await secretDAL.find({ folderId: sourceFolder?.id });
|
||||||
await secretQueueService.replicateSecrets({
|
await secretQueueService.replicateSecrets({
|
||||||
secretPath: secImport.importPath,
|
secretPath: secImport.importPath,
|
||||||
@@ -120,8 +120,8 @@ export const secretImportServiceFactory = ({
|
|||||||
pickOnlyImportIds: [secImport.id],
|
pickOnlyImportIds: [secImport.id],
|
||||||
folderId: sourceFolder.id,
|
folderId: sourceFolder.id,
|
||||||
secrets: importedSecrets.map(({ id, version }) => ({ operation: SecretOperations.Create, version, id })),
|
secrets: importedSecrets.map(({ id, version }) => ({ operation: SecretOperations.Create, version, id })),
|
||||||
// TODO(akhilmhdh): approval based replication this will fail for identity
|
actorId,
|
||||||
membershipId: membership.id,
|
actor,
|
||||||
environmentId: importEnv.id
|
environmentId: importEnv.id
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -310,8 +310,8 @@ export const secretImportServiceFactory = ({
|
|||||||
pickOnlyImportIds: [secretImportDoc.id],
|
pickOnlyImportIds: [secretImportDoc.id],
|
||||||
folderId: sourceFolder.id,
|
folderId: sourceFolder.id,
|
||||||
secrets: importedSecrets.map(({ id, version }) => ({ operation: SecretOperations.Create, version, id })),
|
secrets: importedSecrets.map(({ id, version }) => ({ operation: SecretOperations.Create, version, id })),
|
||||||
// TODO(akhilmhdh): approval based replication this will fail for identity
|
actorId,
|
||||||
membershipId: membership.id,
|
actor,
|
||||||
environmentId: secretImportDoc.importEnv.id
|
environmentId: secretImportDoc.importEnv.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { logger } from "@app/lib/logger";
|
|||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
|
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 { TSecretDALFactory } from "../secret/secret-dal";
|
||||||
import { fnSecretBulkInsert, fnSecretBulkUpdate } from "../secret/secret-fns";
|
import { fnSecretBulkInsert, fnSecretBulkUpdate } from "../secret/secret-fns";
|
||||||
import { TSecretQueueFactory } from "../secret/secret-queue";
|
import { TSecretQueueFactory } from "../secret/secret-queue";
|
||||||
@@ -36,6 +38,7 @@ type TSecretReplicationServiceFactoryDep = {
|
|||||||
secretBlindIndexDAL: Pick<TSecretBlindIndexDALFactory, "findOne">;
|
secretBlindIndexDAL: Pick<TSecretBlindIndexDALFactory, "findOne">;
|
||||||
secretTagDAL: Pick<TSecretTagDALFactory, "findManyTagsById" | "saveTagsToSecret" | "deleteTagsManySecret" | "find">;
|
secretTagDAL: Pick<TSecretTagDALFactory, "findManyTagsById" | "saveTagsToSecret" | "deleteTagsManySecret" | "find">;
|
||||||
secretApprovalRequestDAL: Pick<TSecretApprovalRequestDALFactory, "create" | "transaction">;
|
secretApprovalRequestDAL: Pick<TSecretApprovalRequestDALFactory, "create" | "transaction">;
|
||||||
|
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findOne">;
|
||||||
secretApprovalRequestSecretDAL: Pick<
|
secretApprovalRequestSecretDAL: Pick<
|
||||||
TSecretApprovalRequestSecretDALFactory,
|
TSecretApprovalRequestSecretDALFactory,
|
||||||
"insertMany" | "insertApprovalSecretTags"
|
"insertMany" | "insertApprovalSecretTags"
|
||||||
@@ -60,11 +63,12 @@ export const secretReplicationServiceFactory = ({
|
|||||||
secretApprovalRequestSecretDAL,
|
secretApprovalRequestSecretDAL,
|
||||||
secretApprovalRequestDAL,
|
secretApprovalRequestDAL,
|
||||||
secretQueueService,
|
secretQueueService,
|
||||||
snapshotService
|
snapshotService,
|
||||||
|
projectMembershipDAL
|
||||||
}: TSecretReplicationServiceFactoryDep) => {
|
}: TSecretReplicationServiceFactoryDep) => {
|
||||||
queueService.start(QueueName.SecretReplication, async (job) => {
|
queueService.start(QueueName.SecretReplication, async (job) => {
|
||||||
logger.info(job.data, "Replication started");
|
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({
|
let secretImports = await secretImportDAL.find({
|
||||||
importPath: secretPath,
|
importPath: secretPath,
|
||||||
importEnv: environmentId,
|
importEnv: environmentId,
|
||||||
@@ -140,7 +144,13 @@ export const secretReplicationServiceFactory = ({
|
|||||||
importedFolder.path
|
importedFolder.path
|
||||||
);
|
);
|
||||||
// this means it should be a approval request rather than direct replication
|
// 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 localSecretsLatestVersions = localSecrets.map(({ id }) => id);
|
||||||
const latestSecretVersions = await secretVersionDAL.findLatestVersionMany(
|
const latestSecretVersions = await secretVersionDAL.findLatestVersionMany(
|
||||||
importFolderId,
|
importFolderId,
|
||||||
@@ -154,7 +164,7 @@ export const secretReplicationServiceFactory = ({
|
|||||||
policyId: policy.id,
|
policyId: policy.id,
|
||||||
status: "open",
|
status: "open",
|
||||||
hasMerged: false,
|
hasMerged: false,
|
||||||
committerId: membershipId,
|
committerId: membership.id,
|
||||||
isReplicated: true
|
isReplicated: true
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
@@ -294,7 +304,8 @@ export const secretReplicationServiceFactory = ({
|
|||||||
secrets: nestedImportSecrets,
|
secrets: nestedImportSecrets,
|
||||||
secretPath: importedFolder.path,
|
secretPath: importedFolder.path,
|
||||||
environmentId: importedFolder.envId,
|
environmentId: importedFolder.envId,
|
||||||
membershipId
|
actorId,
|
||||||
|
actor
|
||||||
});
|
});
|
||||||
const folderLock = await keyStore
|
const folderLock = await keyStore
|
||||||
.acquireLock([`secret-replication-${importFolderId}`], 5000)
|
.acquireLock([`secret-replication-${importFolderId}`], 5000)
|
||||||
|
|||||||
@@ -354,7 +354,8 @@ export const secretQueueFactory = ({
|
|||||||
secrets,
|
secrets,
|
||||||
folderId,
|
folderId,
|
||||||
excludeReplication,
|
excludeReplication,
|
||||||
membershipId
|
actorId,
|
||||||
|
actor
|
||||||
} = job.data;
|
} = job.data;
|
||||||
await queueService.queue(
|
await queueService.queue(
|
||||||
QueueName.SecretWebhook,
|
QueueName.SecretWebhook,
|
||||||
@@ -380,7 +381,8 @@ export const secretQueueFactory = ({
|
|||||||
secretPath,
|
secretPath,
|
||||||
folderId,
|
folderId,
|
||||||
secrets,
|
secrets,
|
||||||
membershipId,
|
actorId,
|
||||||
|
actor,
|
||||||
excludeReplication,
|
excludeReplication,
|
||||||
environmentSlug: environment
|
environmentSlug: environment
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ export const secretServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
...inputSecret
|
...inputSecret
|
||||||
}: TCreateSecretDTO) => {
|
}: TCreateSecretDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -238,9 +238,9 @@ export const secretServiceFactory = ({
|
|||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
await secretQueueService.syncSecrets({
|
await secretQueueService.syncSecrets({
|
||||||
secretPath: path,
|
secretPath: path,
|
||||||
// if secret service reached means there was no secret policy
|
folderId: folder.id,
|
||||||
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
|
actorId,
|
||||||
membershipId: membership?.id as string,
|
actor,
|
||||||
projectId,
|
projectId,
|
||||||
environmentSlug: folder.environment.slug,
|
environmentSlug: folder.environment.slug,
|
||||||
environmentId: folder.envId,
|
environmentId: folder.envId,
|
||||||
@@ -265,7 +265,7 @@ export const secretServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
...inputSecret
|
...inputSecret
|
||||||
}: TUpdateSecretDTO) => {
|
}: TUpdateSecretDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -381,9 +381,8 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
await secretQueueService.syncSecrets({
|
await secretQueueService.syncSecrets({
|
||||||
// if secret service reached means there was no secret policy
|
actor,
|
||||||
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
|
actorId,
|
||||||
membershipId: membership?.id as string,
|
|
||||||
secretPath: path,
|
secretPath: path,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -410,7 +409,7 @@ export const secretServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
...inputSecret
|
...inputSecret
|
||||||
}: TDeleteSecretDTO) => {
|
}: TDeleteSecretDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -466,9 +465,8 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
await secretQueueService.syncSecrets({
|
await secretQueueService.syncSecrets({
|
||||||
// if secret service reached means there was no secret policy
|
actor,
|
||||||
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
|
actorId,
|
||||||
membershipId: membership?.id as string,
|
|
||||||
secretPath: path,
|
secretPath: path,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -703,7 +701,7 @@ export const secretServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
}: TCreateBulkSecretDTO) => {
|
}: TCreateBulkSecretDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -768,9 +766,8 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
await secretQueueService.syncSecrets({
|
await secretQueueService.syncSecrets({
|
||||||
// if secret service reached means there was no secret policy
|
actor,
|
||||||
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
|
actorId,
|
||||||
membershipId: membership?.id as string,
|
|
||||||
secretPath: path,
|
secretPath: path,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -792,7 +789,7 @@ export const secretServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
secrets: inputSecrets
|
secrets: inputSecrets
|
||||||
}: TUpdateBulkSecretDTO) => {
|
}: TUpdateBulkSecretDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -878,9 +875,8 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
await secretQueueService.syncSecrets({
|
await secretQueueService.syncSecrets({
|
||||||
// if secret service reached means there was no secret policy
|
actor,
|
||||||
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
|
actorId,
|
||||||
membershipId: membership?.id as string,
|
|
||||||
secretPath: path,
|
secretPath: path,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -902,7 +898,7 @@ export const secretServiceFactory = ({
|
|||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId
|
actorOrgId
|
||||||
}: TDeleteBulkSecretDTO) => {
|
}: TDeleteBulkSecretDTO) => {
|
||||||
const { permission, membership } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
@@ -952,9 +948,8 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
await snapshotService.performSnapshot(folderId);
|
await snapshotService.performSnapshot(folderId);
|
||||||
await secretQueueService.syncSecrets({
|
await secretQueueService.syncSecrets({
|
||||||
// if secret service reached means there was no secret policy
|
actor,
|
||||||
// TODO(akhilmhdh): The policy based replication will fail if machine identity is used.
|
actorId,
|
||||||
membershipId: membership?.id as string,
|
|
||||||
secretPath: path,
|
secretPath: path,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
projectId,
|
projectId,
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import { TSecretBlindIndexDALFactory } from "@app/services/secret-blind-index/se
|
|||||||
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal";
|
||||||
import { TSecretTagDALFactory } from "@app/services/secret-tag/secret-tag-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 TPartialSecret = Pick<TSecrets, "id" | "secretReminderRepeatDays" | "secretReminderNote">;
|
||||||
|
|
||||||
type TPartialInputSecret = Pick<TSecrets, "type" | "secretReminderNote" | "secretReminderRepeatDays" | "id">;
|
type TPartialInputSecret = Pick<TSecrets, "type" | "secretReminderNote" | "secretReminderRepeatDays" | "id">;
|
||||||
@@ -388,7 +390,8 @@ export type TSyncSecretsDTO<T extends boolean = false> = {
|
|||||||
: {
|
: {
|
||||||
environmentId: string;
|
environmentId: string;
|
||||||
folderId: string;
|
folderId: string;
|
||||||
membershipId: string;
|
actor: ActorType;
|
||||||
|
actorId: string;
|
||||||
// used for import creation to trigger replication
|
// used for import creation to trigger replication
|
||||||
pickOnlyImportIds?: string[];
|
pickOnlyImportIds?: string[];
|
||||||
secrets: {
|
secrets: {
|
||||||
|
|||||||
Reference in New Issue
Block a user