mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 01:27:41 +00:00
Merge branch 'main' into feat/zabbixSyncIntegration
This commit is contained in:
@@ -8,6 +8,9 @@ import { Lock } from "@app/lib/red-lock";
|
|||||||
export const mockKeyStore = (): TKeyStoreFactory => {
|
export const mockKeyStore = (): TKeyStoreFactory => {
|
||||||
const store: Record<string, string | number | Buffer> = {};
|
const store: Record<string, string | number | Buffer> = {};
|
||||||
|
|
||||||
|
const getRegex = (pattern: string) =>
|
||||||
|
new RE2(`^${pattern.replace(/[-[\]/{}()+?.\\^$|]/g, "\\$&").replace(/\*/g, ".*")}$`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setItem: async (key, value) => {
|
setItem: async (key, value) => {
|
||||||
store[key] = value;
|
store[key] = value;
|
||||||
@@ -23,7 +26,7 @@ export const mockKeyStore = (): TKeyStoreFactory => {
|
|||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
deleteItems: async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }) => {
|
deleteItems: async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }) => {
|
||||||
const regex = new RE2(`^${pattern.replace(/[-[\]/{}()+?.\\^$|]/g, "\\$&").replace(/\*/g, ".*")}$`);
|
const regex = getRegex(pattern);
|
||||||
let totalDeleted = 0;
|
let totalDeleted = 0;
|
||||||
const keys = Object.keys(store);
|
const keys = Object.keys(store);
|
||||||
|
|
||||||
@@ -53,6 +56,27 @@ export const mockKeyStore = (): TKeyStoreFactory => {
|
|||||||
incrementBy: async () => {
|
incrementBy: async () => {
|
||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
|
getItems: async (keys) => {
|
||||||
|
const values = keys.map((key) => {
|
||||||
|
const value = store[key];
|
||||||
|
if (typeof value === "string") {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
getKeysByPattern: async (pattern) => {
|
||||||
|
const regex = getRegex(pattern);
|
||||||
|
const keys = Object.keys(store);
|
||||||
|
return keys.filter((key) => regex.test(key));
|
||||||
|
},
|
||||||
|
deleteItemsByKeyIn: async (keys) => {
|
||||||
|
for (const key of keys) {
|
||||||
|
delete store[key];
|
||||||
|
}
|
||||||
|
return keys.length;
|
||||||
|
},
|
||||||
acquireLock: () => {
|
acquireLock: () => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
release: () => {}
|
release: () => {}
|
||||||
|
|||||||
Vendored
+2
@@ -74,6 +74,7 @@ import { TAllowedFields } from "@app/services/identity-ldap-auth/identity-ldap-a
|
|||||||
import { TIdentityOciAuthServiceFactory } from "@app/services/identity-oci-auth/identity-oci-auth-service";
|
import { TIdentityOciAuthServiceFactory } from "@app/services/identity-oci-auth/identity-oci-auth-service";
|
||||||
import { TIdentityOidcAuthServiceFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-service";
|
import { TIdentityOidcAuthServiceFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-service";
|
||||||
import { TIdentityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
|
import { TIdentityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
|
||||||
|
import { TIdentityTlsCertAuthServiceFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-types";
|
||||||
import { TIdentityTokenAuthServiceFactory } from "@app/services/identity-token-auth/identity-token-auth-service";
|
import { TIdentityTokenAuthServiceFactory } from "@app/services/identity-token-auth/identity-token-auth-service";
|
||||||
import { TIdentityUaServiceFactory } from "@app/services/identity-ua/identity-ua-service";
|
import { TIdentityUaServiceFactory } from "@app/services/identity-ua/identity-ua-service";
|
||||||
import { TIntegrationServiceFactory } from "@app/services/integration/integration-service";
|
import { TIntegrationServiceFactory } from "@app/services/integration/integration-service";
|
||||||
@@ -218,6 +219,7 @@ declare module "fastify" {
|
|||||||
identityKubernetesAuth: TIdentityKubernetesAuthServiceFactory;
|
identityKubernetesAuth: TIdentityKubernetesAuthServiceFactory;
|
||||||
identityGcpAuth: TIdentityGcpAuthServiceFactory;
|
identityGcpAuth: TIdentityGcpAuthServiceFactory;
|
||||||
identityAliCloudAuth: TIdentityAliCloudAuthServiceFactory;
|
identityAliCloudAuth: TIdentityAliCloudAuthServiceFactory;
|
||||||
|
identityTlsCertAuth: TIdentityTlsCertAuthServiceFactory;
|
||||||
identityAwsAuth: TIdentityAwsAuthServiceFactory;
|
identityAwsAuth: TIdentityAwsAuthServiceFactory;
|
||||||
identityAzureAuth: TIdentityAzureAuthServiceFactory;
|
identityAzureAuth: TIdentityAzureAuthServiceFactory;
|
||||||
identityOciAuth: TIdentityOciAuthServiceFactory;
|
identityOciAuth: TIdentityOciAuthServiceFactory;
|
||||||
|
|||||||
Vendored
+8
@@ -164,6 +164,9 @@ import {
|
|||||||
TIdentityProjectMemberships,
|
TIdentityProjectMemberships,
|
||||||
TIdentityProjectMembershipsInsert,
|
TIdentityProjectMembershipsInsert,
|
||||||
TIdentityProjectMembershipsUpdate,
|
TIdentityProjectMembershipsUpdate,
|
||||||
|
TIdentityTlsCertAuths,
|
||||||
|
TIdentityTlsCertAuthsInsert,
|
||||||
|
TIdentityTlsCertAuthsUpdate,
|
||||||
TIdentityTokenAuths,
|
TIdentityTokenAuths,
|
||||||
TIdentityTokenAuthsInsert,
|
TIdentityTokenAuthsInsert,
|
||||||
TIdentityTokenAuthsUpdate,
|
TIdentityTokenAuthsUpdate,
|
||||||
@@ -794,6 +797,11 @@ declare module "knex/types/tables" {
|
|||||||
TIdentityAlicloudAuthsInsert,
|
TIdentityAlicloudAuthsInsert,
|
||||||
TIdentityAlicloudAuthsUpdate
|
TIdentityAlicloudAuthsUpdate
|
||||||
>;
|
>;
|
||||||
|
[TableName.IdentityTlsCertAuth]: KnexOriginal.CompositeTableType<
|
||||||
|
TIdentityTlsCertAuths,
|
||||||
|
TIdentityTlsCertAuthsInsert,
|
||||||
|
TIdentityTlsCertAuthsUpdate
|
||||||
|
>;
|
||||||
[TableName.IdentityAwsAuth]: KnexOriginal.CompositeTableType<
|
[TableName.IdentityAwsAuth]: KnexOriginal.CompositeTableType<
|
||||||
TIdentityAwsAuths,
|
TIdentityAwsAuths,
|
||||||
TIdentityAwsAuthsInsert,
|
TIdentityAwsAuthsInsert,
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
if (!(await knex.schema.hasTable(TableName.IdentityTlsCertAuth))) {
|
||||||
|
await knex.schema.createTable(TableName.IdentityTlsCertAuth, (t) => {
|
||||||
|
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
|
||||||
|
t.bigInteger("accessTokenTTL").defaultTo(7200).notNullable();
|
||||||
|
t.bigInteger("accessTokenMaxTTL").defaultTo(7200).notNullable();
|
||||||
|
t.bigInteger("accessTokenNumUsesLimit").defaultTo(0).notNullable();
|
||||||
|
t.jsonb("accessTokenTrustedIps").notNullable();
|
||||||
|
t.timestamps(true, true, true);
|
||||||
|
t.uuid("identityId").notNullable().unique();
|
||||||
|
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
|
||||||
|
t.string("allowedCommonNames").nullable();
|
||||||
|
t.binary("encryptedCaCertificate").notNullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await createOnUpdateTrigger(knex, TableName.IdentityTlsCertAuth);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex: Knex): Promise<void> {
|
||||||
|
await knex.schema.dropTableIfExists(TableName.IdentityTlsCertAuth);
|
||||||
|
await dropOnUpdateTrigger(knex, TableName.IdentityTlsCertAuth);
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { ProjectType, TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
const hasTypeColumn = await knex.schema.hasColumn(TableName.Project, "type");
|
||||||
|
const hasDefaultTypeColumn = await knex.schema.hasColumn(TableName.Project, "defaultProduct");
|
||||||
|
if (hasTypeColumn && !hasDefaultTypeColumn) {
|
||||||
|
await knex.schema.alterTable(TableName.Project, (t) => {
|
||||||
|
t.string("type").nullable().alter();
|
||||||
|
t.string("defaultProduct").notNullable().defaultTo(ProjectType.SecretManager);
|
||||||
|
});
|
||||||
|
|
||||||
|
await knex(TableName.Project).update({
|
||||||
|
// eslint-disable-next-line
|
||||||
|
// @ts-ignore this is because this field is created later
|
||||||
|
defaultProduct: knex.raw(`
|
||||||
|
CASE
|
||||||
|
WHEN "type" IS NULL OR "type" = '' THEN 'secret-manager'
|
||||||
|
ELSE "type"
|
||||||
|
END
|
||||||
|
`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasTemplateTypeColumn = await knex.schema.hasColumn(TableName.ProjectTemplates, "type");
|
||||||
|
if (hasTemplateTypeColumn) {
|
||||||
|
await knex.schema.alterTable(TableName.ProjectTemplates, (t) => {
|
||||||
|
t.string("type").nullable().alter();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex: Knex): Promise<void> {
|
||||||
|
const hasDefaultTypeColumn = await knex.schema.hasColumn(TableName.Project, "defaultProduct");
|
||||||
|
if (hasDefaultTypeColumn) {
|
||||||
|
await knex.schema.alterTable(TableName.Project, (t) => {
|
||||||
|
t.dropColumn("defaultProduct");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// Code generated by automation script, DO NOT EDIT.
|
||||||
|
// Automated by pulling database and generating zod schema
|
||||||
|
// To update. Just run npm run generate:schema
|
||||||
|
// Written by akhilmhdh.
|
||||||
|
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { zodBuffer } from "@app/lib/zod";
|
||||||
|
|
||||||
|
import { TImmutableDBKeys } from "./models";
|
||||||
|
|
||||||
|
export const IdentityTlsCertAuthsSchema = z.object({
|
||||||
|
id: z.string().uuid(),
|
||||||
|
accessTokenTTL: z.coerce.number().default(7200),
|
||||||
|
accessTokenMaxTTL: z.coerce.number().default(7200),
|
||||||
|
accessTokenNumUsesLimit: z.coerce.number().default(0),
|
||||||
|
accessTokenTrustedIps: z.unknown(),
|
||||||
|
createdAt: z.date(),
|
||||||
|
updatedAt: z.date(),
|
||||||
|
identityId: z.string().uuid(),
|
||||||
|
allowedCommonNames: z.string().nullable().optional(),
|
||||||
|
encryptedCaCertificate: zodBuffer
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TIdentityTlsCertAuths = z.infer<typeof IdentityTlsCertAuthsSchema>;
|
||||||
|
export type TIdentityTlsCertAuthsInsert = Omit<z.input<typeof IdentityTlsCertAuthsSchema>, TImmutableDBKeys>;
|
||||||
|
export type TIdentityTlsCertAuthsUpdate = Partial<Omit<z.input<typeof IdentityTlsCertAuthsSchema>, TImmutableDBKeys>>;
|
||||||
@@ -52,6 +52,7 @@ export * from "./identity-org-memberships";
|
|||||||
export * from "./identity-project-additional-privilege";
|
export * from "./identity-project-additional-privilege";
|
||||||
export * from "./identity-project-membership-role";
|
export * from "./identity-project-membership-role";
|
||||||
export * from "./identity-project-memberships";
|
export * from "./identity-project-memberships";
|
||||||
|
export * from "./identity-tls-cert-auths";
|
||||||
export * from "./identity-token-auths";
|
export * from "./identity-token-auths";
|
||||||
export * from "./identity-ua-client-secrets";
|
export * from "./identity-ua-client-secrets";
|
||||||
export * from "./identity-universal-auths";
|
export * from "./identity-universal-auths";
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export enum TableName {
|
|||||||
IdentityOidcAuth = "identity_oidc_auths",
|
IdentityOidcAuth = "identity_oidc_auths",
|
||||||
IdentityJwtAuth = "identity_jwt_auths",
|
IdentityJwtAuth = "identity_jwt_auths",
|
||||||
IdentityLdapAuth = "identity_ldap_auths",
|
IdentityLdapAuth = "identity_ldap_auths",
|
||||||
|
IdentityTlsCertAuth = "identity_tls_cert_auths",
|
||||||
IdentityOrgMembership = "identity_org_memberships",
|
IdentityOrgMembership = "identity_org_memberships",
|
||||||
IdentityProjectMembership = "identity_project_memberships",
|
IdentityProjectMembership = "identity_project_memberships",
|
||||||
IdentityProjectMembershipRole = "identity_project_membership_role",
|
IdentityProjectMembershipRole = "identity_project_membership_role",
|
||||||
@@ -251,6 +252,7 @@ export enum IdentityAuthMethod {
|
|||||||
ALICLOUD_AUTH = "alicloud-auth",
|
ALICLOUD_AUTH = "alicloud-auth",
|
||||||
AWS_AUTH = "aws-auth",
|
AWS_AUTH = "aws-auth",
|
||||||
AZURE_AUTH = "azure-auth",
|
AZURE_AUTH = "azure-auth",
|
||||||
|
TLS_CERT_AUTH = "tls-cert-auth",
|
||||||
OCI_AUTH = "oci-auth",
|
OCI_AUTH = "oci-auth",
|
||||||
OIDC_AUTH = "oidc-auth",
|
OIDC_AUTH = "oidc-auth",
|
||||||
JWT_AUTH = "jwt-auth",
|
JWT_AUTH = "jwt-auth",
|
||||||
@@ -265,16 +267,6 @@ export enum ProjectType {
|
|||||||
SecretScanning = "secret-scanning"
|
SecretScanning = "secret-scanning"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ActionProjectType {
|
|
||||||
SecretManager = ProjectType.SecretManager,
|
|
||||||
CertificateManager = ProjectType.CertificateManager,
|
|
||||||
KMS = ProjectType.KMS,
|
|
||||||
SSH = ProjectType.SSH,
|
|
||||||
SecretScanning = ProjectType.SecretScanning,
|
|
||||||
// project operations that happen on all types
|
|
||||||
Any = "any"
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum SortDirection {
|
export enum SortDirection {
|
||||||
ASC = "asc",
|
ASC = "asc",
|
||||||
DESC = "desc"
|
DESC = "desc"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const ProjectTemplatesSchema = z.object({
|
|||||||
orgId: z.string().uuid(),
|
orgId: z.string().uuid(),
|
||||||
createdAt: z.date(),
|
createdAt: z.date(),
|
||||||
updatedAt: z.date(),
|
updatedAt: z.date(),
|
||||||
type: z.string().default("secret-manager")
|
type: z.string().nullable().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TProjectTemplates = z.infer<typeof ProjectTemplatesSchema>;
|
export type TProjectTemplates = z.infer<typeof ProjectTemplatesSchema>;
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ export const ProjectsSchema = z.object({
|
|||||||
kmsSecretManagerKeyId: z.string().uuid().nullable().optional(),
|
kmsSecretManagerKeyId: z.string().uuid().nullable().optional(),
|
||||||
kmsSecretManagerEncryptedDataKey: zodBuffer.nullable().optional(),
|
kmsSecretManagerEncryptedDataKey: zodBuffer.nullable().optional(),
|
||||||
description: z.string().nullable().optional(),
|
description: z.string().nullable().optional(),
|
||||||
type: z.string(),
|
type: z.string().nullable().optional(),
|
||||||
enforceCapitalization: z.boolean().default(false),
|
enforceCapitalization: z.boolean().default(false),
|
||||||
hasDeleteProtection: z.boolean().default(false).nullable().optional(),
|
hasDeleteProtection: z.boolean().default(false).nullable().optional(),
|
||||||
secretSharing: z.boolean().default(true),
|
secretSharing: z.boolean().default(true),
|
||||||
showSnapshotsLegacy: z.boolean().default(false)
|
showSnapshotsLegacy: z.boolean().default(false),
|
||||||
|
defaultProduct: z.string().default("secret-manager")
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TProjects = z.infer<typeof ProjectsSchema>;
|
export type TProjects = z.infer<typeof ProjectsSchema>;
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ export const registerAccessApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
projectSlug: z.string().trim()
|
projectSlug: z.string().trim(),
|
||||||
|
policyId: z.string().trim().optional()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -73,6 +74,7 @@ export const registerAccessApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { count } = await server.services.accessApprovalRequest.getCount({
|
const { count } = await server.services.accessApprovalRequest.getCount({
|
||||||
projectSlug: req.query.projectSlug,
|
projectSlug: req.query.projectSlug,
|
||||||
|
policyId: req.query.policyId,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { ProjectMembershipRole, ProjectTemplatesSchema, ProjectType } from "@app/db/schemas";
|
import { ProjectMembershipRole, ProjectTemplatesSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
|
||||||
import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns";
|
import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns";
|
||||||
@@ -104,9 +104,6 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
|
|||||||
hide: false,
|
hide: false,
|
||||||
tags: [ApiDocsTags.ProjectTemplates],
|
tags: [ApiDocsTags.ProjectTemplates],
|
||||||
description: "List project templates for the current organization.",
|
description: "List project templates for the current organization.",
|
||||||
querystring: z.object({
|
|
||||||
type: z.nativeEnum(ProjectType).optional().describe(ProjectTemplates.LIST.type)
|
|
||||||
}),
|
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
projectTemplates: SanitizedProjectTemplateSchema.array()
|
projectTemplates: SanitizedProjectTemplateSchema.array()
|
||||||
@@ -115,8 +112,7 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { type } = req.query;
|
const projectTemplates = await server.services.projectTemplate.listProjectTemplatesByOrg(req.permission);
|
||||||
const projectTemplates = await server.services.projectTemplate.listProjectTemplatesByOrg(req.permission, type);
|
|
||||||
|
|
||||||
const auditTemplates = projectTemplates.filter((template) => !isInfisicalProjectTemplate(template.name));
|
const auditTemplates = projectTemplates.filter((template) => !isInfisicalProjectTemplate(template.name));
|
||||||
|
|
||||||
@@ -188,7 +184,6 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
|
|||||||
tags: [ApiDocsTags.ProjectTemplates],
|
tags: [ApiDocsTags.ProjectTemplates],
|
||||||
description: "Create a project template.",
|
description: "Create a project template.",
|
||||||
body: z.object({
|
body: z.object({
|
||||||
type: z.nativeEnum(ProjectType).describe(ProjectTemplates.CREATE.type),
|
|
||||||
name: slugSchema({ field: "name" })
|
name: slugSchema({ field: "name" })
|
||||||
.refine((val) => !isInfisicalProjectTemplate(val), {
|
.refine((val) => !isInfisicalProjectTemplate(val), {
|
||||||
message: `The requested project template name is reserved.`
|
message: `The requested project template name is reserved.`
|
||||||
@@ -284,7 +279,6 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
|
|||||||
tags: [ApiDocsTags.ProjectTemplates],
|
tags: [ApiDocsTags.ProjectTemplates],
|
||||||
description: "Delete a project template.",
|
description: "Delete a project template.",
|
||||||
params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.DELETE.templateId) }),
|
params: z.object({ templateId: z.string().uuid().describe(ProjectTemplates.DELETE.templateId) }),
|
||||||
|
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
projectTemplate: SanitizedProjectTemplateSchema
|
projectTemplate: SanitizedProjectTemplateSchema
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim()
|
workspaceId: z.string().trim(),
|
||||||
|
policyId: z.string().trim().optional()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -112,7 +113,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId: req.query.workspaceId
|
projectId: req.query.workspaceId,
|
||||||
|
policyId: req.query.policyId
|
||||||
});
|
});
|
||||||
return { approvals };
|
return { approvals };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export const registerSshCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SignSshKey,
|
event: PostHogEventTypes.SignSshKey,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
certificateTemplateId: req.body.certificateTemplateId,
|
certificateTemplateId: req.body.certificateTemplateId,
|
||||||
principals: req.body.principals,
|
principals: req.body.principals,
|
||||||
@@ -171,6 +172,7 @@ export const registerSshCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueSshCreds,
|
event: PostHogEventTypes.IssueSshCreds,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
certificateTemplateId: req.body.certificateTemplateId,
|
certificateTemplateId: req.body.certificateTemplateId,
|
||||||
principals: req.body.principals,
|
principals: req.body.principals,
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueSshHostUserCert,
|
event: PostHogEventTypes.IssueSshHostUserCert,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
sshHostId: req.params.sshHostId,
|
sshHostId: req.params.sshHostId,
|
||||||
hostname: host.hostname,
|
hostname: host.hostname,
|
||||||
@@ -427,6 +428,7 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueSshHostHostCert,
|
event: PostHogEventTypes.IssueSshHostHostCert,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
sshHostId: req.params.sshHostId,
|
sshHostId: req.params.sshHostId,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
@@ -97,8 +96,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -248,8 +246,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const accessApprovalPolicies = await accessApprovalPolicyDAL.find({ projectId: project.id, deletedAt: null });
|
const accessApprovalPolicies = await accessApprovalPolicyDAL.find({ projectId: project.id, deletedAt: null });
|
||||||
@@ -301,8 +298,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: accessApprovalPolicy.projectId,
|
projectId: accessApprovalPolicy.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
|
||||||
@@ -498,8 +494,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: policy.projectId,
|
projectId: policy.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Delete,
|
ProjectPermissionActions.Delete,
|
||||||
@@ -549,8 +544,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (!membership) {
|
if (!membership) {
|
||||||
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
||||||
@@ -589,8 +583,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: policy.projectId,
|
projectId: policy.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ export interface TAccessApprovalRequestDALFactory extends Omit<TOrmify<TableName
|
|||||||
bypassers: string[];
|
bypassers: string[];
|
||||||
}[]
|
}[]
|
||||||
>;
|
>;
|
||||||
getCount: ({ projectId }: { projectId: string }) => Promise<{
|
getCount: ({ projectId }: { projectId: string; policyId?: string }) => Promise<{
|
||||||
pendingCount: number;
|
pendingCount: number;
|
||||||
finalizedCount: number;
|
finalizedCount: number;
|
||||||
}>;
|
}>;
|
||||||
@@ -702,7 +702,7 @@ export const accessApprovalRequestDALFactory = (db: TDbClient): TAccessApprovalR
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCount: TAccessApprovalRequestDALFactory["getCount"] = async ({ projectId }) => {
|
const getCount: TAccessApprovalRequestDALFactory["getCount"] = async ({ projectId, policyId }) => {
|
||||||
try {
|
try {
|
||||||
const accessRequests = await db
|
const accessRequests = await db
|
||||||
.replicaNode()(TableName.AccessApprovalRequest)
|
.replicaNode()(TableName.AccessApprovalRequest)
|
||||||
@@ -723,8 +723,10 @@ export const accessApprovalRequestDALFactory = (db: TDbClient): TAccessApprovalR
|
|||||||
`${TableName.AccessApprovalRequest}.id`,
|
`${TableName.AccessApprovalRequest}.id`,
|
||||||
`${TableName.AccessApprovalRequestReviewer}.requestId`
|
`${TableName.AccessApprovalRequestReviewer}.requestId`
|
||||||
)
|
)
|
||||||
|
|
||||||
.where(`${TableName.Environment}.projectId`, projectId)
|
.where(`${TableName.Environment}.projectId`, projectId)
|
||||||
|
.where((qb) => {
|
||||||
|
if (policyId) void qb.where(`${TableName.AccessApprovalPolicy}.id`, policyId);
|
||||||
|
})
|
||||||
.select(selectAllTableCols(TableName.AccessApprovalRequest))
|
.select(selectAllTableCols(TableName.AccessApprovalRequest))
|
||||||
.select(db.ref("status").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerStatus"))
|
.select(db.ref("status").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerStatus"))
|
||||||
.select(db.ref("reviewerUserId").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerUserId"))
|
.select(db.ref("reviewerUserId").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerUserId"))
|
||||||
|
|||||||
+20
-18
@@ -1,7 +1,7 @@
|
|||||||
import slugify from "@sindresorhus/slugify";
|
import slugify from "@sindresorhus/slugify";
|
||||||
import msFn from "ms";
|
import msFn from "ms";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas";
|
import { ProjectMembershipRole } from "@app/db/schemas";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { groupBy } from "@app/lib/fn";
|
import { groupBy } from "@app/lib/fn";
|
||||||
@@ -107,8 +107,7 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (!membership) {
|
if (!membership) {
|
||||||
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
||||||
@@ -217,7 +216,7 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const requesterFullName = `${requestedByUser.firstName} ${requestedByUser.lastName}`;
|
const requesterFullName = `${requestedByUser.firstName} ${requestedByUser.lastName}`;
|
||||||
const approvalUrl = `${cfg.SITE_URL}/secret-manager/${project.id}/approval`;
|
const approvalUrl = `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval`;
|
||||||
|
|
||||||
await triggerWorkflowIntegrationNotification({
|
await triggerWorkflowIntegrationNotification({
|
||||||
input: {
|
input: {
|
||||||
@@ -290,8 +289,7 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (!membership) {
|
if (!membership) {
|
||||||
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
||||||
@@ -337,8 +335,7 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: accessApprovalRequest.projectId,
|
projectId: accessApprovalRequest.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!membership) {
|
if (!membership) {
|
||||||
@@ -350,6 +347,12 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
const canBypass = !policy.bypassers.length || policy.bypassers.some((bypasser) => bypasser.userId === actorId);
|
const canBypass = !policy.bypassers.length || policy.bypassers.some((bypasser) => bypasser.userId === actorId);
|
||||||
const cannotBypassUnderSoftEnforcement = !(isSoftEnforcement && canBypass);
|
const cannotBypassUnderSoftEnforcement = !(isSoftEnforcement && canBypass);
|
||||||
|
|
||||||
|
// Calculate break glass attempt before sequence checks
|
||||||
|
const isBreakGlassApprovalAttempt =
|
||||||
|
policy.enforcementLevel === EnforcementLevel.Soft &&
|
||||||
|
actorId === accessApprovalRequest.requestedByUserId &&
|
||||||
|
status === ApprovalStatus.APPROVED;
|
||||||
|
|
||||||
const isApprover = policy.approvers.find((approver) => approver.userId === actorId);
|
const isApprover = policy.approvers.find((approver) => approver.userId === actorId);
|
||||||
// If user is (not an approver OR cant self approve) AND can't bypass policy
|
// If user is (not an approver OR cant self approve) AND can't bypass policy
|
||||||
if ((!isApprover || (!policy.allowedSelfApprovals && isSelfApproval)) && cannotBypassUnderSoftEnforcement) {
|
if ((!isApprover || (!policy.allowedSelfApprovals && isSelfApproval)) && cannotBypassUnderSoftEnforcement) {
|
||||||
@@ -409,15 +412,14 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
const isApproverOfTheSequence = policy.approvers.find(
|
const isApproverOfTheSequence = policy.approvers.find(
|
||||||
(el) => el.sequence === presentSequence.step && el.userId === actorId
|
(el) => el.sequence === presentSequence.step && el.userId === actorId
|
||||||
);
|
);
|
||||||
if (!isApproverOfTheSequence) throw new BadRequestError({ message: "You are not reviewer in this step" });
|
|
||||||
|
// Only throw if actor is not the approver and not bypassing
|
||||||
|
if (!isApproverOfTheSequence && !isBreakGlassApprovalAttempt) {
|
||||||
|
throw new BadRequestError({ message: "You are not a reviewer in this step" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reviewStatus = await accessApprovalRequestReviewerDAL.transaction(async (tx) => {
|
const reviewStatus = await accessApprovalRequestReviewerDAL.transaction(async (tx) => {
|
||||||
const isBreakGlassApprovalAttempt =
|
|
||||||
policy.enforcementLevel === EnforcementLevel.Soft &&
|
|
||||||
actorId === accessApprovalRequest.requestedByUserId &&
|
|
||||||
status === ApprovalStatus.APPROVED;
|
|
||||||
|
|
||||||
let reviewForThisActorProcessing: {
|
let reviewForThisActorProcessing: {
|
||||||
id: string;
|
id: string;
|
||||||
requestId: string;
|
requestId: string;
|
||||||
@@ -543,7 +545,7 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
bypassReason: bypassReason || "No reason provided",
|
bypassReason: bypassReason || "No reason provided",
|
||||||
secretPath: policy.secretPath || "/",
|
secretPath: policy.secretPath || "/",
|
||||||
environment,
|
environment,
|
||||||
approvalUrl: `${cfg.SITE_URL}/secret-manager/${project.id}/approval`,
|
approvalUrl: `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval`,
|
||||||
requestType: "access"
|
requestType: "access"
|
||||||
},
|
},
|
||||||
template: SmtpTemplates.AccessSecretRequestBypassed
|
template: SmtpTemplates.AccessSecretRequestBypassed
|
||||||
@@ -560,6 +562,7 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
|
|
||||||
const getCount: TAccessApprovalRequestServiceFactory["getCount"] = async ({
|
const getCount: TAccessApprovalRequestServiceFactory["getCount"] = async ({
|
||||||
projectSlug,
|
projectSlug,
|
||||||
|
policyId,
|
||||||
actor,
|
actor,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -573,14 +576,13 @@ export const accessApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (!membership) {
|
if (!membership) {
|
||||||
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const count = await accessApprovalRequestDAL.getCount({ projectId: project.id });
|
const count = await accessApprovalRequestDAL.getCount({ projectId: project.id, policyId });
|
||||||
|
|
||||||
return { count };
|
return { count };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export type TVerifyPermission = {
|
|||||||
|
|
||||||
export type TGetAccessRequestCountDTO = {
|
export type TGetAccessRequestCountDTO = {
|
||||||
projectSlug: string;
|
projectSlug: string;
|
||||||
|
policyId?: string;
|
||||||
} & Omit<TProjectPermission, "projectId">;
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TReviewAccessRequestDTO = {
|
export type TReviewAccessRequestDTO = {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
@@ -38,8 +37,7 @@ export const assumePrivilegeServiceFactory = ({
|
|||||||
actorId: actorPermissionDetails.id,
|
actorId: actorPermissionDetails.id,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: actorPermissionDetails.authMethod,
|
actorAuthMethod: actorPermissionDetails.authMethod,
|
||||||
actorOrgId: actorPermissionDetails.orgId,
|
actorOrgId: actorPermissionDetails.orgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (targetActorType === ActorType.USER) {
|
if (targetActorType === ActorType.USER) {
|
||||||
@@ -60,8 +58,7 @@ export const assumePrivilegeServiceFactory = ({
|
|||||||
actorId: targetActorId,
|
actorId: targetActorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: actorPermissionDetails.authMethod,
|
actorAuthMethod: actorPermissionDetails.authMethod,
|
||||||
actorOrgId: actorPermissionDetails.orgId,
|
actorOrgId: actorPermissionDetails.orgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const appCfg = getConfig();
|
const appCfg = getConfig();
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ export const auditLogQueueServiceFactory = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info(`Streaming audit log [url=${url}] for org [orgId=${orgId}]`);
|
|
||||||
const response = await request.post(
|
const response = await request.post(
|
||||||
url,
|
url,
|
||||||
{ ...providerSpecificPayload(url), ...auditLog },
|
{ ...providerSpecificPayload(url), ...auditLog },
|
||||||
@@ -143,9 +142,6 @@ export const auditLogQueueServiceFactory = async ({
|
|||||||
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
logger.info(
|
|
||||||
`Successfully streamed audit log [url=${url}] for org [orgId=${orgId}] [response=${JSON.stringify(response.data)}]`
|
|
||||||
);
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
@@ -237,7 +233,6 @@ export const auditLogQueueServiceFactory = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info(`Streaming audit log [url=${url}] for org [orgId=${orgId}]`);
|
|
||||||
const response = await request.post(
|
const response = await request.post(
|
||||||
url,
|
url,
|
||||||
{ ...providerSpecificPayload(url), ...auditLog },
|
{ ...providerSpecificPayload(url), ...auditLog },
|
||||||
@@ -249,9 +244,6 @@ export const auditLogQueueServiceFactory = async ({
|
|||||||
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
logger.info(
|
|
||||||
`Successfully streamed audit log [url=${url}] for org [orgId=${orgId}] [response=${JSON.stringify(response.data)}]`
|
|
||||||
);
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
@@ -38,8 +37,7 @@ export const auditLogServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: filter.projectId,
|
projectId: filter.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -202,6 +202,12 @@ export enum EventType {
|
|||||||
REVOKE_IDENTITY_ALICLOUD_AUTH = "revoke-identity-alicloud-auth",
|
REVOKE_IDENTITY_ALICLOUD_AUTH = "revoke-identity-alicloud-auth",
|
||||||
GET_IDENTITY_ALICLOUD_AUTH = "get-identity-alicloud-auth",
|
GET_IDENTITY_ALICLOUD_AUTH = "get-identity-alicloud-auth",
|
||||||
|
|
||||||
|
LOGIN_IDENTITY_TLS_CERT_AUTH = "login-identity-tls-cert-auth",
|
||||||
|
ADD_IDENTITY_TLS_CERT_AUTH = "add-identity-tls-cert-auth",
|
||||||
|
UPDATE_IDENTITY_TLS_CERT_AUTH = "update-identity-tls-cert-auth",
|
||||||
|
REVOKE_IDENTITY_TLS_CERT_AUTH = "revoke-identity-tls-cert-auth",
|
||||||
|
GET_IDENTITY_TLS_CERT_AUTH = "get-identity-tls-cert-auth",
|
||||||
|
|
||||||
LOGIN_IDENTITY_AWS_AUTH = "login-identity-aws-auth",
|
LOGIN_IDENTITY_AWS_AUTH = "login-identity-aws-auth",
|
||||||
ADD_IDENTITY_AWS_AUTH = "add-identity-aws-auth",
|
ADD_IDENTITY_AWS_AUTH = "add-identity-aws-auth",
|
||||||
UPDATE_IDENTITY_AWS_AUTH = "update-identity-aws-auth",
|
UPDATE_IDENTITY_AWS_AUTH = "update-identity-aws-auth",
|
||||||
@@ -1141,6 +1147,53 @@ interface GetIdentityAliCloudAuthEvent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface LoginIdentityTlsCertAuthEvent {
|
||||||
|
type: EventType.LOGIN_IDENTITY_TLS_CERT_AUTH;
|
||||||
|
metadata: {
|
||||||
|
identityId: string;
|
||||||
|
identityTlsCertAuthId: string;
|
||||||
|
identityAccessTokenId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AddIdentityTlsCertAuthEvent {
|
||||||
|
type: EventType.ADD_IDENTITY_TLS_CERT_AUTH;
|
||||||
|
metadata: {
|
||||||
|
identityId: string;
|
||||||
|
allowedCommonNames: string | null | undefined;
|
||||||
|
accessTokenTTL: number;
|
||||||
|
accessTokenMaxTTL: number;
|
||||||
|
accessTokenNumUsesLimit: number;
|
||||||
|
accessTokenTrustedIps: Array<TIdentityTrustedIp>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DeleteIdentityTlsCertAuthEvent {
|
||||||
|
type: EventType.REVOKE_IDENTITY_TLS_CERT_AUTH;
|
||||||
|
metadata: {
|
||||||
|
identityId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UpdateIdentityTlsCertAuthEvent {
|
||||||
|
type: EventType.UPDATE_IDENTITY_TLS_CERT_AUTH;
|
||||||
|
metadata: {
|
||||||
|
identityId: string;
|
||||||
|
allowedCommonNames: string | null | undefined;
|
||||||
|
accessTokenTTL?: number;
|
||||||
|
accessTokenMaxTTL?: number;
|
||||||
|
accessTokenNumUsesLimit?: number;
|
||||||
|
accessTokenTrustedIps?: Array<TIdentityTrustedIp>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GetIdentityTlsCertAuthEvent {
|
||||||
|
type: EventType.GET_IDENTITY_TLS_CERT_AUTH;
|
||||||
|
metadata: {
|
||||||
|
identityId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
interface LoginIdentityOciAuthEvent {
|
interface LoginIdentityOciAuthEvent {
|
||||||
type: EventType.LOGIN_IDENTITY_OCI_AUTH;
|
type: EventType.LOGIN_IDENTITY_OCI_AUTH;
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -3358,6 +3411,11 @@ export type Event =
|
|||||||
| UpdateIdentityAliCloudAuthEvent
|
| UpdateIdentityAliCloudAuthEvent
|
||||||
| GetIdentityAliCloudAuthEvent
|
| GetIdentityAliCloudAuthEvent
|
||||||
| DeleteIdentityAliCloudAuthEvent
|
| DeleteIdentityAliCloudAuthEvent
|
||||||
|
| LoginIdentityTlsCertAuthEvent
|
||||||
|
| AddIdentityTlsCertAuthEvent
|
||||||
|
| UpdateIdentityTlsCertAuthEvent
|
||||||
|
| GetIdentityTlsCertAuthEvent
|
||||||
|
| DeleteIdentityTlsCertAuthEvent
|
||||||
| LoginIdentityOciAuthEvent
|
| LoginIdentityOciAuthEvent
|
||||||
| AddIdentityOciAuthEvent
|
| AddIdentityOciAuthEvent
|
||||||
| UpdateIdentityOciAuthEvent
|
| UpdateIdentityOciAuthEvent
|
||||||
|
|||||||
+1
-3
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import * as x509 from "@peculiar/x509";
|
import * as x509 from "@peculiar/x509";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal";
|
import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
@@ -78,8 +77,7 @@ export const certificateAuthorityCrlServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import RE2 from "re2";
|
import RE2 from "re2";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
@@ -85,8 +84,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(actorOrgId);
|
const plan = await licenseService.getPlan(actorOrgId);
|
||||||
@@ -202,8 +200,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
@@ -300,8 +297,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
@@ -389,8 +385,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
||||||
@@ -437,8 +432,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
@@ -78,8 +77,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -202,8 +200,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(actorOrgId);
|
const plan = await licenseService.getPlan(actorOrgId);
|
||||||
@@ -354,8 +351,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
||||||
@@ -420,8 +416,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
||||||
@@ -485,8 +480,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// verify user has access to each env in request
|
// verify user has access to each env in request
|
||||||
@@ -529,8 +523,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionDynamicSecretActions.ReadRootCredential,
|
ProjectPermissionDynamicSecretActions.ReadRootCredential,
|
||||||
@@ -578,8 +571,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
||||||
@@ -616,8 +608,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const userAccessibleFolderMappings = folderMappings.filter(({ path, environment }) =>
|
const userAccessibleFolderMappings = folderMappings.filter(({ path, environment }) =>
|
||||||
@@ -661,8 +652,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environmentSlugs, path);
|
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environmentSlugs, path);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import * as jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
|
|
||||||
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|||||||
+10
-19
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { packRules } from "@casl/ability/extra";
|
import { packRules } from "@casl/ability/extra";
|
||||||
|
|
||||||
import { ActionProjectType, TableName } from "@app/db/schemas";
|
import { TableName } from "@app/db/schemas";
|
||||||
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||||
@@ -61,8 +61,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
@@ -73,8 +72,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId: identityId,
|
actorId: identityId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need to validate that the privilege given is not higher than the assigning users permission
|
// we need to validate that the privilege given is not higher than the assigning users permission
|
||||||
@@ -160,8 +158,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
@@ -172,8 +169,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId: identityProjectMembership.identityId,
|
actorId: identityProjectMembership.identityId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need to validate that the privilege given is not higher than the assigning users permission
|
// we need to validate that the privilege given is not higher than the assigning users permission
|
||||||
@@ -260,8 +256,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
@@ -272,8 +267,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId: identityProjectMembership.identityId,
|
actorId: identityProjectMembership.identityId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
membership.shouldUseNewPrivilegeSystem,
|
membership.shouldUseNewPrivilegeSystem,
|
||||||
@@ -321,8 +315,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
@@ -356,8 +349,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
@@ -392,8 +384,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
|||||||
+8
-17
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError, MongoAbility, RawRuleOf, subject } from "@casl/ability";
|
import { ForbiddenError, MongoAbility, RawRuleOf, subject } from "@casl/ability";
|
||||||
import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
|
import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||||
@@ -73,8 +72,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -87,8 +85,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId: identityId,
|
actorId: identityId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need to validate that the privilege given is not higher than the assigning users permission
|
// we need to validate that the privilege given is not higher than the assigning users permission
|
||||||
@@ -175,8 +172,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -189,8 +185,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId: identityProjectMembership.identityId,
|
actorId: identityProjectMembership.identityId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need to validate that the privilege given is not higher than the assigning users permission
|
// we need to validate that the privilege given is not higher than the assigning users permission
|
||||||
@@ -293,8 +288,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
@@ -306,8 +300,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId: identityProjectMembership.identityId,
|
actorId: identityProjectMembership.identityId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
membership.shouldUseNewPrivilegeSystem,
|
membership.shouldUseNewPrivilegeSystem,
|
||||||
@@ -366,8 +359,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
@@ -409,8 +401,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: identityProjectMembership.projectId,
|
projectId: identityProjectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ type TKmipOperationServiceFactoryDep = {
|
|||||||
kmsService: TKmsServiceFactory;
|
kmsService: TKmsServiceFactory;
|
||||||
kmsDAL: TKmsKeyDALFactory;
|
kmsDAL: TKmsKeyDALFactory;
|
||||||
kmipClientDAL: TKmipClientDALFactory;
|
kmipClientDAL: TKmipClientDALFactory;
|
||||||
projectDAL: Pick<TProjectDALFactory, "getProjectFromSplitId" | "findById">;
|
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { ForbiddenError } from "@casl/ability";
|
|||||||
import * as x509 from "@peculiar/x509";
|
import * as x509 from "@peculiar/x509";
|
||||||
import crypto, { KeyObject } from "crypto";
|
import crypto, { KeyObject } from "crypto";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
|
||||||
import { isValidIp } from "@app/lib/ip";
|
import { isValidIp } from "@app/lib/ip";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
@@ -73,8 +72,7 @@ export const kmipServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -127,8 +125,7 @@ export const kmipServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: kmipClient.projectId,
|
projectId: kmipClient.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -159,8 +156,7 @@ export const kmipServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: kmipClient.projectId,
|
projectId: kmipClient.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -193,8 +189,7 @@ export const kmipServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: kmipClient.projectId,
|
projectId: kmipClient.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip);
|
||||||
@@ -215,8 +210,7 @@ export const kmipServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip);
|
||||||
@@ -252,8 +246,7 @@ export const kmipServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: kmipClient.projectId,
|
projectId: kmipClient.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export interface TPermissionDALFactory {
|
|||||||
userId: string;
|
userId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
username: string;
|
username: string;
|
||||||
projectType: string;
|
projectType?: string | null;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
@@ -163,7 +163,7 @@ export interface TPermissionDALFactory {
|
|||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
projectType: string;
|
projectType?: string | null;
|
||||||
shouldUseNewPrivilegeSystem: boolean;
|
shouldUseNewPrivilegeSystem: boolean;
|
||||||
orgAuthEnforced: boolean;
|
orgAuthEnforced: boolean;
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -201,7 +201,7 @@ export interface TPermissionDALFactory {
|
|||||||
userId: string;
|
userId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
username: string;
|
username: string;
|
||||||
projectType: string;
|
projectType?: string | null;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
@@ -267,7 +267,7 @@ export interface TPermissionDALFactory {
|
|||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
projectType: string;
|
projectType?: string | null;
|
||||||
orgAuthEnforced: boolean;
|
orgAuthEnforced: boolean;
|
||||||
metadata: {
|
metadata: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { MongoAbility, RawRuleOf } from "@casl/ability";
|
import { MongoAbility, RawRuleOf } from "@casl/ability";
|
||||||
import { MongoQuery } from "@ucast/mongo2js";
|
import { MongoQuery } from "@ucast/mongo2js";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
|
import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
import { OrgPermissionSet } from "./org-permission";
|
import { OrgPermissionSet } from "./org-permission";
|
||||||
@@ -21,7 +20,6 @@ export type TGetUserProjectPermissionArg = {
|
|||||||
userId: string;
|
userId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
authMethod: ActorAuthMethod;
|
authMethod: ActorAuthMethod;
|
||||||
actionProjectType: ActionProjectType;
|
|
||||||
userOrgId?: string;
|
userOrgId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,14 +27,12 @@ export type TGetIdentityProjectPermissionArg = {
|
|||||||
identityId: string;
|
identityId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
identityOrgId?: string;
|
identityOrgId?: string;
|
||||||
actionProjectType: ActionProjectType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TGetServiceTokenProjectPermissionArg = {
|
export type TGetServiceTokenProjectPermissionArg = {
|
||||||
serviceTokenId: string;
|
serviceTokenId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
actorOrgId?: string;
|
actorOrgId?: string;
|
||||||
actionProjectType: ActionProjectType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TGetProjectPermissionArg = {
|
export type TGetProjectPermissionArg = {
|
||||||
@@ -45,7 +41,6 @@ export type TGetProjectPermissionArg = {
|
|||||||
projectId: string;
|
projectId: string;
|
||||||
actorAuthMethod: ActorAuthMethod;
|
actorAuthMethod: ActorAuthMethod;
|
||||||
actorOrgId?: string;
|
actorOrgId?: string;
|
||||||
actionProjectType: ActionProjectType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TPermissionServiceFactory = {
|
export type TPermissionServiceFactory = {
|
||||||
@@ -143,13 +138,7 @@ export type TPermissionServiceFactory = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
getUserProjectPermission: ({
|
getUserProjectPermission: ({ userId, projectId, authMethod, userOrgId }: TGetUserProjectPermissionArg) => Promise<{
|
||||||
userId,
|
|
||||||
projectId,
|
|
||||||
authMethod,
|
|
||||||
userOrgId,
|
|
||||||
actionProjectType
|
|
||||||
}: TGetUserProjectPermissionArg) => Promise<{
|
|
||||||
permission: MongoAbility<ProjectPermissionSet, MongoQuery>;
|
permission: MongoAbility<ProjectPermissionSet, MongoQuery>;
|
||||||
membership: {
|
membership: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { MongoQuery } from "@ucast/mongo2js";
|
|||||||
import handlebars from "handlebars";
|
import handlebars from "handlebars";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActionProjectType,
|
|
||||||
OrgMembershipRole,
|
OrgMembershipRole,
|
||||||
ProjectMembershipRole,
|
ProjectMembershipRole,
|
||||||
ServiceTokenScopes,
|
ServiceTokenScopes,
|
||||||
@@ -214,8 +213,7 @@ export const permissionServiceFactory = ({
|
|||||||
userId,
|
userId,
|
||||||
projectId,
|
projectId,
|
||||||
authMethod,
|
authMethod,
|
||||||
userOrgId,
|
userOrgId
|
||||||
actionProjectType
|
|
||||||
}: TGetUserProjectPermissionArg): Promise<TProjectPermissionRT<ActorType.USER>> => {
|
}: TGetUserProjectPermissionArg): Promise<TProjectPermissionRT<ActorType.USER>> => {
|
||||||
const userProjectPermission = await permissionDAL.getProjectPermission(userId, projectId);
|
const userProjectPermission = await permissionDAL.getProjectPermission(userId, projectId);
|
||||||
if (!userProjectPermission) throw new ForbiddenRequestError({ name: "User not a part of the specified project" });
|
if (!userProjectPermission) throw new ForbiddenRequestError({ name: "User not a part of the specified project" });
|
||||||
@@ -242,12 +240,6 @@ export const permissionServiceFactory = ({
|
|||||||
userProjectPermission.orgRole
|
userProjectPermission.orgRole
|
||||||
);
|
);
|
||||||
|
|
||||||
if (actionProjectType !== ActionProjectType.Any && actionProjectType !== userProjectPermission.projectType) {
|
|
||||||
throw new BadRequestError({
|
|
||||||
message: `The project is of type ${userProjectPermission.projectType}. Operations of type ${actionProjectType} are not allowed.`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// join two permissions and pass to build the final permission set
|
// join two permissions and pass to build the final permission set
|
||||||
const rolePermissions = userProjectPermission.roles?.map(({ role, permissions }) => ({ role, permissions })) || [];
|
const rolePermissions = userProjectPermission.roles?.map(({ role, permissions }) => ({ role, permissions })) || [];
|
||||||
const additionalPrivileges =
|
const additionalPrivileges =
|
||||||
@@ -295,8 +287,7 @@ export const permissionServiceFactory = ({
|
|||||||
const getIdentityProjectPermission = async ({
|
const getIdentityProjectPermission = async ({
|
||||||
identityId,
|
identityId,
|
||||||
projectId,
|
projectId,
|
||||||
identityOrgId,
|
identityOrgId
|
||||||
actionProjectType
|
|
||||||
}: TGetIdentityProjectPermissionArg): Promise<TProjectPermissionRT<ActorType.IDENTITY>> => {
|
}: TGetIdentityProjectPermissionArg): Promise<TProjectPermissionRT<ActorType.IDENTITY>> => {
|
||||||
const identityProjectPermission = await permissionDAL.getProjectIdentityPermission(identityId, projectId);
|
const identityProjectPermission = await permissionDAL.getProjectIdentityPermission(identityId, projectId);
|
||||||
if (!identityProjectPermission)
|
if (!identityProjectPermission)
|
||||||
@@ -316,12 +307,6 @@ export const permissionServiceFactory = ({
|
|||||||
throw new ForbiddenRequestError({ name: "Identity is not a member of the specified organization" });
|
throw new ForbiddenRequestError({ name: "Identity is not a member of the specified organization" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionProjectType !== ActionProjectType.Any && actionProjectType !== identityProjectPermission.projectType) {
|
|
||||||
throw new BadRequestError({
|
|
||||||
message: `The project is of type ${identityProjectPermission.projectType}. Operations of type ${actionProjectType} are not allowed.`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const rolePermissions =
|
const rolePermissions =
|
||||||
identityProjectPermission.roles?.map(({ role, permissions }) => ({ role, permissions })) || [];
|
identityProjectPermission.roles?.map(({ role, permissions }) => ({ role, permissions })) || [];
|
||||||
const additionalPrivileges =
|
const additionalPrivileges =
|
||||||
@@ -376,8 +361,7 @@ export const permissionServiceFactory = ({
|
|||||||
const getServiceTokenProjectPermission = async ({
|
const getServiceTokenProjectPermission = async ({
|
||||||
serviceTokenId,
|
serviceTokenId,
|
||||||
projectId,
|
projectId,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType
|
|
||||||
}: TGetServiceTokenProjectPermissionArg) => {
|
}: TGetServiceTokenProjectPermissionArg) => {
|
||||||
const serviceToken = await serviceTokenDAL.findById(serviceTokenId);
|
const serviceToken = await serviceTokenDAL.findById(serviceTokenId);
|
||||||
if (!serviceToken) throw new NotFoundError({ message: `Service token with ID '${serviceTokenId}' not found` });
|
if (!serviceToken) throw new NotFoundError({ message: `Service token with ID '${serviceTokenId}' not found` });
|
||||||
@@ -402,12 +386,6 @@ export const permissionServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionProjectType !== ActionProjectType.Any && actionProjectType !== serviceTokenProject.type) {
|
|
||||||
throw new BadRequestError({
|
|
||||||
message: `The project is of type ${serviceTokenProject.type}. Operations of type ${actionProjectType} are not allowed.`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const scopes = ServiceTokenScopes.parse(serviceToken.scopes || []);
|
const scopes = ServiceTokenScopes.parse(serviceToken.scopes || []);
|
||||||
return {
|
return {
|
||||||
permission: buildServiceTokenProjectPermission(scopes, serviceToken.permissions),
|
permission: buildServiceTokenProjectPermission(scopes, serviceToken.permissions),
|
||||||
@@ -559,8 +537,7 @@ export const permissionServiceFactory = ({
|
|||||||
actorId: inputActorId,
|
actorId: inputActorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType
|
|
||||||
}: TGetProjectPermissionArg): Promise<TProjectPermissionRT<T>> => {
|
}: TGetProjectPermissionArg): Promise<TProjectPermissionRT<T>> => {
|
||||||
let actor = inputActor;
|
let actor = inputActor;
|
||||||
let actorId = inputActorId;
|
let actorId = inputActorId;
|
||||||
@@ -581,22 +558,19 @@ export const permissionServiceFactory = ({
|
|||||||
userId: actorId,
|
userId: actorId,
|
||||||
projectId,
|
projectId,
|
||||||
authMethod: actorAuthMethod,
|
authMethod: actorAuthMethod,
|
||||||
userOrgId: actorOrgId,
|
userOrgId: actorOrgId
|
||||||
actionProjectType
|
|
||||||
}) as Promise<TProjectPermissionRT<T>>;
|
}) as Promise<TProjectPermissionRT<T>>;
|
||||||
case ActorType.SERVICE:
|
case ActorType.SERVICE:
|
||||||
return getServiceTokenProjectPermission({
|
return getServiceTokenProjectPermission({
|
||||||
serviceTokenId: actorId,
|
serviceTokenId: actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType
|
|
||||||
}) as Promise<TProjectPermissionRT<T>>;
|
}) as Promise<TProjectPermissionRT<T>>;
|
||||||
case ActorType.IDENTITY:
|
case ActorType.IDENTITY:
|
||||||
return getIdentityProjectPermission({
|
return getIdentityProjectPermission({
|
||||||
identityId: actorId,
|
identityId: actorId,
|
||||||
projectId,
|
projectId,
|
||||||
identityOrgId: actorOrgId,
|
identityOrgId: actorOrgId
|
||||||
actionProjectType
|
|
||||||
}) as Promise<TProjectPermissionRT<T>>;
|
}) as Promise<TProjectPermissionRT<T>>;
|
||||||
default:
|
default:
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { NotFoundError } from "@app/lib/errors";
|
import { NotFoundError } from "@app/lib/errors";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
@@ -321,8 +320,7 @@ export const pitServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(userPermission).throwUnlessCan(
|
ForbiddenError.from(userPermission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { ProjectType } from "@app/db/schemas";
|
|
||||||
import {
|
import {
|
||||||
InfisicalProjectTemplate,
|
InfisicalProjectTemplate,
|
||||||
TUnpackedPermission
|
TUnpackedPermission
|
||||||
@@ -7,21 +6,18 @@ import { getPredefinedRoles } from "@app/services/project-role/project-role-fns"
|
|||||||
|
|
||||||
import { ProjectTemplateDefaultEnvironments } from "./project-template-constants";
|
import { ProjectTemplateDefaultEnvironments } from "./project-template-constants";
|
||||||
|
|
||||||
export const getDefaultProjectTemplate = (orgId: string, type: ProjectType) => ({
|
export const getDefaultProjectTemplate = (orgId: string) => ({
|
||||||
id: "b11b49a9-09a9-4443-916a-4246f9ff2c69", // random ID to appease zod
|
id: "b11b49a9-09a9-4443-916a-4246f9ff2c69", // random ID to appease zod
|
||||||
type,
|
|
||||||
name: InfisicalProjectTemplate.Default,
|
name: InfisicalProjectTemplate.Default,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
description: `Infisical's ${type} default project template`,
|
description: `Infisical's default project template`,
|
||||||
environments: type === ProjectType.SecretManager ? ProjectTemplateDefaultEnvironments : null,
|
environments: ProjectTemplateDefaultEnvironments,
|
||||||
roles: [...getPredefinedRoles({ projectId: "project-template", projectType: type })].map(
|
roles: getPredefinedRoles({ projectId: "project-template" }) as Array<{
|
||||||
({ name, slug, permissions }) => ({
|
name: string;
|
||||||
name,
|
slug: string;
|
||||||
slug,
|
permissions: TUnpackedPermission[];
|
||||||
permissions: permissions as TUnpackedPermission[]
|
}>,
|
||||||
})
|
|
||||||
),
|
|
||||||
orgId
|
orgId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import { packRules } from "@casl/ability/extra";
|
import { packRules } from "@casl/ability/extra";
|
||||||
|
|
||||||
import { ProjectType, TProjectTemplates } from "@app/db/schemas";
|
import { TProjectTemplates } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
@@ -29,13 +29,11 @@ const $unpackProjectTemplate = ({ roles, environments, ...rest }: TProjectTempla
|
|||||||
...rest,
|
...rest,
|
||||||
environments: environments as TProjectTemplateEnvironment[],
|
environments: environments as TProjectTemplateEnvironment[],
|
||||||
roles: [
|
roles: [
|
||||||
...getPredefinedRoles({ projectId: "project-template", projectType: rest.type as ProjectType }).map(
|
...getPredefinedRoles({ projectId: "project-template" }).map(({ name, slug, permissions }) => ({
|
||||||
({ name, slug, permissions }) => ({
|
name,
|
||||||
name,
|
slug,
|
||||||
slug,
|
permissions: permissions as TUnpackedPermission[]
|
||||||
permissions: permissions as TUnpackedPermission[]
|
})),
|
||||||
})
|
|
||||||
),
|
|
||||||
...(roles as TProjectTemplateRole[]).map((role) => ({
|
...(roles as TProjectTemplateRole[]).map((role) => ({
|
||||||
...role,
|
...role,
|
||||||
permissions: unpackPermissions(role.permissions)
|
permissions: unpackPermissions(role.permissions)
|
||||||
@@ -48,10 +46,7 @@ export const projectTemplateServiceFactory = ({
|
|||||||
permissionService,
|
permissionService,
|
||||||
projectTemplateDAL
|
projectTemplateDAL
|
||||||
}: TProjectTemplatesServiceFactoryDep): TProjectTemplateServiceFactory => {
|
}: TProjectTemplatesServiceFactoryDep): TProjectTemplateServiceFactory => {
|
||||||
const listProjectTemplatesByOrg: TProjectTemplateServiceFactory["listProjectTemplatesByOrg"] = async (
|
const listProjectTemplatesByOrg: TProjectTemplateServiceFactory["listProjectTemplatesByOrg"] = async (actor) => {
|
||||||
actor,
|
|
||||||
type
|
|
||||||
) => {
|
|
||||||
const plan = await licenseService.getPlan(actor.orgId);
|
const plan = await licenseService.getPlan(actor.orgId);
|
||||||
|
|
||||||
if (!plan.projectTemplates)
|
if (!plan.projectTemplates)
|
||||||
@@ -70,14 +65,11 @@ export const projectTemplateServiceFactory = ({
|
|||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.ProjectTemplates);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.ProjectTemplates);
|
||||||
|
|
||||||
const projectTemplates = await projectTemplateDAL.find({
|
const projectTemplates = await projectTemplateDAL.find({
|
||||||
orgId: actor.orgId,
|
orgId: actor.orgId
|
||||||
...(type ? { type } : {})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...(type
|
getDefaultProjectTemplate(actor.orgId),
|
||||||
? [getDefaultProjectTemplate(actor.orgId, type)]
|
|
||||||
: Object.values(ProjectType).map((projectType) => getDefaultProjectTemplate(actor.orgId, projectType))),
|
|
||||||
...projectTemplates.map((template) => $unpackProjectTemplate(template))
|
...projectTemplates.map((template) => $unpackProjectTemplate(template))
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -142,7 +134,7 @@ export const projectTemplateServiceFactory = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createProjectTemplate: TProjectTemplateServiceFactory["createProjectTemplate"] = async (
|
const createProjectTemplate: TProjectTemplateServiceFactory["createProjectTemplate"] = async (
|
||||||
{ roles, environments, type, ...params },
|
{ roles, environments, ...params },
|
||||||
actor
|
actor
|
||||||
) => {
|
) => {
|
||||||
const plan = await licenseService.getPlan(actor.orgId);
|
const plan = await licenseService.getPlan(actor.orgId);
|
||||||
@@ -162,10 +154,6 @@ export const projectTemplateServiceFactory = ({
|
|||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.ProjectTemplates);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.ProjectTemplates);
|
||||||
|
|
||||||
if (environments && type !== ProjectType.SecretManager) {
|
|
||||||
throw new BadRequestError({ message: "Cannot configure environments for non-SecretManager project templates" });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (environments && plan.environmentLimit !== null && environments.length > plan.environmentLimit) {
|
if (environments && plan.environmentLimit !== null && environments.length > plan.environmentLimit) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
@@ -188,10 +176,8 @@ export const projectTemplateServiceFactory = ({
|
|||||||
const projectTemplate = await projectTemplateDAL.create({
|
const projectTemplate = await projectTemplateDAL.create({
|
||||||
...params,
|
...params,
|
||||||
roles: JSON.stringify(roles.map((role) => ({ ...role, permissions: packRules(role.permissions) }))),
|
roles: JSON.stringify(roles.map((role) => ({ ...role, permissions: packRules(role.permissions) }))),
|
||||||
environments:
|
environments: environments ? JSON.stringify(environments ?? ProjectTemplateDefaultEnvironments) : null,
|
||||||
type === ProjectType.SecretManager ? JSON.stringify(environments ?? ProjectTemplateDefaultEnvironments) : null,
|
orgId: actor.orgId
|
||||||
orgId: actor.orgId,
|
|
||||||
type
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return $unpackProjectTemplate(projectTemplate);
|
return $unpackProjectTemplate(projectTemplate);
|
||||||
@@ -223,12 +209,6 @@ export const projectTemplateServiceFactory = ({
|
|||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.ProjectTemplates);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.ProjectTemplates);
|
||||||
|
|
||||||
if (projectTemplate.type !== ProjectType.SecretManager && environments)
|
|
||||||
throw new BadRequestError({ message: "Cannot configure environments for non-SecretManager project templates" });
|
|
||||||
|
|
||||||
if (projectTemplate.type === ProjectType.SecretManager && environments === null)
|
|
||||||
throw new BadRequestError({ message: "Environments cannot be removed for SecretManager project templates" });
|
|
||||||
|
|
||||||
if (environments && plan.environmentLimit !== null && environments.length > plan.environmentLimit) {
|
if (environments && plan.environmentLimit !== null && environments.length > plan.environmentLimit) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { ProjectMembershipRole, ProjectType, TProjectEnvironments } from "@app/db/schemas";
|
import { ProjectMembershipRole, TProjectEnvironments } from "@app/db/schemas";
|
||||||
import { TProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
|
import { TProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
|
||||||
import { OrgServiceActor } from "@app/lib/types";
|
import { OrgServiceActor } from "@app/lib/types";
|
||||||
import { UnpackedPermissionSchema } from "@app/server/routes/sanitizedSchema/permission";
|
import { UnpackedPermissionSchema } from "@app/server/routes/sanitizedSchema/permission";
|
||||||
@@ -16,7 +16,6 @@ export type TProjectTemplateRole = {
|
|||||||
export type TCreateProjectTemplateDTO = {
|
export type TCreateProjectTemplateDTO = {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
type: ProjectType;
|
|
||||||
roles: TProjectTemplateRole[];
|
roles: TProjectTemplateRole[];
|
||||||
environments?: TProjectTemplateEnvironment[] | null;
|
environments?: TProjectTemplateEnvironment[] | null;
|
||||||
};
|
};
|
||||||
@@ -30,14 +29,10 @@ export enum InfisicalProjectTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type TProjectTemplateServiceFactory = {
|
export type TProjectTemplateServiceFactory = {
|
||||||
listProjectTemplatesByOrg: (
|
listProjectTemplatesByOrg: (actor: OrgServiceActor) => Promise<
|
||||||
actor: OrgServiceActor,
|
|
||||||
type?: ProjectType
|
|
||||||
) => Promise<
|
|
||||||
(
|
(
|
||||||
| {
|
| {
|
||||||
id: string;
|
id: string;
|
||||||
type: ProjectType;
|
|
||||||
name: InfisicalProjectTemplate;
|
name: InfisicalProjectTemplate;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
@@ -74,7 +69,6 @@ export type TProjectTemplateServiceFactory = {
|
|||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
|
||||||
orgId: string;
|
orgId: string;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
@@ -99,7 +93,6 @@ export type TProjectTemplateServiceFactory = {
|
|||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
|
||||||
orgId: string;
|
orgId: string;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
@@ -123,7 +116,6 @@ export type TProjectTemplateServiceFactory = {
|
|||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
|
||||||
orgId: string;
|
orgId: string;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
@@ -146,7 +138,6 @@ export type TProjectTemplateServiceFactory = {
|
|||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
|
||||||
orgId: string;
|
orgId: string;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
@@ -170,7 +161,6 @@ export type TProjectTemplateServiceFactory = {
|
|||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
|
||||||
orgId: string;
|
orgId: string;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
@@ -194,7 +184,6 @@ export type TProjectTemplateServiceFactory = {
|
|||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
|
||||||
orgId: string;
|
orgId: string;
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|||||||
+8
-15
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
|
import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
|
||||||
import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
|
import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
|
||||||
|
|
||||||
import { ActionProjectType, TableName } from "@app/db/schemas";
|
import { TableName } from "@app/db/schemas";
|
||||||
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||||
@@ -61,8 +61,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
|
||||||
const { permission: targetUserPermission, membership } = await permissionService.getProjectPermission({
|
const { permission: targetUserPermission, membership } = await permissionService.getProjectPermission({
|
||||||
@@ -70,8 +69,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId: projectMembership.userId,
|
actorId: projectMembership.userId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need to validate that the privilege given is not higher than the assigning users permission
|
// we need to validate that the privilege given is not higher than the assigning users permission
|
||||||
@@ -166,8 +164,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
|
||||||
const { permission: targetUserPermission } = await permissionService.getProjectPermission({
|
const { permission: targetUserPermission } = await permissionService.getProjectPermission({
|
||||||
@@ -175,8 +172,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId: projectMembership.userId,
|
actorId: projectMembership.userId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we need to validate that the privilege given is not higher than the assigning users permission
|
// we need to validate that the privilege given is not higher than the assigning users permission
|
||||||
@@ -276,8 +272,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
|
||||||
|
|
||||||
@@ -322,8 +317,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member);
|
||||||
|
|
||||||
@@ -349,8 +343,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: projectMembership.projectId,
|
projectId: projectMembership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Read, ProjectPermissionSub.Member);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import picomatch from "picomatch";
|
import picomatch from "picomatch";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
@@ -91,8 +90,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Create,
|
ProjectPermissionActions.Create,
|
||||||
@@ -267,8 +265,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: secretApprovalPolicy.projectId,
|
projectId: secretApprovalPolicy.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
|
||||||
|
|
||||||
@@ -423,8 +420,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sapPolicy.projectId,
|
projectId: sapPolicy.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Delete,
|
ProjectPermissionActions.Delete,
|
||||||
@@ -463,8 +459,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
|
||||||
|
|
||||||
@@ -508,8 +503,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return getSecretApprovalPolicy(projectId, environment, secretPath);
|
return getSecretApprovalPolicy(projectId, environment, secretPath);
|
||||||
@@ -535,8 +529,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sapPolicy.projectId,
|
projectId: sapPolicy.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const findProjectRequestCount = async (projectId: string, userId: string, tx?: Knex) => {
|
const findProjectRequestCount = async (projectId: string, userId: string, policyId?: string, tx?: Knex) => {
|
||||||
try {
|
try {
|
||||||
const docs = await (tx || db)
|
const docs = await (tx || db)
|
||||||
.with(
|
.with(
|
||||||
@@ -309,6 +309,9 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
|
|||||||
`${TableName.SecretApprovalPolicy}.id`
|
`${TableName.SecretApprovalPolicy}.id`
|
||||||
)
|
)
|
||||||
.where({ projectId })
|
.where({ projectId })
|
||||||
|
.where((qb) => {
|
||||||
|
if (policyId) void qb.where(`${TableName.SecretApprovalPolicy}.id`, policyId);
|
||||||
|
})
|
||||||
.andWhere(
|
.andWhere(
|
||||||
(bd) =>
|
(bd) =>
|
||||||
void bd
|
void bd
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const sendApprovalEmailsFn = async ({
|
|||||||
firstName: reviewerUser.firstName,
|
firstName: reviewerUser.firstName,
|
||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
organizationName: project.organization.name,
|
organizationName: project.organization.name,
|
||||||
approvalUrl: `${cfg.SITE_URL}/secret-manager/${project.id}/approval?requestId=${secretApprovalRequest.id}`
|
approvalUrl: `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval?requestId=${secretApprovalRequest.id}`
|
||||||
},
|
},
|
||||||
template: SmtpTemplates.SecretApprovalRequestNeedsReview
|
template: SmtpTemplates.SecretApprovalRequestNeedsReview
|
||||||
});
|
});
|
||||||
|
|||||||
+18
-20
@@ -2,7 +2,6 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActionProjectType,
|
|
||||||
ProjectMembershipRole,
|
ProjectMembershipRole,
|
||||||
SecretEncryptionAlgo,
|
SecretEncryptionAlgo,
|
||||||
SecretKeyEncoding,
|
SecretKeyEncoding,
|
||||||
@@ -168,7 +167,14 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
microsoftTeamsService,
|
microsoftTeamsService,
|
||||||
folderCommitService
|
folderCommitService
|
||||||
}: TSecretApprovalRequestServiceFactoryDep) => {
|
}: TSecretApprovalRequestServiceFactoryDep) => {
|
||||||
const requestCount = async ({ projectId, actor, actorId, actorOrgId, actorAuthMethod }: TApprovalRequestCountDTO) => {
|
const requestCount = async ({
|
||||||
|
projectId,
|
||||||
|
policyId,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
actorOrgId,
|
||||||
|
actorAuthMethod
|
||||||
|
}: TApprovalRequestCountDTO) => {
|
||||||
if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" });
|
if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" });
|
||||||
|
|
||||||
await permissionService.getProjectPermission({
|
await permissionService.getProjectPermission({
|
||||||
@@ -176,11 +182,10 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const count = await secretApprovalRequestDAL.findProjectRequestCount(projectId, actorId);
|
const count = await secretApprovalRequestDAL.findProjectRequestCount(projectId, actorId, policyId);
|
||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -204,8 +209,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId);
|
const { shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId);
|
||||||
@@ -257,8 +261,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (
|
if (
|
||||||
!hasRole(ProjectMembershipRole.Admin) &&
|
!hasRole(ProjectMembershipRole.Admin) &&
|
||||||
@@ -407,8 +410,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: secretApprovalRequest.projectId,
|
projectId: secretApprovalRequest.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (
|
if (
|
||||||
!hasRole(ProjectMembershipRole.Admin) &&
|
!hasRole(ProjectMembershipRole.Admin) &&
|
||||||
@@ -477,8 +479,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: secretApprovalRequest.projectId,
|
projectId: secretApprovalRequest.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
if (
|
if (
|
||||||
!hasRole(ProjectMembershipRole.Admin) &&
|
!hasRole(ProjectMembershipRole.Admin) &&
|
||||||
@@ -534,8 +535,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -951,7 +951,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
bypassReason,
|
bypassReason,
|
||||||
secretPath: policy.secretPath,
|
secretPath: policy.secretPath,
|
||||||
environment: env.name,
|
environment: env.name,
|
||||||
approvalUrl: `${cfg.SITE_URL}/secret-manager/${project.id}/approval`
|
approvalUrl: `${cfg.SITE_URL}/projects/${project.id}/secret-manager/approval`
|
||||||
},
|
},
|
||||||
template: SmtpTemplates.AccessSecretRequestBypassed
|
template: SmtpTemplates.AccessSecretRequestBypassed
|
||||||
});
|
});
|
||||||
@@ -980,8 +980,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||||
@@ -1271,8 +1270,7 @@ export const secretApprovalRequestServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||||
if (!folder)
|
if (!folder)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export type TReviewRequestDTO = {
|
|||||||
comment?: string;
|
comment?: string;
|
||||||
} & Omit<TProjectPermission, "projectId">;
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TApprovalRequestCountDTO = TProjectPermission;
|
export type TApprovalRequestCountDTO = TProjectPermission & { policyId?: string };
|
||||||
|
|
||||||
export type TListApprovalsDTO = {
|
export type TListApprovalsDTO = {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
|
|||||||
@@ -166,7 +166,9 @@ export const secretRotationV2QueueServiceFactory = async ({
|
|||||||
secretPath: folder.path,
|
secretPath: folder.path,
|
||||||
environment: environment.name,
|
environment: environment.name,
|
||||||
projectName: project.name,
|
projectName: project.name,
|
||||||
rotationUrl: encodeURI(`${appCfg.SITE_URL}/secret-manager/${projectId}/secrets/${environment.slug}`)
|
rotationUrl: encodeURI(
|
||||||
|
`${appCfg.SITE_URL}/projects/${projectId}/secret-manager/secrets/${environment.slug}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability";
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
|
||||||
import { ActionProjectType, SecretType, TableName } from "@app/db/schemas";
|
import { SecretType, TableName } from "@app/db/schemas";
|
||||||
import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { hasSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
import { hasSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
||||||
@@ -218,7 +218,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -380,7 +380,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -625,7 +625,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -775,7 +775,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1105,7 +1105,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1152,7 +1152,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1204,7 +1204,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretManager,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1320,8 +1320,7 @@ export const secretRotationV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const permissiveFolderMappings = folderMappings.filter(({ path, environment }) =>
|
const permissiveFolderMappings = folderMappings.filter(({ path, environment }) =>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import Ajv from "ajv";
|
import Ajv from "ajv";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectVersion, TableName } from "@app/db/schemas";
|
import { ProjectVersion, TableName } from "@app/db/schemas";
|
||||||
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto/encryption";
|
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto/encryption";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { TProjectPermission } from "@app/lib/types";
|
import { TProjectPermission } from "@app/lib/types";
|
||||||
@@ -66,8 +66,7 @@ export const secretRotationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionSecretRotationActions.Read,
|
ProjectPermissionSecretRotationActions.Read,
|
||||||
@@ -98,8 +97,7 @@ export const secretRotationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionSecretRotationActions.Read,
|
ProjectPermissionSecretRotationActions.Read,
|
||||||
@@ -215,8 +213,7 @@ export const secretRotationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionSecretRotationActions.Read,
|
ProjectPermissionSecretRotationActions.Read,
|
||||||
@@ -264,8 +261,7 @@ export const secretRotationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionSecretRotationActions.Edit,
|
ProjectPermissionSecretRotationActions.Edit,
|
||||||
@@ -285,8 +281,7 @@ export const secretRotationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: doc.projectId,
|
projectId: doc.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionSecretRotationActions.Delete,
|
ProjectPermissionSecretRotationActions.Delete,
|
||||||
|
|||||||
@@ -588,7 +588,7 @@ export const secretScanningV2QueueServiceFactory = async ({
|
|||||||
numberOfSecrets: payload.numberOfSecrets,
|
numberOfSecrets: payload.numberOfSecrets,
|
||||||
isDiffScan: payload.isDiffScan,
|
isDiffScan: payload.isDiffScan,
|
||||||
url: encodeURI(
|
url: encodeURI(
|
||||||
`${appCfg.SITE_URL}/secret-scanning/${projectId}/findings?search=scanId:${payload.scanId}`
|
`${appCfg.SITE_URL}/projects/${projectId}/secret-scanning/findings?search=scanId:${payload.scanId}`
|
||||||
),
|
),
|
||||||
timestamp
|
timestamp
|
||||||
}
|
}
|
||||||
@@ -599,7 +599,7 @@ export const secretScanningV2QueueServiceFactory = async ({
|
|||||||
timestamp,
|
timestamp,
|
||||||
errorMessage: payload.errorMessage,
|
errorMessage: payload.errorMessage,
|
||||||
url: encodeURI(
|
url: encodeURI(
|
||||||
`${appCfg.SITE_URL}/secret-scanning/${projectId}/data-sources/${dataSource.type}/${dataSource.id}`
|
`${appCfg.SITE_URL}/projects/${projectId}/secret-scanning/data-sources/${dataSource.type}/${dataSource.id}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
@@ -92,7 +91,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -154,7 +153,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -199,7 +198,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -233,7 +232,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: payload.projectId
|
projectId: payload.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -346,7 +345,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -399,7 +398,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -444,7 +443,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -508,7 +507,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -553,7 +552,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -596,7 +595,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -639,7 +638,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: dataSource.projectId
|
projectId: dataSource.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -672,7 +671,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -706,7 +705,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -746,7 +745,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId: finding.projectId
|
projectId: finding.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -777,7 +776,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -812,7 +811,7 @@ export const secretScanningV2ServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId,
|
||||||
actionProjectType: ActionProjectType.SecretScanning,
|
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// akhilmhdh: I did this, quite strange bug with eslint. Everything do have a type stil has this error
|
// akhilmhdh: I did this, quite strange bug with eslint. Everything do have a type stil has this error
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType, TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas";
|
import { TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas";
|
||||||
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||||
import { InternalServerError, NotFoundError } from "@app/lib/errors";
|
import { InternalServerError, NotFoundError } from "@app/lib/errors";
|
||||||
import { groupBy } from "@app/lib/fn";
|
import { groupBy } from "@app/lib/fn";
|
||||||
@@ -103,8 +103,7 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||||
|
|
||||||
@@ -140,8 +139,7 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||||
|
|
||||||
@@ -169,8 +167,7 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: snapshot.projectId,
|
projectId: snapshot.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||||
@@ -390,8 +387,7 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: snapshot.projectId,
|
projectId: snapshot.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Create,
|
ProjectPermissionActions.Create,
|
||||||
|
|||||||
+4
-9
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
@@ -59,8 +58,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -132,8 +130,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -201,8 +198,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certificateTemplate.projectId,
|
projectId: certificateTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -228,8 +224,7 @@ export const sshCertificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { TSshHostDALFactory } from "@app/ee/services/ssh-host/ssh-host-dal";
|
import { TSshHostDALFactory } from "@app/ee/services/ssh-host/ssh-host-dal";
|
||||||
@@ -80,8 +79,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.SshHostGroups);
|
||||||
@@ -173,8 +171,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshHostGroup.projectId,
|
projectId: sshHostGroup.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups);
|
||||||
@@ -270,8 +267,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshHostGroup.projectId,
|
projectId: sshHostGroup.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups);
|
||||||
@@ -294,8 +290,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshHostGroup.projectId,
|
projectId: sshHostGroup.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.SshHostGroups);
|
||||||
@@ -321,8 +316,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshHostGroup.projectId,
|
projectId: sshHostGroup.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SshHostGroups);
|
||||||
@@ -360,8 +354,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshHostGroup.projectId,
|
projectId: sshHostGroup.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups);
|
||||||
@@ -400,8 +393,7 @@ export const sshHostGroupServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshHostGroup.projectId,
|
projectId: sshHostGroup.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SshHostGroups);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
|
|
||||||
import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "../permission/project-permission";
|
import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "../permission/project-permission";
|
||||||
@@ -63,8 +62,7 @@ export const createSshLoginMappings = async ({
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
projectId,
|
projectId,
|
||||||
authMethod: actorAuthMethod,
|
authMethod: actorAuthMethod,
|
||||||
userOrgId: actorOrgId,
|
userOrgId: actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectType } from "@app/db/schemas";
|
|
||||||
import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
|
import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
@@ -12,11 +11,13 @@ import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certif
|
|||||||
import { TSshHostDALFactory } from "@app/ee/services/ssh-host/ssh-host-dal";
|
import { TSshHostDALFactory } from "@app/ee/services/ssh-host/ssh-host-dal";
|
||||||
import { TSshHostLoginUserMappingDALFactory } from "@app/ee/services/ssh-host/ssh-host-login-user-mapping-dal";
|
import { TSshHostLoginUserMappingDALFactory } from "@app/ee/services/ssh-host/ssh-host-login-user-mapping-dal";
|
||||||
import { TSshHostLoginUserDALFactory } from "@app/ee/services/ssh-host/ssh-login-user-dal";
|
import { TSshHostLoginUserDALFactory } from "@app/ee/services/ssh-host/ssh-login-user-dal";
|
||||||
|
import { PgSqlLock } from "@app/keystore/keystore";
|
||||||
import { BadRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||||
import { KmsDataKey } from "@app/services/kms/kms-types";
|
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||||
|
import { bootstrapSshProject } from "@app/services/project/project-fns";
|
||||||
import { TProjectSshConfigDALFactory } from "@app/services/project/project-ssh-config-dal";
|
import { TProjectSshConfigDALFactory } from "@app/services/project/project-ssh-config-dal";
|
||||||
import { TUserDALFactory } from "@app/services/user/user-dal";
|
import { TUserDALFactory } from "@app/services/user/user-dal";
|
||||||
|
|
||||||
@@ -43,9 +44,9 @@ type TSshHostServiceFactoryDep = {
|
|||||||
userDAL: Pick<TUserDALFactory, "findById" | "find">;
|
userDAL: Pick<TUserDALFactory, "findById" | "find">;
|
||||||
groupDAL: Pick<TGroupDALFactory, "findGroupsByProjectId">;
|
groupDAL: Pick<TGroupDALFactory, "findGroupsByProjectId">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "find">;
|
projectDAL: Pick<TProjectDALFactory, "find">;
|
||||||
projectSshConfigDAL: Pick<TProjectSshConfigDALFactory, "findOne">;
|
projectSshConfigDAL: Pick<TProjectSshConfigDALFactory, "findOne" | "transaction" | "create">;
|
||||||
sshCertificateAuthorityDAL: Pick<TSshCertificateAuthorityDALFactory, "findOne">;
|
sshCertificateAuthorityDAL: Pick<TSshCertificateAuthorityDALFactory, "findOne" | "transaction" | "create">;
|
||||||
sshCertificateAuthoritySecretDAL: Pick<TSshCertificateAuthoritySecretDALFactory, "findOne">;
|
sshCertificateAuthoritySecretDAL: Pick<TSshCertificateAuthoritySecretDALFactory, "findOne" | "create">;
|
||||||
sshCertificateDAL: Pick<TSshCertificateDALFactory, "create" | "transaction">;
|
sshCertificateDAL: Pick<TSshCertificateDALFactory, "create" | "transaction">;
|
||||||
sshCertificateBodyDAL: Pick<TSshCertificateBodyDALFactory, "create">;
|
sshCertificateBodyDAL: Pick<TSshCertificateBodyDALFactory, "create">;
|
||||||
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembershipsByUserIdInOrg">;
|
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembershipsByUserIdInOrg">;
|
||||||
@@ -98,8 +99,7 @@ export const sshHostServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sshProjects = await projectDAL.find({
|
const sshProjects = await projectDAL.find({
|
||||||
orgId: actorOrgId,
|
orgId: actorOrgId
|
||||||
type: ProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const allowedHosts = [];
|
const allowedHosts = [];
|
||||||
@@ -111,8 +111,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectHosts = await sshHostDAL.findUserAccessibleSshHosts([project.id], actorId);
|
const projectHosts = await sshHostDAL.findUserAccessibleSshHosts([project.id], actorId);
|
||||||
@@ -145,8 +144,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -184,7 +182,25 @@ export const sshHostServiceFactory = ({
|
|||||||
return ca.id;
|
return ca.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const projectSshConfig = await projectSshConfigDAL.findOne({ projectId });
|
let projectSshConfig = await projectSshConfigDAL.findOne({ projectId });
|
||||||
|
if (!projectSshConfig) {
|
||||||
|
projectSshConfig = await projectSshConfigDAL.transaction(async (tx) => {
|
||||||
|
await tx.raw("SELECT pg_advisory_xact_lock(?)", [PgSqlLock.SshInit(projectId)]);
|
||||||
|
|
||||||
|
let sshConfig = await projectSshConfigDAL.findOne({ projectId }, tx);
|
||||||
|
if (sshConfig) return sshConfig;
|
||||||
|
|
||||||
|
sshConfig = await bootstrapSshProject({
|
||||||
|
projectId,
|
||||||
|
sshCertificateAuthorityDAL,
|
||||||
|
sshCertificateAuthoritySecretDAL,
|
||||||
|
kmsService,
|
||||||
|
projectSshConfigDAL,
|
||||||
|
tx
|
||||||
|
});
|
||||||
|
return sshConfig;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const userSshCaId = await resolveSshCaId({
|
const userSshCaId = await resolveSshCaId({
|
||||||
requestedId: requestedUserSshCaId,
|
requestedId: requestedUserSshCaId,
|
||||||
@@ -257,8 +273,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: host.projectId,
|
projectId: host.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -319,8 +334,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: host.projectId,
|
projectId: host.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -348,8 +362,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: host.projectId,
|
projectId: host.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -388,8 +401,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: host.projectId,
|
projectId: host.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const internalPrincipals = await convertActorToPrincipals({
|
const internalPrincipals = await convertActorToPrincipals({
|
||||||
@@ -508,8 +520,7 @@ export const sshHostServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: host.projectId,
|
projectId: host.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal";
|
import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal";
|
||||||
@@ -73,8 +72,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -109,8 +107,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -178,8 +175,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -217,8 +213,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -259,8 +254,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshCertificateTemplate.projectId,
|
projectId: sshCertificateTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -381,8 +375,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: sshCertificateTemplate.projectId,
|
projectId: sshCertificateTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -479,8 +472,7 @@ export const sshCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SSH
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||||
@@ -36,8 +35,7 @@ export const trustedIpServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList);
|
||||||
const trustedIps = await trustedIpDAL.find({
|
const trustedIps = await trustedIpDAL.find({
|
||||||
@@ -61,8 +59,7 @@ export const trustedIpServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
|
||||||
|
|
||||||
@@ -107,8 +104,7 @@ export const trustedIpServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
|
||||||
|
|
||||||
@@ -153,8 +149,7 @@ export const trustedIpServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ export const PgSqlLock = {
|
|||||||
OrgGatewayCertExchange: (orgId: string) => pgAdvisoryLockHashText(`org-gateway-cert-exchange:${orgId}`),
|
OrgGatewayCertExchange: (orgId: string) => pgAdvisoryLockHashText(`org-gateway-cert-exchange:${orgId}`),
|
||||||
SecretRotationV2Creation: (folderId: string) => pgAdvisoryLockHashText(`secret-rotation-v2-creation:${folderId}`),
|
SecretRotationV2Creation: (folderId: string) => pgAdvisoryLockHashText(`secret-rotation-v2-creation:${folderId}`),
|
||||||
CreateProject: (orgId: string) => pgAdvisoryLockHashText(`create-project:${orgId}`),
|
CreateProject: (orgId: string) => pgAdvisoryLockHashText(`create-project:${orgId}`),
|
||||||
CreateFolder: (envId: string, projectId: string) => pgAdvisoryLockHashText(`create-folder:${envId}-${projectId}`)
|
CreateFolder: (envId: string, projectId: string) => pgAdvisoryLockHashText(`create-folder:${envId}-${projectId}`),
|
||||||
|
SshInit: (projectId: string) => pgAdvisoryLockHashText(`ssh-bootstrap:${projectId}`)
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// all the key prefixes used must be set here to avoid conflict
|
// all the key prefixes used must be set here to avoid conflict
|
||||||
@@ -73,6 +74,7 @@ type TWaitTillReady = {
|
|||||||
export type TKeyStoreFactory = {
|
export type TKeyStoreFactory = {
|
||||||
setItem: (key: string, value: string | number | Buffer, prefix?: string) => Promise<"OK">;
|
setItem: (key: string, value: string | number | Buffer, prefix?: string) => Promise<"OK">;
|
||||||
getItem: (key: string, prefix?: string) => Promise<string | null>;
|
getItem: (key: string, prefix?: string) => Promise<string | null>;
|
||||||
|
getItems: (keys: string[], prefix?: string) => Promise<(string | null)[]>;
|
||||||
setExpiry: (key: string, expiryInSeconds: number) => Promise<number>;
|
setExpiry: (key: string, expiryInSeconds: number) => Promise<number>;
|
||||||
setItemWithExpiry: (
|
setItemWithExpiry: (
|
||||||
key: string,
|
key: string,
|
||||||
@@ -81,6 +83,7 @@ export type TKeyStoreFactory = {
|
|||||||
prefix?: string
|
prefix?: string
|
||||||
) => Promise<"OK">;
|
) => Promise<"OK">;
|
||||||
deleteItem: (key: string) => Promise<number>;
|
deleteItem: (key: string) => Promise<number>;
|
||||||
|
deleteItemsByKeyIn: (keys: string[]) => Promise<number>;
|
||||||
deleteItems: (arg: TDeleteItems) => Promise<number>;
|
deleteItems: (arg: TDeleteItems) => Promise<number>;
|
||||||
incrementBy: (key: string, value: number) => Promise<number>;
|
incrementBy: (key: string, value: number) => Promise<number>;
|
||||||
acquireLock(
|
acquireLock(
|
||||||
@@ -89,6 +92,7 @@ export type TKeyStoreFactory = {
|
|||||||
settings?: Partial<Settings>
|
settings?: Partial<Settings>
|
||||||
): Promise<{ release: () => Promise<ExecutionResult> }>;
|
): Promise<{ release: () => Promise<ExecutionResult> }>;
|
||||||
waitTillReady: ({ key, waitingCb, keyCheckCb, waitIteration, delay, jitter }: TWaitTillReady) => Promise<void>;
|
waitTillReady: ({ key, waitingCb, keyCheckCb, waitIteration, delay, jitter }: TWaitTillReady) => Promise<void>;
|
||||||
|
getKeysByPattern: (pattern: string, limit?: number) => Promise<string[]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFactory => {
|
export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFactory => {
|
||||||
@@ -100,6 +104,9 @@ export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFac
|
|||||||
|
|
||||||
const getItem = async (key: string, prefix?: string) => redis.get(prefix ? `${prefix}:${key}` : key);
|
const getItem = async (key: string, prefix?: string) => redis.get(prefix ? `${prefix}:${key}` : key);
|
||||||
|
|
||||||
|
const getItems = async (keys: string[], prefix?: string) =>
|
||||||
|
redis.mget(keys.map((key) => (prefix ? `${prefix}:${key}` : key)));
|
||||||
|
|
||||||
const setItemWithExpiry = async (
|
const setItemWithExpiry = async (
|
||||||
key: string,
|
key: string,
|
||||||
expiryInSeconds: number | string,
|
expiryInSeconds: number | string,
|
||||||
@@ -109,6 +116,11 @@ export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFac
|
|||||||
|
|
||||||
const deleteItem = async (key: string) => redis.del(key);
|
const deleteItem = async (key: string) => redis.del(key);
|
||||||
|
|
||||||
|
const deleteItemsByKeyIn = async (keys: string[]) => {
|
||||||
|
if (keys.length === 0) return 0;
|
||||||
|
return redis.del(keys);
|
||||||
|
};
|
||||||
|
|
||||||
const deleteItems = async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }: TDeleteItems) => {
|
const deleteItems = async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }: TDeleteItems) => {
|
||||||
let cursor = "0";
|
let cursor = "0";
|
||||||
let totalDeleted = 0;
|
let totalDeleted = 0;
|
||||||
@@ -164,6 +176,24 @@ export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFac
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getKeysByPattern = async (pattern: string, limit?: number) => {
|
||||||
|
let cursor = "0";
|
||||||
|
const allKeys: string[] = [];
|
||||||
|
|
||||||
|
do {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const [nextCursor, keys] = await redis.scan(cursor, "MATCH", pattern, "COUNT", 1000);
|
||||||
|
cursor = nextCursor;
|
||||||
|
allKeys.push(...keys);
|
||||||
|
|
||||||
|
if (limit && allKeys.length >= limit) {
|
||||||
|
return allKeys.slice(0, limit);
|
||||||
|
}
|
||||||
|
} while (cursor !== "0");
|
||||||
|
|
||||||
|
return allKeys;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setItem,
|
setItem,
|
||||||
getItem,
|
getItem,
|
||||||
@@ -175,6 +205,9 @@ export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFac
|
|||||||
acquireLock(resources: string[], duration: number, settings?: Partial<Settings>) {
|
acquireLock(resources: string[], duration: number, settings?: Partial<Settings>) {
|
||||||
return redisLock.acquire(resources, duration, settings);
|
return redisLock.acquire(resources, duration, settings);
|
||||||
},
|
},
|
||||||
waitTillReady
|
waitTillReady,
|
||||||
|
getKeysByPattern,
|
||||||
|
deleteItemsByKeyIn,
|
||||||
|
getItems
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { TKeyStoreFactory } from "./keystore";
|
|||||||
|
|
||||||
export const inMemoryKeyStore = (): TKeyStoreFactory => {
|
export const inMemoryKeyStore = (): TKeyStoreFactory => {
|
||||||
const store: Record<string, string | number | Buffer> = {};
|
const store: Record<string, string | number | Buffer> = {};
|
||||||
|
const getRegex = (pattern: string) =>
|
||||||
|
new RE2(`^${pattern.replace(/[-[\]/{}()+?.\\^$|]/g, "\\$&").replace(/\*/g, ".*")}$`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setItem: async (key, value) => {
|
setItem: async (key, value) => {
|
||||||
@@ -24,7 +26,7 @@ export const inMemoryKeyStore = (): TKeyStoreFactory => {
|
|||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
deleteItems: async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }) => {
|
deleteItems: async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }) => {
|
||||||
const regex = new RE2(`^${pattern.replace(/[-[\]/{}()+?.\\^$|]/g, "\\$&").replace(/\*/g, ".*")}$`);
|
const regex = getRegex(pattern);
|
||||||
let totalDeleted = 0;
|
let totalDeleted = 0;
|
||||||
const keys = Object.keys(store);
|
const keys = Object.keys(store);
|
||||||
|
|
||||||
@@ -59,6 +61,27 @@ export const inMemoryKeyStore = (): TKeyStoreFactory => {
|
|||||||
release: () => {}
|
release: () => {}
|
||||||
}) as Promise<Lock>;
|
}) as Promise<Lock>;
|
||||||
},
|
},
|
||||||
waitTillReady: async () => {}
|
waitTillReady: async () => {},
|
||||||
|
getKeysByPattern: async (pattern) => {
|
||||||
|
const regex = getRegex(pattern);
|
||||||
|
const keys = Object.keys(store);
|
||||||
|
return keys.filter((key) => regex.test(key));
|
||||||
|
},
|
||||||
|
deleteItemsByKeyIn: async (keys) => {
|
||||||
|
for (const key of keys) {
|
||||||
|
delete store[key];
|
||||||
|
}
|
||||||
|
return keys.length;
|
||||||
|
},
|
||||||
|
getItems: async (keys) => {
|
||||||
|
const values = keys.map((key) => {
|
||||||
|
const value = store[key];
|
||||||
|
if (typeof value === "string") {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return values;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export enum ApiDocsTags {
|
|||||||
UniversalAuth = "Universal Auth",
|
UniversalAuth = "Universal Auth",
|
||||||
GcpAuth = "GCP Auth",
|
GcpAuth = "GCP Auth",
|
||||||
AliCloudAuth = "Alibaba Cloud Auth",
|
AliCloudAuth = "Alibaba Cloud Auth",
|
||||||
|
TlsCertAuth = "TLS Certificate Auth",
|
||||||
AwsAuth = "AWS Auth",
|
AwsAuth = "AWS Auth",
|
||||||
OciAuth = "OCI Auth",
|
OciAuth = "OCI Auth",
|
||||||
AzureAuth = "Azure Auth",
|
AzureAuth = "Azure Auth",
|
||||||
@@ -283,6 +284,38 @@ export const ALICLOUD_AUTH = {
|
|||||||
}
|
}
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const TLS_CERT_AUTH = {
|
||||||
|
LOGIN: {
|
||||||
|
identityId: "The ID of the identity to login."
|
||||||
|
},
|
||||||
|
ATTACH: {
|
||||||
|
identityId: "The ID of the identity to attach the configuration onto.",
|
||||||
|
allowedCommonNames:
|
||||||
|
"The comma-separated list of trusted common names that are allowed to authenticate with Infisical.",
|
||||||
|
caCertificate: "The PEM-encoded CA certificate to validate client certificates.",
|
||||||
|
accessTokenTTL: "The lifetime for an access token in seconds.",
|
||||||
|
accessTokenMaxTTL: "The maximum lifetime for an access token in seconds.",
|
||||||
|
accessTokenNumUsesLimit: "The maximum number of times that an access token can be used.",
|
||||||
|
accessTokenTrustedIps: "The IPs or CIDR ranges that access tokens can be used from."
|
||||||
|
},
|
||||||
|
UPDATE: {
|
||||||
|
identityId: "The ID of the identity to update the auth method for.",
|
||||||
|
allowedCommonNames:
|
||||||
|
"The comma-separated list of trusted common names that are allowed to authenticate with Infisical.",
|
||||||
|
caCertificate: "The PEM-encoded CA certificate to validate client certificates.",
|
||||||
|
accessTokenTTL: "The new lifetime for an access token in seconds.",
|
||||||
|
accessTokenMaxTTL: "The new maximum lifetime for an access token in seconds.",
|
||||||
|
accessTokenNumUsesLimit: "The new maximum number of times that an access token can be used.",
|
||||||
|
accessTokenTrustedIps: "The new IPs or CIDR ranges that access tokens can be used from."
|
||||||
|
},
|
||||||
|
RETRIEVE: {
|
||||||
|
identityId: "The ID of the identity to retrieve the auth method for."
|
||||||
|
},
|
||||||
|
REVOKE: {
|
||||||
|
identityId: "The ID of the identity to revoke the auth method for."
|
||||||
|
}
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const AWS_AUTH = {
|
export const AWS_AUTH = {
|
||||||
LOGIN: {
|
LOGIN: {
|
||||||
identityId: "The ID of the identity to login.",
|
identityId: "The ID of the identity to login.",
|
||||||
@@ -667,7 +700,8 @@ export const PROJECTS = {
|
|||||||
slug: "An optional slug for the project. (must be unique within the organization)",
|
slug: "An optional slug for the project. (must be unique within the organization)",
|
||||||
hasDeleteProtection: "Enable or disable delete protection for the project.",
|
hasDeleteProtection: "Enable or disable delete protection for the project.",
|
||||||
secretSharing: "Enable or disable secret sharing for the project.",
|
secretSharing: "Enable or disable secret sharing for the project.",
|
||||||
showSnapshotsLegacy: "Enable or disable legacy snapshots for the project."
|
showSnapshotsLegacy: "Enable or disable legacy snapshots for the project.",
|
||||||
|
defaultProduct: "The default product in which the project will open"
|
||||||
},
|
},
|
||||||
GET_KEY: {
|
GET_KEY: {
|
||||||
workspaceId: "The ID of the project to get the key from."
|
workspaceId: "The ID of the project to get the key from."
|
||||||
@@ -2398,7 +2432,8 @@ export const SecretSyncs = {
|
|||||||
keyOcid: "The OCID (Oracle Cloud Identifier) of the encryption key to use when creating secrets in the vault."
|
keyOcid: "The OCID (Oracle Cloud Identifier) of the encryption key to use when creating secrets in the vault."
|
||||||
},
|
},
|
||||||
ONEPASS: {
|
ONEPASS: {
|
||||||
vaultId: "The ID of the 1Password vault to sync secrets to."
|
vaultId: "The ID of the 1Password vault to sync secrets to.",
|
||||||
|
valueLabel: "The label of the entry that holds the secret value."
|
||||||
},
|
},
|
||||||
HEROKU: {
|
HEROKU: {
|
||||||
app: "The ID of the Heroku app to sync secrets to.",
|
app: "The ID of the Heroku app to sync secrets to.",
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ const envSchema = z
|
|||||||
PYLON_API_KEY: zpStr(z.string().optional()),
|
PYLON_API_KEY: zpStr(z.string().optional()),
|
||||||
DISABLE_AUDIT_LOG_GENERATION: zodStrBool.default("false"),
|
DISABLE_AUDIT_LOG_GENERATION: zodStrBool.default("false"),
|
||||||
SSL_CLIENT_CERTIFICATE_HEADER_KEY: zpStr(z.string().optional()).default("x-ssl-client-cert"),
|
SSL_CLIENT_CERTIFICATE_HEADER_KEY: zpStr(z.string().optional()).default("x-ssl-client-cert"),
|
||||||
|
IDENTITY_TLS_CERT_AUTH_CLIENT_CERTIFICATE_HEADER_KEY: zpStr(z.string().optional()).default(
|
||||||
|
"x-identity-tls-cert-auth-client-cert"
|
||||||
|
),
|
||||||
WORKFLOW_SLACK_CLIENT_ID: zpStr(z.string().optional()),
|
WORKFLOW_SLACK_CLIENT_ID: zpStr(z.string().optional()),
|
||||||
WORKFLOW_SLACK_CLIENT_SECRET: zpStr(z.string().optional()),
|
WORKFLOW_SLACK_CLIENT_SECRET: zpStr(z.string().optional()),
|
||||||
ENABLE_MSSQL_SECRET_ROTATION_ENCRYPT: zodStrBool.default("true"),
|
ENABLE_MSSQL_SECRET_ROTATION_ENCRYPT: zodStrBool.default("true"),
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ export enum QueueName {
|
|||||||
SecretRotationV2 = "secret-rotation-v2",
|
SecretRotationV2 = "secret-rotation-v2",
|
||||||
FolderTreeCheckpoint = "folder-tree-checkpoint",
|
FolderTreeCheckpoint = "folder-tree-checkpoint",
|
||||||
InvalidateCache = "invalidate-cache",
|
InvalidateCache = "invalidate-cache",
|
||||||
SecretScanningV2 = "secret-scanning-v2"
|
SecretScanningV2 = "secret-scanning-v2",
|
||||||
|
TelemetryAggregatedEvents = "telemetry-aggregated-events"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum QueueJobs {
|
export enum QueueJobs {
|
||||||
@@ -101,7 +102,8 @@ export enum QueueJobs {
|
|||||||
SecretScanningV2DiffScan = "secret-scanning-v2-diff-scan",
|
SecretScanningV2DiffScan = "secret-scanning-v2-diff-scan",
|
||||||
SecretScanningV2SendNotification = "secret-scanning-v2-notification",
|
SecretScanningV2SendNotification = "secret-scanning-v2-notification",
|
||||||
CaOrderCertificateForSubscriber = "ca-order-certificate-for-subscriber",
|
CaOrderCertificateForSubscriber = "ca-order-certificate-for-subscriber",
|
||||||
PkiSubscriberDailyAutoRenewal = "pki-subscriber-daily-auto-renewal"
|
PkiSubscriberDailyAutoRenewal = "pki-subscriber-daily-auto-renewal",
|
||||||
|
TelemetryAggregatedEvents = "telemetry-aggregated-events"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TQueueJobTypes = {
|
export type TQueueJobTypes = {
|
||||||
@@ -292,6 +294,10 @@ export type TQueueJobTypes = {
|
|||||||
name: QueueJobs.PkiSubscriberDailyAutoRenewal;
|
name: QueueJobs.PkiSubscriberDailyAutoRenewal;
|
||||||
payload: undefined;
|
payload: undefined;
|
||||||
};
|
};
|
||||||
|
[QueueName.TelemetryAggregatedEvents]: {
|
||||||
|
name: QueueJobs.TelemetryAggregatedEvents;
|
||||||
|
payload: undefined;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const SECRET_SCANNING_JOBS = [
|
const SECRET_SCANNING_JOBS = [
|
||||||
|
|||||||
@@ -193,6 +193,8 @@ import { identityOidcAuthServiceFactory } from "@app/services/identity-oidc-auth
|
|||||||
import { identityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
|
import { identityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
|
||||||
import { identityProjectMembershipRoleDALFactory } from "@app/services/identity-project/identity-project-membership-role-dal";
|
import { identityProjectMembershipRoleDALFactory } from "@app/services/identity-project/identity-project-membership-role-dal";
|
||||||
import { identityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
|
import { identityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
|
||||||
|
import { identityTlsCertAuthDALFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-dal";
|
||||||
|
import { identityTlsCertAuthServiceFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-service";
|
||||||
import { identityTokenAuthDALFactory } from "@app/services/identity-token-auth/identity-token-auth-dal";
|
import { identityTokenAuthDALFactory } from "@app/services/identity-token-auth/identity-token-auth-dal";
|
||||||
import { identityTokenAuthServiceFactory } from "@app/services/identity-token-auth/identity-token-auth-service";
|
import { identityTokenAuthServiceFactory } from "@app/services/identity-token-auth/identity-token-auth-service";
|
||||||
import { identityUaClientSecretDALFactory } from "@app/services/identity-ua/identity-ua-client-secret-dal";
|
import { identityUaClientSecretDALFactory } from "@app/services/identity-ua/identity-ua-client-secret-dal";
|
||||||
@@ -384,6 +386,7 @@ export const registerRoutes = async (
|
|||||||
const identityKubernetesAuthDAL = identityKubernetesAuthDALFactory(db);
|
const identityKubernetesAuthDAL = identityKubernetesAuthDALFactory(db);
|
||||||
const identityUaClientSecretDAL = identityUaClientSecretDALFactory(db);
|
const identityUaClientSecretDAL = identityUaClientSecretDALFactory(db);
|
||||||
const identityAliCloudAuthDAL = identityAliCloudAuthDALFactory(db);
|
const identityAliCloudAuthDAL = identityAliCloudAuthDALFactory(db);
|
||||||
|
const identityTlsCertAuthDAL = identityTlsCertAuthDALFactory(db);
|
||||||
const identityAwsAuthDAL = identityAwsAuthDALFactory(db);
|
const identityAwsAuthDAL = identityAwsAuthDALFactory(db);
|
||||||
const identityGcpAuthDAL = identityGcpAuthDALFactory(db);
|
const identityGcpAuthDAL = identityGcpAuthDALFactory(db);
|
||||||
const identityOciAuthDAL = identityOciAuthDALFactory(db);
|
const identityOciAuthDAL = identityOciAuthDALFactory(db);
|
||||||
@@ -684,7 +687,8 @@ export const registerRoutes = async (
|
|||||||
const telemetryQueue = telemetryQueueServiceFactory({
|
const telemetryQueue = telemetryQueueServiceFactory({
|
||||||
keyStore,
|
keyStore,
|
||||||
telemetryDAL,
|
telemetryDAL,
|
||||||
queueService
|
queueService,
|
||||||
|
telemetryService
|
||||||
});
|
});
|
||||||
|
|
||||||
const invalidateCacheQueue = invalidateCacheQueueFactory({
|
const invalidateCacheQueue = invalidateCacheQueueFactory({
|
||||||
@@ -991,8 +995,7 @@ export const registerRoutes = async (
|
|||||||
pkiAlertDAL,
|
pkiAlertDAL,
|
||||||
pkiCollectionDAL,
|
pkiCollectionDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
smtpService,
|
smtpService
|
||||||
projectDAL
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const pkiCollectionService = pkiCollectionServiceFactory({
|
const pkiCollectionService = pkiCollectionServiceFactory({
|
||||||
@@ -1000,8 +1003,7 @@ export const registerRoutes = async (
|
|||||||
pkiCollectionItemDAL,
|
pkiCollectionItemDAL,
|
||||||
certificateAuthorityDAL,
|
certificateAuthorityDAL,
|
||||||
certificateDAL,
|
certificateDAL,
|
||||||
permissionService,
|
permissionService
|
||||||
projectDAL
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectTemplateService = projectTemplateServiceFactory({
|
const projectTemplateService = projectTemplateServiceFactory({
|
||||||
@@ -1185,7 +1187,9 @@ export const registerRoutes = async (
|
|||||||
projectEnvDAL,
|
projectEnvDAL,
|
||||||
snapshotService,
|
snapshotService,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
folderCommitService
|
folderCommitService,
|
||||||
|
secretApprovalPolicyService,
|
||||||
|
secretV2BridgeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretImportService = secretImportServiceFactory({
|
const secretImportService = secretImportServiceFactory({
|
||||||
@@ -1415,7 +1419,8 @@ export const registerRoutes = async (
|
|||||||
const identityAccessTokenService = identityAccessTokenServiceFactory({
|
const identityAccessTokenService = identityAccessTokenServiceFactory({
|
||||||
identityAccessTokenDAL,
|
identityAccessTokenDAL,
|
||||||
identityOrgMembershipDAL,
|
identityOrgMembershipDAL,
|
||||||
accessTokenQueue
|
accessTokenQueue,
|
||||||
|
identityDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const identityProjectService = identityProjectServiceFactory({
|
const identityProjectService = identityProjectServiceFactory({
|
||||||
@@ -1491,6 +1496,15 @@ export const registerRoutes = async (
|
|||||||
permissionService
|
permissionService
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const identityTlsCertAuthService = identityTlsCertAuthServiceFactory({
|
||||||
|
identityAccessTokenDAL,
|
||||||
|
identityTlsCertAuthDAL,
|
||||||
|
identityOrgMembershipDAL,
|
||||||
|
licenseService,
|
||||||
|
permissionService,
|
||||||
|
kmsService
|
||||||
|
});
|
||||||
|
|
||||||
const identityAwsAuthService = identityAwsAuthServiceFactory({
|
const identityAwsAuthService = identityAwsAuthServiceFactory({
|
||||||
identityAccessTokenDAL,
|
identityAccessTokenDAL,
|
||||||
identityAwsAuthDAL,
|
identityAwsAuthDAL,
|
||||||
@@ -1649,8 +1663,7 @@ export const registerRoutes = async (
|
|||||||
const cmekService = cmekServiceFactory({
|
const cmekService = cmekServiceFactory({
|
||||||
kmsDAL,
|
kmsDAL,
|
||||||
kmsService,
|
kmsService,
|
||||||
permissionService,
|
permissionService
|
||||||
projectDAL
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const externalMigrationQueue = externalMigrationQueueFactory({
|
const externalMigrationQueue = externalMigrationQueueFactory({
|
||||||
@@ -1792,7 +1805,6 @@ export const registerRoutes = async (
|
|||||||
|
|
||||||
const certificateAuthorityService = certificateAuthorityServiceFactory({
|
const certificateAuthorityService = certificateAuthorityServiceFactory({
|
||||||
certificateAuthorityDAL,
|
certificateAuthorityDAL,
|
||||||
projectDAL,
|
|
||||||
permissionService,
|
permissionService,
|
||||||
appConnectionDAL,
|
appConnectionDAL,
|
||||||
appConnectionService,
|
appConnectionService,
|
||||||
@@ -1802,7 +1814,8 @@ export const registerRoutes = async (
|
|||||||
certificateBodyDAL,
|
certificateBodyDAL,
|
||||||
certificateSecretDAL,
|
certificateSecretDAL,
|
||||||
kmsService,
|
kmsService,
|
||||||
pkiSubscriberDAL
|
pkiSubscriberDAL,
|
||||||
|
projectDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const internalCaFns = InternalCertificateAuthorityFns({
|
const internalCaFns = InternalCertificateAuthorityFns({
|
||||||
@@ -1945,6 +1958,7 @@ export const registerRoutes = async (
|
|||||||
identityAwsAuth: identityAwsAuthService,
|
identityAwsAuth: identityAwsAuthService,
|
||||||
identityAzureAuth: identityAzureAuthService,
|
identityAzureAuth: identityAzureAuthService,
|
||||||
identityOciAuth: identityOciAuthService,
|
identityOciAuth: identityOciAuthService,
|
||||||
|
identityTlsCertAuth: identityTlsCertAuthService,
|
||||||
identityOidcAuth: identityOidcAuthService,
|
identityOidcAuth: identityOidcAuthService,
|
||||||
identityJwtAuth: identityJwtAuthService,
|
identityJwtAuth: identityJwtAuthService,
|
||||||
identityLdapAuth: identityLdapAuthService,
|
identityLdapAuth: identityLdapAuthService,
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ export const SanitizedProjectSchema = ProjectsSchema.pick({
|
|||||||
name: true,
|
name: true,
|
||||||
description: true,
|
description: true,
|
||||||
type: true,
|
type: true,
|
||||||
|
defaultProduct: true,
|
||||||
slug: true,
|
slug: true,
|
||||||
autoCapitalization: true,
|
autoCapitalization: true,
|
||||||
orgId: true,
|
orgId: true,
|
||||||
|
|||||||
@@ -722,6 +722,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.InvalidateCache,
|
event: PostHogEventTypes.InvalidateCache,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
...req.auditLogInfo
|
...req.auditLogInfo
|
||||||
|
|||||||
@@ -692,6 +692,7 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueCert,
|
event: PostHogEventTypes.IssueCert,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
caId: ca.id,
|
caId: ca.id,
|
||||||
@@ -786,6 +787,7 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SignCert,
|
event: PostHogEventTypes.SignCert,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
caId: ca.id,
|
caId: ca.id,
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueCert,
|
event: PostHogEventTypes.IssueCert,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
caId: req.body.caId,
|
caId: req.body.caId,
|
||||||
certificateTemplateId: req.body.certificateTemplateId,
|
certificateTemplateId: req.body.certificateTemplateId,
|
||||||
@@ -442,6 +443,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SignCert,
|
event: PostHogEventTypes.SignCert,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
caId: req.body.caId,
|
caId: req.body.caId,
|
||||||
certificateTemplateId: req.body.certificateTemplateId,
|
certificateTemplateId: req.body.certificateTemplateId,
|
||||||
|
|||||||
@@ -475,6 +475,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secretCountFromEnv,
|
numberOfSecrets: secretCountFromEnv,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
@@ -979,6 +980,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secretCount,
|
numberOfSecrets: secretCount,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
@@ -1144,6 +1146,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secretCountForEnv,
|
numberOfSecrets: secretCountForEnv,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
@@ -1336,6 +1339,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.MachineIdentityCreated,
|
event: PostHogEventTypes.MachineIdentityCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
orgId: req.body.organizationId,
|
orgId: req.body.organizationId,
|
||||||
name: identity.name,
|
name: identity.name,
|
||||||
|
|||||||
@@ -0,0 +1,396 @@
|
|||||||
|
import crypto from "node:crypto";
|
||||||
|
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { IdentityTlsCertAuthsSchema } from "@app/db/schemas";
|
||||||
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { ApiDocsTags, TLS_CERT_AUTH } from "@app/lib/api-docs";
|
||||||
|
import { getConfig } from "@app/lib/config/env";
|
||||||
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
import { TIdentityTrustedIp } from "@app/services/identity/identity-types";
|
||||||
|
import { isSuperAdmin } from "@app/services/super-admin/super-admin-fns";
|
||||||
|
|
||||||
|
const validateCommonNames = z
|
||||||
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.trim()
|
||||||
|
.transform((el) =>
|
||||||
|
el
|
||||||
|
.split(",")
|
||||||
|
.map((i) => i.trim())
|
||||||
|
.join(",")
|
||||||
|
);
|
||||||
|
|
||||||
|
const validateCaCertificate = (caCert: string) => {
|
||||||
|
if (!caCert) return true;
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line no-new
|
||||||
|
new crypto.X509Certificate(caCert);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const registerIdentityTlsCertAuthRouter = async (server: FastifyZodProvider) => {
|
||||||
|
server.route({
|
||||||
|
method: "POST",
|
||||||
|
url: "/login",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.TlsCertAuth],
|
||||||
|
description: "Login with TLS Certificate Auth",
|
||||||
|
body: z.object({
|
||||||
|
identityId: z.string().trim().describe(TLS_CERT_AUTH.LOGIN.identityId)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
accessToken: z.string(),
|
||||||
|
expiresIn: z.coerce.number(),
|
||||||
|
accessTokenMaxTTL: z.coerce.number(),
|
||||||
|
tokenType: z.literal("Bearer")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const appCfg = getConfig();
|
||||||
|
const clientCertificate = req.headers[appCfg.IDENTITY_TLS_CERT_AUTH_CLIENT_CERTIFICATE_HEADER_KEY];
|
||||||
|
if (!clientCertificate) {
|
||||||
|
throw new BadRequestError({ message: "Missing TLS certificate in header" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { identityTlsCertAuth, accessToken, identityAccessToken, identityMembershipOrg } =
|
||||||
|
await server.services.identityTlsCertAuth.login({
|
||||||
|
identityId: req.body.identityId,
|
||||||
|
clientCertificate: clientCertificate as string
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
orgId: identityMembershipOrg?.orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.LOGIN_IDENTITY_TLS_CERT_AUTH,
|
||||||
|
metadata: {
|
||||||
|
identityId: identityTlsCertAuth.identityId,
|
||||||
|
identityAccessTokenId: identityAccessToken.id,
|
||||||
|
identityTlsCertAuthId: identityTlsCertAuth.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
accessToken,
|
||||||
|
tokenType: "Bearer" as const,
|
||||||
|
expiresIn: identityTlsCertAuth.accessTokenTTL,
|
||||||
|
accessTokenMaxTTL: identityTlsCertAuth.accessTokenMaxTTL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "POST",
|
||||||
|
url: "/identities/:identityId",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.TlsCertAuth],
|
||||||
|
description: "Attach TLS Certificate Auth configuration onto identity",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
identityId: z.string().trim().describe(TLS_CERT_AUTH.ATTACH.identityId)
|
||||||
|
}),
|
||||||
|
body: z
|
||||||
|
.object({
|
||||||
|
allowedCommonNames: validateCommonNames
|
||||||
|
.optional()
|
||||||
|
.nullable()
|
||||||
|
.describe(TLS_CERT_AUTH.ATTACH.allowedCommonNames),
|
||||||
|
caCertificate: z
|
||||||
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.max(10240)
|
||||||
|
.refine(validateCaCertificate, "Invalid CA Certificate.")
|
||||||
|
.describe(TLS_CERT_AUTH.ATTACH.caCertificate),
|
||||||
|
accessTokenTrustedIps: z
|
||||||
|
.object({
|
||||||
|
ipAddress: z.string().trim()
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
.min(1)
|
||||||
|
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }])
|
||||||
|
.describe(TLS_CERT_AUTH.ATTACH.accessTokenTrustedIps),
|
||||||
|
accessTokenTTL: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.min(0)
|
||||||
|
.max(315360000)
|
||||||
|
.default(2592000)
|
||||||
|
.describe(TLS_CERT_AUTH.ATTACH.accessTokenTTL),
|
||||||
|
accessTokenMaxTTL: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.min(1)
|
||||||
|
.max(315360000)
|
||||||
|
.default(2592000)
|
||||||
|
.describe(TLS_CERT_AUTH.ATTACH.accessTokenMaxTTL),
|
||||||
|
accessTokenNumUsesLimit: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.min(0)
|
||||||
|
.default(0)
|
||||||
|
.describe(TLS_CERT_AUTH.ATTACH.accessTokenNumUsesLimit)
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(val) => val.accessTokenTTL <= val.accessTokenMaxTTL,
|
||||||
|
"Access Token TTL cannot be greater than Access Token Max TTL."
|
||||||
|
),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
identityTlsCertAuth: IdentityTlsCertAuthsSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const identityTlsCertAuth = await server.services.identityTlsCertAuth.attachTlsCertAuth({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
identityId: req.params.identityId,
|
||||||
|
isActorSuperAdmin: isSuperAdmin(req.auth)
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
orgId: req.permission.orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.ADD_IDENTITY_TLS_CERT_AUTH,
|
||||||
|
metadata: {
|
||||||
|
identityId: identityTlsCertAuth.identityId,
|
||||||
|
allowedCommonNames: identityTlsCertAuth.allowedCommonNames,
|
||||||
|
accessTokenTTL: identityTlsCertAuth.accessTokenTTL,
|
||||||
|
accessTokenMaxTTL: identityTlsCertAuth.accessTokenMaxTTL,
|
||||||
|
accessTokenTrustedIps: identityTlsCertAuth.accessTokenTrustedIps as TIdentityTrustedIp[],
|
||||||
|
accessTokenNumUsesLimit: identityTlsCertAuth.accessTokenNumUsesLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { identityTlsCertAuth };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "PATCH",
|
||||||
|
url: "/identities/:identityId",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.TlsCertAuth],
|
||||||
|
description: "Update TLS Certificate Auth configuration on identity",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
identityId: z.string().describe(TLS_CERT_AUTH.UPDATE.identityId)
|
||||||
|
}),
|
||||||
|
body: z
|
||||||
|
.object({
|
||||||
|
caCertificate: z
|
||||||
|
.string()
|
||||||
|
.min(1)
|
||||||
|
.max(10240)
|
||||||
|
.refine(validateCaCertificate, "Invalid CA Certificate.")
|
||||||
|
.optional()
|
||||||
|
.describe(TLS_CERT_AUTH.UPDATE.caCertificate),
|
||||||
|
allowedCommonNames: validateCommonNames
|
||||||
|
.optional()
|
||||||
|
.nullable()
|
||||||
|
.describe(TLS_CERT_AUTH.UPDATE.allowedCommonNames),
|
||||||
|
accessTokenTrustedIps: z
|
||||||
|
.object({
|
||||||
|
ipAddress: z.string().trim()
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
.min(1)
|
||||||
|
.optional()
|
||||||
|
.describe(TLS_CERT_AUTH.UPDATE.accessTokenTrustedIps),
|
||||||
|
accessTokenTTL: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.min(0)
|
||||||
|
.max(315360000)
|
||||||
|
.optional()
|
||||||
|
.describe(TLS_CERT_AUTH.UPDATE.accessTokenTTL),
|
||||||
|
accessTokenNumUsesLimit: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.min(0)
|
||||||
|
.optional()
|
||||||
|
.describe(TLS_CERT_AUTH.UPDATE.accessTokenNumUsesLimit),
|
||||||
|
accessTokenMaxTTL: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.max(315360000)
|
||||||
|
.min(0)
|
||||||
|
.optional()
|
||||||
|
.describe(TLS_CERT_AUTH.UPDATE.accessTokenMaxTTL)
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(val) => (val.accessTokenMaxTTL && val.accessTokenTTL ? val.accessTokenTTL <= val.accessTokenMaxTTL : true),
|
||||||
|
"Access Token TTL cannot be greater than Access Token Max TTL."
|
||||||
|
),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
identityTlsCertAuth: IdentityTlsCertAuthsSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const identityTlsCertAuth = await server.services.identityTlsCertAuth.updateTlsCertAuth({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
identityId: req.params.identityId
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
orgId: req.permission.orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.UPDATE_IDENTITY_TLS_CERT_AUTH,
|
||||||
|
metadata: {
|
||||||
|
identityId: identityTlsCertAuth.identityId,
|
||||||
|
allowedCommonNames: identityTlsCertAuth.allowedCommonNames,
|
||||||
|
accessTokenTTL: identityTlsCertAuth.accessTokenTTL,
|
||||||
|
accessTokenMaxTTL: identityTlsCertAuth.accessTokenMaxTTL,
|
||||||
|
accessTokenTrustedIps: identityTlsCertAuth.accessTokenTrustedIps as TIdentityTrustedIp[],
|
||||||
|
accessTokenNumUsesLimit: identityTlsCertAuth.accessTokenNumUsesLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { identityTlsCertAuth };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/identities/:identityId",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.TlsCertAuth],
|
||||||
|
description: "Retrieve TLS Certificate Auth configuration on identity",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
identityId: z.string().describe(TLS_CERT_AUTH.RETRIEVE.identityId)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
identityTlsCertAuth: IdentityTlsCertAuthsSchema.extend({
|
||||||
|
caCertificate: z.string()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const identityTlsCertAuth = await server.services.identityTlsCertAuth.getTlsCertAuth({
|
||||||
|
identityId: req.params.identityId,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
actorAuthMethod: req.permission.authMethod
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
orgId: req.permission.orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.GET_IDENTITY_TLS_CERT_AUTH,
|
||||||
|
metadata: {
|
||||||
|
identityId: identityTlsCertAuth.identityId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { identityTlsCertAuth };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "DELETE",
|
||||||
|
url: "/identities/:identityId",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.TlsCertAuth],
|
||||||
|
description: "Delete TLS Certificate Auth configuration on identity",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
identityId: z.string().describe(TLS_CERT_AUTH.REVOKE.identityId)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
identityTlsCertAuth: IdentityTlsCertAuthsSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const identityTlsCertAuth = await server.services.identityTlsCertAuth.revokeTlsCertAuth({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
identityId: req.params.identityId
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
orgId: req.permission.orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.REVOKE_IDENTITY_TLS_CERT_AUTH,
|
||||||
|
metadata: {
|
||||||
|
identityId: identityTlsCertAuth.identityId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { identityTlsCertAuth };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -25,6 +25,7 @@ import { registerIdentityLdapAuthRouter } from "./identity-ldap-auth-router";
|
|||||||
import { registerIdentityOciAuthRouter } from "./identity-oci-auth-router";
|
import { registerIdentityOciAuthRouter } from "./identity-oci-auth-router";
|
||||||
import { registerIdentityOidcAuthRouter } from "./identity-oidc-auth-router";
|
import { registerIdentityOidcAuthRouter } from "./identity-oidc-auth-router";
|
||||||
import { registerIdentityRouter } from "./identity-router";
|
import { registerIdentityRouter } from "./identity-router";
|
||||||
|
import { registerIdentityTlsCertAuthRouter } from "./identity-tls-cert-auth-router";
|
||||||
import { registerIdentityTokenAuthRouter } from "./identity-token-auth-router";
|
import { registerIdentityTokenAuthRouter } from "./identity-token-auth-router";
|
||||||
import { registerIdentityUaRouter } from "./identity-universal-auth-router";
|
import { registerIdentityUaRouter } from "./identity-universal-auth-router";
|
||||||
import { registerIntegrationAuthRouter } from "./integration-auth-router";
|
import { registerIntegrationAuthRouter } from "./integration-auth-router";
|
||||||
@@ -66,6 +67,7 @@ export const registerV1Routes = async (server: FastifyZodProvider) => {
|
|||||||
await authRouter.register(registerIdentityAccessTokenRouter);
|
await authRouter.register(registerIdentityAccessTokenRouter);
|
||||||
await authRouter.register(registerIdentityAliCloudAuthRouter);
|
await authRouter.register(registerIdentityAliCloudAuthRouter);
|
||||||
await authRouter.register(registerIdentityAwsAuthRouter);
|
await authRouter.register(registerIdentityAwsAuthRouter);
|
||||||
|
await authRouter.register(registerIdentityTlsCertAuthRouter, { prefix: "/tls-cert-auth" });
|
||||||
await authRouter.register(registerIdentityAzureAuthRouter);
|
await authRouter.register(registerIdentityAzureAuthRouter);
|
||||||
await authRouter.register(registerIdentityOciAuthRouter);
|
await authRouter.register(registerIdentityOciAuthRouter);
|
||||||
await authRouter.register(registerIdentityOidcAuthRouter);
|
await authRouter.register(registerIdentityOidcAuthRouter);
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IntegrationCreated,
|
event: PostHogEventTypes.IntegrationCreated,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
...createIntegrationEventProperty,
|
...createIntegrationEventProperty,
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export const registerInviteOrgRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.UserOrgInvitation,
|
event: PostHogEventTypes.UserOrgInvitation,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
inviteeEmails: req.body.inviteeEmails,
|
inviteeEmails: req.body.inviteeEmails,
|
||||||
organizationRoleSlug: req.body.organizationRoleSlug,
|
organizationRoleSlug: req.body.organizationRoleSlug,
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
|||||||
|
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueCert,
|
event: PostHogEventTypes.IssueCert,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
subscriberId: subscriber.id,
|
subscriberId: subscriber.id,
|
||||||
@@ -399,6 +400,7 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.IssueCert,
|
event: PostHogEventTypes.IssueCert,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
subscriberId: subscriber.id,
|
subscriberId: subscriber.id,
|
||||||
commonName: subscriber.commonName,
|
commonName: subscriber.commonName,
|
||||||
@@ -471,6 +473,7 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SignCert,
|
event: PostHogEventTypes.SignCert,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
subscriberId: subscriber.id,
|
subscriberId: subscriber.id,
|
||||||
commonName: subscriber.commonName,
|
commonName: subscriber.commonName,
|
||||||
|
|||||||
@@ -158,17 +158,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
includeRoles: z
|
includeRoles: z
|
||||||
.enum(["true", "false"])
|
.enum(["true", "false"])
|
||||||
.default("false")
|
.default("false")
|
||||||
.transform((value) => value === "true"),
|
.transform((value) => value === "true")
|
||||||
type: z
|
|
||||||
.enum([
|
|
||||||
ProjectType.SecretManager,
|
|
||||||
ProjectType.KMS,
|
|
||||||
ProjectType.CertificateManager,
|
|
||||||
ProjectType.SSH,
|
|
||||||
ProjectType.SecretScanning,
|
|
||||||
"all"
|
|
||||||
])
|
|
||||||
.optional()
|
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -187,8 +177,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId
|
||||||
type: req.query.type
|
|
||||||
});
|
});
|
||||||
return { workspaces };
|
return { workspaces };
|
||||||
}
|
}
|
||||||
@@ -377,7 +366,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
.optional()
|
.optional()
|
||||||
.describe(PROJECTS.UPDATE.slug),
|
.describe(PROJECTS.UPDATE.slug),
|
||||||
secretSharing: z.boolean().optional().describe(PROJECTS.UPDATE.secretSharing),
|
secretSharing: z.boolean().optional().describe(PROJECTS.UPDATE.secretSharing),
|
||||||
showSnapshotsLegacy: z.boolean().optional().describe(PROJECTS.UPDATE.showSnapshotsLegacy)
|
showSnapshotsLegacy: z.boolean().optional().describe(PROJECTS.UPDATE.showSnapshotsLegacy),
|
||||||
|
defaultProduct: z.nativeEnum(ProjectType).optional().describe(PROJECTS.UPDATE.defaultProduct)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -396,6 +386,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
name: req.body.name,
|
name: req.body.name,
|
||||||
description: req.body.description,
|
description: req.body.description,
|
||||||
autoCapitalization: req.body.autoCapitalization,
|
autoCapitalization: req.body.autoCapitalization,
|
||||||
|
defaultProduct: req.body.defaultProduct,
|
||||||
hasDeleteProtection: req.body.hasDeleteProtection,
|
hasDeleteProtection: req.body.hasDeleteProtection,
|
||||||
slug: req.body.slug,
|
slug: req.body.slug,
|
||||||
secretSharing: req.body.secretSharing,
|
secretSharing: req.body.secretSharing,
|
||||||
@@ -1059,7 +1050,6 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
limit: z.number().default(100),
|
limit: z.number().default(100),
|
||||||
offset: z.number().default(0),
|
offset: z.number().default(0),
|
||||||
type: z.nativeEnum(ProjectType).optional(),
|
|
||||||
orderBy: z.nativeEnum(SearchProjectSortBy).optional().default(SearchProjectSortBy.NAME),
|
orderBy: z.nativeEnum(SearchProjectSortBy).optional().default(SearchProjectSortBy.NAME),
|
||||||
orderDirection: z.nativeEnum(SortDirection).optional().default(SortDirection.ASC),
|
orderDirection: z.nativeEnum(SortDirection).optional().default(SortDirection.ASC),
|
||||||
name: z
|
name: z
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ export const registerSecretRequestsRouter = async (server: FastifyZodProvider) =
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretRequestDeleted,
|
event: PostHogEventTypes.SecretRequestDeleted,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
secretRequestId: req.params.id,
|
secretRequestId: req.params.id,
|
||||||
organizationId: req.permission.orgId,
|
organizationId: req.permission.orgId,
|
||||||
@@ -256,6 +257,7 @@ export const registerSecretRequestsRouter = async (server: FastifyZodProvider) =
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretRequestCreated,
|
event: PostHogEventTypes.SecretRequestCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
secretRequestId: shareRequest.id,
|
secretRequestId: shareRequest.id,
|
||||||
organizationId: req.permission.orgId,
|
organizationId: req.permission.orgId,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
OrgMembershipsSchema,
|
OrgMembershipsSchema,
|
||||||
ProjectMembershipsSchema,
|
ProjectMembershipsSchema,
|
||||||
ProjectsSchema,
|
ProjectsSchema,
|
||||||
ProjectType,
|
|
||||||
UserEncryptionKeysSchema,
|
UserEncryptionKeysSchema,
|
||||||
UsersSchema
|
UsersSchema
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
@@ -85,9 +84,6 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
|||||||
params: z.object({
|
params: z.object({
|
||||||
organizationId: z.string().trim().describe(ORGANIZATIONS.GET_PROJECTS.organizationId)
|
organizationId: z.string().trim().describe(ORGANIZATIONS.GET_PROJECTS.organizationId)
|
||||||
}),
|
}),
|
||||||
querystring: z.object({
|
|
||||||
type: z.nativeEnum(ProjectType).optional().describe(ORGANIZATIONS.GET_PROJECTS.type)
|
|
||||||
}),
|
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
workspaces: z
|
workspaces: z
|
||||||
@@ -114,8 +110,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
orgId: req.params.organizationId,
|
orgId: req.params.organizationId
|
||||||
type: req.query.type
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { workspaces };
|
return { workspaces };
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.ProjectCreated,
|
event: PostHogEventTypes.ProjectCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
orgId: project.orgId,
|
orgId: project.orgId,
|
||||||
name: project.name,
|
name: project.name,
|
||||||
@@ -456,6 +457,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.PkiAlerting],
|
||||||
params: z.object({
|
params: z.object({
|
||||||
projectId: z.string().trim()
|
projectId: z.string().trim()
|
||||||
}),
|
}),
|
||||||
@@ -486,6 +489,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.PkiCertificateCollections],
|
||||||
params: z.object({
|
params: z.object({
|
||||||
projectId: z.string().trim()
|
projectId: z.string().trim()
|
||||||
}),
|
}),
|
||||||
@@ -548,6 +553,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.PkiCertificateTemplates],
|
||||||
params: z.object({
|
params: z.object({
|
||||||
projectId: z.string().trim()
|
projectId: z.string().trim()
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -333,6 +333,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -489,6 +490,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
if (getUserAgentType(req.headers["user-agent"]) !== UserAgentType.K8_OPERATOR) {
|
if (getUserAgentType(req.headers["user-agent"]) !== UserAgentType.K8_OPERATOR) {
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
@@ -615,6 +617,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretCreated,
|
event: PostHogEventTypes.SecretCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
@@ -750,6 +753,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretUpdated,
|
event: PostHogEventTypes.SecretUpdated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
@@ -850,6 +854,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretDeleted,
|
event: PostHogEventTypes.SecretDeleted,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: projectId,
|
workspaceId: projectId,
|
||||||
@@ -957,6 +962,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: req.query.workspaceId,
|
workspaceId: req.query.workspaceId,
|
||||||
@@ -1036,6 +1042,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
event: PostHogEventTypes.SecretPulled,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: req.query.workspaceId,
|
workspaceId: req.query.workspaceId,
|
||||||
@@ -1207,6 +1214,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretCreated,
|
event: PostHogEventTypes.SecretCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: req.body.workspaceId,
|
workspaceId: req.body.workspaceId,
|
||||||
@@ -1396,6 +1404,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretUpdated,
|
event: PostHogEventTypes.SecretUpdated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: req.body.workspaceId,
|
workspaceId: req.body.workspaceId,
|
||||||
@@ -1519,6 +1528,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretDeleted,
|
event: PostHogEventTypes.SecretDeleted,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: 1,
|
numberOfSecrets: 1,
|
||||||
workspaceId: req.body.workspaceId,
|
workspaceId: req.body.workspaceId,
|
||||||
@@ -1702,6 +1712,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretCreated,
|
event: PostHogEventTypes.SecretCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: req.body.workspaceId,
|
workspaceId: req.body.workspaceId,
|
||||||
@@ -1828,6 +1839,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretUpdated,
|
event: PostHogEventTypes.SecretUpdated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: req.body.workspaceId,
|
workspaceId: req.body.workspaceId,
|
||||||
@@ -1946,6 +1958,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretDeleted,
|
event: PostHogEventTypes.SecretDeleted,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: req.body.workspaceId,
|
workspaceId: req.body.workspaceId,
|
||||||
@@ -2054,6 +2067,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretCreated,
|
event: PostHogEventTypes.SecretCreated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: secrets[0].workspace,
|
workspaceId: secrets[0].workspace,
|
||||||
@@ -2209,6 +2223,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretUpdated,
|
event: PostHogEventTypes.SecretUpdated,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: secrets[0].workspace,
|
workspaceId: secrets[0].workspace,
|
||||||
@@ -2307,6 +2322,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
event: PostHogEventTypes.SecretDeleted,
|
event: PostHogEventTypes.SecretDeleted,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
organizationId: req.permission.orgId,
|
||||||
properties: {
|
properties: {
|
||||||
numberOfSecrets: secrets.length,
|
numberOfSecrets: secrets.length,
|
||||||
workspaceId: secrets[0].workspace,
|
workspaceId: secrets[0].workspace,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { logger } from "@app/lib/logger";
|
||||||
import { OrgServiceActor } from "@app/lib/types";
|
import { OrgServiceActor } from "@app/lib/types";
|
||||||
|
|
||||||
import { AppConnection } from "../app-connection-enums";
|
import { AppConnection } from "../app-connection-enums";
|
||||||
@@ -19,6 +20,7 @@ export const gcpConnectionService = (getAppConnection: TGetAppConnectionFunc) =>
|
|||||||
|
|
||||||
return projects;
|
return projects;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
logger.error(error, "Error listing GCP secret manager projects");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectType, TableName } from "@app/db/schemas";
|
import { TableName } from "@app/db/schemas";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
@@ -50,10 +50,7 @@ type TCertificateAuthorityServiceFactoryDep = {
|
|||||||
>;
|
>;
|
||||||
externalCertificateAuthorityDAL: Pick<TExternalCertificateAuthorityDALFactory, "create" | "update">;
|
externalCertificateAuthorityDAL: Pick<TExternalCertificateAuthorityDALFactory, "create" | "update">;
|
||||||
internalCertificateAuthorityService: TInternalCertificateAuthorityServiceFactory;
|
internalCertificateAuthorityService: TInternalCertificateAuthorityServiceFactory;
|
||||||
projectDAL: Pick<
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||||
TProjectDALFactory,
|
|
||||||
"findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction" | "getProjectFromSplitId"
|
|
||||||
>;
|
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
certificateDAL: Pick<TCertificateDALFactory, "create" | "transaction">;
|
certificateDAL: Pick<TCertificateDALFactory, "create" | "transaction">;
|
||||||
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
||||||
@@ -98,23 +95,12 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
{ type, projectId, name, enableDirectIssuance, configuration, status }: TCreateCertificateAuthorityDTO,
|
{ type, projectId, name, enableDirectIssuance, configuration, status }: TCreateCertificateAuthorityDTO,
|
||||||
actor: OrgServiceActor
|
actor: OrgServiceActor
|
||||||
) => {
|
) => {
|
||||||
let finalProjectId: string = projectId;
|
|
||||||
const certManagerProjectFromSplit = await projectDAL.getProjectFromSplitId(
|
|
||||||
projectId,
|
|
||||||
ProjectType.CertificateManager
|
|
||||||
);
|
|
||||||
|
|
||||||
if (certManagerProjectFromSplit) {
|
|
||||||
finalProjectId = certManagerProjectFromSplit.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor: actor.type,
|
actor: actor.type,
|
||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: finalProjectId,
|
projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -126,7 +112,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
const ca = await internalCertificateAuthorityService.createCa({
|
const ca = await internalCertificateAuthorityService.createCa({
|
||||||
...(configuration as TCreateInternalCertificateAuthorityDTO["configuration"]),
|
...(configuration as TCreateInternalCertificateAuthorityDTO["configuration"]),
|
||||||
isInternal: true,
|
isInternal: true,
|
||||||
projectId: finalProjectId,
|
projectId,
|
||||||
enableDirectIssuance,
|
enableDirectIssuance,
|
||||||
name
|
name
|
||||||
});
|
});
|
||||||
@@ -142,7 +128,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
type,
|
type,
|
||||||
enableDirectIssuance: ca.enableDirectIssuance,
|
enableDirectIssuance: ca.enableDirectIssuance,
|
||||||
name: ca.name,
|
name: ca.name,
|
||||||
projectId: finalProjectId,
|
projectId,
|
||||||
status,
|
status,
|
||||||
configuration: ca.internalCa
|
configuration: ca.internalCa
|
||||||
} as TCertificateAuthority;
|
} as TCertificateAuthority;
|
||||||
@@ -151,7 +137,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
if (type === CaType.ACME) {
|
if (type === CaType.ACME) {
|
||||||
return acmeFns.createCertificateAuthority({
|
return acmeFns.createCertificateAuthority({
|
||||||
name,
|
name,
|
||||||
projectId: finalProjectId,
|
projectId,
|
||||||
configuration: configuration as TCreateAcmeCertificateAuthorityDTO["configuration"],
|
configuration: configuration as TCreateAcmeCertificateAuthorityDTO["configuration"],
|
||||||
enableDirectIssuance,
|
enableDirectIssuance,
|
||||||
status,
|
status,
|
||||||
@@ -181,8 +167,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: certificateAuthority.projectId,
|
projectId: certificateAuthority.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -225,23 +210,12 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
{ projectId, type }: { projectId: string; type: CaType },
|
{ projectId, type }: { projectId: string; type: CaType },
|
||||||
actor: OrgServiceActor
|
actor: OrgServiceActor
|
||||||
) => {
|
) => {
|
||||||
let finalProjectId: string = projectId;
|
|
||||||
const certManagerProjectFromSplit = await projectDAL.getProjectFromSplitId(
|
|
||||||
projectId,
|
|
||||||
ProjectType.CertificateManager
|
|
||||||
);
|
|
||||||
|
|
||||||
if (certManagerProjectFromSplit) {
|
|
||||||
finalProjectId = certManagerProjectFromSplit.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor: actor.type,
|
actor: actor.type,
|
||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: finalProjectId,
|
projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -251,7 +225,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
|
|
||||||
if (type === CaType.INTERNAL) {
|
if (type === CaType.INTERNAL) {
|
||||||
const cas = await certificateAuthorityDAL.findWithAssociatedCa({
|
const cas = await certificateAuthorityDAL.findWithAssociatedCa({
|
||||||
[`${TableName.CertificateAuthority}.projectId` as "projectId"]: finalProjectId,
|
[`${TableName.CertificateAuthority}.projectId` as "projectId"]: projectId,
|
||||||
$notNull: [`${TableName.InternalCertificateAuthority}.id` as "id"]
|
$notNull: [`${TableName.InternalCertificateAuthority}.id` as "id"]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -269,7 +243,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === CaType.ACME) {
|
if (type === CaType.ACME) {
|
||||||
return acmeFns.listCertificateAuthorities({ projectId: finalProjectId });
|
return acmeFns.listCertificateAuthorities({ projectId });
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new BadRequestError({ message: "Invalid certificate authority type" });
|
throw new BadRequestError({ message: "Invalid certificate authority type" });
|
||||||
@@ -294,8 +268,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: certificateAuthority.projectId,
|
projectId: certificateAuthority.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -368,8 +341,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: certificateAuthority.projectId,
|
projectId: certificateAuthority.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
+15
-45
@@ -5,13 +5,7 @@ import slugify from "@sindresorhus/slugify";
|
|||||||
import crypto, { KeyObject } from "crypto";
|
import crypto, { KeyObject } from "crypto";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import {
|
import { TableName, TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas";
|
||||||
ActionProjectType,
|
|
||||||
ProjectType,
|
|
||||||
TableName,
|
|
||||||
TCertificateAuthorities,
|
|
||||||
TCertificateTemplates
|
|
||||||
} from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
@@ -105,10 +99,7 @@ type TInternalCertificateAuthorityServiceFactoryDep = {
|
|||||||
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
||||||
pkiCollectionDAL: Pick<TPkiCollectionDALFactory, "findById">;
|
pkiCollectionDAL: Pick<TPkiCollectionDALFactory, "findById">;
|
||||||
pkiCollectionItemDAL: Pick<TPkiCollectionItemDALFactory, "create">;
|
pkiCollectionItemDAL: Pick<TPkiCollectionItemDALFactory, "create">;
|
||||||
projectDAL: Pick<
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||||
TProjectDALFactory,
|
|
||||||
"findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction" | "getProjectFromSplitId"
|
|
||||||
>;
|
|
||||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
};
|
};
|
||||||
@@ -154,21 +145,12 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
if (!project) throw new NotFoundError({ message: `Project with slug '${dto.projectSlug}' not found` });
|
if (!project) throw new NotFoundError({ message: `Project with slug '${dto.projectSlug}' not found` });
|
||||||
projectId = project.id;
|
projectId = project.id;
|
||||||
|
|
||||||
const certManagerProjectFromSplit = await projectDAL.getProjectFromSplitId(
|
|
||||||
projectId,
|
|
||||||
ProjectType.CertificateManager
|
|
||||||
);
|
|
||||||
if (certManagerProjectFromSplit) {
|
|
||||||
projectId = certManagerProjectFromSplit.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor: dto.actor,
|
actor: dto.actor,
|
||||||
actorId: dto.actorId,
|
actorId: dto.actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: dto.actorAuthMethod,
|
actorAuthMethod: dto.actorAuthMethod,
|
||||||
actorOrgId: dto.actorOrgId,
|
actorOrgId: dto.actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -351,8 +333,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionActions.Read,
|
||||||
@@ -376,8 +357,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId: dto.actorId,
|
actorId: dto.actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod: dto.actorAuthMethod,
|
actorAuthMethod: dto.actorAuthMethod,
|
||||||
actorOrgId: dto.actorOrgId,
|
actorOrgId: dto.actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -409,8 +389,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -435,8 +414,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -499,8 +477,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -786,8 +763,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -823,8 +799,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -904,8 +879,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -1052,8 +1026,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -1224,8 +1197,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -1581,8 +1553,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId: dto.actorId,
|
actorId: dto.actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod: dto.actorAuthMethod,
|
actorAuthMethod: dto.actorAuthMethod,
|
||||||
actorOrgId: dto.actorOrgId,
|
actorOrgId: dto.actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -1949,8 +1920,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const certificateTemplates = await certificateTemplateDAL.find({ caId });
|
const certificateTemplates = await certificateTemplateDAL.find({ caId });
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability";
|
|||||||
import * as x509 from "@peculiar/x509";
|
import * as x509 from "@peculiar/x509";
|
||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
|
|
||||||
import { ActionProjectType, TCertificateTemplateEstConfigsUpdate } from "@app/db/schemas";
|
import { TCertificateTemplateEstConfigsUpdate } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
@@ -76,8 +76,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -138,8 +137,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -203,8 +201,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -230,8 +227,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -272,8 +268,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -355,8 +350,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -435,8 +429,7 @@ export const certificateTemplateServiceFactory = ({
|
|||||||
actorId: dto.actorId,
|
actorId: dto.actorId,
|
||||||
projectId: certTemplate.projectId,
|
projectId: certTemplate.projectId,
|
||||||
actorAuthMethod: dto.actorAuthMethod,
|
actorAuthMethod: dto.actorAuthMethod,
|
||||||
actorOrgId: dto.actorOrgId,
|
actorOrgId: dto.actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { ForbiddenError } from "@casl/ability";
|
|||||||
import * as x509 from "@peculiar/x509";
|
import * as x509 from "@peculiar/x509";
|
||||||
import { createPrivateKey, createPublicKey, sign, verify } from "crypto";
|
import { createPrivateKey, createPublicKey, sign, verify } from "crypto";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectType } from "@app/db/schemas";
|
|
||||||
import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal";
|
import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
@@ -48,10 +47,7 @@ type TCertificateServiceFactoryDep = {
|
|||||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||||
pkiCollectionDAL: Pick<TPkiCollectionDALFactory, "findById">;
|
pkiCollectionDAL: Pick<TPkiCollectionDALFactory, "findById">;
|
||||||
pkiCollectionItemDAL: Pick<TPkiCollectionItemDALFactory, "create">;
|
pkiCollectionItemDAL: Pick<TPkiCollectionItemDALFactory, "create">;
|
||||||
projectDAL: Pick<
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||||
TProjectDALFactory,
|
|
||||||
"findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction" | "getProjectFromSplitId"
|
|
||||||
>;
|
|
||||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
};
|
};
|
||||||
@@ -83,8 +79,7 @@ export const certificateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: cert.projectId,
|
projectId: cert.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -114,8 +109,7 @@ export const certificateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: cert.projectId,
|
projectId: cert.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -148,8 +142,7 @@ export const certificateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: cert.projectId,
|
projectId: cert.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -198,8 +191,7 @@ export const certificateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -247,8 +239,7 @@ export const certificateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: cert.projectId,
|
projectId: cert.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -321,23 +312,14 @@ export const certificateServiceFactory = ({
|
|||||||
|
|
||||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
|
if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` });
|
||||||
let projectId = project.id;
|
const projectId = project.id;
|
||||||
|
|
||||||
const certManagerProjectFromSplit = await projectDAL.getProjectFromSplitId(
|
|
||||||
projectId,
|
|
||||||
ProjectType.CertificateManager
|
|
||||||
);
|
|
||||||
if (certManagerProjectFromSplit) {
|
|
||||||
projectId = certManagerProjectFromSplit.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -541,8 +523,7 @@ export const certificateServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: cert.projectId,
|
projectId: cert.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.CertificateManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectType } from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionCmekActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionCmekActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { SigningAlgorithm } from "@app/lib/crypto/sign";
|
import { SigningAlgorithm } from "@app/lib/crypto/sign";
|
||||||
@@ -23,32 +22,23 @@ import { TKmsKeyDALFactory } from "@app/services/kms/kms-key-dal";
|
|||||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||||
|
|
||||||
import { KmsKeyUsage } from "../kms/kms-types";
|
import { KmsKeyUsage } from "../kms/kms-types";
|
||||||
import { TProjectDALFactory } from "../project/project-dal";
|
|
||||||
|
|
||||||
type TCmekServiceFactoryDep = {
|
type TCmekServiceFactoryDep = {
|
||||||
kmsService: TKmsServiceFactory;
|
kmsService: TKmsServiceFactory;
|
||||||
kmsDAL: TKmsKeyDALFactory;
|
kmsDAL: TKmsKeyDALFactory;
|
||||||
permissionService: TPermissionServiceFactory;
|
permissionService: TPermissionServiceFactory;
|
||||||
projectDAL: Pick<TProjectDALFactory, "getProjectFromSplitId">;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TCmekServiceFactory = ReturnType<typeof cmekServiceFactory>;
|
export type TCmekServiceFactory = ReturnType<typeof cmekServiceFactory>;
|
||||||
|
|
||||||
export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, projectDAL }: TCmekServiceFactoryDep) => {
|
export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TCmekServiceFactoryDep) => {
|
||||||
const createCmek = async ({ projectId: preSplitProjectId, ...dto }: TCreateCmekDTO, actor: OrgServiceActor) => {
|
const createCmek = async ({ projectId, ...dto }: TCreateCmekDTO, actor: OrgServiceActor) => {
|
||||||
let projectId = preSplitProjectId;
|
|
||||||
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
|
|
||||||
if (cmekProjectFromSplit) {
|
|
||||||
projectId = cmekProjectFromSplit.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor: actor.type,
|
actor: actor.type,
|
||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Create, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Create, ProjectPermissionSub.Cmek);
|
||||||
|
|
||||||
@@ -87,8 +77,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Edit, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Edit, ProjectPermissionSub.Cmek);
|
||||||
@@ -124,8 +113,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Delete, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Delete, ProjectPermissionSub.Cmek);
|
||||||
@@ -135,23 +123,13 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
return key;
|
return key;
|
||||||
};
|
};
|
||||||
|
|
||||||
const listCmeksByProjectId = async (
|
const listCmeksByProjectId = async ({ projectId, ...filters }: TListCmeksByProjectIdDTO, actor: OrgServiceActor) => {
|
||||||
{ projectId: preSplitProjectId, ...filters }: TListCmeksByProjectIdDTO,
|
|
||||||
actor: OrgServiceActor
|
|
||||||
) => {
|
|
||||||
let projectId = preSplitProjectId;
|
|
||||||
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(preSplitProjectId, ProjectType.KMS);
|
|
||||||
if (cmekProjectFromSplit) {
|
|
||||||
projectId = cmekProjectFromSplit.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor: actor.type,
|
actor: actor.type,
|
||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||||
@@ -173,8 +151,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||||
@@ -195,8 +172,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||||
@@ -218,8 +194,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Encrypt, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Encrypt, ProjectPermissionSub.Cmek);
|
||||||
@@ -246,8 +221,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||||
@@ -294,8 +268,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||||
@@ -318,8 +291,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Sign, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Sign, ProjectPermissionSub.Cmek);
|
||||||
@@ -353,8 +325,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Verify, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Verify, ProjectPermissionSub.Cmek);
|
||||||
@@ -389,8 +360,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
|
|||||||
actorId: actor.id,
|
actorId: actor.id,
|
||||||
projectId: key.projectId,
|
projectId: key.projectId,
|
||||||
actorAuthMethod: actor.authMethod,
|
actorAuthMethod: actor.authMethod,
|
||||||
actorOrgId: actor.orgId,
|
actorOrgId: actor.orgId
|
||||||
actionProjectType: ActionProjectType.KMS
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Decrypt, ProjectPermissionSub.Cmek);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Decrypt, ProjectPermissionSub.Cmek);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
import { ProjectType, TSecretFolderVersions, TSecretVersionsV2 } from "@app/db/schemas";
|
import { TSecretFolderVersions, TSecretVersionsV2 } from "@app/db/schemas";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
|
|
||||||
import { ActorType } from "../auth/auth-type";
|
import { ActorType } from "../auth/auth-type";
|
||||||
@@ -433,8 +433,7 @@ describe("folderCommitServiceFactory", () => {
|
|||||||
mockFolderCommitDAL.findCommitsToRecreate.mockResolvedValue([]);
|
mockFolderCommitDAL.findCommitsToRecreate.mockResolvedValue([]);
|
||||||
mockProjectDAL.findProjectByEnvId.mockResolvedValue({
|
mockProjectDAL.findProjectByEnvId.mockResolvedValue({
|
||||||
id: "project-id",
|
id: "project-id",
|
||||||
name: "test-project",
|
name: "test-project"
|
||||||
type: ProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|||||||
@@ -2,13 +2,7 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import {
|
import { TSecretFolders, TSecretFolderVersions, TSecretV2TagJunctionInsert, TSecretVersionsV2 } from "@app/db/schemas";
|
||||||
ActionProjectType,
|
|
||||||
TSecretFolders,
|
|
||||||
TSecretFolderVersions,
|
|
||||||
TSecretV2TagJunctionInsert,
|
|
||||||
TSecretVersionsV2
|
|
||||||
} from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
@@ -223,8 +217,7 @@ export const folderCommitServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCommitsActions.Read, ProjectPermissionSub.Commits);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCommitsActions.Read, ProjectPermissionSub.Commits);
|
||||||
@@ -2067,8 +2060,7 @@ export const folderCommitServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectMembershipRole, SecretKeyEncoding, TGroups } from "@app/db/schemas";
|
import { ProjectMembershipRole, SecretKeyEncoding, TGroups } from "@app/db/schemas";
|
||||||
import { TListProjectGroupUsersDTO } from "@app/ee/services/group/group-types";
|
import { TListProjectGroupUsersDTO } from "@app/ee/services/group/group-types";
|
||||||
import {
|
import {
|
||||||
constructPermissionErrorMessage,
|
constructPermissionErrorMessage,
|
||||||
@@ -79,8 +79,7 @@ export const groupProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Create, ProjectPermissionSub.Groups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Create, ProjectPermissionSub.Groups);
|
||||||
|
|
||||||
@@ -267,8 +266,7 @@ export const groupProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Edit, ProjectPermissionSub.Groups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Edit, ProjectPermissionSub.Groups);
|
||||||
|
|
||||||
@@ -381,8 +379,7 @@ export const groupProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Delete, ProjectPermissionSub.Groups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Delete, ProjectPermissionSub.Groups);
|
||||||
|
|
||||||
@@ -426,8 +423,7 @@ export const groupProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups);
|
||||||
|
|
||||||
@@ -454,8 +450,7 @@ export const groupProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups);
|
||||||
|
|
||||||
@@ -496,8 +491,7 @@ export const groupProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups);
|
||||||
|
|
||||||
|
|||||||
@@ -17,70 +17,11 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
|
|||||||
const doc = await (tx || db.replicaNode())(TableName.IdentityAccessToken)
|
const doc = await (tx || db.replicaNode())(TableName.IdentityAccessToken)
|
||||||
.where(filter)
|
.where(filter)
|
||||||
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityAccessToken}.identityId`)
|
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityAccessToken}.identityId`)
|
||||||
.leftJoin(
|
|
||||||
TableName.IdentityUaClientSecret,
|
|
||||||
`${TableName.IdentityAccessToken}.identityUAClientSecretId`,
|
|
||||||
`${TableName.IdentityUaClientSecret}.id`
|
|
||||||
)
|
|
||||||
.leftJoin(
|
|
||||||
TableName.IdentityUniversalAuth,
|
|
||||||
`${TableName.IdentityUaClientSecret}.identityUAId`,
|
|
||||||
`${TableName.IdentityUniversalAuth}.id`
|
|
||||||
)
|
|
||||||
.leftJoin(TableName.IdentityGcpAuth, `${TableName.Identity}.id`, `${TableName.IdentityGcpAuth}.identityId`)
|
|
||||||
.leftJoin(
|
|
||||||
TableName.IdentityAliCloudAuth,
|
|
||||||
`${TableName.Identity}.id`,
|
|
||||||
`${TableName.IdentityAliCloudAuth}.identityId`
|
|
||||||
)
|
|
||||||
.leftJoin(TableName.IdentityAwsAuth, `${TableName.Identity}.id`, `${TableName.IdentityAwsAuth}.identityId`)
|
|
||||||
.leftJoin(TableName.IdentityAzureAuth, `${TableName.Identity}.id`, `${TableName.IdentityAzureAuth}.identityId`)
|
|
||||||
.leftJoin(TableName.IdentityLdapAuth, `${TableName.Identity}.id`, `${TableName.IdentityLdapAuth}.identityId`)
|
|
||||||
.leftJoin(
|
|
||||||
TableName.IdentityKubernetesAuth,
|
|
||||||
`${TableName.Identity}.id`,
|
|
||||||
`${TableName.IdentityKubernetesAuth}.identityId`
|
|
||||||
)
|
|
||||||
.leftJoin(TableName.IdentityOciAuth, `${TableName.Identity}.id`, `${TableName.IdentityOciAuth}.identityId`)
|
|
||||||
.leftJoin(TableName.IdentityOidcAuth, `${TableName.Identity}.id`, `${TableName.IdentityOidcAuth}.identityId`)
|
|
||||||
.leftJoin(TableName.IdentityTokenAuth, `${TableName.Identity}.id`, `${TableName.IdentityTokenAuth}.identityId`)
|
|
||||||
.leftJoin(TableName.IdentityJwtAuth, `${TableName.Identity}.id`, `${TableName.IdentityJwtAuth}.identityId`)
|
|
||||||
.select(selectAllTableCols(TableName.IdentityAccessToken))
|
.select(selectAllTableCols(TableName.IdentityAccessToken))
|
||||||
.select(
|
.select(db.ref("name").withSchema(TableName.Identity))
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityUniversalAuth).as("accessTokenTrustedIpsUa"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityGcpAuth).as("accessTokenTrustedIpsGcp"),
|
|
||||||
db
|
|
||||||
.ref("accessTokenTrustedIps")
|
|
||||||
.withSchema(TableName.IdentityAliCloudAuth)
|
|
||||||
.as("accessTokenTrustedIpsAliCloud"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityAwsAuth).as("accessTokenTrustedIpsAws"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityAzureAuth).as("accessTokenTrustedIpsAzure"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityKubernetesAuth).as("accessTokenTrustedIpsK8s"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityOciAuth).as("accessTokenTrustedIpsOci"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityOidcAuth).as("accessTokenTrustedIpsOidc"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityTokenAuth).as("accessTokenTrustedIpsToken"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityJwtAuth).as("accessTokenTrustedIpsJwt"),
|
|
||||||
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityLdapAuth).as("accessTokenTrustedIpsLdap"),
|
|
||||||
db.ref("name").withSchema(TableName.Identity)
|
|
||||||
)
|
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (!doc) return;
|
return doc;
|
||||||
|
|
||||||
return {
|
|
||||||
...doc,
|
|
||||||
trustedIpsUniversalAuth: doc.accessTokenTrustedIpsUa,
|
|
||||||
trustedIpsGcpAuth: doc.accessTokenTrustedIpsGcp,
|
|
||||||
trustedIpsAliCloudAuth: doc.accessTokenTrustedIpsAliCloud,
|
|
||||||
trustedIpsAwsAuth: doc.accessTokenTrustedIpsAws,
|
|
||||||
trustedIpsAzureAuth: doc.accessTokenTrustedIpsAzure,
|
|
||||||
trustedIpsKubernetesAuth: doc.accessTokenTrustedIpsK8s,
|
|
||||||
trustedIpsOciAuth: doc.accessTokenTrustedIpsOci,
|
|
||||||
trustedIpsOidcAuth: doc.accessTokenTrustedIpsOidc,
|
|
||||||
trustedIpsAccessTokenAuth: doc.accessTokenTrustedIpsToken,
|
|
||||||
trustedIpsAccessJwtAuth: doc.accessTokenTrustedIpsJwt,
|
|
||||||
trustedIpsAccessLdapAuth: doc.accessTokenTrustedIpsLdap
|
|
||||||
};
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new DatabaseError({ error, name: "IdAccessTokenFindOne" });
|
throw new DatabaseError({ error, name: "IdAccessTokenFindOne" });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ import { checkIPAgainstBlocklist, TIp } from "@app/lib/ip";
|
|||||||
|
|
||||||
import { TAccessTokenQueueServiceFactory } from "../access-token-queue/access-token-queue";
|
import { TAccessTokenQueueServiceFactory } from "../access-token-queue/access-token-queue";
|
||||||
import { AuthTokenType } from "../auth/auth-type";
|
import { AuthTokenType } from "../auth/auth-type";
|
||||||
|
import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||||
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||||
import { TIdentityAccessTokenDALFactory } from "./identity-access-token-dal";
|
import { TIdentityAccessTokenDALFactory } from "./identity-access-token-dal";
|
||||||
import { TIdentityAccessTokenJwtPayload, TRenewAccessTokenDTO } from "./identity-access-token-types";
|
import { TIdentityAccessTokenJwtPayload, TRenewAccessTokenDTO } from "./identity-access-token-types";
|
||||||
|
|
||||||
type TIdentityAccessTokenServiceFactoryDep = {
|
type TIdentityAccessTokenServiceFactoryDep = {
|
||||||
identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
|
identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
|
||||||
|
identityDAL: Pick<TIdentityDALFactory, "getTrustedIpsByAuthMethod">;
|
||||||
identityOrgMembershipDAL: TIdentityOrgDALFactory;
|
identityOrgMembershipDAL: TIdentityOrgDALFactory;
|
||||||
accessTokenQueue: Pick<
|
accessTokenQueue: Pick<
|
||||||
TAccessTokenQueueServiceFactory,
|
TAccessTokenQueueServiceFactory,
|
||||||
@@ -25,7 +27,8 @@ export type TIdentityAccessTokenServiceFactory = ReturnType<typeof identityAcces
|
|||||||
export const identityAccessTokenServiceFactory = ({
|
export const identityAccessTokenServiceFactory = ({
|
||||||
identityAccessTokenDAL,
|
identityAccessTokenDAL,
|
||||||
identityOrgMembershipDAL,
|
identityOrgMembershipDAL,
|
||||||
accessTokenQueue
|
accessTokenQueue,
|
||||||
|
identityDAL
|
||||||
}: TIdentityAccessTokenServiceFactoryDep) => {
|
}: TIdentityAccessTokenServiceFactoryDep) => {
|
||||||
const validateAccessTokenExp = async (identityAccessToken: TIdentityAccessTokens) => {
|
const validateAccessTokenExp = async (identityAccessToken: TIdentityAccessTokens) => {
|
||||||
const {
|
const {
|
||||||
@@ -190,23 +193,11 @@ export const identityAccessTokenServiceFactory = ({
|
|||||||
message: "Failed to authorize revoked access token, access token is revoked"
|
message: "Failed to authorize revoked access token, access token is revoked"
|
||||||
});
|
});
|
||||||
|
|
||||||
const trustedIpsMap: Record<IdentityAuthMethod, unknown> = {
|
const trustedIps = await identityDAL.getTrustedIpsByAuthMethod(
|
||||||
[IdentityAuthMethod.UNIVERSAL_AUTH]: identityAccessToken.trustedIpsUniversalAuth,
|
identityAccessToken.identityId,
|
||||||
[IdentityAuthMethod.GCP_AUTH]: identityAccessToken.trustedIpsGcpAuth,
|
identityAccessToken.authMethod as IdentityAuthMethod
|
||||||
[IdentityAuthMethod.ALICLOUD_AUTH]: identityAccessToken.trustedIpsAliCloudAuth,
|
);
|
||||||
[IdentityAuthMethod.AWS_AUTH]: identityAccessToken.trustedIpsAwsAuth,
|
if (ipAddress && trustedIps) {
|
||||||
[IdentityAuthMethod.OCI_AUTH]: identityAccessToken.trustedIpsOciAuth,
|
|
||||||
[IdentityAuthMethod.AZURE_AUTH]: identityAccessToken.trustedIpsAzureAuth,
|
|
||||||
[IdentityAuthMethod.KUBERNETES_AUTH]: identityAccessToken.trustedIpsKubernetesAuth,
|
|
||||||
[IdentityAuthMethod.OIDC_AUTH]: identityAccessToken.trustedIpsOidcAuth,
|
|
||||||
[IdentityAuthMethod.TOKEN_AUTH]: identityAccessToken.trustedIpsAccessTokenAuth,
|
|
||||||
[IdentityAuthMethod.JWT_AUTH]: identityAccessToken.trustedIpsAccessJwtAuth,
|
|
||||||
[IdentityAuthMethod.LDAP_AUTH]: identityAccessToken.trustedIpsAccessLdapAuth
|
|
||||||
};
|
|
||||||
|
|
||||||
const trustedIps = trustedIpsMap[identityAccessToken.authMethod as IdentityAuthMethod];
|
|
||||||
|
|
||||||
if (ipAddress) {
|
|
||||||
checkIPAgainstBlocklist({
|
checkIPAgainstBlocklist({
|
||||||
ipAddress,
|
ipAddress,
|
||||||
trustedIps: trustedIps as TIp[]
|
trustedIps: trustedIps as TIp[]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas";
|
import { ProjectMembershipRole } from "@app/db/schemas";
|
||||||
import {
|
import {
|
||||||
constructPermissionErrorMessage,
|
constructPermissionErrorMessage,
|
||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
@@ -62,8 +62,7 @@ export const identityProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Create,
|
ProjectPermissionIdentityActions.Create,
|
||||||
@@ -180,8 +179,7 @@ export const identityProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
@@ -291,8 +289,7 @@ export const identityProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Delete,
|
ProjectPermissionIdentityActions.Delete,
|
||||||
@@ -320,8 +317,7 @@ export const identityProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
@@ -354,8 +350,7 @@ export const identityProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
@@ -391,8 +386,7 @@ export const identityProjectServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: membership.projectId,
|
projectId: membership.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.Any
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { TDbClient } from "@app/db";
|
||||||
|
import { TableName } from "@app/db/schemas";
|
||||||
|
import { ormify, TOrmify } from "@app/lib/knex";
|
||||||
|
|
||||||
|
export type TIdentityTlsCertAuthDALFactory = TOrmify<TableName.IdentityTlsCertAuth>;
|
||||||
|
|
||||||
|
export const identityTlsCertAuthDALFactory = (db: TDbClient) => {
|
||||||
|
const orm = ormify(db, TableName.IdentityTlsCertAuth);
|
||||||
|
return orm;
|
||||||
|
};
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
import crypto from "node:crypto";
|
||||||
|
|
||||||
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
import jwt from "jsonwebtoken";
|
||||||
|
|
||||||
|
import { IdentityAuthMethod } from "@app/db/schemas";
|
||||||
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
|
import {
|
||||||
|
constructPermissionErrorMessage,
|
||||||
|
validatePrivilegeChangeOperation
|
||||||
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { extractX509CertFromChain } from "@app/lib/certificates/extract-certificate";
|
||||||
|
import { getConfig } from "@app/lib/config/env";
|
||||||
|
import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors";
|
||||||
|
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||||
|
|
||||||
|
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||||
|
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||||
|
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
|
||||||
|
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
|
||||||
|
import { TKmsServiceFactory } from "../kms/kms-service";
|
||||||
|
import { KmsDataKey } from "../kms/kms-types";
|
||||||
|
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
|
||||||
|
import { TIdentityTlsCertAuthDALFactory } from "./identity-tls-cert-auth-dal";
|
||||||
|
import { TIdentityTlsCertAuthServiceFactory } from "./identity-tls-cert-auth-types";
|
||||||
|
|
||||||
|
type TIdentityTlsCertAuthServiceFactoryDep = {
|
||||||
|
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
||||||
|
identityTlsCertAuthDAL: Pick<
|
||||||
|
TIdentityTlsCertAuthDALFactory,
|
||||||
|
"findOne" | "transaction" | "create" | "updateById" | "delete"
|
||||||
|
>;
|
||||||
|
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
|
||||||
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseSubjectDetails = (data: string) => {
|
||||||
|
const values: Record<string, string> = {};
|
||||||
|
data.split("\n").forEach((el) => {
|
||||||
|
const [key, value] = el.split("=");
|
||||||
|
values[key.trim()] = value.trim();
|
||||||
|
});
|
||||||
|
return values;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const identityTlsCertAuthServiceFactory = ({
|
||||||
|
identityAccessTokenDAL,
|
||||||
|
identityTlsCertAuthDAL,
|
||||||
|
identityOrgMembershipDAL,
|
||||||
|
licenseService,
|
||||||
|
permissionService,
|
||||||
|
kmsService
|
||||||
|
}: TIdentityTlsCertAuthServiceFactoryDep): TIdentityTlsCertAuthServiceFactory => {
|
||||||
|
const login: TIdentityTlsCertAuthServiceFactory["login"] = async ({ identityId, clientCertificate }) => {
|
||||||
|
const identityTlsCertAuth = await identityTlsCertAuthDAL.findOne({ identityId });
|
||||||
|
if (!identityTlsCertAuth) {
|
||||||
|
throw new NotFoundError({
|
||||||
|
message: "TLS Certificate auth method not found for identity, did you configure TLS Certificate auth?"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({
|
||||||
|
identityId: identityTlsCertAuth.identityId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!identityMembershipOrg) {
|
||||||
|
throw new NotFoundError({
|
||||||
|
message: `Identity organization membership for identity with ID '${identityTlsCertAuth.identityId}' not found`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.Organization,
|
||||||
|
orgId: identityMembershipOrg.orgId
|
||||||
|
});
|
||||||
|
|
||||||
|
const caCertificate = decryptor({
|
||||||
|
cipherTextBlob: identityTlsCertAuth.encryptedCaCertificate
|
||||||
|
}).toString();
|
||||||
|
|
||||||
|
const leafCertificate = extractX509CertFromChain(decodeURIComponent(clientCertificate))?.[0];
|
||||||
|
if (!leafCertificate) {
|
||||||
|
throw new BadRequestError({ message: "Missing client certificate" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientCertificateX509 = new crypto.X509Certificate(leafCertificate);
|
||||||
|
const caCertificateX509 = new crypto.X509Certificate(caCertificate);
|
||||||
|
|
||||||
|
const isValidCertificate = clientCertificateX509.verify(caCertificateX509.publicKey);
|
||||||
|
if (!isValidCertificate)
|
||||||
|
throw new UnauthorizedError({
|
||||||
|
message: "Access denied: Certificate not issued by the provided CA."
|
||||||
|
});
|
||||||
|
|
||||||
|
if (new Date(clientCertificateX509.validTo) < new Date()) {
|
||||||
|
throw new UnauthorizedError({
|
||||||
|
message: "Access denied: Certificate has expired."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new Date(clientCertificateX509.validFrom) > new Date()) {
|
||||||
|
throw new UnauthorizedError({
|
||||||
|
message: "Access denied: Certificate not yet valid."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const subjectDetails = parseSubjectDetails(clientCertificateX509.subject);
|
||||||
|
if (identityTlsCertAuth.allowedCommonNames) {
|
||||||
|
const isValidCommonName = identityTlsCertAuth.allowedCommonNames.split(",").includes(subjectDetails.CN);
|
||||||
|
if (!isValidCommonName) {
|
||||||
|
throw new UnauthorizedError({
|
||||||
|
message: "Access denied: TLS Certificate Auth common name not allowed."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the token
|
||||||
|
const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
||||||
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
|
{
|
||||||
|
identityId: identityTlsCertAuth.identityId,
|
||||||
|
isAccessTokenRevoked: false,
|
||||||
|
accessTokenTTL: identityTlsCertAuth.accessTokenTTL,
|
||||||
|
accessTokenMaxTTL: identityTlsCertAuth.accessTokenMaxTTL,
|
||||||
|
accessTokenNumUses: 0,
|
||||||
|
accessTokenNumUsesLimit: identityTlsCertAuth.accessTokenNumUsesLimit,
|
||||||
|
authMethod: IdentityAuthMethod.TLS_CERT_AUTH
|
||||||
|
},
|
||||||
|
tx
|
||||||
|
);
|
||||||
|
return newToken;
|
||||||
|
});
|
||||||
|
|
||||||
|
const appCfg = getConfig();
|
||||||
|
const accessToken = jwt.sign(
|
||||||
|
{
|
||||||
|
identityId: identityTlsCertAuth.identityId,
|
||||||
|
identityAccessTokenId: identityAccessToken.id,
|
||||||
|
authTokenType: AuthTokenType.IDENTITY_ACCESS_TOKEN
|
||||||
|
} as TIdentityAccessTokenJwtPayload,
|
||||||
|
appCfg.AUTH_SECRET,
|
||||||
|
Number(identityAccessToken.accessTokenTTL) === 0
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
expiresIn: Number(identityAccessToken.accessTokenTTL)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
identityTlsCertAuth,
|
||||||
|
accessToken,
|
||||||
|
identityAccessToken,
|
||||||
|
identityMembershipOrg
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const attachTlsCertAuth: TIdentityTlsCertAuthServiceFactory["attachTlsCertAuth"] = async ({
|
||||||
|
identityId,
|
||||||
|
accessTokenTTL,
|
||||||
|
accessTokenMaxTTL,
|
||||||
|
accessTokenNumUsesLimit,
|
||||||
|
accessTokenTrustedIps,
|
||||||
|
actorId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actor,
|
||||||
|
actorOrgId,
|
||||||
|
isActorSuperAdmin,
|
||||||
|
caCertificate,
|
||||||
|
allowedCommonNames
|
||||||
|
}) => {
|
||||||
|
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
|
||||||
|
|
||||||
|
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||||
|
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||||
|
|
||||||
|
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Failed to add TLS Certificate Auth to already configured identity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accessTokenMaxTTL > 0 && accessTokenTTL > accessTokenMaxTTL) {
|
||||||
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { permission } = await permissionService.getOrgPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
identityMembershipOrg.orgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||||
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
|
if (
|
||||||
|
!plan.ipAllowlisting &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "::/0"
|
||||||
|
)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message:
|
||||||
|
"Failed to add IP access range to access token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
|
});
|
||||||
|
if (!isValidIpOrCidr(accessTokenTrustedIp.ipAddress))
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "The IP is not a valid IPv4, IPv6, or CIDR block"
|
||||||
|
});
|
||||||
|
return extractIPDetails(accessTokenTrustedIp.ipAddress);
|
||||||
|
});
|
||||||
|
|
||||||
|
const { encryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.Organization,
|
||||||
|
orgId: identityMembershipOrg.orgId
|
||||||
|
});
|
||||||
|
|
||||||
|
const identityTlsCertAuth = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
||||||
|
const doc = await identityTlsCertAuthDAL.create(
|
||||||
|
{
|
||||||
|
identityId: identityMembershipOrg.identityId,
|
||||||
|
accessTokenMaxTTL,
|
||||||
|
allowedCommonNames,
|
||||||
|
accessTokenTTL,
|
||||||
|
encryptedCaCertificate: encryptor({ plainText: Buffer.from(caCertificate) }).cipherTextBlob,
|
||||||
|
accessTokenNumUsesLimit,
|
||||||
|
accessTokenTrustedIps: JSON.stringify(reformattedAccessTokenTrustedIps)
|
||||||
|
},
|
||||||
|
tx
|
||||||
|
);
|
||||||
|
return doc;
|
||||||
|
});
|
||||||
|
return { ...identityTlsCertAuth, orgId: identityMembershipOrg.orgId };
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateTlsCertAuth: TIdentityTlsCertAuthServiceFactory["updateTlsCertAuth"] = async ({
|
||||||
|
identityId,
|
||||||
|
caCertificate,
|
||||||
|
allowedCommonNames,
|
||||||
|
accessTokenTTL,
|
||||||
|
accessTokenMaxTTL,
|
||||||
|
accessTokenNumUsesLimit,
|
||||||
|
accessTokenTrustedIps,
|
||||||
|
actorId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actor,
|
||||||
|
actorOrgId
|
||||||
|
}) => {
|
||||||
|
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||||
|
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||||
|
|
||||||
|
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
|
||||||
|
throw new NotFoundError({
|
||||||
|
message: "The identity does not have TLS Certificate Auth attached"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const identityTlsCertAuth = await identityTlsCertAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
|
if (
|
||||||
|
(accessTokenMaxTTL || identityTlsCertAuth.accessTokenMaxTTL) > 0 &&
|
||||||
|
(accessTokenTTL || identityTlsCertAuth.accessTokenTTL) >
|
||||||
|
(accessTokenMaxTTL || identityTlsCertAuth.accessTokenMaxTTL)
|
||||||
|
) {
|
||||||
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { permission } = await permissionService.getOrgPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
identityMembershipOrg.orgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||||
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
|
if (
|
||||||
|
!plan.ipAllowlisting &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "::/0"
|
||||||
|
)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message:
|
||||||
|
"Failed to add IP access range to access token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
|
});
|
||||||
|
if (!isValidIpOrCidr(accessTokenTrustedIp.ipAddress))
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "The IP is not a valid IPv4, IPv6, or CIDR block"
|
||||||
|
});
|
||||||
|
return extractIPDetails(accessTokenTrustedIp.ipAddress);
|
||||||
|
});
|
||||||
|
const { encryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.Organization,
|
||||||
|
orgId: identityMembershipOrg.orgId
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedTlsCertAuth = await identityTlsCertAuthDAL.updateById(identityTlsCertAuth.id, {
|
||||||
|
allowedCommonNames,
|
||||||
|
encryptedCaCertificate: caCertificate
|
||||||
|
? encryptor({ plainText: Buffer.from(caCertificate) }).cipherTextBlob
|
||||||
|
: undefined,
|
||||||
|
accessTokenMaxTTL,
|
||||||
|
accessTokenTTL,
|
||||||
|
accessTokenNumUsesLimit,
|
||||||
|
accessTokenTrustedIps: reformattedAccessTokenTrustedIps
|
||||||
|
? JSON.stringify(reformattedAccessTokenTrustedIps)
|
||||||
|
: undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
return { ...updatedTlsCertAuth, orgId: identityMembershipOrg.orgId };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTlsCertAuth: TIdentityTlsCertAuthServiceFactory["getTlsCertAuth"] = async ({
|
||||||
|
identityId,
|
||||||
|
actorId,
|
||||||
|
actor,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
}) => {
|
||||||
|
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||||
|
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||||
|
|
||||||
|
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "The identity does not have TLS Certificate Auth attached"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const identityAuth = await identityTlsCertAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
|
const { permission } = await permissionService.getOrgPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
identityMembershipOrg.orgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
|
type: KmsDataKey.Organization,
|
||||||
|
orgId: identityMembershipOrg.orgId
|
||||||
|
});
|
||||||
|
let caCertificate = "";
|
||||||
|
if (identityAuth.encryptedCaCertificate) {
|
||||||
|
caCertificate = decryptor({ cipherTextBlob: identityAuth.encryptedCaCertificate }).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...identityAuth, caCertificate, orgId: identityMembershipOrg.orgId };
|
||||||
|
};
|
||||||
|
|
||||||
|
const revokeTlsCertAuth: TIdentityTlsCertAuthServiceFactory["revokeTlsCertAuth"] = async ({
|
||||||
|
identityId,
|
||||||
|
actorId,
|
||||||
|
actor,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
}) => {
|
||||||
|
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||||
|
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||||
|
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "The identity does not have TLS Certificate auth"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const { permission, membership } = await permissionService.getOrgPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
identityMembershipOrg.orgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||||
|
ActorType.IDENTITY,
|
||||||
|
identityMembershipOrg.identityId,
|
||||||
|
identityMembershipOrg.orgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
membership.shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke TLS Certificate auth of identity with more privileged role",
|
||||||
|
membership.shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
|
||||||
|
const revokedIdentityTlsCertAuth = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
||||||
|
const deletedTlsCertAuth = await identityTlsCertAuthDAL.delete({ identityId }, tx);
|
||||||
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.TLS_CERT_AUTH }, tx);
|
||||||
|
|
||||||
|
return { ...deletedTlsCertAuth?.[0], orgId: identityMembershipOrg.orgId };
|
||||||
|
});
|
||||||
|
return revokedIdentityTlsCertAuth;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
login,
|
||||||
|
attachTlsCertAuth,
|
||||||
|
updateTlsCertAuth,
|
||||||
|
getTlsCertAuth,
|
||||||
|
revokeTlsCertAuth
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { TIdentityAccessTokens, TIdentityOrgMemberships, TIdentityTlsCertAuths } from "@app/db/schemas";
|
||||||
|
import { TProjectPermission } from "@app/lib/types";
|
||||||
|
|
||||||
|
export type TLoginTlsCertAuthDTO = {
|
||||||
|
identityId: string;
|
||||||
|
clientCertificate: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TAttachTlsCertAuthDTO = {
|
||||||
|
identityId: string;
|
||||||
|
caCertificate: string;
|
||||||
|
allowedCommonNames?: string | null;
|
||||||
|
accessTokenTTL: number;
|
||||||
|
accessTokenMaxTTL: number;
|
||||||
|
accessTokenNumUsesLimit: number;
|
||||||
|
accessTokenTrustedIps: { ipAddress: string }[];
|
||||||
|
isActorSuperAdmin?: boolean;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TUpdateTlsCertAuthDTO = {
|
||||||
|
identityId: string;
|
||||||
|
caCertificate?: string;
|
||||||
|
allowedCommonNames?: string | null;
|
||||||
|
accessTokenTTL?: number;
|
||||||
|
accessTokenMaxTTL?: number;
|
||||||
|
accessTokenNumUsesLimit?: number;
|
||||||
|
accessTokenTrustedIps?: { ipAddress: string }[];
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TGetTlsCertAuthDTO = {
|
||||||
|
identityId: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TRevokeTlsCertAuthDTO = {
|
||||||
|
identityId: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TIdentityTlsCertAuthServiceFactory = {
|
||||||
|
login: (dto: TLoginTlsCertAuthDTO) => Promise<{
|
||||||
|
identityTlsCertAuth: TIdentityTlsCertAuths;
|
||||||
|
accessToken: string;
|
||||||
|
identityAccessToken: TIdentityAccessTokens;
|
||||||
|
identityMembershipOrg: TIdentityOrgMemberships;
|
||||||
|
}>;
|
||||||
|
attachTlsCertAuth: (dto: TAttachTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>;
|
||||||
|
updateTlsCertAuth: (dto: TUpdateTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>;
|
||||||
|
revokeTlsCertAuth: (dto: TRevokeTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>;
|
||||||
|
getTlsCertAuth: (dto: TGetTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths & { caCertificate: string }>;
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { TDbClient } from "@app/db";
|
import { TDbClient } from "@app/db";
|
||||||
import { TableName, TIdentities } from "@app/db/schemas";
|
import { IdentityAuthMethod, TableName, TIdentities } from "@app/db/schemas";
|
||||||
import { DatabaseError } from "@app/lib/errors";
|
import { DatabaseError } from "@app/lib/errors";
|
||||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||||
|
|
||||||
@@ -8,6 +8,28 @@ export type TIdentityDALFactory = ReturnType<typeof identityDALFactory>;
|
|||||||
export const identityDALFactory = (db: TDbClient) => {
|
export const identityDALFactory = (db: TDbClient) => {
|
||||||
const identityOrm = ormify(db, TableName.Identity);
|
const identityOrm = ormify(db, TableName.Identity);
|
||||||
|
|
||||||
|
const getTrustedIpsByAuthMethod = async (identityId: string, authMethod: IdentityAuthMethod) => {
|
||||||
|
const authMethodToTableName = {
|
||||||
|
[IdentityAuthMethod.TOKEN_AUTH]: TableName.IdentityTokenAuth,
|
||||||
|
[IdentityAuthMethod.UNIVERSAL_AUTH]: TableName.IdentityUniversalAuth,
|
||||||
|
[IdentityAuthMethod.KUBERNETES_AUTH]: TableName.IdentityKubernetesAuth,
|
||||||
|
[IdentityAuthMethod.GCP_AUTH]: TableName.IdentityGcpAuth,
|
||||||
|
[IdentityAuthMethod.ALICLOUD_AUTH]: TableName.IdentityAliCloudAuth,
|
||||||
|
[IdentityAuthMethod.AWS_AUTH]: TableName.IdentityAwsAuth,
|
||||||
|
[IdentityAuthMethod.AZURE_AUTH]: TableName.IdentityAzureAuth,
|
||||||
|
[IdentityAuthMethod.TLS_CERT_AUTH]: TableName.IdentityTlsCertAuth,
|
||||||
|
[IdentityAuthMethod.OCI_AUTH]: TableName.IdentityOciAuth,
|
||||||
|
[IdentityAuthMethod.OIDC_AUTH]: TableName.IdentityOidcAuth,
|
||||||
|
[IdentityAuthMethod.JWT_AUTH]: TableName.IdentityJwtAuth,
|
||||||
|
[IdentityAuthMethod.LDAP_AUTH]: TableName.IdentityLdapAuth
|
||||||
|
} as const;
|
||||||
|
const tableName = authMethodToTableName[authMethod];
|
||||||
|
if (!tableName) return;
|
||||||
|
const data = await db(tableName).where({ identityId }).first();
|
||||||
|
if (!data) return;
|
||||||
|
return data.accessTokenTrustedIps;
|
||||||
|
};
|
||||||
|
|
||||||
const getIdentitiesByFilter = async ({
|
const getIdentitiesByFilter = async ({
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
@@ -38,5 +60,5 @@ export const identityDALFactory = (db: TDbClient) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return { ...identityOrm, getIdentitiesByFilter };
|
return { ...identityOrm, getTrustedIpsByAuthMethod, getIdentitiesByFilter };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ export const buildAuthMethods = ({
|
|||||||
azureId,
|
azureId,
|
||||||
tokenId,
|
tokenId,
|
||||||
jwtId,
|
jwtId,
|
||||||
ldapId
|
ldapId,
|
||||||
|
tlsCertId
|
||||||
}: {
|
}: {
|
||||||
uaId?: string;
|
uaId?: string;
|
||||||
gcpId?: string;
|
gcpId?: string;
|
||||||
@@ -24,6 +25,7 @@ export const buildAuthMethods = ({
|
|||||||
tokenId?: string;
|
tokenId?: string;
|
||||||
jwtId?: string;
|
jwtId?: string;
|
||||||
ldapId?: string;
|
ldapId?: string;
|
||||||
|
tlsCertId?: string;
|
||||||
}) => {
|
}) => {
|
||||||
return [
|
return [
|
||||||
...[uaId ? IdentityAuthMethod.UNIVERSAL_AUTH : null],
|
...[uaId ? IdentityAuthMethod.UNIVERSAL_AUTH : null],
|
||||||
@@ -36,6 +38,7 @@ export const buildAuthMethods = ({
|
|||||||
...[azureId ? IdentityAuthMethod.AZURE_AUTH : null],
|
...[azureId ? IdentityAuthMethod.AZURE_AUTH : null],
|
||||||
...[tokenId ? IdentityAuthMethod.TOKEN_AUTH : null],
|
...[tokenId ? IdentityAuthMethod.TOKEN_AUTH : null],
|
||||||
...[jwtId ? IdentityAuthMethod.JWT_AUTH : null],
|
...[jwtId ? IdentityAuthMethod.JWT_AUTH : null],
|
||||||
...[ldapId ? IdentityAuthMethod.LDAP_AUTH : null]
|
...[ldapId ? IdentityAuthMethod.LDAP_AUTH : null],
|
||||||
|
...[tlsCertId ? IdentityAuthMethod.TLS_CERT_AUTH : null]
|
||||||
].filter((authMethod) => authMethod) as IdentityAuthMethod[];
|
].filter((authMethod) => authMethod) as IdentityAuthMethod[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
TIdentityOciAuths,
|
TIdentityOciAuths,
|
||||||
TIdentityOidcAuths,
|
TIdentityOidcAuths,
|
||||||
TIdentityOrgMemberships,
|
TIdentityOrgMemberships,
|
||||||
|
TIdentityTlsCertAuths,
|
||||||
TIdentityTokenAuths,
|
TIdentityTokenAuths,
|
||||||
TIdentityUniversalAuths,
|
TIdentityUniversalAuths,
|
||||||
TOrgRoles
|
TOrgRoles
|
||||||
@@ -99,7 +100,11 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
`${TableName.IdentityOrgMembership}.identityId`,
|
`${TableName.IdentityOrgMembership}.identityId`,
|
||||||
`${TableName.IdentityLdapAuth}.identityId`
|
`${TableName.IdentityLdapAuth}.identityId`
|
||||||
)
|
)
|
||||||
|
.leftJoin<TIdentityTlsCertAuths>(
|
||||||
|
TableName.IdentityTlsCertAuth,
|
||||||
|
`${TableName.IdentityOrgMembership}.identityId`,
|
||||||
|
`${TableName.IdentityTlsCertAuth}.identityId`
|
||||||
|
)
|
||||||
.select(
|
.select(
|
||||||
selectAllTableCols(TableName.IdentityOrgMembership),
|
selectAllTableCols(TableName.IdentityOrgMembership),
|
||||||
|
|
||||||
@@ -114,6 +119,7 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("id").as("tokenId").withSchema(TableName.IdentityTokenAuth),
|
db.ref("id").as("tokenId").withSchema(TableName.IdentityTokenAuth),
|
||||||
db.ref("id").as("jwtId").withSchema(TableName.IdentityJwtAuth),
|
db.ref("id").as("jwtId").withSchema(TableName.IdentityJwtAuth),
|
||||||
db.ref("id").as("ldapId").withSchema(TableName.IdentityLdapAuth),
|
db.ref("id").as("ldapId").withSchema(TableName.IdentityLdapAuth),
|
||||||
|
db.ref("id").as("tlsCertId").withSchema(TableName.IdentityTlsCertAuth),
|
||||||
db.ref("name").withSchema(TableName.Identity),
|
db.ref("name").withSchema(TableName.Identity),
|
||||||
db.ref("hasDeleteProtection").withSchema(TableName.Identity)
|
db.ref("hasDeleteProtection").withSchema(TableName.Identity)
|
||||||
);
|
);
|
||||||
@@ -238,7 +244,11 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
"paginatedIdentity.identityId",
|
"paginatedIdentity.identityId",
|
||||||
`${TableName.IdentityLdapAuth}.identityId`
|
`${TableName.IdentityLdapAuth}.identityId`
|
||||||
)
|
)
|
||||||
|
.leftJoin<TIdentityTlsCertAuths>(
|
||||||
|
TableName.IdentityTlsCertAuth,
|
||||||
|
"paginatedIdentity.identityId",
|
||||||
|
`${TableName.IdentityTlsCertAuth}.identityId`
|
||||||
|
)
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema("paginatedIdentity"),
|
db.ref("id").withSchema("paginatedIdentity"),
|
||||||
db.ref("role").withSchema("paginatedIdentity"),
|
db.ref("role").withSchema("paginatedIdentity"),
|
||||||
@@ -260,7 +270,8 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("id").as("azureId").withSchema(TableName.IdentityAzureAuth),
|
db.ref("id").as("azureId").withSchema(TableName.IdentityAzureAuth),
|
||||||
db.ref("id").as("tokenId").withSchema(TableName.IdentityTokenAuth),
|
db.ref("id").as("tokenId").withSchema(TableName.IdentityTokenAuth),
|
||||||
db.ref("id").as("jwtId").withSchema(TableName.IdentityJwtAuth),
|
db.ref("id").as("jwtId").withSchema(TableName.IdentityJwtAuth),
|
||||||
db.ref("id").as("ldapId").withSchema(TableName.IdentityLdapAuth)
|
db.ref("id").as("ldapId").withSchema(TableName.IdentityLdapAuth),
|
||||||
|
db.ref("id").as("tlsCertId").withSchema(TableName.IdentityTlsCertAuth)
|
||||||
)
|
)
|
||||||
// cr stands for custom role
|
// cr stands for custom role
|
||||||
.select(db.ref("id").as("crId").withSchema(TableName.OrgRoles))
|
.select(db.ref("id").as("crId").withSchema(TableName.OrgRoles))
|
||||||
@@ -306,6 +317,7 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
azureId,
|
azureId,
|
||||||
tokenId,
|
tokenId,
|
||||||
ldapId,
|
ldapId,
|
||||||
|
tlsCertId,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt
|
updatedAt
|
||||||
}) => ({
|
}) => ({
|
||||||
@@ -313,7 +325,6 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
roleId,
|
roleId,
|
||||||
identityId,
|
identityId,
|
||||||
id,
|
id,
|
||||||
|
|
||||||
orgId,
|
orgId,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
@@ -341,7 +352,8 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
azureId,
|
azureId,
|
||||||
tokenId,
|
tokenId,
|
||||||
jwtId,
|
jwtId,
|
||||||
ldapId
|
ldapId,
|
||||||
|
tlsCertId
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -380,7 +392,12 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityOrgMembership}.identityId`)
|
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityOrgMembership}.identityId`)
|
||||||
.where(`${TableName.IdentityOrgMembership}.orgId`, orgId)
|
.where(`${TableName.IdentityOrgMembership}.orgId`, orgId)
|
||||||
.leftJoin(TableName.OrgRoles, `${TableName.IdentityOrgMembership}.roleId`, `${TableName.OrgRoles}.id`)
|
.leftJoin(TableName.OrgRoles, `${TableName.IdentityOrgMembership}.roleId`, `${TableName.OrgRoles}.id`)
|
||||||
.orderBy(`${TableName.Identity}.${orderBy}`, orderDirection)
|
.orderBy(
|
||||||
|
orderBy === OrgIdentityOrderBy.Role
|
||||||
|
? `${TableName.IdentityOrgMembership}.${orderBy}`
|
||||||
|
: `${TableName.Identity}.${orderBy}`,
|
||||||
|
orderDirection
|
||||||
|
)
|
||||||
.select(`${TableName.IdentityOrgMembership}.id`)
|
.select(`${TableName.IdentityOrgMembership}.id`)
|
||||||
.select<{ id: string; total_count: string }>(
|
.select<{ id: string; total_count: string }>(
|
||||||
db.raw(
|
db.raw(
|
||||||
@@ -511,6 +528,23 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
if (orderBy === OrgIdentityOrderBy.Name) {
|
if (orderBy === OrgIdentityOrderBy.Name) {
|
||||||
void query.orderBy("identityName", orderDirection);
|
void query.orderBy("identityName", orderDirection);
|
||||||
|
} else if (orderBy === OrgIdentityOrderBy.Role) {
|
||||||
|
void query.orderByRaw(
|
||||||
|
`
|
||||||
|
CASE
|
||||||
|
WHEN ??.role = ?
|
||||||
|
THEN ??.slug
|
||||||
|
ELSE ??.role
|
||||||
|
END ?
|
||||||
|
`,
|
||||||
|
[
|
||||||
|
TableName.IdentityOrgMembership,
|
||||||
|
"custom",
|
||||||
|
TableName.OrgRoles,
|
||||||
|
TableName.IdentityOrgMembership,
|
||||||
|
db.raw(orderDirection)
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const docs = await query;
|
const docs = await query;
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ export type TListOrgIdentitiesByOrgIdDTO = {
|
|||||||
} & TOrgPermission;
|
} & TOrgPermission;
|
||||||
|
|
||||||
export enum OrgIdentityOrderBy {
|
export enum OrgIdentityOrderBy {
|
||||||
Name = "name"
|
Name = "name",
|
||||||
// Role = "role"
|
Role = "role"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TSearchOrgIdentitiesByOrgIdDAL = {
|
export type TSearchOrgIdentitiesByOrgIdDAL = {
|
||||||
|
|||||||
@@ -4,13 +4,7 @@ import { Octokit } from "@octokit/rest";
|
|||||||
import { Client as OctopusClient, SpaceRepository as OctopusSpaceRepository } from "@octopusdeploy/api-client";
|
import { Client as OctopusClient, SpaceRepository as OctopusSpaceRepository } from "@octopusdeploy/api-client";
|
||||||
import AWS from "aws-sdk";
|
import AWS from "aws-sdk";
|
||||||
|
|
||||||
import {
|
import { SecretEncryptionAlgo, SecretKeyEncoding, TIntegrationAuths, TIntegrationAuthsInsert } from "@app/db/schemas";
|
||||||
ActionProjectType,
|
|
||||||
SecretEncryptionAlgo,
|
|
||||||
SecretKeyEncoding,
|
|
||||||
TIntegrationAuths,
|
|
||||||
TIntegrationAuthsInsert
|
|
||||||
} from "@app/db/schemas";
|
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
@@ -103,8 +97,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const authorizations = await integrationAuthDAL.find({ projectId });
|
const authorizations = await integrationAuthDAL.find({ projectId });
|
||||||
@@ -122,8 +115,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: auth.projectId,
|
projectId: auth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations) ? auth : null;
|
return permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations) ? auth : null;
|
||||||
@@ -146,8 +138,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
return integrationAuth;
|
return integrationAuth;
|
||||||
@@ -172,8 +163,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -282,8 +272,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -417,8 +406,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -679,8 +667,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -714,8 +701,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -745,8 +731,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -787,8 +772,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -816,8 +800,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -891,8 +874,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -939,8 +921,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -974,8 +955,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1033,8 +1013,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1070,8 +1049,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1112,8 +1090,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1153,8 +1130,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1194,8 +1170,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1234,8 +1209,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1275,8 +1249,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1344,8 +1317,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1419,8 +1391,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1470,8 +1441,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1519,8 +1489,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1588,8 +1557,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1630,8 +1598,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1743,8 +1710,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -1767,8 +1733,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -1801,8 +1766,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(sourcePermission).throwUnlessCan(
|
ForbiddenError.from(sourcePermission).throwUnlessCan(
|
||||||
@@ -1815,8 +1779,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(targetPermission).throwUnlessCan(
|
ForbiddenError.from(targetPermission).throwUnlessCan(
|
||||||
@@ -1849,8 +1812,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -1884,8 +1846,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
@@ -1925,8 +1886,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
import { ActionProjectType } from "@app/db/schemas";
|
|
||||||
import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import {
|
import {
|
||||||
@@ -91,8 +90,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integrationAuth.projectId,
|
projectId: integrationAuth.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -167,8 +165,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integration.projectId,
|
projectId: integration.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -231,8 +228,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integration.projectId,
|
projectId: integration.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -259,8 +255,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integration.projectId,
|
projectId: integration.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -302,8 +297,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integration.projectId,
|
projectId: integration.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -339,8 +333,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
@@ -359,8 +352,7 @@ export const integrationServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
projectId: integration.projectId,
|
projectId: integration.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId
|
||||||
actionProjectType: ActionProjectType.SecretManager
|
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||||
|
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ export const buildTeamsPayload = (notification: TNotification) => {
|
|||||||
{
|
{
|
||||||
type: "Action.OpenUrl",
|
type: "Action.OpenUrl",
|
||||||
title: "View request in Infisical",
|
title: "View request in Infisical",
|
||||||
url: `${appCfg.SITE_URL}/secret-manager/${payload.projectId}/approval?requestId=${payload.requestId}`
|
url: `${appCfg.SITE_URL}/projects/${payload.projectId}/secret-manager/approval?requestId=${payload.requestId}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user