mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 13:28:27 +00:00
PKI refine access control
This commit is contained in:
+5
-2
@@ -4,7 +4,10 @@ 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 { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import {
|
||||
ProjectPermissionCertificateAuthorityActions,
|
||||
ProjectPermissionSub
|
||||
} from "@app/ee/services/permission/project-permission";
|
||||
import { NotFoundError } from "@app/lib/errors";
|
||||
import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
|
||||
import { expandInternalCa } from "@app/services/certificate-authority/certificate-authority-fns";
|
||||
@@ -83,7 +86,7 @@ export const certificateAuthorityCrlServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
ProjectPermissionAppConnectionActions,
|
||||
ProjectPermissionAuditLogsActions,
|
||||
ProjectPermissionCertificateActions,
|
||||
ProjectPermissionCertificateAuthorityActions,
|
||||
ProjectPermissionCertificateProfileActions,
|
||||
ProjectPermissionCmekActions,
|
||||
ProjectPermissionCommitsActions,
|
||||
@@ -46,7 +47,6 @@ const buildAdminPermissionRules = () => {
|
||||
ProjectPermissionSub.Tags,
|
||||
ProjectPermissionSub.AuditLogs,
|
||||
ProjectPermissionSub.IpAllowList,
|
||||
ProjectPermissionSub.CertificateAuthorities,
|
||||
ProjectPermissionSub.PkiAlerts,
|
||||
ProjectPermissionSub.PkiCollections,
|
||||
ProjectPermissionSub.SshCertificateAuthorities,
|
||||
@@ -67,6 +67,19 @@ const buildAdminPermissionRules = () => {
|
||||
);
|
||||
});
|
||||
|
||||
can(
|
||||
[
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
ProjectPermissionCertificateAuthorityActions.Create,
|
||||
ProjectPermissionCertificateAuthorityActions.Edit,
|
||||
ProjectPermissionCertificateAuthorityActions.Delete,
|
||||
ProjectPermissionCertificateAuthorityActions.List,
|
||||
ProjectPermissionCertificateAuthorityActions.Renew,
|
||||
ProjectPermissionCertificateAuthorityActions.SignIntermediate
|
||||
],
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
);
|
||||
|
||||
can(
|
||||
[
|
||||
ProjectPermissionPkiTemplateActions.Read,
|
||||
@@ -95,7 +108,9 @@ const buildAdminPermissionRules = () => {
|
||||
ProjectPermissionCertificateActions.Edit,
|
||||
ProjectPermissionCertificateActions.Create,
|
||||
ProjectPermissionCertificateActions.Delete,
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionCertificateActions.Import,
|
||||
ProjectPermissionCertificateActions.List
|
||||
],
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
@@ -103,6 +118,7 @@ const buildAdminPermissionRules = () => {
|
||||
can(
|
||||
[
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionCertificateProfileActions.List,
|
||||
ProjectPermissionCertificateProfileActions.Edit,
|
||||
ProjectPermissionCertificateProfileActions.Create,
|
||||
ProjectPermissionCertificateProfileActions.Delete,
|
||||
@@ -460,7 +476,7 @@ const buildMemberPermissionRules = () => {
|
||||
can([ProjectPermissionActions.Read], ProjectPermissionSub.IpAllowList);
|
||||
|
||||
// double check if all CRUD are needed for CA and Certificates
|
||||
can([ProjectPermissionActions.Read], ProjectPermissionSub.CertificateAuthorities);
|
||||
can([ProjectPermissionCertificateAuthorityActions.Read], ProjectPermissionSub.CertificateAuthorities);
|
||||
can([ProjectPermissionPkiTemplateActions.Read], ProjectPermissionSub.CertificateTemplates);
|
||||
|
||||
can(
|
||||
@@ -468,7 +484,9 @@ const buildMemberPermissionRules = () => {
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
ProjectPermissionCertificateActions.Edit,
|
||||
ProjectPermissionCertificateActions.Create,
|
||||
ProjectPermissionCertificateActions.Delete
|
||||
ProjectPermissionCertificateActions.Delete,
|
||||
ProjectPermissionCertificateActions.Import,
|
||||
ProjectPermissionCertificateActions.List
|
||||
],
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
@@ -476,6 +494,7 @@ const buildMemberPermissionRules = () => {
|
||||
can(
|
||||
[
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionCertificateProfileActions.List,
|
||||
ProjectPermissionCertificateProfileActions.Edit,
|
||||
ProjectPermissionCertificateProfileActions.Create,
|
||||
ProjectPermissionCertificateProfileActions.Delete
|
||||
@@ -599,8 +618,9 @@ const buildViewerPermissionRules = () => {
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags);
|
||||
can(ProjectPermissionAuditLogsActions.Read, ProjectPermissionSub.AuditLogs);
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList);
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.CertificateAuthorities);
|
||||
can(ProjectPermissionCertificateAuthorityActions.Read, ProjectPermissionSub.CertificateAuthorities);
|
||||
can(ProjectPermissionCertificateActions.Read, ProjectPermissionSub.Certificates);
|
||||
can(ProjectPermissionCertificateActions.List, ProjectPermissionSub.Certificates);
|
||||
can(ProjectPermissionPkiTemplateActions.Read, ProjectPermissionSub.CertificateTemplates);
|
||||
can(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificates);
|
||||
|
||||
@@ -23,12 +23,24 @@ export enum ProjectPermissionCommitsActions {
|
||||
PerformRollback = "perform-rollback"
|
||||
}
|
||||
|
||||
export enum ProjectPermissionCertificateAuthorityActions {
|
||||
Read = "read",
|
||||
Create = "create",
|
||||
Edit = "edit",
|
||||
Delete = "delete",
|
||||
List = "list",
|
||||
Renew = "renew",
|
||||
SignIntermediate = "sign-intermediate"
|
||||
}
|
||||
|
||||
export enum ProjectPermissionCertificateActions {
|
||||
Read = "read",
|
||||
Create = "create",
|
||||
Edit = "edit",
|
||||
Delete = "delete",
|
||||
ReadPrivateKey = "read-private-key"
|
||||
List = "list",
|
||||
ReadPrivateKey = "read-private-key",
|
||||
Import = "import"
|
||||
}
|
||||
|
||||
export enum ProjectPermissionSecretActions {
|
||||
@@ -117,6 +129,7 @@ export enum ProjectPermissionPkiSubscriberActions {
|
||||
|
||||
export enum ProjectPermissionCertificateProfileActions {
|
||||
Read = "read",
|
||||
List = "list",
|
||||
Create = "create",
|
||||
Edit = "edit",
|
||||
Delete = "delete",
|
||||
@@ -140,6 +153,7 @@ export enum ProjectPermissionPkiSyncActions {
|
||||
Create = "create",
|
||||
Edit = "edit",
|
||||
Delete = "delete",
|
||||
List = "list",
|
||||
SyncCertificates = "sync-certificates",
|
||||
ImportCertificates = "import-certificates",
|
||||
RemoveCertificates = "remove-certificates"
|
||||
@@ -242,6 +256,7 @@ export enum ProjectPermissionSub {
|
||||
CertificateAuthorities = "certificate-authorities",
|
||||
Certificates = "certificates",
|
||||
CertificateTemplates = "certificate-templates",
|
||||
CertificateTemplatesV2 = "certificate-templates-v2",
|
||||
SshCertificateAuthorities = "ssh-certificate-authorities",
|
||||
SshCertificates = "ssh-certificates",
|
||||
SshCertificateTemplates = "ssh-certificate-templates",
|
||||
@@ -292,7 +307,7 @@ export type SecretSyncSubjectFields = {
|
||||
};
|
||||
|
||||
export type PkiSyncSubjectFields = {
|
||||
subscriberName: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type DynamicSecretSubjectFields = {
|
||||
@@ -332,6 +347,26 @@ export type PkiSubscriberSubjectFields = {
|
||||
// (dangtony98): consider adding [commonName] as a subject field in the future
|
||||
};
|
||||
|
||||
export type CertificateAuthoritySubjectFields = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type CertificateSubjectFields = {
|
||||
commonName?: string;
|
||||
altNames?: string;
|
||||
serialNumber?: string;
|
||||
friendlyName?: string;
|
||||
status?: string;
|
||||
};
|
||||
|
||||
export type CertificateProfileSubjectFields = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type CertificateTemplateV2SubjectFields = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type AppConnectionSubjectFields = {
|
||||
connectionId: string;
|
||||
};
|
||||
@@ -399,8 +434,17 @@ export type ProjectPermissionSet =
|
||||
ProjectPermissionIdentityActions,
|
||||
ProjectPermissionSub.Identity | (ForcedSubject<ProjectPermissionSub.Identity> & IdentityManagementSubjectFields)
|
||||
]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities]
|
||||
| [ProjectPermissionCertificateActions, ProjectPermissionSub.Certificates]
|
||||
| [
|
||||
ProjectPermissionCertificateAuthorityActions,
|
||||
(
|
||||
| ProjectPermissionSub.CertificateAuthorities
|
||||
| (ForcedSubject<ProjectPermissionSub.CertificateAuthorities> & CertificateAuthoritySubjectFields)
|
||||
)
|
||||
]
|
||||
| [
|
||||
ProjectPermissionCertificateActions,
|
||||
ProjectPermissionSub.Certificates | (ForcedSubject<ProjectPermissionSub.Certificates> & CertificateSubjectFields)
|
||||
]
|
||||
| [
|
||||
ProjectPermissionPkiTemplateActions,
|
||||
(
|
||||
@@ -408,6 +452,13 @@ export type ProjectPermissionSet =
|
||||
| (ForcedSubject<ProjectPermissionSub.CertificateTemplates> & PkiTemplateSubjectFields)
|
||||
)
|
||||
]
|
||||
| [
|
||||
ProjectPermissionActions,
|
||||
(
|
||||
| ProjectPermissionSub.CertificateTemplatesV2
|
||||
| (ForcedSubject<ProjectPermissionSub.CertificateTemplatesV2> & CertificateTemplateV2SubjectFields)
|
||||
)
|
||||
]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateAuthorities]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificates]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateTemplates]
|
||||
@@ -454,7 +505,13 @@ export type ProjectPermissionSet =
|
||||
ProjectPermissionSub.PamAccounts | (ForcedSubject<ProjectPermissionSub.PamAccounts> & PamAccountSubjectFields)
|
||||
]
|
||||
| [ProjectPermissionPamSessionActions, ProjectPermissionSub.PamSessions]
|
||||
| [ProjectPermissionCertificateProfileActions, ProjectPermissionSub.CertificateProfiles];
|
||||
| [
|
||||
ProjectPermissionCertificateProfileActions,
|
||||
(
|
||||
| ProjectPermissionSub.CertificateProfiles
|
||||
| (ForcedSubject<ProjectPermissionSub.CertificateProfiles> & CertificateProfileSubjectFields)
|
||||
)
|
||||
];
|
||||
|
||||
const SECRET_PATH_MISSING_SLASH_ERR_MSG = "Invalid Secret Path; it must start with a '/'";
|
||||
const SECRET_PATH_PERMISSION_OPERATOR_SCHEMA = z.union([
|
||||
@@ -572,7 +629,7 @@ const SecretSyncConditionV2Schema = z
|
||||
|
||||
const PkiSyncConditionSchema = z
|
||||
.object({
|
||||
subscriberName: z.union([
|
||||
name: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
@@ -749,6 +806,113 @@ const PamAccountConditionSchema = z
|
||||
})
|
||||
.partial();
|
||||
|
||||
const CertificateAuthorityConditionSchema = z
|
||||
.object({
|
||||
name: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
])
|
||||
})
|
||||
.partial();
|
||||
|
||||
const CertificateConditionSchema = z
|
||||
.object({
|
||||
commonName: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
]),
|
||||
altNames: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
]),
|
||||
serialNumber: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
]),
|
||||
friendlyName: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
]),
|
||||
status: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN]
|
||||
})
|
||||
.partial()
|
||||
])
|
||||
})
|
||||
.partial();
|
||||
|
||||
const CertificateProfileConditionSchema = z
|
||||
.object({
|
||||
slug: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
])
|
||||
})
|
||||
.partial();
|
||||
|
||||
const CertificateTemplateV2ConditionSchema = z
|
||||
.object({
|
||||
name: z.union([
|
||||
z.string(),
|
||||
z
|
||||
.object({
|
||||
[PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ],
|
||||
[PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ],
|
||||
[PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN],
|
||||
[PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB]
|
||||
})
|
||||
.partial()
|
||||
])
|
||||
})
|
||||
.partial();
|
||||
|
||||
const GeneralPermissionSchema = [
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.SecretApproval).describe("The entity this permission pertains to."),
|
||||
@@ -828,18 +992,6 @@ const GeneralPermissionSchema = [
|
||||
"Describe what action an entity can take."
|
||||
)
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.CertificateAuthorities).describe("The entity this permission pertains to."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
)
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.Certificates).describe("The entity this permission pertains to."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionCertificateActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
)
|
||||
}),
|
||||
z.object({
|
||||
subject: z
|
||||
.literal(ProjectPermissionSub.SshCertificateAuthorities)
|
||||
@@ -1130,7 +1282,40 @@ export const ProjectPermissionV2Schema = z.discriminatedUnion("subject", [
|
||||
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionCertificateProfileActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
)
|
||||
),
|
||||
conditions: CertificateProfileConditionSchema.describe(
|
||||
"When specified, only matching conditions will be allowed to access given resource."
|
||||
).optional()
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.CertificateAuthorities).describe("The entity this permission pertains to."),
|
||||
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionCertificateAuthorityActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
),
|
||||
conditions: CertificateAuthorityConditionSchema.describe(
|
||||
"When specified, only matching conditions will be allowed to access given resource."
|
||||
).optional()
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.Certificates).describe("The entity this permission pertains to."),
|
||||
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionCertificateActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
),
|
||||
conditions: CertificateConditionSchema.describe(
|
||||
"When specified, only matching conditions will be allowed to access given resource."
|
||||
).optional()
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(ProjectPermissionSub.CertificateTemplatesV2).describe("The entity this permission pertains to."),
|
||||
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe(
|
||||
"Describe what action an entity can take."
|
||||
),
|
||||
conditions: CertificateTemplateV2ConditionSchema.describe(
|
||||
"When specified, only matching conditions will be allowed to access given resource."
|
||||
).optional()
|
||||
}),
|
||||
...GeneralPermissionSchema
|
||||
]);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
|
||||
import { ActionProjectType, TableName } from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import {
|
||||
ProjectPermissionCertificateAuthorityActions,
|
||||
ProjectPermissionSub
|
||||
} from "@app/ee/services/permission/project-permission";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
|
||||
@@ -137,8 +140,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Create,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name })
|
||||
);
|
||||
|
||||
if (type === CaType.INTERNAL) {
|
||||
@@ -207,8 +210,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: certificateAuthority.name })
|
||||
);
|
||||
|
||||
if (type === CaType.INTERNAL) {
|
||||
@@ -222,6 +225,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
id: certificateAuthority.id,
|
||||
type,
|
||||
enableDirectIssuance: certificateAuthority.enableDirectIssuance,
|
||||
subject: ProjectPermissionSub.CertificateAuthorities,
|
||||
name: certificateAuthority.name,
|
||||
projectId: certificateAuthority.projectId,
|
||||
configuration: certificateAuthority.internalCa,
|
||||
@@ -270,8 +274,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: caName })
|
||||
);
|
||||
|
||||
if (type === CaType.INTERNAL) {
|
||||
@@ -323,8 +327,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: "*" })
|
||||
);
|
||||
|
||||
if (type === CaType.INTERNAL) {
|
||||
@@ -378,8 +382,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Edit,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Edit,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: certificateAuthority.name })
|
||||
);
|
||||
|
||||
if (type === CaType.INTERNAL) {
|
||||
@@ -454,8 +458,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Delete,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Delete,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: certificateAuthority.name })
|
||||
);
|
||||
|
||||
if (!certificateAuthority.internalCa?.id && type === CaType.INTERNAL) {
|
||||
@@ -519,8 +523,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Edit,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Edit,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: certificateAuthority.name })
|
||||
);
|
||||
|
||||
if (type === CaType.INTERNAL) {
|
||||
@@ -601,8 +605,8 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Delete,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Delete,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: certificateAuthority.name })
|
||||
);
|
||||
|
||||
if (!certificateAuthority.internalCa?.id && type === CaType.INTERNAL) {
|
||||
@@ -657,6 +661,13 @@ export const certificateAuthorityServiceFactory = ({
|
||||
actorAuthMethod: OrgServiceActor["authMethod"];
|
||||
actorOrgId?: string;
|
||||
}) => {
|
||||
const certificateAuthority = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId);
|
||||
|
||||
if (!certificateAuthority)
|
||||
throw new NotFoundError({
|
||||
message: `Could not find certificate authority with id "${caId}"`
|
||||
});
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
@@ -667,8 +678,10 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, {
|
||||
name: certificateAuthority.name
|
||||
})
|
||||
);
|
||||
|
||||
return azureAdCsFns.getTemplates({
|
||||
|
||||
+21
-21
@@ -7,8 +7,8 @@ import { Knex } from "knex";
|
||||
import { ActionProjectType, TableName, TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionCertificateActions,
|
||||
ProjectPermissionCertificateAuthorityActions,
|
||||
ProjectPermissionCertificateProfileActions,
|
||||
ProjectPermissionPkiTemplateActions,
|
||||
ProjectPermissionSub
|
||||
@@ -173,8 +173,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Create,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: commonName })
|
||||
);
|
||||
} else {
|
||||
projectId = dto.projectId;
|
||||
@@ -356,8 +356,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.CertificateManager
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
return expandInternalCa(ca);
|
||||
@@ -382,8 +382,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Edit,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Edit,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
}
|
||||
|
||||
@@ -415,8 +415,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Delete,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Delete,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
await certificateAuthorityDAL.deleteById(ca.id);
|
||||
@@ -441,8 +441,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Create,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
if (ca.internalCa.type === InternalCaType.ROOT)
|
||||
@@ -505,8 +505,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Renew,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
if (ca.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
||||
@@ -792,8 +792,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
const caCertChains = await getCaCertChains({
|
||||
@@ -829,8 +829,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
const { caCert, caCertChain, serialNumber } = await getCaCertChain({
|
||||
@@ -910,8 +910,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.SignIntermediate,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
if (ca.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
||||
@@ -1058,8 +1058,8 @@ export const internalCertificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
ProjectPermissionCertificateAuthorityActions.Create,
|
||||
subject(ProjectPermissionSub.CertificateAuthorities, { name: ca.name })
|
||||
);
|
||||
|
||||
if (ca.internalCa.parentCaId) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
import * as x509 from "@peculiar/x509";
|
||||
|
||||
import { ActionProjectType } from "@app/db/schemas";
|
||||
@@ -235,7 +235,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Create,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: data.slug
|
||||
})
|
||||
);
|
||||
|
||||
const project = await projectDAL.findById(projectId);
|
||||
@@ -381,7 +383,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Edit,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: existingProfile.slug
|
||||
})
|
||||
);
|
||||
|
||||
if (data.certificateTemplateId) {
|
||||
@@ -494,7 +498,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
const converted = convertDalToService(profile);
|
||||
@@ -530,7 +536,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
if (profile.estConfig && profile.estConfig.caChain) {
|
||||
@@ -589,7 +597,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug
|
||||
})
|
||||
);
|
||||
|
||||
const profile = await certificateProfileDAL.findBySlugAndProjectId(slug, projectId);
|
||||
@@ -637,7 +647,7 @@ export const certificateProfileServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.CertificateManager
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionCertificateProfileActions.List,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
);
|
||||
|
||||
@@ -740,7 +750,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Delete,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
const deletedProfile = await certificateProfileDAL.deleteById(profileId);
|
||||
@@ -786,7 +798,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
const certificates = await certificateProfileDAL.getCertificatesByProfile(profileId, {
|
||||
@@ -827,17 +841,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
const cert = await certificateProfileDAL.getLatestActiveCertificateForProfile(profileId);
|
||||
@@ -846,6 +852,24 @@ export const certificateProfileServiceFactory = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||
|
||||
const certificateManagerKeyId = await getProjectKmsCertificateKeyId({
|
||||
@@ -939,7 +963,9 @@ export const certificateProfileServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.Read,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -990,7 +1016,9 @@ export const certificateProfileServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.RevealAcmeEabSecret,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
if (profile.enrollmentType !== EnrollmentType.ACME) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
import RE2 from "re2";
|
||||
|
||||
@@ -77,12 +77,12 @@ export const certificateTemplateV2ServiceFactory = ({
|
||||
};
|
||||
|
||||
const validateSubjectAttributePolicy = (
|
||||
subject: Array<{ type: string; allowed?: string[]; required?: string[]; denied?: string[] }>
|
||||
subjectAttributes: Array<{ type: string; allowed?: string[]; required?: string[]; denied?: string[] }>
|
||||
) => {
|
||||
if (!subject || subject.length === 0) return;
|
||||
if (!subjectAttributes || subjectAttributes.length === 0) return;
|
||||
|
||||
// Validate each subject attribute policy
|
||||
for (const attr of subject) {
|
||||
for (const attr of subjectAttributes) {
|
||||
// Ensure at least one field is provided
|
||||
if (!attr.allowed && !attr.required && !attr.denied) {
|
||||
throw new ForbiddenRequestError({
|
||||
@@ -634,7 +634,9 @@ export const certificateTemplateV2ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiTemplateActions.Create,
|
||||
ProjectPermissionSub.CertificateTemplates
|
||||
subject(ProjectPermissionSub.CertificateTemplates, {
|
||||
name: data.name
|
||||
})
|
||||
);
|
||||
|
||||
if (!data) {
|
||||
@@ -711,7 +713,9 @@ export const certificateTemplateV2ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiTemplateActions.Edit,
|
||||
ProjectPermissionSub.CertificateTemplates
|
||||
subject(ProjectPermissionSub.CertificateTemplates, {
|
||||
name: existingTemplate.name
|
||||
})
|
||||
);
|
||||
|
||||
const consolidatedData = {
|
||||
@@ -784,7 +788,9 @@ export const certificateTemplateV2ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiTemplateActions.Read,
|
||||
ProjectPermissionSub.CertificateTemplates
|
||||
subject(ProjectPermissionSub.CertificateTemplates, {
|
||||
name: template.name
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -815,16 +821,17 @@ export const certificateTemplateV2ServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.CertificateManager
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiTemplateActions.Read,
|
||||
ProjectPermissionSub.CertificateTemplates
|
||||
);
|
||||
|
||||
const template = await certificateTemplateV2DAL.findByNameAndProjectId(slug, projectId);
|
||||
if (!template) {
|
||||
throw new NotFoundError({ message: "Certificate template not found" });
|
||||
}
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiTemplateActions.Read,
|
||||
subject(ProjectPermissionSub.CertificateTemplates, {
|
||||
name: template.name
|
||||
})
|
||||
);
|
||||
return template;
|
||||
};
|
||||
|
||||
@@ -907,7 +914,9 @@ export const certificateTemplateV2ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiTemplateActions.Delete,
|
||||
ProjectPermissionSub.CertificateTemplates
|
||||
subject(ProjectPermissionSub.CertificateTemplates, {
|
||||
name: template.name
|
||||
})
|
||||
);
|
||||
|
||||
const isInUse = await certificateTemplateV2DAL.isTemplateInUse(templateId);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
import * as x509 from "@peculiar/x509";
|
||||
import { randomUUID } from "crypto";
|
||||
import RE2 from "re2";
|
||||
@@ -155,7 +155,9 @@ const validateProfileAndPermissions = async (
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.IssueCert,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, {
|
||||
slug: profile.slug
|
||||
})
|
||||
);
|
||||
|
||||
return profile;
|
||||
@@ -1275,7 +1277,7 @@ export const certificateV3ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateProfileActions.IssueCert,
|
||||
ProjectPermissionSub.CertificateProfiles
|
||||
subject(ProjectPermissionSub.CertificateProfiles, { slug: profile?.slug || "*" })
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1568,7 +1570,11 @@ export const certificateV3ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Edit,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: certificate.commonName,
|
||||
altNames: certificate.altNames ?? undefined,
|
||||
serialNumber: certificate.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
if (!certificate.profileId) {
|
||||
@@ -1671,7 +1677,11 @@ export const certificateV3ServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Edit,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: certificate.commonName,
|
||||
altNames: certificate.altNames ?? undefined,
|
||||
serialNumber: certificate.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
if (!certificate.profileId) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { ForbiddenError, subject } from "@casl/ability";
|
||||
import * as x509 from "@peculiar/x509";
|
||||
|
||||
import { ActionProjectType } from "@app/db/schemas";
|
||||
@@ -108,7 +108,11 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -140,7 +144,11 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
const { certPrivateKey } = await getCertificateCredentials({
|
||||
@@ -174,7 +182,11 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Delete,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
const deletedCert = await certificateDAL.deleteById(cert.id);
|
||||
@@ -234,7 +246,13 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Delete,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber,
|
||||
friendlyName: cert.friendlyName,
|
||||
status: cert.status
|
||||
})
|
||||
);
|
||||
|
||||
if (cert.status === CertStatus.REVOKED) throw new Error("Certificate already revoked");
|
||||
@@ -309,7 +327,11 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber
|
||||
})
|
||||
);
|
||||
|
||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||
@@ -397,7 +419,7 @@ export const certificateServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Create,
|
||||
ProjectPermissionCertificateActions.Import,
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
|
||||
@@ -610,11 +632,23 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber,
|
||||
friendlyName: cert.friendlyName,
|
||||
status: cert.status
|
||||
})
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber,
|
||||
friendlyName: cert.friendlyName,
|
||||
status: cert.status
|
||||
})
|
||||
);
|
||||
|
||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||
@@ -726,7 +760,13 @@ export const certificateServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
subject(ProjectPermissionSub.Certificates, {
|
||||
commonName: cert.commonName,
|
||||
altNames: cert.altNames ?? undefined,
|
||||
serialNumber: cert.serialNumber,
|
||||
friendlyName: cert.friendlyName,
|
||||
status: cert.status
|
||||
})
|
||||
);
|
||||
|
||||
// Get certificate bundle (certificate, chain, private key)
|
||||
|
||||
@@ -145,9 +145,7 @@ export const pkiSyncServiceFactory = ({
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Create,
|
||||
subscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: subscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
subject(ProjectPermissionSub.PkiSyncs, { name: subscriber ? subscriber.name : name })
|
||||
);
|
||||
|
||||
// Get the destination app type based on PKI sync destination
|
||||
@@ -236,8 +234,8 @@ export const pkiSyncServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Edit,
|
||||
currentSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: currentSubscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: currentSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
if (name && name !== pkiSync.name) {
|
||||
@@ -332,8 +330,8 @@ export const pkiSyncServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Delete,
|
||||
pkiSyncSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: pkiSyncSubscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: pkiSyncSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
return pkiSyncDAL.deleteById(id);
|
||||
@@ -352,7 +350,7 @@ export const pkiSyncServiceFactory = ({
|
||||
projectId
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionPkiSyncActions.Read, ProjectPermissionSub.PkiSyncs);
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionPkiSyncActions.List, ProjectPermissionSub.PkiSyncs);
|
||||
|
||||
const pkiSyncsWithSubscribers = await pkiSyncDAL.findByProjectIdWithSubscribers(projectId);
|
||||
|
||||
@@ -407,8 +405,8 @@ export const pkiSyncServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Read,
|
||||
findSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: findSubscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: findSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
const result = {
|
||||
@@ -443,8 +441,8 @@ export const pkiSyncServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.SyncCertificates,
|
||||
syncSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: syncSubscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: syncSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
await pkiSyncQueue.queuePkiSyncSyncCertificatesById({ syncId: id });
|
||||
@@ -484,8 +482,8 @@ export const pkiSyncServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.ImportCertificates,
|
||||
importSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: importSubscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: importSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
await pkiSyncQueue.queuePkiSyncImportCertificatesById({ syncId: id });
|
||||
@@ -517,8 +515,8 @@ export const pkiSyncServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.RemoveCertificates,
|
||||
removeSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { subscriberName: removeSubscriber.name })
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: removeSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
await pkiSyncQueue.queuePkiSyncRemoveCertificatesById({ syncId: id });
|
||||
@@ -549,7 +547,17 @@ export const pkiSyncServiceFactory = ({
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionPkiSyncActions.Edit, ProjectPermissionSub.PkiSyncs);
|
||||
let pkiSyncSubscriber;
|
||||
if (pkiSync.subscriberId) {
|
||||
pkiSyncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
|
||||
}
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Edit,
|
||||
pkiSyncSubscriber
|
||||
? subject(ProjectPermissionSub.PkiSyncs, { name: pkiSyncSubscriber.name })
|
||||
: subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
await validateCertificatesProjectOwnership(certificateIds, pkiSync.projectId);
|
||||
|
||||
@@ -588,7 +596,10 @@ export const pkiSyncServiceFactory = ({
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionPkiSyncActions.Edit, ProjectPermissionSub.PkiSyncs);
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Edit,
|
||||
subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
const removedCount = await certificateSyncDAL.removeCertificates(pkiSyncId, certificateIds);
|
||||
|
||||
@@ -626,7 +637,10 @@ export const pkiSyncServiceFactory = ({
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionPkiSyncActions.Read, ProjectPermissionSub.PkiSyncs);
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionPkiSyncActions.Read,
|
||||
subject(ProjectPermissionSub.PkiSyncs, { name: pkiSync.name })
|
||||
);
|
||||
|
||||
const result = await certificateSyncDAL.findWithDetails({
|
||||
pkiSyncId,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionCertificateActions,
|
||||
ProjectPermissionCertificateAuthorityActions,
|
||||
ProjectPermissionMemberActions,
|
||||
ProjectPermissionPkiSubscriberActions,
|
||||
ProjectPermissionPkiTemplateActions,
|
||||
@@ -911,7 +912,7 @@ export const projectServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionCertificateAuthorityActions.List,
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
);
|
||||
|
||||
@@ -959,7 +960,7 @@ export const projectServiceFactory = ({
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionCertificateActions.Read,
|
||||
ProjectPermissionCertificateActions.List,
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user