fix(m-2): thread context through CertificateService cluster

Collapses CertificateService, RevocationSvc, and CAOperationsSvc to
ctx-accepting method signatures. Removes context.Background() synthesis
at 24 internal call sites across certificate.go, revocation_svc.go, and
ca_operations.go.

- Primary repo calls inherit request cancellation via the passed ctx.
- Audit and notification dispatches use context.WithoutCancel(ctx) so
  they survive client disconnect.
- Collapses TriggerRenewal/TriggerRenewalWithActor,
  TriggerDeployment/TriggerDeploymentWithActor, and
  RevokeCertificate/RevokeCertificateWithActor sibling pairs into single
  canonical ctx-accepting methods (decisions D-1, D-2).

Handlers pass r.Context(). Mocks and tests updated to match new
signatures. No HTTP surface change, no OpenAPI change.

PR 1 of 6 in the M-2 remediation chain. Master green at this commit.

Refs: certctl-audit-report.md M-2 (L143, L224)
This commit is contained in:
shankar0123
2026-04-18 00:29:37 +00:00
parent e951d319d0
commit cdc9d03d5b
12 changed files with 225 additions and 235 deletions
@@ -27,6 +27,7 @@ package handler
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
@@ -120,7 +121,7 @@ func TestGetCertificate_PathInjection(t *testing.T) {
handler, mock := newCertHandlerWithMock()
// Force a 404 so we can distinguish "service was called" from
// "parser accepted the ID"; a 200 with null body is also fine.
mock.GetCertificateFn = func(id string) (*domain.ManagedCertificate, error) {
mock.GetCertificateFn = func(_ context.Context, id string) (*domain.ManagedCertificate, error) {
return nil, ErrMockNotFound
}
@@ -156,7 +157,7 @@ func TestUpdateCertificate_PathInjection(t *testing.T) {
}()
handler, mock := newCertHandlerWithMock()
mock.UpdateCertificateFn = func(id string, cert domain.ManagedCertificate) (*domain.ManagedCertificate, error) {
mock.UpdateCertificateFn = func(_ context.Context, id string, cert domain.ManagedCertificate) (*domain.ManagedCertificate, error) {
return nil, ErrMockNotFound
}
@@ -184,7 +185,7 @@ func TestArchiveCertificate_PathInjection(t *testing.T) {
}()
handler, mock := newCertHandlerWithMock()
mock.ArchiveCertificateFn = func(id string) error { return ErrMockNotFound }
mock.ArchiveCertificateFn = func(_ context.Context, id string) error { return ErrMockNotFound }
req := httptest.NewRequest(http.MethodDelete, "/api/v1/certificates/x", nil)
req.URL.Path = "/api/v1/certificates/" + tc.input
@@ -227,7 +228,7 @@ func TestGetCertificateVersions_MultiSegment(t *testing.T) {
}()
handler, mock := newCertHandlerWithMock()
mock.GetCertificateVersionsFn = func(certID string, page, perPage int) ([]domain.CertificateVersion, int64, error) {
mock.GetCertificateVersionsFn = func(_ context.Context, certID string, page, perPage int) ([]domain.CertificateVersion, int64, error) {
return []domain.CertificateVersion{}, 0, nil
}
@@ -277,7 +278,7 @@ func TestHandleOCSP_MultiSegment(t *testing.T) {
}()
handler, mock := newCertHandlerWithMock()
mock.GetOCSPResponseFn = func(issuerID, serialHex string) ([]byte, error) {
mock.GetOCSPResponseFn = func(_ context.Context, issuerID, serialHex string) ([]byte, error) {
return nil, ErrMockNotFound
}
@@ -311,7 +312,7 @@ func TestGetDERCRL_IssuerPathInjection(t *testing.T) {
}()
handler, mock := newCertHandlerWithMock()
mock.GenerateDERCRLFn = func(issuerID string) ([]byte, error) {
mock.GenerateDERCRLFn = func(_ context.Context, issuerID string) ([]byte, error) {
return nil, ErrMockNotFound
}