2018-03-26 12:12:03 +00:00
package acme
import (
"crypto/tls"
"testing"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
)
func TestGetUncheckedCertificates ( t * testing . T ) {
wildcardMap := make ( map [ string ] * tls . Certificate )
wildcardMap [ "*.traefik.wtf" ] = & tls . Certificate { }
wildcardSafe := & safe . Safe { }
wildcardSafe . Set ( wildcardMap )
domainMap := make ( map [ string ] * tls . Certificate )
domainMap [ "traefik.wtf" ] = & tls . Certificate { }
domainSafe := & safe . Safe { }
domainSafe . Set ( domainMap )
testCases := [ ] struct {
desc string
dynamicCerts * safe . Safe
staticCerts map [ string ] * tls . Certificate
acmeCertificates [ ] * Certificate
domains [ ] string
expectedDomains [ ] string
} {
{
desc : "wildcard to generate" ,
domains : [ ] string { "*.traefik.wtf" } ,
expectedDomains : [ ] string { "*.traefik.wtf" } ,
} ,
{
desc : "wildcard already exists in dynamic certificates" ,
domains : [ ] string { "*.traefik.wtf" } ,
dynamicCerts : wildcardSafe ,
expectedDomains : nil ,
} ,
{
desc : "wildcard already exists in static certificates" ,
domains : [ ] string { "*.traefik.wtf" } ,
staticCerts : wildcardMap ,
expectedDomains : nil ,
} ,
{
desc : "wildcard already exists in ACME certificates" ,
domains : [ ] string { "*.traefik.wtf" } ,
acmeCertificates : [ ] * Certificate {
{
Domain : types . Domain { Main : "*.traefik.wtf" } ,
} ,
} ,
expectedDomains : nil ,
} ,
{
desc : "domain CN and SANs to generate" ,
domains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
expectedDomains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
} ,
{
desc : "domain CN already exists in dynamic certificates and SANs to generate" ,
domains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
dynamicCerts : domainSafe ,
expectedDomains : [ ] string { "foo.traefik.wtf" } ,
} ,
{
desc : "domain CN already exists in static certificates and SANs to generate" ,
domains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
staticCerts : domainMap ,
expectedDomains : [ ] string { "foo.traefik.wtf" } ,
} ,
{
desc : "domain CN already exists in ACME certificates and SANs to generate" ,
domains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
acmeCertificates : [ ] * Certificate {
{
Domain : types . Domain { Main : "traefik.wtf" } ,
} ,
} ,
expectedDomains : [ ] string { "foo.traefik.wtf" } ,
} ,
{
desc : "domain already exists in dynamic certificates" ,
domains : [ ] string { "traefik.wtf" } ,
dynamicCerts : domainSafe ,
expectedDomains : nil ,
} ,
{
desc : "domain already exists in static certificates" ,
domains : [ ] string { "traefik.wtf" } ,
staticCerts : domainMap ,
expectedDomains : nil ,
} ,
{
desc : "domain already exists in ACME certificates" ,
domains : [ ] string { "traefik.wtf" } ,
acmeCertificates : [ ] * Certificate {
{
Domain : types . Domain { Main : "traefik.wtf" } ,
} ,
} ,
expectedDomains : nil ,
} ,
{
desc : "domain matched by wildcard in dynamic certificates" ,
domains : [ ] string { "who.traefik.wtf" , "foo.traefik.wtf" } ,
dynamicCerts : wildcardSafe ,
expectedDomains : nil ,
} ,
{
desc : "domain matched by wildcard in static certificates" ,
domains : [ ] string { "who.traefik.wtf" , "foo.traefik.wtf" } ,
staticCerts : wildcardMap ,
expectedDomains : nil ,
} ,
{
desc : "domain matched by wildcard in ACME certificates" ,
domains : [ ] string { "who.traefik.wtf" , "foo.traefik.wtf" } ,
acmeCertificates : [ ] * Certificate {
{
Domain : types . Domain { Main : "*.traefik.wtf" } ,
} ,
} ,
expectedDomains : nil ,
} ,
{
desc : "root domain with wildcard in ACME certificates" ,
domains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
acmeCertificates : [ ] * Certificate {
{
Domain : types . Domain { Main : "*.traefik.wtf" } ,
} ,
} ,
expectedDomains : [ ] string { "traefik.wtf" } ,
} ,
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
acmeProvider := Provider {
dynamicCerts : test . dynamicCerts ,
staticCerts : test . staticCerts ,
certificates : test . acmeCertificates ,
}
domains := acmeProvider . getUncheckedDomains ( test . domains , false )
assert . Equal ( t , len ( test . expectedDomains ) , len ( domains ) , "Unexpected domains." )
} )
}
}
func TestGetValidDomain ( t * testing . T ) {
testCases := [ ] struct {
desc string
domains types . Domain
wildcardAllowed bool
dnsChallenge * DNSChallenge
expectedErr string
expectedDomains [ ] string
} {
{
desc : "valid wildcard" ,
domains : types . Domain { Main : "*.traefik.wtf" } ,
dnsChallenge : & DNSChallenge { } ,
wildcardAllowed : true ,
expectedErr : "" ,
expectedDomains : [ ] string { "*.traefik.wtf" } ,
} ,
{
desc : "no wildcard" ,
domains : types . Domain { Main : "traefik.wtf" , SANs : [ ] string { "foo.traefik.wtf" } } ,
dnsChallenge : & DNSChallenge { } ,
expectedErr : "" ,
wildcardAllowed : true ,
expectedDomains : [ ] string { "traefik.wtf" , "foo.traefik.wtf" } ,
} ,
{
desc : "unauthorized wildcard" ,
domains : types . Domain { Main : "*.traefik.wtf" } ,
dnsChallenge : & DNSChallenge { } ,
wildcardAllowed : false ,
expectedErr : "unable to generate a wildcard certificate in ACME provider for domain \"*.traefik.wtf\" from a 'Host' rule" ,
expectedDomains : nil ,
} ,
{
desc : "no domain" ,
domains : types . Domain { } ,
dnsChallenge : nil ,
wildcardAllowed : true ,
expectedErr : "unable to generate a certificate in ACME provider when no domain is given" ,
expectedDomains : nil ,
} ,
{
desc : "no DNSChallenge" ,
domains : types . Domain { Main : "*.traefik.wtf" , SANs : [ ] string { "foo.traefik.wtf" } } ,
dnsChallenge : nil ,
wildcardAllowed : true ,
expectedErr : "unable to generate a wildcard certificate in ACME provider for domain \"*.traefik.wtf,foo.traefik.wtf\" : ACME needs a DNSChallenge" ,
expectedDomains : nil ,
} ,
2018-04-11 15:16:07 +00:00
{
desc : "unauthorized wildcard with SAN" ,
domains : types . Domain { Main : "*.*.traefik.wtf" , SANs : [ ] string { "foo.traefik.wtf" } } ,
dnsChallenge : & DNSChallenge { } ,
wildcardAllowed : true ,
expectedErr : "unable to generate a wildcard certificate in ACME provider for domain \"*.*.traefik.wtf,foo.traefik.wtf\" : ACME does not allow '*.*' wildcard domain" ,
expectedDomains : nil ,
} ,
{
desc : "wildcard and SANs" ,
domains : types . Domain { Main : "*.traefik.wtf" , SANs : [ ] string { "traefik.wtf" } } ,
dnsChallenge : & DNSChallenge { } ,
wildcardAllowed : true ,
expectedErr : "" ,
expectedDomains : [ ] string { "*.traefik.wtf" , "traefik.wtf" } ,
} ,
2018-03-26 12:12:03 +00:00
{
desc : "unexpected SANs" ,
2018-04-11 15:16:07 +00:00
domains : types . Domain { Main : "*.traefik.wtf" , SANs : [ ] string { "*.acme.wtf" } } ,
2018-03-26 12:12:03 +00:00
dnsChallenge : & DNSChallenge { } ,
wildcardAllowed : true ,
2018-04-11 15:16:07 +00:00
expectedErr : "unable to generate a certificate in ACME provider for domains \"*.traefik.wtf,*.acme.wtf\": SAN \"*.acme.wtf\" can not be a wildcard domain" ,
2018-03-26 12:12:03 +00:00
expectedDomains : nil ,
} ,
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
acmeProvider := Provider { Configuration : & Configuration { DNSChallenge : test . dnsChallenge } }
domains , err := acmeProvider . getValidDomains ( test . domains , test . wildcardAllowed )
if len ( test . expectedErr ) > 0 {
assert . EqualError ( t , err , test . expectedErr , "Unexpected error." )
} else {
assert . Equal ( t , len ( test . expectedDomains ) , len ( domains ) , "Unexpected domains." )
}
} )
}
}
func TestDeleteUnnecessaryDomains ( t * testing . T ) {
testCases := [ ] struct {
desc string
domains [ ] types . Domain
expectedDomains [ ] types . Domain
} {
{
desc : "no domain to delete" ,
domains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "foo.bar" } ,
} ,
{
Main : "*.foo.acme.wtf" ,
} ,
{
2018-04-11 15:16:07 +00:00
Main : "acme02.wtf" ,
SANs : [ ] string { "traefik.acme02.wtf" , "bar.foo" } ,
2018-03-26 12:12:03 +00:00
} ,
} ,
expectedDomains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "foo.bar" } ,
} ,
{
Main : "*.foo.acme.wtf" ,
2018-04-11 15:16:07 +00:00
SANs : [ ] string { } ,
} ,
{
Main : "acme02.wtf" ,
SANs : [ ] string { "traefik.acme02.wtf" , "bar.foo" } ,
} ,
} ,
} ,
{
desc : "wildcard and root domain" ,
domains : [ ] types . Domain {
{
Main : "acme.wtf" ,
2018-03-26 12:12:03 +00:00
} ,
2018-04-11 15:16:07 +00:00
{
Main : "*.acme.wtf" ,
SANs : [ ] string { "acme.wtf" } ,
} ,
} ,
expectedDomains : [ ] types . Domain {
2018-03-26 12:12:03 +00:00
{
Main : "acme.wtf" ,
2018-04-11 15:16:07 +00:00
SANs : [ ] string { } ,
} ,
{
Main : "*.acme.wtf" ,
SANs : [ ] string { } ,
2018-03-26 12:12:03 +00:00
} ,
} ,
} ,
{
2018-04-11 15:16:07 +00:00
desc : "2 equals domains" ,
2018-03-26 12:12:03 +00:00
domains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "foo.bar" } ,
} ,
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "foo.bar" } ,
} ,
} ,
expectedDomains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "foo.bar" } ,
} ,
} ,
} ,
2018-04-11 15:16:07 +00:00
{
desc : "2 domains with same values" ,
domains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" } ,
} ,
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "foo.bar" } ,
} ,
} ,
expectedDomains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" } ,
} ,
{
Main : "foo.bar" ,
SANs : [ ] string { } ,
} ,
} ,
} ,
2018-03-26 12:12:03 +00:00
{
desc : "domain totally checked by wildcard" ,
domains : [ ] types . Domain {
{
Main : "who.acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "bar.acme.wtf" } ,
} ,
{
Main : "*.acme.wtf" ,
} ,
} ,
expectedDomains : [ ] types . Domain {
{
Main : "*.acme.wtf" ,
2018-04-11 15:16:07 +00:00
SANs : [ ] string { } ,
} ,
} ,
} ,
{
desc : "duplicated wildcard" ,
domains : [ ] types . Domain {
{
Main : "*.acme.wtf" ,
SANs : [ ] string { "acme.wtf" } ,
} ,
{
Main : "*.acme.wtf" ,
} ,
} ,
expectedDomains : [ ] types . Domain {
{
Main : "*.acme.wtf" ,
SANs : [ ] string { "acme.wtf" } ,
2018-03-26 12:12:03 +00:00
} ,
} ,
} ,
{
desc : "domain partially checked by wildcard" ,
domains : [ ] types . Domain {
{
Main : "traefik.acme.wtf" ,
SANs : [ ] string { "acme.wtf" , "foo.bar" } ,
} ,
{
Main : "*.acme.wtf" ,
} ,
2018-04-11 15:16:07 +00:00
{
Main : "who.acme.wtf" ,
SANs : [ ] string { "traefik.acme.wtf" , "bar.acme.wtf" } ,
} ,
2018-03-26 12:12:03 +00:00
} ,
expectedDomains : [ ] types . Domain {
{
Main : "acme.wtf" ,
SANs : [ ] string { "foo.bar" } ,
} ,
{
Main : "*.acme.wtf" ,
2018-04-11 15:16:07 +00:00
SANs : [ ] string { } ,
2018-03-26 12:12:03 +00:00
} ,
} ,
} ,
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
acmeProvider := Provider { Configuration : & Configuration { Domains : test . domains } }
acmeProvider . deleteUnnecessaryDomains ( )
assert . Equal ( t , test . expectedDomains , acmeProvider . Domains , "unexpected domain" )
} )
}
}