2019-05-27 00:41:10 +00:00
package acme
import (
2021-03-24 23:50:35 +00:00
"crypto"
"encoding/base64"
"testing"
2021-10-08 11:18:23 +00:00
"time"
2019-05-27 00:41:10 +00:00
2021-03-24 23:50:35 +00:00
"github.com/pkg/errors"
"go.step.sm/crypto/jose"
2022-04-26 08:15:17 +00:00
"github.com/smallstep/assert"
2019-05-27 00:41:10 +00:00
)
2021-03-24 23:50:35 +00:00
func TestKeyToID ( t * testing . T ) {
2019-05-27 00:41:10 +00:00
type test struct {
2021-03-24 23:50:35 +00:00
jwk * jose . JSONWebKey
exp string
2019-05-27 00:41:10 +00:00
err * Error
}
tests := map [ string ] func ( t * testing . T ) test {
2021-03-24 23:50:35 +00:00
"fail/error-generating-thumbprint" : func ( t * testing . T ) test {
jwk , err := jose . GenerateJWK ( "EC" , "P-256" , "ES256" , "sig" , "" , 0 )
2019-05-27 00:41:10 +00:00
assert . FatalError ( t , err )
2021-03-24 23:50:35 +00:00
jwk . Key = "foo"
2019-05-27 00:41:10 +00:00
return test {
2021-03-24 23:50:35 +00:00
jwk : jwk ,
2023-12-13 00:36:48 +00:00
err : NewErrorISE ( "error generating jwk thumbprint: go-jose/go-jose: unknown key type 'string'" ) ,
2019-05-27 00:41:10 +00:00
}
} ,
"ok" : func ( t * testing . T ) test {
2021-03-24 23:50:35 +00:00
jwk , err := jose . GenerateJWK ( "EC" , "P-256" , "ES256" , "sig" , "" , 0 )
2019-05-27 00:41:10 +00:00
assert . FatalError ( t , err )
2021-03-24 23:50:35 +00:00
kid , err := jwk . Thumbprint ( crypto . SHA256 )
2019-05-27 00:41:10 +00:00
assert . FatalError ( t , err )
return test {
2021-03-24 23:50:35 +00:00
jwk : jwk ,
exp : base64 . RawURLEncoding . EncodeToString ( kid ) ,
2019-05-27 00:41:10 +00:00
}
} ,
}
for name , run := range tests {
t . Run ( name , func ( t * testing . T ) {
tc := run ( t )
2021-03-24 23:50:35 +00:00
if id , err := KeyToID ( tc . jwk ) ; err != nil {
2019-05-27 00:41:10 +00:00
if assert . NotNil ( t , tc . err ) {
2022-08-23 19:43:48 +00:00
var k * Error
if errors . As ( err , & k ) {
2021-03-24 23:50:35 +00:00
assert . Equals ( t , k . Type , tc . err . Type )
assert . Equals ( t , k . Detail , tc . err . Detail )
assert . Equals ( t , k . Status , tc . err . Status )
assert . Equals ( t , k . Err . Error ( ) , tc . err . Err . Error ( ) )
assert . Equals ( t , k . Detail , tc . err . Detail )
2022-08-23 19:43:48 +00:00
} else {
2021-03-24 23:50:35 +00:00
assert . FatalError ( t , errors . New ( "unexpected error type" ) )
}
2019-05-27 00:41:10 +00:00
}
} else {
if assert . Nil ( t , tc . err ) {
2021-03-24 23:50:35 +00:00
assert . Equals ( t , id , tc . exp )
2019-05-27 00:41:10 +00:00
}
}
} )
}
}
2023-06-07 06:37:51 +00:00
func TestAccount_GetLocation ( t * testing . T ) {
locationPrefix := "https://test.ca.smallstep.com/acme/foo/account/"
type test struct {
acc * Account
exp string
}
tests := map [ string ] test {
"empty" : { acc : & Account { LocationPrefix : "" } , exp : "" } ,
"not-empty" : { acc : & Account { ID : "bar" , LocationPrefix : locationPrefix } , exp : locationPrefix + "bar" } ,
}
for name , tc := range tests {
t . Run ( name , func ( t * testing . T ) {
assert . Equals ( t , tc . acc . GetLocation ( ) , tc . exp )
} )
}
}
2021-03-24 23:50:35 +00:00
func TestAccount_IsValid ( t * testing . T ) {
2019-05-27 00:41:10 +00:00
type test struct {
2021-03-24 23:50:35 +00:00
acc * Account
exp bool
2019-05-27 00:41:10 +00:00
}
2021-03-24 23:50:35 +00:00
tests := map [ string ] test {
"valid" : { acc : & Account { Status : StatusValid } , exp : true } ,
"invalid" : { acc : & Account { Status : StatusInvalid } , exp : false } ,
2019-05-27 00:41:10 +00:00
}
2021-03-24 23:50:35 +00:00
for name , tc := range tests {
2019-05-27 00:41:10 +00:00
t . Run ( name , func ( t * testing . T ) {
2021-03-24 23:50:35 +00:00
assert . Equals ( t , tc . acc . IsValid ( ) , tc . exp )
2019-05-27 00:41:10 +00:00
} )
}
}
2021-10-08 11:18:23 +00:00
func TestExternalAccountKey_BindTo ( t * testing . T ) {
boundAt := time . Now ( )
tests := [ ] struct {
name string
eak * ExternalAccountKey
acct * Account
err * Error
} {
{
name : "ok" ,
eak : & ExternalAccountKey {
2022-01-07 15:59:55 +00:00
ID : "eakID" ,
ProvisionerID : "provID" ,
Reference : "ref" ,
2022-04-26 08:15:17 +00:00
HmacKey : [ ] byte { 1 , 3 , 3 , 7 } ,
2021-10-08 11:18:23 +00:00
} ,
acct : & Account {
ID : "accountID" ,
} ,
err : nil ,
} ,
{
name : "fail/already-bound" ,
eak : & ExternalAccountKey {
2022-01-07 15:59:55 +00:00
ID : "eakID" ,
ProvisionerID : "provID" ,
Reference : "ref" ,
2022-04-26 08:15:17 +00:00
HmacKey : [ ] byte { 1 , 3 , 3 , 7 } ,
2022-01-07 15:59:55 +00:00
AccountID : "someAccountID" ,
BoundAt : boundAt ,
2021-10-08 11:18:23 +00:00
} ,
acct : & Account {
ID : "accountID" ,
} ,
err : NewError ( ErrorUnauthorizedType , "external account binding key with id '%s' was already bound to account '%s' on %s" , "eakID" , "someAccountID" , boundAt ) ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
eak := tt . eak
acct := tt . acct
err := eak . BindTo ( acct )
wantErr := tt . err != nil
gotErr := err != nil
if wantErr != gotErr {
t . Errorf ( "ExternalAccountKey.BindTo() error = %v, wantErr %v" , err , tt . err )
}
if wantErr {
assert . NotNil ( t , err )
2022-08-23 19:43:48 +00:00
var ae * Error
if assert . True ( t , errors . As ( err , & ae ) ) {
assert . Equals ( t , ae . Type , tt . err . Type )
assert . Equals ( t , ae . Detail , tt . err . Detail )
assert . Equals ( t , ae . Subproblems , tt . err . Subproblems )
}
2021-10-08 11:18:23 +00:00
} else {
assert . Equals ( t , eak . AccountID , acct . ID )
2022-04-26 08:15:17 +00:00
assert . Equals ( t , eak . HmacKey , [ ] byte { } )
2021-10-08 11:18:23 +00:00
assert . NotNil ( t , eak . BoundAt )
}
} )
}
}