mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Skip private key on response if user do not have access to read
This commit is contained in:
@@ -225,6 +225,10 @@ describe("CertificateRequestService", () => {
|
||||
{
|
||||
action: ProjectPermissionCertificateActions.Read,
|
||||
subject: ProjectPermissionSub.Certificates
|
||||
},
|
||||
{
|
||||
action: ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
subject: ProjectPermissionSub.Certificates
|
||||
}
|
||||
])
|
||||
};
|
||||
@@ -319,7 +323,7 @@ describe("CertificateRequestService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should get certificate from request successfully when private key access is denied", async () => {
|
||||
it("should get certificate from request successfully when user lacks private key permission", async () => {
|
||||
const mockPermission = {
|
||||
permission: createMongoAbility<ProjectPermissionSet>([
|
||||
{
|
||||
@@ -349,7 +353,6 @@ describe("CertificateRequestService", () => {
|
||||
(mockPermissionService.getProjectPermission as any).mockResolvedValue(mockPermission);
|
||||
(mockCertificateRequestDAL.findByIdWithCertificate as any).mockResolvedValue(mockRequestWithCert);
|
||||
(mockCertificateService.getCertBody as any).mockResolvedValue(mockCertBody);
|
||||
(mockCertificateService.getCertPrivateKey as any).mockRejectedValue(new Error("Private key access denied"));
|
||||
|
||||
const result = await service.getCertificateFromRequest(mockGetData);
|
||||
|
||||
@@ -363,8 +366,68 @@ describe("CertificateRequestService", () => {
|
||||
actorAuthMethod: AuthMethod.EMAIL,
|
||||
actorOrgId: "550e8400-e29b-41d4-a716-446655440002"
|
||||
});
|
||||
expect(mockCertificateService.getCertPrivateKey).not.toHaveBeenCalled();
|
||||
expect(result).toEqual({
|
||||
status: CertificateRequestStatus.ISSUED,
|
||||
certificate: "-----BEGIN CERTIFICATE-----\nMOCK_CERT_PEM\n-----END CERTIFICATE-----",
|
||||
privateKey: null,
|
||||
serialNumber: "123456",
|
||||
errorMessage: null,
|
||||
createdAt: mockRequestWithCert.createdAt,
|
||||
updatedAt: mockRequestWithCert.updatedAt
|
||||
});
|
||||
});
|
||||
|
||||
it("should get certificate from request successfully when user has private key permission but key retrieval fails", async () => {
|
||||
const mockPermission = {
|
||||
permission: createMongoAbility<ProjectPermissionSet>([
|
||||
{
|
||||
action: ProjectPermissionCertificateActions.Read,
|
||||
subject: ProjectPermissionSub.Certificates
|
||||
},
|
||||
{
|
||||
action: ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
subject: ProjectPermissionSub.Certificates
|
||||
}
|
||||
])
|
||||
};
|
||||
const mockCertificate = {
|
||||
id: "550e8400-e29b-41d4-a716-446655440009",
|
||||
serialNumber: "123456",
|
||||
commonName: "test.example.com"
|
||||
};
|
||||
const mockRequestWithCert = {
|
||||
id: "550e8400-e29b-41d4-a716-446655440005",
|
||||
projectId: "550e8400-e29b-41d4-a716-446655440003",
|
||||
status: CertificateRequestStatus.ISSUED,
|
||||
certificate: mockCertificate,
|
||||
errorMessage: null,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
};
|
||||
const mockCertBody = {
|
||||
certificate: "-----BEGIN CERTIFICATE-----\nMOCK_CERT_PEM\n-----END CERTIFICATE-----"
|
||||
};
|
||||
|
||||
(mockPermissionService.getProjectPermission as any).mockResolvedValue(mockPermission);
|
||||
(mockCertificateRequestDAL.findByIdWithCertificate as any).mockResolvedValue(mockRequestWithCert);
|
||||
(mockCertificateService.getCertBody as any).mockResolvedValue(mockCertBody);
|
||||
(mockCertificateService.getCertPrivateKey as any).mockRejectedValue(new Error("Private key not found"));
|
||||
|
||||
const result = await service.getCertificateFromRequest(mockGetData);
|
||||
|
||||
expect(mockCertificateRequestDAL.findByIdWithCertificate).toHaveBeenCalledWith(
|
||||
"550e8400-e29b-41d4-a716-446655440005"
|
||||
);
|
||||
expect(mockCertificateService.getCertBody).toHaveBeenCalledWith({
|
||||
id: "550e8400-e29b-41d4-a716-446655440009",
|
||||
actor: ActorType.USER,
|
||||
actorId: "550e8400-e29b-41d4-a716-446655440001",
|
||||
actorAuthMethod: AuthMethod.EMAIL,
|
||||
actorOrgId: "550e8400-e29b-41d4-a716-446655440002"
|
||||
});
|
||||
expect(mockCertificateService.getCertPrivateKey).toHaveBeenCalledWith({
|
||||
id: "550e8400-e29b-41d4-a716-446655440008",
|
||||
id: "550e8400-e29b-41d4-a716-446655440009",
|
||||
actor: ActorType.USER,
|
||||
actorId: "550e8400-e29b-41d4-a716-446655440001",
|
||||
actorAuthMethod: AuthMethod.EMAIL,
|
||||
|
||||
@@ -218,20 +218,25 @@ export const certificateRequestServiceFactory = ({
|
||||
actorOrgId
|
||||
});
|
||||
|
||||
// Try to get private key (may fail if user doesn't have permission)
|
||||
const canReadPrivateKey = permission.can(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
|
||||
let privateKey: string | null = null;
|
||||
try {
|
||||
const certPrivateKey = await certificateService.getCertPrivateKey({
|
||||
id: certificateRequest.certificate.id,
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
});
|
||||
privateKey = certPrivateKey.certPrivateKey;
|
||||
} catch (error) {
|
||||
// Private key access denied - continue without it
|
||||
privateKey = null;
|
||||
if (canReadPrivateKey) {
|
||||
try {
|
||||
const certPrivateKey = await certificateService.getCertPrivateKey({
|
||||
id: certificateRequest.certificate.id,
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
});
|
||||
privateKey = certPrivateKey.certPrivateKey;
|
||||
} catch (error) {
|
||||
privateKey = null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -1001,11 +1001,27 @@ export const certificateV3ServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId: profile.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager
|
||||
});
|
||||
|
||||
const canReadPrivateKey = permission.can(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
|
||||
const privateKeyForResponse = canReadPrivateKey ? selfSignedResult.privateKey.toString("utf8") : undefined;
|
||||
|
||||
return {
|
||||
certificate: selfSignedResult.certificate.toString("utf8"),
|
||||
issuingCaCertificate: "",
|
||||
certificateChain: selfSignedResult.certificate.toString("utf8"),
|
||||
privateKey: selfSignedResult.privateKey.toString("utf8"),
|
||||
privateKey: privateKeyForResponse,
|
||||
serialNumber: selfSignedResult.serialNumber,
|
||||
certificateId: certificateData.id,
|
||||
certificateRequestId,
|
||||
@@ -1102,11 +1118,28 @@ export const certificateV3ServiceFactory = ({
|
||||
finalCertificateChain = removeRootCaFromChain(finalCertificateChain);
|
||||
}
|
||||
|
||||
// Check if user has permission to read private key
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId: profile.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager
|
||||
});
|
||||
|
||||
const canReadPrivateKey = permission.can(
|
||||
ProjectPermissionCertificateActions.ReadPrivateKey,
|
||||
ProjectPermissionSub.Certificates
|
||||
);
|
||||
|
||||
const privateKeyForResponse = canReadPrivateKey ? bufferToString(privateKey) : undefined;
|
||||
|
||||
return {
|
||||
certificate: bufferToString(certificate),
|
||||
issuingCaCertificate: bufferToString(issuingCaCertificate),
|
||||
certificateChain: finalCertificateChain,
|
||||
privateKey: bufferToString(privateKey),
|
||||
privateKey: privateKeyForResponse,
|
||||
serialNumber,
|
||||
certificateId: cert.id,
|
||||
certificateRequestId,
|
||||
|
||||
Reference in New Issue
Block a user