mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 09:26:47 +00:00
review fixes
This commit is contained in:
@@ -17,6 +17,14 @@ export enum ProjectPermissionActions {
|
|||||||
Delete = "delete"
|
Delete = "delete"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ProjectPermissionCertificateActions {
|
||||||
|
Read = "read",
|
||||||
|
Create = "create",
|
||||||
|
Edit = "edit",
|
||||||
|
Delete = "delete",
|
||||||
|
ReadPrivateKey = "read-private-key"
|
||||||
|
}
|
||||||
|
|
||||||
export enum ProjectPermissionSecretActions {
|
export enum ProjectPermissionSecretActions {
|
||||||
DescribeAndReadValue = "read",
|
DescribeAndReadValue = "read",
|
||||||
DescribeSecret = "describeSecret",
|
DescribeSecret = "describeSecret",
|
||||||
@@ -129,7 +137,6 @@ export enum ProjectPermissionSub {
|
|||||||
Identity = "identity",
|
Identity = "identity",
|
||||||
CertificateAuthorities = "certificate-authorities",
|
CertificateAuthorities = "certificate-authorities",
|
||||||
Certificates = "certificates",
|
Certificates = "certificates",
|
||||||
CertificatePrivateKey = "certificate-private-key",
|
|
||||||
CertificateTemplates = "certificate-templates",
|
CertificateTemplates = "certificate-templates",
|
||||||
SshCertificateAuthorities = "ssh-certificate-authorities",
|
SshCertificateAuthorities = "ssh-certificate-authorities",
|
||||||
SshCertificates = "ssh-certificates",
|
SshCertificates = "ssh-certificates",
|
||||||
@@ -232,8 +239,7 @@ export type ProjectPermissionSet =
|
|||||||
ProjectPermissionSub.Identity | (ForcedSubject<ProjectPermissionSub.Identity> & IdentityManagementSubjectFields)
|
ProjectPermissionSub.Identity | (ForcedSubject<ProjectPermissionSub.Identity> & IdentityManagementSubjectFields)
|
||||||
]
|
]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities]
|
| [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.Certificates]
|
| [ProjectPermissionCertificateActions, ProjectPermissionSub.Certificates]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificatePrivateKey]
|
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateTemplates]
|
| [ProjectPermissionActions, ProjectPermissionSub.CertificateTemplates]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateAuthorities]
|
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateAuthorities]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificates]
|
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificates]
|
||||||
@@ -482,12 +488,6 @@ const GeneralPermissionSchema = [
|
|||||||
"Describe what action an entity can take."
|
"Describe what action an entity can take."
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
z.object({
|
|
||||||
subject: z.literal(ProjectPermissionSub.CertificatePrivateKey).describe("The entity this permission pertains to."),
|
|
||||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe(
|
|
||||||
"Describe what action an entity can take."
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
z.object({
|
z.object({
|
||||||
subject: z.literal(ProjectPermissionSub.CertificateTemplates).describe("The entity this permission pertains to."),
|
subject: z.literal(ProjectPermissionSub.CertificateTemplates).describe("The entity this permission pertains to."),
|
||||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe(
|
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe(
|
||||||
@@ -688,8 +688,6 @@ const buildAdminPermissionRules = () => {
|
|||||||
ProjectPermissionSub.AuditLogs,
|
ProjectPermissionSub.AuditLogs,
|
||||||
ProjectPermissionSub.IpAllowList,
|
ProjectPermissionSub.IpAllowList,
|
||||||
ProjectPermissionSub.CertificateAuthorities,
|
ProjectPermissionSub.CertificateAuthorities,
|
||||||
ProjectPermissionSub.Certificates,
|
|
||||||
ProjectPermissionSub.CertificatePrivateKey,
|
|
||||||
ProjectPermissionSub.CertificateTemplates,
|
ProjectPermissionSub.CertificateTemplates,
|
||||||
ProjectPermissionSub.PkiAlerts,
|
ProjectPermissionSub.PkiAlerts,
|
||||||
ProjectPermissionSub.PkiCollections,
|
ProjectPermissionSub.PkiCollections,
|
||||||
@@ -708,6 +706,17 @@ const buildAdminPermissionRules = () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
can(
|
||||||
|
[
|
||||||
|
ProjectPermissionCertificateActions.Read,
|
||||||
|
ProjectPermissionCertificateActions.Edit,
|
||||||
|
ProjectPermissionCertificateActions.Create,
|
||||||
|
ProjectPermissionCertificateActions.Delete,
|
||||||
|
ProjectPermissionCertificateActions.ReadPrivateKey
|
||||||
|
],
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
can(
|
can(
|
||||||
[
|
[
|
||||||
ProjectPermissionSshHostActions.Edit,
|
ProjectPermissionSshHostActions.Edit,
|
||||||
@@ -965,10 +974,10 @@ const buildMemberPermissionRules = () => {
|
|||||||
|
|
||||||
can(
|
can(
|
||||||
[
|
[
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionCertificateActions.Read,
|
||||||
ProjectPermissionActions.Edit,
|
ProjectPermissionCertificateActions.Edit,
|
||||||
ProjectPermissionActions.Create,
|
ProjectPermissionCertificateActions.Create,
|
||||||
ProjectPermissionActions.Delete
|
ProjectPermissionCertificateActions.Delete
|
||||||
],
|
],
|
||||||
ProjectPermissionSub.Certificates
|
ProjectPermissionSub.Certificates
|
||||||
);
|
);
|
||||||
@@ -1041,7 +1050,7 @@ const buildViewerPermissionRules = () => {
|
|||||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs);
|
can(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs);
|
||||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList);
|
can(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList);
|
||||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.CertificateAuthorities);
|
can(ProjectPermissionActions.Read, ProjectPermissionSub.CertificateAuthorities);
|
||||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
|
can(ProjectPermissionCertificateActions.Read, ProjectPermissionSub.Certificates);
|
||||||
can(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
can(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
|
||||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificates);
|
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificates);
|
||||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificateTemplates);
|
can(ProjectPermissionActions.Read, ProjectPermissionSub.SshCertificateTemplates);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { FastifyReply } from "fastify";
|
||||||
|
|
||||||
|
export const addNoCacheHeaders = (reply: FastifyReply) => {
|
||||||
|
void reply.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
|
||||||
|
void reply.header("Pragma", "no-cache");
|
||||||
|
void reply.header("Expires", "0");
|
||||||
|
void reply.header("Surrogate-Control", "no-store");
|
||||||
|
};
|
||||||
@@ -6,6 +6,7 @@ import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
|||||||
import { ApiDocsTags, CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs";
|
import { ApiDocsTags, CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { addNoCacheHeaders } from "@app/server/lib/caching";
|
||||||
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
|
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
@@ -106,11 +107,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent proxies from caching sensitive data (private key)
|
addNoCacheHeaders(reply);
|
||||||
reply.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
|
|
||||||
reply.header("Pragma", "no-cache");
|
|
||||||
reply.header("Expires", "0");
|
|
||||||
reply.header("Surrogate-Control", "no-store");
|
|
||||||
|
|
||||||
return certPrivateKey;
|
return certPrivateKey;
|
||||||
}
|
}
|
||||||
@@ -134,7 +131,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
certificate: z.string().trim().describe(CERTIFICATES.GET_CERT.certificate),
|
certificate: z.string().trim().describe(CERTIFICATES.GET_CERT.certificate),
|
||||||
certificateChain: z.string().trim().describe(CERTIFICATES.GET_CERT.certificateChain),
|
certificateChain: z.string().trim().nullish().describe(CERTIFICATES.GET_CERT.certificateChain),
|
||||||
privateKey: z.string().trim().describe(CERTIFICATES.GET_CERT.privateKey),
|
privateKey: z.string().trim().describe(CERTIFICATES.GET_CERT.privateKey),
|
||||||
serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumberRes)
|
serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumberRes)
|
||||||
})
|
})
|
||||||
@@ -163,11 +160,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent proxies from caching sensitive data (private key)
|
addNoCacheHeaders(reply);
|
||||||
reply.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
|
|
||||||
reply.header("Pragma", "no-cache");
|
|
||||||
reply.header("Expires", "0");
|
|
||||||
reply.header("Surrogate-Control", "no-store");
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
certificate,
|
certificate,
|
||||||
@@ -525,7 +518,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
|
|||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
certificate: z.string().trim().describe(CERTIFICATES.GET_CERT.certificate),
|
certificate: z.string().trim().describe(CERTIFICATES.GET_CERT.certificate),
|
||||||
certificateChain: z.string().trim().describe(CERTIFICATES.GET_CERT.certificateChain),
|
certificateChain: z.string().trim().nullish().describe(CERTIFICATES.GET_CERT.certificateChain),
|
||||||
serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumberRes)
|
serialNumber: z.string().trim().describe(CERTIFICATES.GET_CERT.serialNumberRes)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { ActionProjectType, ProjectType, TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas";
|
import { ActionProjectType, ProjectType, TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import {
|
||||||
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
|
ProjectPermissionSub
|
||||||
|
} from "@app/ee/services/permission/project-permission";
|
||||||
import { extractX509CertFromChain } from "@app/lib/certificates/extract-certificate";
|
import { extractX509CertFromChain } from "@app/lib/certificates/extract-certificate";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
@@ -1160,7 +1164,10 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Certificates);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.Create,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
if (ca.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
if (ca.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
||||||
if (!ca.activeCaCertId) throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
if (!ca.activeCaCertId) throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
||||||
@@ -1508,7 +1515,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Create,
|
ProjectPermissionCertificateActions.Create,
|
||||||
ProjectPermissionSub.Certificates
|
ProjectPermissionSub.Certificates
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ import * as x509 from "@peculiar/x509";
|
|||||||
import { ActionProjectType } from "@app/db/schemas";
|
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";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
import {
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
|
ProjectPermissionSub
|
||||||
|
} from "@app/ee/services/permission/project-permission";
|
||||||
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
|
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
|
||||||
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
|
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
|
||||||
import { TCertificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
|
import { TCertificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
|
||||||
@@ -70,7 +73,10 @@ export const certificateServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.Read,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cert,
|
cert,
|
||||||
@@ -101,8 +107,8 @@ export const certificateServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||||
ProjectPermissionSub.CertificatePrivateKey
|
ProjectPermissionSub.Certificates
|
||||||
);
|
);
|
||||||
|
|
||||||
const { certPrivateKey } = await getCertificateCredentials({
|
const { certPrivateKey } = await getCertificateCredentials({
|
||||||
@@ -136,7 +142,10 @@ export const certificateServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Certificates);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.Delete,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
const deletedCert = await certificateDAL.deleteById(cert.id);
|
const deletedCert = await certificateDAL.deleteById(cert.id);
|
||||||
|
|
||||||
@@ -171,7 +180,10 @@ export const certificateServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Certificates);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.Delete,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
if (cert.status === CertStatus.REVOKED) throw new Error("Certificate already revoked");
|
if (cert.status === CertStatus.REVOKED) throw new Error("Certificate already revoked");
|
||||||
|
|
||||||
@@ -218,7 +230,10 @@ export const certificateServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.Read,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||||
|
|
||||||
@@ -279,10 +294,13 @@ export const certificateServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionCertificateActions.Read,
|
||||||
ProjectPermissionSub.CertificatePrivateKey
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
);
|
);
|
||||||
|
|
||||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/servi
|
|||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
import {
|
import {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
ProjectPermissionSecretActions,
|
ProjectPermissionSecretActions,
|
||||||
ProjectPermissionSshHostActions,
|
ProjectPermissionSshHostActions,
|
||||||
ProjectPermissionSub
|
ProjectPermissionSub
|
||||||
@@ -927,7 +928,10 @@ export const projectServiceFactory = ({
|
|||||||
actionProjectType: ActionProjectType.CertificateManager
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionCertificateActions.Read,
|
||||||
|
ProjectPermissionSub.Certificates
|
||||||
|
);
|
||||||
|
|
||||||
const cas = await certificateAuthorityDAL.find({ projectId });
|
const cas = await certificateAuthorityDAL.find({ projectId });
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export { useProjectPermission } from "./ProjectPermissionContext";
|
|||||||
export type { ProjectPermissionSet, TProjectPermission } from "./types";
|
export type { ProjectPermissionSet, TProjectPermission } from "./types";
|
||||||
export {
|
export {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
ProjectPermissionCmekActions,
|
ProjectPermissionCmekActions,
|
||||||
ProjectPermissionDynamicSecretActions,
|
ProjectPermissionDynamicSecretActions,
|
||||||
ProjectPermissionGroupActions,
|
ProjectPermissionGroupActions,
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ export enum ProjectPermissionActions {
|
|||||||
Delete = "delete"
|
Delete = "delete"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ProjectPermissionCertificateActions {
|
||||||
|
Read = "read",
|
||||||
|
Create = "create",
|
||||||
|
Edit = "edit",
|
||||||
|
Delete = "delete",
|
||||||
|
ReadPrivateKey = "read-private-key"
|
||||||
|
}
|
||||||
|
|
||||||
export enum ProjectPermissionSecretActions {
|
export enum ProjectPermissionSecretActions {
|
||||||
DescribeAndReadValue = "read",
|
DescribeAndReadValue = "read",
|
||||||
DescribeSecret = "describeSecret",
|
DescribeSecret = "describeSecret",
|
||||||
@@ -170,7 +178,6 @@ export enum ProjectPermissionSub {
|
|||||||
Identity = "identity",
|
Identity = "identity",
|
||||||
CertificateAuthorities = "certificate-authorities",
|
CertificateAuthorities = "certificate-authorities",
|
||||||
Certificates = "certificates",
|
Certificates = "certificates",
|
||||||
CertificatePrivateKey = "certificate-private-key",
|
|
||||||
CertificateTemplates = "certificate-templates",
|
CertificateTemplates = "certificate-templates",
|
||||||
SshCertificateAuthorities = "ssh-certificate-authorities",
|
SshCertificateAuthorities = "ssh-certificate-authorities",
|
||||||
SshCertificateTemplates = "ssh-certificate-templates",
|
SshCertificateTemplates = "ssh-certificate-templates",
|
||||||
@@ -268,9 +275,8 @@ export type ProjectPermissionSet =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities]
|
| [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.Certificates]
|
| [ProjectPermissionCertificateActions, ProjectPermissionSub.Certificates]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateTemplates]
|
| [ProjectPermissionActions, ProjectPermissionSub.CertificateTemplates]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificatePrivateKey]
|
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateAuthorities]
|
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateAuthorities]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateTemplates]
|
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateTemplates]
|
||||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificates]
|
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificates]
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export {
|
|||||||
export type { TProjectPermission } from "./ProjectPermissionContext";
|
export type { TProjectPermission } from "./ProjectPermissionContext";
|
||||||
export {
|
export {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
ProjectPermissionCmekActions,
|
ProjectPermissionCmekActions,
|
||||||
ProjectPermissionDynamicSecretActions,
|
ProjectPermissionDynamicSecretActions,
|
||||||
ProjectPermissionGroupActions,
|
ProjectPermissionGroupActions,
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ import { useTranslation } from "react-i18next";
|
|||||||
|
|
||||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||||
import { PageHeader } from "@app/components/v2";
|
import { PageHeader } from "@app/components/v2";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission } from "@app/context";
|
import {
|
||||||
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
|
ProjectPermissionSub,
|
||||||
|
useProjectPermission
|
||||||
|
} from "@app/context";
|
||||||
|
|
||||||
import { PkiCollectionSection } from "../AlertingPage/components";
|
import { PkiCollectionSection } from "../AlertingPage/components";
|
||||||
import { CertificatesSection } from "./components";
|
import { CertificatesSection } from "./components";
|
||||||
@@ -17,7 +22,7 @@ export const CertificatesPage = () => {
|
|||||||
ProjectPermissionSub.PkiCollections
|
ProjectPermissionSub.PkiCollections
|
||||||
);
|
);
|
||||||
const canAccessCerts = permission.can(
|
const canAccessCerts = permission.can(
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionCertificateActions.Read,
|
||||||
ProjectPermissionSub.Certificates
|
ProjectPermissionSub.Certificates
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -40,7 +45,7 @@ export const CertificatesPage = () => {
|
|||||||
)}
|
)}
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
renderGuardBanner
|
renderGuardBanner
|
||||||
I={ProjectPermissionActions.Read}
|
I={ProjectPermissionCertificateActions.Read}
|
||||||
a={ProjectPermissionSub.Certificates}
|
a={ProjectPermissionSub.Certificates}
|
||||||
>
|
>
|
||||||
<CertificatesSection />
|
<CertificatesSection />
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
import {
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
|
ProjectPermissionSub,
|
||||||
|
useWorkspace
|
||||||
|
} from "@app/context";
|
||||||
import { useDeleteCert } from "@app/hooks/api";
|
import { useDeleteCert } from "@app/hooks/api";
|
||||||
import { usePopUp } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
@@ -50,7 +54,7 @@ export const CertificatesSection = () => {
|
|||||||
<div className="mb-4 flex justify-between">
|
<div className="mb-4 flex justify-between">
|
||||||
<p className="text-xl font-semibold text-mineshaft-100">Certificates</p>
|
<p className="text-xl font-semibold text-mineshaft-100">Certificates</p>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Create}
|
I={ProjectPermissionCertificateActions.Create}
|
||||||
a={ProjectPermissionSub.Certificates}
|
a={ProjectPermissionSub.Certificates}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
|
|||||||
@@ -30,7 +30,11 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
import {
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
|
ProjectPermissionSub,
|
||||||
|
useWorkspace
|
||||||
|
} from "@app/context";
|
||||||
import { useListWorkspaceCertificates } from "@app/hooks/api";
|
import { useListWorkspaceCertificates } from "@app/hooks/api";
|
||||||
import { CertStatus } from "@app/hooks/api/certificates/enums";
|
import { CertStatus } from "@app/hooks/api/certificates/enums";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
@@ -110,7 +114,7 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="start" className="p-1">
|
<DropdownMenuContent align="start" className="p-1">
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Read}
|
I={ProjectPermissionCertificateActions.Read}
|
||||||
a={ProjectPermissionSub.Certificates}
|
a={ProjectPermissionSub.Certificates}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
@@ -131,7 +135,7 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Read}
|
I={ProjectPermissionCertificateActions.Read}
|
||||||
a={ProjectPermissionSub.Certificates}
|
a={ProjectPermissionSub.Certificates}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
@@ -152,7 +156,7 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Delete}
|
I={ProjectPermissionCertificateActions.Delete}
|
||||||
a={ProjectPermissionSub.Certificates}
|
a={ProjectPermissionSub.Certificates}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
@@ -173,7 +177,7 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
<ProjectPermissionCan
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Delete}
|
I={ProjectPermissionCertificateActions.Delete}
|
||||||
a={ProjectPermissionSub.Certificates}
|
a={ProjectPermissionSub.Certificates}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
|
|||||||
+34
-17
@@ -6,6 +6,7 @@ import { z } from "zod";
|
|||||||
import { Tooltip } from "@app/components/v2";
|
import { Tooltip } from "@app/components/v2";
|
||||||
import {
|
import {
|
||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionCertificateActions,
|
||||||
ProjectPermissionCmekActions,
|
ProjectPermissionCmekActions,
|
||||||
ProjectPermissionSub
|
ProjectPermissionSub
|
||||||
} from "@app/context";
|
} from "@app/context";
|
||||||
@@ -32,6 +33,14 @@ const GeneralPolicyActionSchema = z.object({
|
|||||||
create: z.boolean().optional()
|
create: z.boolean().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const CertificatePolicyActionSchema = z.object({
|
||||||
|
[ProjectPermissionCertificateActions.Create]: z.boolean().optional(),
|
||||||
|
[ProjectPermissionCertificateActions.Delete]: z.boolean().optional(),
|
||||||
|
[ProjectPermissionCertificateActions.Edit]: z.boolean().optional(),
|
||||||
|
[ProjectPermissionCertificateActions.Read]: z.boolean().optional(),
|
||||||
|
[ProjectPermissionCertificateActions.ReadPrivateKey]: z.boolean().optional()
|
||||||
|
});
|
||||||
|
|
||||||
const SecretPolicyActionSchema = z.object({
|
const SecretPolicyActionSchema = z.object({
|
||||||
[ProjectPermissionSecretActions.DescribeAndReadValue]: z.boolean().optional(), // existing read, gives both describe and read value
|
[ProjectPermissionSecretActions.DescribeAndReadValue]: z.boolean().optional(), // existing read, gives both describe and read value
|
||||||
[ProjectPermissionSecretActions.DescribeSecret]: z.boolean().optional(),
|
[ProjectPermissionSecretActions.DescribeSecret]: z.boolean().optional(),
|
||||||
@@ -219,11 +228,10 @@ export const projectRoleFormSchema = z.object({
|
|||||||
[ProjectPermissionSub.AuditLogs]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.AuditLogs]: GeneralPolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.IpAllowList]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.IpAllowList]: GeneralPolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.CertificateAuthorities]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.CertificateAuthorities]: GeneralPolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.Certificates]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.Certificates]: CertificatePolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.PkiAlerts]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.PkiAlerts]: GeneralPolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.PkiCollections]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.PkiCollections]: GeneralPolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.CertificateTemplates]: GeneralPolicyActionSchema.array().default([]),
|
[ProjectPermissionSub.CertificateTemplates]: GeneralPolicyActionSchema.array().default([]),
|
||||||
[ProjectPermissionSub.CertificatePrivateKey]: GeneralPolicyActionSchema.array().default([]),
|
|
||||||
[ProjectPermissionSub.SshCertificateAuthorities]: GeneralPolicyActionSchema.array().default(
|
[ProjectPermissionSub.SshCertificateAuthorities]: GeneralPolicyActionSchema.array().default(
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
@@ -371,11 +379,9 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
|
|||||||
ProjectPermissionSub.AuditLogs,
|
ProjectPermissionSub.AuditLogs,
|
||||||
ProjectPermissionSub.IpAllowList,
|
ProjectPermissionSub.IpAllowList,
|
||||||
ProjectPermissionSub.CertificateAuthorities,
|
ProjectPermissionSub.CertificateAuthorities,
|
||||||
ProjectPermissionSub.Certificates,
|
|
||||||
ProjectPermissionSub.PkiAlerts,
|
ProjectPermissionSub.PkiAlerts,
|
||||||
ProjectPermissionSub.PkiCollections,
|
ProjectPermissionSub.PkiCollections,
|
||||||
ProjectPermissionSub.CertificateTemplates,
|
ProjectPermissionSub.CertificateTemplates,
|
||||||
ProjectPermissionSub.CertificatePrivateKey,
|
|
||||||
ProjectPermissionSub.SecretApproval,
|
ProjectPermissionSub.SecretApproval,
|
||||||
ProjectPermissionSub.Tags,
|
ProjectPermissionSub.Tags,
|
||||||
ProjectPermissionSub.SecretRotation,
|
ProjectPermissionSub.SecretRotation,
|
||||||
@@ -507,6 +513,25 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subject === ProjectPermissionSub.Certificates) {
|
||||||
|
const canRead = action.includes(ProjectPermissionCertificateActions.Read);
|
||||||
|
const canEdit = action.includes(ProjectPermissionCertificateActions.Edit);
|
||||||
|
const canDelete = action.includes(ProjectPermissionCertificateActions.Delete);
|
||||||
|
const canCreate = action.includes(ProjectPermissionCertificateActions.Create);
|
||||||
|
const canReadPrivateKey = action.includes(ProjectPermissionCertificateActions.ReadPrivateKey);
|
||||||
|
|
||||||
|
if (!formVal[subject]) formVal[subject] = [{}];
|
||||||
|
|
||||||
|
// from above statement we are sure it won't be undefined
|
||||||
|
if (canRead) formVal[subject]![0].read = true;
|
||||||
|
if (canEdit) formVal[subject]![0].edit = true;
|
||||||
|
if (canCreate) formVal[subject]![0].create = true;
|
||||||
|
if (canDelete) formVal[subject]![0].delete = true;
|
||||||
|
if (canReadPrivateKey)
|
||||||
|
formVal[subject]![0][ProjectPermissionCertificateActions.ReadPrivateKey] = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (subject === ProjectPermissionSub.Project) {
|
if (subject === ProjectPermissionSub.Project) {
|
||||||
const canEdit = action.includes(ProjectPermissionActions.Edit);
|
const canEdit = action.includes(ProjectPermissionActions.Edit);
|
||||||
const canDelete = action.includes(ProjectPermissionActions.Delete);
|
const canDelete = action.includes(ProjectPermissionActions.Delete);
|
||||||
@@ -1014,19 +1039,11 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = {
|
|||||||
[ProjectPermissionSub.Certificates]: {
|
[ProjectPermissionSub.Certificates]: {
|
||||||
title: "Certificates",
|
title: "Certificates",
|
||||||
actions: [
|
actions: [
|
||||||
{ label: "Read", value: "read" },
|
{ label: "Read", value: ProjectPermissionCertificateActions.Read },
|
||||||
{ label: "Create", value: "create" },
|
{ label: "Read Private Key", value: ProjectPermissionCertificateActions.ReadPrivateKey },
|
||||||
{ label: "Modify", value: "edit" },
|
{ label: "Create", value: ProjectPermissionCertificateActions.Create },
|
||||||
{ label: "Remove", value: "delete" }
|
{ label: "Modify", value: ProjectPermissionCertificateActions.Edit },
|
||||||
]
|
{ label: "Remove", value: ProjectPermissionCertificateActions.Delete }
|
||||||
},
|
|
||||||
[ProjectPermissionSub.CertificatePrivateKey]: {
|
|
||||||
title: "Certificate Private Key",
|
|
||||||
actions: [
|
|
||||||
{ label: "Read", value: "read" },
|
|
||||||
{ label: "Create", value: "create" },
|
|
||||||
{ label: "Modify", value: "edit" },
|
|
||||||
{ label: "Remove", value: "delete" }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
[ProjectPermissionSub.CertificateTemplates]: {
|
[ProjectPermissionSub.CertificateTemplates]: {
|
||||||
|
|||||||
Reference in New Issue
Block a user