@ -27,83 +27,18 @@ func testNext(w http.ResponseWriter, r *http.Request) {
w . Write ( testBody )
w . Write ( testBody )
}
}
func Test_baseURLFromRequest ( t * testing . T ) {
func newBaseContext ( ctx context . Context , args ... interface { } ) context . Context {
tests := [ ] struct {
for _ , a := range args {
name string
switch v := a . ( type ) {
targetURL string
case acme . DB :
expectedResult * url . URL
ctx = acme . NewDatabaseContext ( ctx , v )
requestPreparer func ( * http . Request )
case acme . Linker :
} {
ctx = acme . NewLinkerContext ( ctx , v )
{
case acme . PrerequisitesChecker :
"HTTPS host pass-through failed." ,
ctx = acme . NewPrerequisitesCheckerContext ( ctx , v )
"https://my.dummy.host" ,
& url . URL { Scheme : "https" , Host : "my.dummy.host" } ,
nil ,
} ,
{
"Port pass-through failed" ,
"https://host.with.port:8080" ,
& url . URL { Scheme : "https" , Host : "host.with.port:8080" } ,
nil ,
} ,
{
"Explicit host from Request.Host was not used." ,
"https://some.target.host:8080" ,
& url . URL { Scheme : "https" , Host : "proxied.host" } ,
func ( r * http . Request ) {
r . Host = "proxied.host"
} ,
} ,
{
"Missing Request.Host value did not result in empty string result." ,
"https://some.host" ,
nil ,
func ( r * http . Request ) {
r . Host = ""
} ,
} ,
}
for _ , tc := range tests {
t . Run ( tc . name , func ( t * testing . T ) {
request := httptest . NewRequest ( "GET" , tc . targetURL , nil )
if tc . requestPreparer != nil {
tc . requestPreparer ( request )
}
result := getBaseURLFromRequest ( request )
if result == nil || tc . expectedResult == nil {
assert . Equals ( t , result , tc . expectedResult )
} else if result . String ( ) != tc . expectedResult . String ( ) {
t . Errorf ( "Expected %q, but got %q" , tc . expectedResult . String ( ) , result . String ( ) )
}
} )
}
}
func TestHandler_baseURLFromRequest ( t * testing . T ) {
// h := &Handler{}
req := httptest . NewRequest ( "GET" , "/foo" , nil )
req . Host = "test.ca.smallstep.com:8080"
w := httptest . NewRecorder ( )
next := func ( w http . ResponseWriter , r * http . Request ) {
bu := baseURLFromContext ( r . Context ( ) )
if assert . NotNil ( t , bu ) {
assert . Equals ( t , bu . Host , "test.ca.smallstep.com:8080" )
assert . Equals ( t , bu . Scheme , "https" )
}
}
}
}
return ctx
baseURLFromRequest ( next ) ( w , req )
req = httptest . NewRequest ( "GET" , "/foo" , nil )
req . Host = ""
next = func ( w http . ResponseWriter , r * http . Request ) {
assert . Equals ( t , baseURLFromContext ( r . Context ( ) ) , nil )
}
baseURLFromRequest ( next ) ( w , req )
}
}
func TestHandler_addNonce ( t * testing . T ) {
func TestHandler_addNonce ( t * testing . T ) {
@ -139,8 +74,8 @@ func TestHandler_addNonce(t *testing.T) {
for name , run := range tests {
for name , run := range tests {
tc := run ( t )
tc := run ( t )
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
// h := &Handler{db: tc.db}
ctx := newBaseContext ( context . Background ( ) , tc . db )
req := httptest . NewRequest ( "GET" , u , nil )
req := httptest . NewRequest ( "GET" , u , nil ) . WithContext ( ctx )
w := httptest . NewRecorder ( )
w := httptest . NewRecorder ( )
addNonce ( testNext ) ( w , req )
addNonce ( testNext ) ( w , req )
res := w . Result ( )
res := w . Result ( )
@ -175,17 +110,15 @@ func TestHandler_addDirLink(t *testing.T) {
baseURL := & url . URL { Scheme : "https" , Host : "test.ca.smallstep.com" }
baseURL := & url . URL { Scheme : "https" , Host : "test.ca.smallstep.com" }
type test struct {
type test struct {
link string
link string
linker Linker
statusCode int
statusCode int
ctx context . Context
ctx context . Context
err * acme . Error
err * acme . Error
}
}
var tests = map [ string ] func ( t * testing . T ) test {
var tests = map [ string ] func ( t * testing . T ) test {
"ok" : func ( t * testing . T ) test {
"ok" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context. WithValue ( ctx , baseURLContextKey , baseURL )
ctx = acme. NewLinkerContext ( ctx , acme . NewLinker ( "test.ca.smallstep.com" , "acme" ) )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
link : fmt . Sprintf ( "%s/acme/%s/directory" , baseURL . String ( ) , provName ) ,
link : fmt . Sprintf ( "%s/acme/%s/directory" , baseURL . String ( ) , provName ) ,
statusCode : 200 ,
statusCode : 200 ,
@ -195,7 +128,6 @@ func TestHandler_addDirLink(t *testing.T) {
for name , run := range tests {
for name , run := range tests {
tc := run ( t )
tc := run ( t )
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
// h := &Handler{linker: tc.linker}
req := httptest . NewRequest ( "GET" , "/foo" , nil )
req := httptest . NewRequest ( "GET" , "/foo" , nil )
req = req . WithContext ( tc . ctx )
req = req . WithContext ( tc . ctx )
w := httptest . NewRecorder ( )
w := httptest . NewRecorder ( )
@ -231,7 +163,6 @@ func TestHandler_verifyContentType(t *testing.T) {
baseURL := & url . URL { Scheme : "https" , Host : "test.ca.smallstep.com" }
baseURL := & url . URL { Scheme : "https" , Host : "test.ca.smallstep.com" }
u := fmt . Sprintf ( "%s/acme/%s/certificate/abc123" , baseURL . String ( ) , escProvName )
u := fmt . Sprintf ( "%s/acme/%s/certificate/abc123" , baseURL . String ( ) , escProvName )
type test struct {
type test struct {
h Handler
ctx context . Context
ctx context . Context
contentType string
contentType string
err * acme . Error
err * acme . Error
@ -241,9 +172,6 @@ func TestHandler_verifyContentType(t *testing.T) {
var tests = map [ string ] func ( t * testing . T ) test {
var tests = map [ string ] func ( t * testing . T ) test {
"fail/provisioner-not-set" : func ( t * testing . T ) test {
"fail/provisioner-not-set" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
// linker: NewLinker("dns", "acme"),
} ,
url : u ,
url : u ,
ctx : context . Background ( ) ,
ctx : context . Background ( ) ,
contentType : "foo" ,
contentType : "foo" ,
@ -253,11 +181,8 @@ func TestHandler_verifyContentType(t *testing.T) {
} ,
} ,
"fail/general-bad-content-type" : func ( t * testing . T ) test {
"fail/general-bad-content-type" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
// linker: NewLinker("dns", "acme"),
} ,
url : u ,
url : u ,
ctx : context. WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
contentType : "foo" ,
contentType : "foo" ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "expected content-type to be in [application/jose+json], but got foo" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "expected content-type to be in [application/jose+json], but got foo" ) ,
@ -265,10 +190,7 @@ func TestHandler_verifyContentType(t *testing.T) {
} ,
} ,
"fail/certificate-bad-content-type" : func ( t * testing . T ) test {
"fail/certificate-bad-content-type" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
// linker: NewLinker("dns", "acme"),
} ,
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
contentType : "foo" ,
contentType : "foo" ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "expected content-type to be in [application/jose+json application/pkix-cert application/pkcs7-mime], but got foo" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "expected content-type to be in [application/jose+json application/pkix-cert application/pkcs7-mime], but got foo" ) ,
@ -276,40 +198,28 @@ func TestHandler_verifyContentType(t *testing.T) {
} ,
} ,
"ok" : func ( t * testing . T ) test {
"ok" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
// linker: NewLinker("dns", "acme"),
} ,
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
contentType : "application/jose+json" ,
contentType : "application/jose+json" ,
statusCode : 200 ,
statusCode : 200 ,
}
}
} ,
} ,
"ok/certificate/pkix-cert" : func ( t * testing . T ) test {
"ok/certificate/pkix-cert" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
// linker: NewLinker("dns", "acme"),
} ,
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
contentType : "application/pkix-cert" ,
contentType : "application/pkix-cert" ,
statusCode : 200 ,
statusCode : 200 ,
}
}
} ,
} ,
"ok/certificate/jose+json" : func ( t * testing . T ) test {
"ok/certificate/jose+json" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
// linker: NewLinker("dns", "acme"),
} ,
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
contentType : "application/jose+json" ,
contentType : "application/jose+json" ,
statusCode : 200 ,
statusCode : 200 ,
}
}
} ,
} ,
"ok/certificate/pkcs7-mime" : func ( t * testing . T ) test {
"ok/certificate/pkcs7-mime" : func ( t * testing . T ) test {
return test {
return test {
h : Handler {
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
// linker: NewLinker("dns", "acme"),
} ,
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
contentType : "application/pkcs7-mime" ,
contentType : "application/pkcs7-mime" ,
statusCode : 200 ,
statusCode : 200 ,
}
}
@ -733,7 +643,7 @@ func TestHandler_lookupJWK(t *testing.T) {
parsedJWS , err := jose . ParseJWS ( raw )
parsedJWS , err := jose . ParseJWS ( raw )
assert . FatalError ( t , err )
assert . FatalError ( t , err )
type test struct {
type test struct {
linker Linker
linker acme. Linker
db acme . DB
db acme . DB
ctx context . Context
ctx context . Context
next func ( http . ResponseWriter , * http . Request )
next func ( http . ResponseWriter , * http . Request )
@ -743,15 +653,19 @@ func TestHandler_lookupJWK(t *testing.T) {
var tests = map [ string ] func ( t * testing . T ) test {
var tests = map [ string ] func ( t * testing . T ) test {
"fail/no-jws" : func ( t * testing . T ) test {
"fail/no-jws" : func ( t * testing . T ) test {
return test {
return test {
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
db : & acme . MockDB { } ,
linker : acme . NewLinker ( "test.ca.smallstep.com" , "acme" ) ,
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
statusCode : 500 ,
statusCode : 500 ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
}
}
} ,
} ,
"fail/nil-jws" : func ( t * testing . T ) test {
"fail/nil-jws" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , nil )
ctx = context . WithValue ( ctx , jwsContextKey , nil )
return test {
return test {
db : & acme . MockDB { } ,
linker : acme . NewLinker ( "test.ca.smallstep.com" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
statusCode : 500 ,
statusCode : 500 ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
@ -765,11 +679,11 @@ func TestHandler_lookupJWK(t *testing.T) {
assert . FatalError ( t , err )
assert . FatalError ( t , err )
_jws , err := _signer . Sign ( [ ] byte ( "baz" ) )
_jws , err := _signer . Sign ( [ ] byte ( "baz" ) )
assert . FatalError ( t , err )
assert . FatalError ( t , err )
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , _jws )
ctx = context . WithValue ( ctx , jwsContextKey , _jws )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
db : & acme . MockDB { } ,
linker : acme . NewLinker ( "test.ca.smallstep.com" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "kid does not have required prefix; expected %s, but got " , prefix ) ,
err : acme . NewError ( acme . ErrorMalformedType , "kid does not have required prefix; expected %s, but got " , prefix ) ,
@ -789,22 +703,21 @@ func TestHandler_lookupJWK(t *testing.T) {
assert . FatalError ( t , err )
assert . FatalError ( t , err )
_parsed , err := jose . ParseJWS ( _raw )
_parsed , err := jose . ParseJWS ( _raw )
assert . FatalError ( t , err )
assert . FatalError ( t , err )
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , _parsed )
ctx = context . WithValue ( ctx , jwsContextKey , _parsed )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
db : & acme . MockDB { } ,
linker : acme . NewLinker ( "test.ca.smallstep.com" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "kid does not have required prefix; expected %s, but got foo" , prefix ) ,
err : acme . NewError ( acme . ErrorMalformedType , "kid does not have required prefix; expected %s, but got foo" , prefix ) ,
}
}
} ,
} ,
"fail/account-not-found" : func ( t * testing . T ) test {
"fail/account-not-found" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns ", "acme" ) ,
linker : acme . NewLinker ( "test.ca.smallstep.com ", "acme" ) ,
db : & acme . MockDB {
db : & acme . MockDB {
MockGetAccount : func ( ctx context . Context , accID string ) ( * acme . Account , error ) {
MockGetAccount : func ( ctx context . Context , accID string ) ( * acme . Account , error ) {
assert . Equals ( t , accID , accID )
assert . Equals ( t , accID , accID )
@ -817,11 +730,10 @@ func TestHandler_lookupJWK(t *testing.T) {
}
}
} ,
} ,
"fail/GetAccount-error" : func ( t * testing . T ) test {
"fail/GetAccount-error" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns ", "acme" ) ,
linker : acme . NewLinker ( "test.ca.smallstep.com ", "acme" ) ,
db : & acme . MockDB {
db : & acme . MockDB {
MockGetAccount : func ( ctx context . Context , id string ) ( * acme . Account , error ) {
MockGetAccount : func ( ctx context . Context , id string ) ( * acme . Account , error ) {
assert . Equals ( t , id , accID )
assert . Equals ( t , id , accID )
@ -835,11 +747,10 @@ func TestHandler_lookupJWK(t *testing.T) {
} ,
} ,
"fail/account-not-valid" : func ( t * testing . T ) test {
"fail/account-not-valid" : func ( t * testing . T ) test {
acc := & acme . Account { Status : "deactivated" }
acc := & acme . Account { Status : "deactivated" }
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns ", "acme" ) ,
linker : acme . NewLinker ( "test.ca.smallstep.com ", "acme" ) ,
db : & acme . MockDB {
db : & acme . MockDB {
MockGetAccount : func ( ctx context . Context , id string ) ( * acme . Account , error ) {
MockGetAccount : func ( ctx context . Context , id string ) ( * acme . Account , error ) {
assert . Equals ( t , id , accID )
assert . Equals ( t , id , accID )
@ -853,11 +764,10 @@ func TestHandler_lookupJWK(t *testing.T) {
} ,
} ,
"ok" : func ( t * testing . T ) test {
"ok" : func ( t * testing . T ) test {
acc := & acme . Account { Status : "valid" , Key : jwk }
acc := & acme . Account { Status : "valid" , Key : jwk }
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns ", "acme" ) ,
linker : acme . NewLinker ( "test.ca.smallstep.com ", "acme" ) ,
db : & acme . MockDB {
db : & acme . MockDB {
MockGetAccount : func ( ctx context . Context , id string ) ( * acme . Account , error ) {
MockGetAccount : func ( ctx context . Context , id string ) ( * acme . Account , error ) {
assert . Equals ( t , id , accID )
assert . Equals ( t , id , accID )
@ -881,9 +791,9 @@ func TestHandler_lookupJWK(t *testing.T) {
for name , run := range tests {
for name , run := range tests {
tc := run ( t )
tc := run ( t )
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
// h := &Handler{db: tc.db, linker: tc.linker}
ctx := newBaseContext ( tc . ctx , tc . db , tc . linker )
req := httptest . NewRequest ( "GET" , u , nil )
req := httptest . NewRequest ( "GET" , u , nil )
req = req . WithContext ( tc. ctx)
req = req . WithContext ( ctx)
w := httptest . NewRecorder ( )
w := httptest . NewRecorder ( )
lookupJWK ( tc . next ) ( w , req )
lookupJWK ( tc . next ) ( w , req )
res := w . Result ( )
res := w . Result ( )
@ -945,15 +855,17 @@ func TestHandler_extractJWK(t *testing.T) {
var tests = map [ string ] func ( t * testing . T ) test {
var tests = map [ string ] func ( t * testing . T ) test {
"fail/no-jws" : func ( t * testing . T ) test {
"fail/no-jws" : func ( t * testing . T ) test {
return test {
return test {
ctx : context . WithValue ( context . Background ( ) , provisionerContextKey , prov ) ,
db : & acme . MockDB { } ,
ctx : acme . NewProvisionerContext ( context . Background ( ) , prov ) ,
statusCode : 500 ,
statusCode : 500 ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
}
}
} ,
} ,
"fail/nil-jws" : func ( t * testing . T ) test {
"fail/nil-jws" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , nil )
ctx = context . WithValue ( ctx , jwsContextKey , nil )
return test {
return test {
db : & acme . MockDB { } ,
ctx : ctx ,
ctx : ctx ,
statusCode : 500 ,
statusCode : 500 ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
@ -969,9 +881,10 @@ func TestHandler_extractJWK(t *testing.T) {
} ,
} ,
} ,
} ,
}
}
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , _jws )
ctx = context . WithValue ( ctx , jwsContextKey , _jws )
return test {
return test {
db : & acme . MockDB { } ,
ctx : ctx ,
ctx : ctx ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "jwk expected in protected header" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "jwk expected in protected header" ) ,
@ -987,16 +900,17 @@ func TestHandler_extractJWK(t *testing.T) {
} ,
} ,
} ,
} ,
}
}
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , _jws )
ctx = context . WithValue ( ctx , jwsContextKey , _jws )
return test {
return test {
db : & acme . MockDB { } ,
ctx : ctx ,
ctx : ctx ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "invalid jwk in protected header" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "invalid jwk in protected header" ) ,
}
}
} ,
} ,
"fail/GetAccountByKey-error" : func ( t * testing . T ) test {
"fail/GetAccountByKey-error" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
return test {
return test {
ctx : ctx ,
ctx : ctx ,
@ -1012,7 +926,7 @@ func TestHandler_extractJWK(t *testing.T) {
} ,
} ,
"fail/account-not-valid" : func ( t * testing . T ) test {
"fail/account-not-valid" : func ( t * testing . T ) test {
acc := & acme . Account { Status : "deactivated" }
acc := & acme . Account { Status : "deactivated" }
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
return test {
return test {
ctx : ctx ,
ctx : ctx ,
@ -1028,7 +942,7 @@ func TestHandler_extractJWK(t *testing.T) {
} ,
} ,
"ok" : func ( t * testing . T ) test {
"ok" : func ( t * testing . T ) test {
acc := & acme . Account { Status : "valid" }
acc := & acme . Account { Status : "valid" }
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
return test {
return test {
ctx : ctx ,
ctx : ctx ,
@ -1051,7 +965,7 @@ func TestHandler_extractJWK(t *testing.T) {
}
}
} ,
} ,
"ok/no-account" : func ( t * testing . T ) test {
"ok/no-account" : func ( t * testing . T ) test {
ctx := context. WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme. NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
return test {
return test {
ctx : ctx ,
ctx : ctx ,
@ -1077,9 +991,9 @@ func TestHandler_extractJWK(t *testing.T) {
for name , run := range tests {
for name , run := range tests {
tc := run ( t )
tc := run ( t )
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
// h := &Handler{db: tc.db}
ctx := newBaseContext ( tc . ctx , tc . db )
req := httptest . NewRequest ( "GET" , u , nil )
req := httptest . NewRequest ( "GET" , u , nil )
req = req . WithContext ( tc. ctx)
req = req . WithContext ( ctx)
w := httptest . NewRecorder ( )
w := httptest . NewRecorder ( )
extractJWK ( tc . next ) ( w , req )
extractJWK ( tc . next ) ( w , req )
res := w . Result ( )
res := w . Result ( )
@ -1118,6 +1032,7 @@ func TestHandler_validateJWS(t *testing.T) {
var tests = map [ string ] func ( t * testing . T ) test {
var tests = map [ string ] func ( t * testing . T ) test {
"fail/no-jws" : func ( t * testing . T ) test {
"fail/no-jws" : func ( t * testing . T ) test {
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . Background ( ) ,
ctx : context . Background ( ) ,
statusCode : 500 ,
statusCode : 500 ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
@ -1125,6 +1040,7 @@ func TestHandler_validateJWS(t *testing.T) {
} ,
} ,
"fail/nil-jws" : func ( t * testing . T ) test {
"fail/nil-jws" : func ( t * testing . T ) test {
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , nil ) ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , nil ) ,
statusCode : 500 ,
statusCode : 500 ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
err : acme . NewErrorISE ( "jws expected in request context" ) ,
@ -1132,6 +1048,7 @@ func TestHandler_validateJWS(t *testing.T) {
} ,
} ,
"fail/no-signature" : func ( t * testing . T ) test {
"fail/no-signature" : func ( t * testing . T ) test {
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , & jose . JSONWebSignature { } ) ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , & jose . JSONWebSignature { } ) ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "request body does not contain a signature" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "request body does not contain a signature" ) ,
@ -1145,6 +1062,7 @@ func TestHandler_validateJWS(t *testing.T) {
} ,
} ,
}
}
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "request body contains more than one signature" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "request body contains more than one signature" ) ,
@ -1157,6 +1075,7 @@ func TestHandler_validateJWS(t *testing.T) {
} ,
} ,
}
}
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorMalformedType , "unprotected header must not be used" ) ,
err : acme . NewError ( acme . ErrorMalformedType , "unprotected header must not be used" ) ,
@ -1169,6 +1088,7 @@ func TestHandler_validateJWS(t *testing.T) {
} ,
} ,
}
}
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorBadSignatureAlgorithmType , "unsuitable algorithm: none" ) ,
err : acme . NewError ( acme . ErrorBadSignatureAlgorithmType , "unsuitable algorithm: none" ) ,
@ -1181,6 +1101,7 @@ func TestHandler_validateJWS(t *testing.T) {
} ,
} ,
}
}
return test {
return test {
db : & acme . MockDB { } ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
ctx : context . WithValue ( context . Background ( ) , jwsContextKey , jws ) ,
statusCode : 400 ,
statusCode : 400 ,
err : acme . NewError ( acme . ErrorBadSignatureAlgorithmType , "unsuitable algorithm: %s" , jose . HS256 ) ,
err : acme . NewError ( acme . ErrorBadSignatureAlgorithmType , "unsuitable algorithm: %s" , jose . HS256 ) ,
@ -1444,9 +1365,9 @@ func TestHandler_validateJWS(t *testing.T) {
for name , run := range tests {
for name , run := range tests {
tc := run ( t )
tc := run ( t )
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
// h := &Handler{db: tc.db}
ctx := newBaseContext ( tc . ctx , tc . db )
req := httptest . NewRequest ( "GET" , u , nil )
req := httptest . NewRequest ( "GET" , u , nil )
req = req . WithContext ( tc. ctx)
req = req . WithContext ( ctx)
w := httptest . NewRecorder ( )
w := httptest . NewRecorder ( )
validateJWS ( tc . next ) ( w , req )
validateJWS ( tc . next ) ( w , req )
res := w . Result ( )
res := w . Result ( )
@ -1542,7 +1463,7 @@ func TestHandler_extractOrLookupJWK(t *testing.T) {
u := "https://ca.smallstep.com/acme/account"
u := "https://ca.smallstep.com/acme/account"
type test struct {
type test struct {
db acme . DB
db acme . DB
linker Linker
linker acme. Linker
statusCode int
statusCode int
ctx context . Context
ctx context . Context
err * acme . Error
err * acme . Error
@ -1570,7 +1491,7 @@ func TestHandler_extractOrLookupJWK(t *testing.T) {
parsedJWS , err := jose . ParseJWS ( raw )
parsedJWS , err := jose . ParseJWS ( raw )
assert . FatalError ( t , err )
assert . FatalError ( t , err )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
linker : acme . NewLinker ( "dns" , "acme" ) ,
db : & acme . MockDB {
db : & acme . MockDB {
MockGetAccountByKeyID : func ( ctx context . Context , kid string ) ( * acme . Account , error ) {
MockGetAccountByKeyID : func ( ctx context . Context , kid string ) ( * acme . Account , error ) {
assert . Equals ( t , kid , pub . KeyID )
assert . Equals ( t , kid , pub . KeyID )
@ -1606,11 +1527,10 @@ func TestHandler_extractOrLookupJWK(t *testing.T) {
parsedJWS , err := jose . ParseJWS ( raw )
parsedJWS , err := jose . ParseJWS ( raw )
assert . FatalError ( t , err )
assert . FatalError ( t , err )
acc := & acme . Account { ID : "accID" , Key : jwk , Status : "valid" }
acc := & acme . Account { ID : "accID" , Key : jwk , Status : "valid" }
ctx := context . WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme . NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
ctx = context . WithValue ( ctx , jwsContextKey , parsedJWS )
return test {
return test {
linker : NewLinker ( "test.ca.smallstep.com" , "acme" ) ,
linker : acme . NewLinker ( "test.ca.smallstep.com" , "acme" ) ,
db : & acme . MockDB {
db : & acme . MockDB {
MockGetAccount : func ( ctx context . Context , accID string ) ( * acme . Account , error ) {
MockGetAccount : func ( ctx context . Context , accID string ) ( * acme . Account , error ) {
assert . Equals ( t , accID , acc . ID )
assert . Equals ( t , accID , acc . ID )
@ -1628,9 +1548,9 @@ func TestHandler_extractOrLookupJWK(t *testing.T) {
for name , prep := range tests {
for name , prep := range tests {
tc := prep ( t )
tc := prep ( t )
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
// h := &Handler{db: tc.db, linker: tc.linker}
ctx := newBaseContext ( tc . ctx , tc . db , tc . linker )
req := httptest . NewRequest ( "GET" , u , nil )
req := httptest . NewRequest ( "GET" , u , nil )
req = req . WithContext ( tc. ctx)
req = req . WithContext ( ctx)
w := httptest . NewRecorder ( )
w := httptest . NewRecorder ( )
extractOrLookupJWK ( tc . next ) ( w , req )
extractOrLookupJWK ( tc . next ) ( w , req )
res := w . Result ( )
res := w . Result ( )
@ -1664,7 +1584,7 @@ func TestHandler_checkPrerequisites(t *testing.T) {
u := fmt . Sprintf ( "%s/acme/%s/account/1234" ,
u := fmt . Sprintf ( "%s/acme/%s/account/1234" ,
baseURL , provName )
baseURL , provName )
type test struct {
type test struct {
linker Linker
linker acme. Linker
ctx context . Context
ctx context . Context
prerequisitesChecker func ( context . Context ) ( bool , error )
prerequisitesChecker func ( context . Context ) ( bool , error )
next func ( http . ResponseWriter , * http . Request )
next func ( http . ResponseWriter , * http . Request )
@ -1673,10 +1593,9 @@ func TestHandler_checkPrerequisites(t *testing.T) {
}
}
var tests = map [ string ] func ( t * testing . T ) test {
var tests = map [ string ] func ( t * testing . T ) test {
"fail/error" : func ( t * testing . T ) test {
"fail/error" : func ( t * testing . T ) test {
ctx := context . WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme . NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
linker : acme . NewLinker ( "dns" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
prerequisitesChecker : func ( context . Context ) ( bool , error ) { return false , errors . New ( "force" ) } ,
prerequisitesChecker : func ( context . Context ) ( bool , error ) { return false , errors . New ( "force" ) } ,
next : func ( w http . ResponseWriter , r * http . Request ) {
next : func ( w http . ResponseWriter , r * http . Request ) {
@ -1687,10 +1606,9 @@ func TestHandler_checkPrerequisites(t *testing.T) {
}
}
} ,
} ,
"fail/prerequisites-nok" : func ( t * testing . T ) test {
"fail/prerequisites-nok" : func ( t * testing . T ) test {
ctx := context . WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme . NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
linker : acme . NewLinker ( "dns" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
prerequisitesChecker : func ( context . Context ) ( bool , error ) { return false , nil } ,
prerequisitesChecker : func ( context . Context ) ( bool , error ) { return false , nil } ,
next : func ( w http . ResponseWriter , r * http . Request ) {
next : func ( w http . ResponseWriter , r * http . Request ) {
@ -1701,10 +1619,9 @@ func TestHandler_checkPrerequisites(t *testing.T) {
}
}
} ,
} ,
"ok" : func ( t * testing . T ) test {
"ok" : func ( t * testing . T ) test {
ctx := context . WithValue ( context . Background ( ) , provisionerContextKey , prov )
ctx := acme . NewProvisionerContext ( context . Background ( ) , prov )
ctx = context . WithValue ( ctx , baseURLContextKey , baseURL )
return test {
return test {
linker : NewLinker ( "dns" , "acme" ) ,
linker : acme . NewLinker ( "dns" , "acme" ) ,
ctx : ctx ,
ctx : ctx ,
prerequisitesChecker : func ( context . Context ) ( bool , error ) { return true , nil } ,
prerequisitesChecker : func ( context . Context ) ( bool , error ) { return true , nil } ,
next : func ( w http . ResponseWriter , r * http . Request ) {
next : func ( w http . ResponseWriter , r * http . Request ) {