diff --git a/modules/caddytls/acmeissuer.go b/modules/caddytls/acmeissuer.go index b511346b5..193c8bfc7 100644 --- a/modules/caddytls/acmeissuer.go +++ b/modules/caddytls/acmeissuer.go @@ -140,6 +140,42 @@ func (iss *ACMEIssuer) Provision(ctx caddy.Context) error { iss.Email = email } + // expand CA endpoint, if non-empty + if iss.CA != "" { + ca, err := repl.ReplaceOrErr(iss.CA, true, true) + if err != nil { + return fmt.Errorf("expanding CA endpoint '%s': %v", iss.CA, err) + } + iss.CA = ca + } + + // expand TestCA endpoint, if non-empty + if iss.TestCA != "" { + testca, err := repl.ReplaceOrErr(iss.TestCA, true, true) + if err != nil { + return fmt.Errorf("expanding TestCA endpoint '%s': %v", iss.TestCA, err) + } + iss.TestCA = testca + } + + // expand EAB credentials, if non-empty + if iss.ExternalAccount != nil { + if iss.ExternalAccount.KeyID != "" { + keyID, err := repl.ReplaceOrErr(iss.ExternalAccount.KeyID, true, true) + if err != nil { + return fmt.Errorf("expanding EAB key ID '%s': %v", iss.ExternalAccount.KeyID, err) + } + iss.ExternalAccount.KeyID = keyID + } + if iss.ExternalAccount.MACKey != "" { + macKey, err := repl.ReplaceOrErr(iss.ExternalAccount.MACKey, true, true) + if err != nil { + return fmt.Errorf("expanding EAB MAC key (redacted): %v", err) + } + iss.ExternalAccount.MACKey = macKey + } + } + // expand account key, if non-empty if iss.AccountKey != "" { accountKey, err := repl.ReplaceOrErr(iss.AccountKey, true, true) diff --git a/modules/caddytls/acmeissuer_test.go b/modules/caddytls/acmeissuer_test.go new file mode 100644 index 000000000..661f7b9e5 --- /dev/null +++ b/modules/caddytls/acmeissuer_test.go @@ -0,0 +1,43 @@ +package caddytls + +import ( + "github.com/caddyserver/caddy/v2" + "github.com/mholt/acmez/v3/acme" + "testing" +) + +func TestACMEIssuerExpandPlaceholders(t *testing.T) { + t.Setenv("CADDY_TEST_CA_URL", "https://acme.example.com/directory") + t.Setenv("CADDY_TEST_TEST_CA_URL", "https://acme2.example.com/directory") + t.Setenv("CADDY_TEST_EAB_KEY_ID", "example-key-id") + t.Setenv("CADDY_TEST_EAB_MAC_KEY", "example-mac-key") + + caddyCtx, cancel := caddy.NewContext(caddy.Context{Context: t.Context()}) + defer cancel() + + iss := &ACMEIssuer{ + CA: "{env.CADDY_TEST_CA_URL}", + TestCA: "{env.CADDY_TEST_TEST_CA_URL}", + ExternalAccount: &acme.EAB{ + KeyID: "{env.CADDY_TEST_EAB_KEY_ID}", + MACKey: "{env.CADDY_TEST_EAB_MAC_KEY}", + }, + } + + if err := iss.Provision(caddyCtx); err != nil { + t.Fatalf("Provision() returned unexpected error: %v", err) + } + + if want := "https://acme.example.com/directory"; iss.CA != want { + t.Errorf("CA: got %q, want %q", iss.CA, want) + } + if want := "https://acme2.example.com/directory"; iss.TestCA != want { + t.Errorf("TestCA: got %q, want %q", iss.TestCA, want) + } + if want := "example-key-id"; iss.ExternalAccount.KeyID != want { + t.Errorf("ExternalAccount.KeyID: got %q, want %q", iss.ExternalAccount.KeyID, want) + } + if want := "example-mac-key"; iss.ExternalAccount.MACKey != want { + t.Errorf("ExternalAccount.MACKey: got %q, want %q", iss.ExternalAccount.MACKey, want) + } +}