mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 05:27:52 +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,
|
action: ProjectPermissionCertificateActions.Read,
|
||||||
subject: ProjectPermissionSub.Certificates
|
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 = {
|
const mockPermission = {
|
||||||
permission: createMongoAbility<ProjectPermissionSet>([
|
permission: createMongoAbility<ProjectPermissionSet>([
|
||||||
{
|
{
|
||||||
@@ -349,7 +353,6 @@ describe("CertificateRequestService", () => {
|
|||||||
(mockPermissionService.getProjectPermission as any).mockResolvedValue(mockPermission);
|
(mockPermissionService.getProjectPermission as any).mockResolvedValue(mockPermission);
|
||||||
(mockCertificateRequestDAL.findByIdWithCertificate as any).mockResolvedValue(mockRequestWithCert);
|
(mockCertificateRequestDAL.findByIdWithCertificate as any).mockResolvedValue(mockRequestWithCert);
|
||||||
(mockCertificateService.getCertBody as any).mockResolvedValue(mockCertBody);
|
(mockCertificateService.getCertBody as any).mockResolvedValue(mockCertBody);
|
||||||
(mockCertificateService.getCertPrivateKey as any).mockRejectedValue(new Error("Private key access denied"));
|
|
||||||
|
|
||||||
const result = await service.getCertificateFromRequest(mockGetData);
|
const result = await service.getCertificateFromRequest(mockGetData);
|
||||||
|
|
||||||
@@ -363,8 +366,68 @@ describe("CertificateRequestService", () => {
|
|||||||
actorAuthMethod: AuthMethod.EMAIL,
|
actorAuthMethod: AuthMethod.EMAIL,
|
||||||
actorOrgId: "550e8400-e29b-41d4-a716-446655440002"
|
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({
|
expect(mockCertificateService.getCertPrivateKey).toHaveBeenCalledWith({
|
||||||
id: "550e8400-e29b-41d4-a716-446655440008",
|
id: "550e8400-e29b-41d4-a716-446655440009",
|
||||||
actor: ActorType.USER,
|
actor: ActorType.USER,
|
||||||
actorId: "550e8400-e29b-41d4-a716-446655440001",
|
actorId: "550e8400-e29b-41d4-a716-446655440001",
|
||||||
actorAuthMethod: AuthMethod.EMAIL,
|
actorAuthMethod: AuthMethod.EMAIL,
|
||||||
|
|||||||
@@ -218,20 +218,25 @@ export const certificateRequestServiceFactory = ({
|
|||||||
actorOrgId
|
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;
|
let privateKey: string | null = null;
|
||||||
try {
|
if (canReadPrivateKey) {
|
||||||
const certPrivateKey = await certificateService.getCertPrivateKey({
|
try {
|
||||||
id: certificateRequest.certificate.id,
|
const certPrivateKey = await certificateService.getCertPrivateKey({
|
||||||
actor,
|
id: certificateRequest.certificate.id,
|
||||||
actorId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
privateKey = certPrivateKey.certPrivateKey;
|
});
|
||||||
} catch (error) {
|
privateKey = certPrivateKey.certPrivateKey;
|
||||||
// Private key access denied - continue without it
|
} catch (error) {
|
||||||
privateKey = null;
|
privateKey = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
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 {
|
return {
|
||||||
certificate: selfSignedResult.certificate.toString("utf8"),
|
certificate: selfSignedResult.certificate.toString("utf8"),
|
||||||
issuingCaCertificate: "",
|
issuingCaCertificate: "",
|
||||||
certificateChain: selfSignedResult.certificate.toString("utf8"),
|
certificateChain: selfSignedResult.certificate.toString("utf8"),
|
||||||
privateKey: selfSignedResult.privateKey.toString("utf8"),
|
privateKey: privateKeyForResponse,
|
||||||
serialNumber: selfSignedResult.serialNumber,
|
serialNumber: selfSignedResult.serialNumber,
|
||||||
certificateId: certificateData.id,
|
certificateId: certificateData.id,
|
||||||
certificateRequestId,
|
certificateRequestId,
|
||||||
@@ -1102,11 +1118,28 @@ export const certificateV3ServiceFactory = ({
|
|||||||
finalCertificateChain = removeRootCaFromChain(finalCertificateChain);
|
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 {
|
return {
|
||||||
certificate: bufferToString(certificate),
|
certificate: bufferToString(certificate),
|
||||||
issuingCaCertificate: bufferToString(issuingCaCertificate),
|
issuingCaCertificate: bufferToString(issuingCaCertificate),
|
||||||
certificateChain: finalCertificateChain,
|
certificateChain: finalCertificateChain,
|
||||||
privateKey: bufferToString(privateKey),
|
privateKey: privateKeyForResponse,
|
||||||
serialNumber,
|
serialNumber,
|
||||||
certificateId: cert.id,
|
certificateId: cert.id,
|
||||||
certificateRequestId,
|
certificateRequestId,
|
||||||
|
|||||||
Reference in New Issue
Block a user