@@ -3,7 +3,9 @@ package httpcaddyfile
33import (
44 "encoding/json"
55 "testing"
6+ "time"
67
8+ "github.com/caddyserver/caddy/v2"
79 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
810 "github.com/caddyserver/caddy/v2/modules/caddytls"
911 _ "github.com/caddyserver/caddy/v2/modules/logging"
@@ -166,3 +168,126 @@ func TestGlobalResolversOption(t *testing.T) {
166168 })
167169 }
168170}
171+
172+ func TestGlobalCertIssuerAppliesToImplicitACMEIssuer (t * testing.T ) {
173+ adapter := caddyfile.Adapter {
174+ ServerType : ServerType {},
175+ }
176+
177+ input := `{
178+ cert_issuer acme {
179+ disable_tlsalpn_challenge
180+ }
181+ }
182+ report.company.intern {
183+ tls {
184+ ca https://deglacme01.company.intern/acme/acme/directory
185+ ca_root /etc/certs/company_root2.crt
186+ }
187+ respond "ok"
188+ }`
189+
190+ out , _ , err := adapter .Adapt ([]byte (input ), nil )
191+ if err != nil {
192+ t .Fatalf ("adapting caddyfile: %v" , err )
193+ }
194+
195+ var config struct {
196+ Apps struct {
197+ TLS * caddytls.TLS `json:"tls"`
198+ } `json:"apps"`
199+ }
200+ if err := json .Unmarshal (out , & config ); err != nil {
201+ t .Fatalf ("unmarshaling adapted config: %v" , err )
202+ }
203+ if config .Apps .TLS == nil || config .Apps .TLS .Automation == nil {
204+ t .Fatal ("expected tls automation config" )
205+ }
206+
207+ var subjectPolicy * caddytls.AutomationPolicy
208+ for _ , ap := range config .Apps .TLS .Automation .Policies {
209+ if len (ap .SubjectsRaw ) == 1 && ap .SubjectsRaw [0 ] == "report.company.intern" {
210+ subjectPolicy = ap
211+ break
212+ }
213+ }
214+ if subjectPolicy == nil {
215+ t .Fatal ("expected subject-specific automation policy" )
216+ }
217+ if len (subjectPolicy .IssuersRaw ) != 1 {
218+ t .Fatalf ("expected one issuer for subject-specific policy, got %d" , len (subjectPolicy .IssuersRaw ))
219+ }
220+
221+ var issuer caddytls.ACMEIssuer
222+ if err := json .Unmarshal (subjectPolicy .IssuersRaw [0 ], & issuer ); err != nil {
223+ t .Fatalf ("unmarshaling issuer: %v" , err )
224+ }
225+ if issuer .CA != "https://deglacme01.company.intern/acme/acme/directory" {
226+ t .Fatalf ("expected custom ACME CA, got %q" , issuer .CA )
227+ }
228+ if len (issuer .TrustedRootsPEMFiles ) != 1 || issuer .TrustedRootsPEMFiles [0 ] != "/etc/certs/company_root2.crt" {
229+ t .Fatalf ("expected trusted roots to include site CA root, got %v" , issuer .TrustedRootsPEMFiles )
230+ }
231+ if issuer .Challenges == nil || issuer .Challenges .TLSALPN == nil || ! issuer .Challenges .TLSALPN .Disabled {
232+ t .Fatalf ("expected tls-alpn challenge to be disabled, got %#v" , issuer .Challenges )
233+ }
234+ }
235+
236+ func TestMergeACMEIssuers (t * testing.T ) {
237+ base := & caddytls.ACMEIssuer {
238+ Email : "ops@example.com" ,
239+ Challenges : & caddytls.ChallengesConfig {
240+ HTTP : & caddytls.HTTPChallengeConfig {
241+ AlternatePort : 8080 ,
242+ },
243+ TLSALPN : & caddytls.TLSALPNChallengeConfig {
244+ Disabled : true ,
245+ AlternatePort : 8443 ,
246+ },
247+ DNS : & caddytls.DNSChallengeConfig {
248+ Resolvers : []string {"1.1.1.1" },
249+ OverrideDomain : "_acme-challenge.example.net" ,
250+ },
251+ },
252+ TrustedRootsPEMFiles : []string {"global.pem" },
253+ }
254+ overrides := & caddytls.ACMEIssuer {
255+ CA : "https://deglacme01.company.intern/acme/acme/directory" ,
256+ Challenges : & caddytls.ChallengesConfig {
257+ HTTP : & caddytls.HTTPChallengeConfig {
258+ Disabled : true ,
259+ },
260+ DNS : & caddytls.DNSChallengeConfig {
261+ PropagationTimeout : caddy .Duration (time .Minute ),
262+ },
263+ },
264+ TrustedRootsPEMFiles : []string {"site.pem" },
265+ }
266+
267+ merged := mergeACMEIssuers (base , overrides )
268+ if merged .CA != overrides .CA {
269+ t .Fatalf ("expected merged CA %q, got %q" , overrides .CA , merged .CA )
270+ }
271+ if merged .Email != base .Email {
272+ t .Fatalf ("expected merged email %q, got %q" , base .Email , merged .Email )
273+ }
274+ if len (merged .TrustedRootsPEMFiles ) != 2 || merged .TrustedRootsPEMFiles [0 ] != "global.pem" || merged .TrustedRootsPEMFiles [1 ] != "site.pem" {
275+ t .Fatalf ("expected merged roots [global.pem site.pem], got %v" , merged .TrustedRootsPEMFiles )
276+ }
277+ if merged .Challenges == nil || merged .Challenges .HTTP == nil || ! merged .Challenges .HTTP .Disabled || merged .Challenges .HTTP .AlternatePort != 8080 {
278+ t .Fatalf ("expected merged HTTP challenge config to preserve alternate port and apply disable flag, got %#v" , merged .Challenges )
279+ }
280+ if merged .Challenges .TLSALPN == nil || ! merged .Challenges .TLSALPN .Disabled || merged .Challenges .TLSALPN .AlternatePort != 8443 {
281+ t .Fatalf ("expected merged TLS-ALPN challenge config to preserve global settings, got %#v" , merged .Challenges )
282+ }
283+ if merged .Challenges .DNS == nil || merged .Challenges .DNS .PropagationTimeout != caddy .Duration (time .Minute ) || len (merged .Challenges .DNS .Resolvers ) != 1 || merged .Challenges .DNS .Resolvers [0 ] != "1.1.1.1" || merged .Challenges .DNS .OverrideDomain != "_acme-challenge.example.net" {
284+ t .Fatalf ("expected merged DNS challenge config to preserve global values and apply overrides, got %#v" , merged .Challenges )
285+ }
286+
287+ if base .CA != "" {
288+ t .Fatalf ("expected base issuer to remain unchanged, got CA %q" , base .CA )
289+ }
290+ if len (base .TrustedRootsPEMFiles ) != 1 || base .TrustedRootsPEMFiles [0 ] != "global.pem" {
291+ t .Fatalf ("expected base roots to remain unchanged, got %v" , base .TrustedRootsPEMFiles )
292+ }
293+ }
0 commit comments