@ -25,6 +25,8 @@ import (
"github.com/smallstep/certificates/authority/policy"
"github.com/smallstep/certificates/authority/policy"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/authority/provisioner/wire"
"github.com/smallstep/certificates/authority/provisioner/wire"
sassert "github.com/stretchr/testify/assert"
)
)
func TestNewOrderRequest_Validate ( t * testing . T ) {
func TestNewOrderRequest_Validate ( t * testing . T ) {
@ -564,6 +566,37 @@ func TestHandler_GetOrder(t *testing.T) {
func TestHandler_newAuthorization ( t * testing . T ) {
func TestHandler_newAuthorization ( t * testing . T ) {
defaultProvisioner := newProv ( )
defaultProvisioner := newProv ( )
fakeKey := ` -- -- - BEGIN PUBLIC KEY -- -- -
MCowBQYDK2VwAyEA5c + 4 NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx / YeGAJ35k =
-- -- - END PUBLIC KEY -- -- - `
wireProvisioner := newWireProvisionerWithOptions ( t , & provisioner . Options {
Wire : & wire . Options {
OIDC : & wire . OIDCOptions {
Provider : & wire . Provider {
IssuerURL : "https://issuer.example.com" ,
Algorithms : [ ] string { "ES256" } ,
} ,
Config : & wire . Config {
ClientID : "test" ,
SignatureAlgorithms : [ ] string { "ES256" } ,
Now : time . Now ,
} ,
TransformTemplate : "" ,
} ,
DPOP : & wire . DPOPOptions {
SigningKey : [ ] byte ( fakeKey ) ,
} ,
} ,
} )
wireProvisionerFailOptions := & provisioner . ACME {
Type : "ACME" ,
Name : "test@acme-<test>provisioner.com" ,
Options : & provisioner . Options { } ,
Challenges : [ ] provisioner . ACMEChallenge {
provisioner . WIREOIDC_01 ,
provisioner . WIREDPOP_01 ,
} ,
}
type test struct {
type test struct {
az * acme . Authorization
az * acme . Authorization
prov acme . Provisioner
prov acme . Provisioner
@ -592,7 +625,12 @@ func TestHandler_newAuthorization(t *testing.T) {
} ,
} ,
} ,
} ,
az : az ,
az : az ,
err : acme . NewErrorISE ( "error creating challenge: force" ) ,
err : & acme . Error {
Type : "urn:ietf:params:acme:error:serverInternal" ,
Err : errors . New ( "error creating challenge: force" ) ,
Detail : "The server experienced an internal error" ,
Status : 500 ,
} ,
}
}
} ,
} ,
"fail/error-db.CreateAuthorization" : func ( t * testing . T ) test {
"fail/error-db.CreateAuthorization" : func ( t * testing . T ) test {
@ -647,7 +685,100 @@ func TestHandler_newAuthorization(t *testing.T) {
} ,
} ,
} ,
} ,
az : az ,
az : az ,
err : acme . NewErrorISE ( "error creating authorization: force" ) ,
err : & acme . Error {
Type : "urn:ietf:params:acme:error:serverInternal" ,
Err : errors . New ( "error creating authorization: force" ) ,
Detail : "The server experienced an internal error" ,
Status : 500 ,
} ,
}
} ,
"fail/wireapp-user-options" : func ( t * testing . T ) test {
az := & acme . Authorization {
AccountID : "accID" ,
Identifier : acme . Identifier {
Type : "wireapp-user" ,
Value : "wireapp://%40alice.smith.qa@example.com" ,
} ,
Status : acme . StatusPending ,
ExpiresAt : clock . Now ( ) ,
}
return test {
prov : wireProvisionerFailOptions ,
db : & acme . MockDB { } ,
az : az ,
err : & acme . Error {
Type : "urn:ietf:params:acme:error:serverInternal" ,
Err : errors . New ( "failed getting Wire options" ) ,
Detail : "The server experienced an internal error" ,
Status : 500 ,
} ,
}
} ,
"fail/wireapp-device-parse-id" : func ( t * testing . T ) test {
az := & acme . Authorization {
AccountID : "accID" ,
Identifier : acme . Identifier {
Type : "wireapp-device" ,
Value : ` { "name} ` ,
} ,
Status : acme . StatusPending ,
ExpiresAt : clock . Now ( ) ,
}
return test {
prov : wireProvisioner ,
db : & acme . MockDB { } ,
az : az ,
err : & acme . Error {
Type : "urn:ietf:params:acme:error:malformed" ,
Err : errors . New ( "failed parsing WireDevice: unexpected end of JSON input" ) ,
Detail : "The request message was malformed" ,
Status : 400 ,
} ,
}
} ,
"fail/wireapp-device-parse-client-id" : func ( t * testing . T ) test {
az := & acme . Authorization {
AccountID : "accID" ,
Identifier : acme . Identifier {
Type : "wireapp-device" ,
Value : ` { "name": "device", "domain": "wire.com", "client-id": "CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com", "handle": "wireapp://%40alice_wire@wire.com"} ` ,
} ,
Status : acme . StatusPending ,
ExpiresAt : clock . Now ( ) ,
}
return test {
prov : wireProvisioner ,
db : & acme . MockDB { } ,
az : az ,
err : & acme . Error {
Type : "urn:ietf:params:acme:error:malformed" ,
Err : errors . New ( "failed parsing ClientID: invalid Wire client ID URI \"CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com\": error parsing CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com: scheme is missing" ) ,
Detail : "The request message was malformed" ,
Status : 400 ,
} ,
}
} ,
"fail/wireapp-device-options" : func ( t * testing . T ) test {
az := & acme . Authorization {
AccountID : "accID" ,
Identifier : acme . Identifier {
Type : "wireapp-device" ,
Value : ` { "name": "device", "domain": "wire.com", "client-id": "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com", "handle": "wireapp://%40alice_wire@wire.com"} ` ,
} ,
Status : acme . StatusPending ,
ExpiresAt : clock . Now ( ) ,
}
return test {
prov : wireProvisionerFailOptions ,
db : & acme . MockDB { } ,
az : az ,
err : & acme . Error {
Type : "urn:ietf:params:acme:error:serverInternal" ,
Err : errors . New ( "failed getting Wire options" ) ,
Detail : "The server experienced an internal error" ,
Status : 500 ,
} ,
}
}
} ,
} ,
"ok/no-wildcard" : func ( t * testing . T ) test {
"ok/no-wildcard" : func ( t * testing . T ) test {
@ -816,12 +947,12 @@ func TestHandler_newAuthorization(t *testing.T) {
az : az ,
az : az ,
}
}
} ,
} ,
"ok/wire ": func ( t * testing . T ) test {
"ok/wire app-user ": func ( t * testing . T ) test {
az := & acme . Authorization {
az := & acme . Authorization {
AccountID : "accID" ,
AccountID : "accID" ,
Identifier : acme . Identifier {
Identifier : acme . Identifier {
Type : "wireapp ",
Type : "wireapp -user ",
Value : "wireapp:// user!client@domain ",
Value : "wireapp:// %40alice.smith.qa@example.com ",
} ,
} ,
Status : acme . StatusPending ,
Status : acme . StatusPending ,
ExpiresAt : clock . Now ( ) ,
ExpiresAt : clock . Now ( ) ,
@ -829,12 +960,12 @@ func TestHandler_newAuthorization(t *testing.T) {
count := 0
count := 0
var ch1 * * acme . Challenge
var ch1 * * acme . Challenge
return test {
return test {
prov : default Provisioner,
prov : wire Provisioner,
db : & acme . MockDB {
db : & acme . MockDB {
MockCreateChallenge : func ( ctx context . Context , ch * acme . Challenge ) error {
MockCreateChallenge : func ( ctx context . Context , ch * acme . Challenge ) error {
switch count {
switch count {
case 0 :
case 0 :
ch . ID = "wireapp "
ch . ID = "wireapp -user "
assert . Equals ( t , ch . Type , acme . WIREOIDC01 )
assert . Equals ( t , ch . Type , acme . WIREOIDC01 )
ch1 = & ch
ch1 = & ch
default :
default :
@ -863,31 +994,73 @@ func TestHandler_newAuthorization(t *testing.T) {
az : az ,
az : az ,
}
}
} ,
} ,
"ok/wireapp-device" : func ( t * testing . T ) test {
az := & acme . Authorization {
AccountID : "accID" ,
Identifier : acme . Identifier {
Type : "wireapp-device" ,
Value : ` { "name": "device", "domain": "wire.com", "client-id": "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com", "handle": "wireapp://%40alice_wire@wire.com"} ` ,
} ,
Status : acme . StatusPending ,
ExpiresAt : clock . Now ( ) ,
}
count := 0
var ch1 * * acme . Challenge
return test {
prov : wireProvisioner ,
db : & acme . MockDB {
MockCreateChallenge : func ( ctx context . Context , ch * acme . Challenge ) error {
switch count {
case 0 :
ch . ID = "wireapp-device"
assert . Equals ( t , ch . Type , acme . WIREDPOP01 )
ch1 = & ch
default :
assert . FatalError ( t , errors . New ( "test logic error" ) )
return errors . New ( "force" )
}
count ++
assert . Equals ( t , ch . AccountID , az . AccountID )
assert . Equals ( t , ch . Token , az . Token )
assert . Equals ( t , ch . Status , acme . StatusPending )
assert . Equals ( t , ch . Value , az . Identifier . Value )
return nil
} ,
MockCreateAuthorization : func ( ctx context . Context , _az * acme . Authorization ) error {
assert . Equals ( t , _az . AccountID , az . AccountID )
assert . Equals ( t , _az . Token , az . Token )
assert . Equals ( t , _az . Status , acme . StatusPending )
assert . Equals ( t , _az . Identifier , az . Identifier )
assert . Equals ( t , _az . ExpiresAt , az . ExpiresAt )
_ = ch1
// assert.Equals(t, _az.Challenges, []*acme.Challenge{*ch1})
assert . Equals ( t , _az . Wildcard , false )
return nil
} ,
} ,
az : az ,
}
} ,
}
}
for name , run := range tests {
for name , run := range tests {
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
if name == "ok/permanent-identifier-enabled" {
println ( 1 )
}
tc := run ( t )
tc := run ( t )
ctx := newBaseContext ( context . Background ( ) , tc . db )
ctx := newBaseContext ( context . Background ( ) , tc . db )
ctx = acme . NewProvisionerContext ( ctx , tc . prov )
ctx = acme . NewProvisionerContext ( ctx , tc . prov )
if err := newAuthorization ( ctx , tc . az ) ; err != nil {
err := newAuthorization ( ctx , tc . az )
if assert . NotNil ( t , tc . err ) {
if tc . err != nil {
sassert . Error ( t , err )
var k * acme . Error
var k * acme . Error
if assert . True ( t , errors . As ( err , & k ) ) {
if sassert . True ( t , errors . As ( err , & k ) ) {
assert . Equals ( t , k . Type , tc . err . Type )
sassert . Equal ( t , tc . err . Type , k . Type )
assert . Equals ( t , k . Detail , tc . err . Detail )
sassert . Equal ( t , tc . err . Detail , k . Detail )
assert . Equals ( t , k . Status , tc . err . Status )
sassert . Equal ( t , tc . err . Status , k . Status )
assert . Equals ( t , k . Err . Error ( ) , tc . err . Err . Error ( ) )
sassert . EqualError ( t , k . Err , tc . err . Error ( ) )
assert . Equals ( t , k . Detail , tc . err . Detail )
} else {
assert . FatalError ( t , errors . New ( "unexpected error type" ) )
}
}
return
}
}
} else {
assert . Nil ( t , tc . err )
sassert . NoError ( t , err )
}
} )
} )
}
}
}
}