Skip to content

Commit

Permalink
Improve test coverage for Wire authorizations
Browse files Browse the repository at this point in the history
  • Loading branch information
hslatman committed Feb 6, 2024
1 parent ef657d7 commit c6a6622
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 27 deletions.
2 changes: 1 addition & 1 deletion acme/api/order.go
Expand Up @@ -299,7 +299,7 @@ func newAuthorization(ctx context.Context, az *acme.Authorization) error {
case acme.WireDevice:
wireID, err := wire.ParseDeviceID([]byte(az.Identifier.Value))
if err != nil {
return acme.WrapError(acme.ErrorMalformedType, err, "failed parsing WireUser")
return acme.WrapError(acme.ErrorMalformedType, err, "failed parsing WireDevice")
}
clientID, err := wire.ParseClientID(wireID.ClientID)
if err != nil {
Expand Down
225 changes: 199 additions & 26 deletions acme/api/order_test.go
Expand Up @@ -25,6 +25,8 @@ import (
"github.com/smallstep/certificates/authority/policy"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/authority/provisioner/wire"

sassert "github.com/stretchr/testify/assert"
)

func TestNewOrderRequest_Validate(t *testing.T) {
Expand Down Expand Up @@ -564,6 +566,37 @@ func TestHandler_GetOrder(t *testing.T) {

func TestHandler_newAuthorization(t *testing.T) {
defaultProvisioner := newProv()
fakeKey := `-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/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 {
az *acme.Authorization
prov acme.Provisioner
Expand Down Expand Up @@ -591,8 +624,13 @@ func TestHandler_newAuthorization(t *testing.T) {
return errors.New("force")
},
},
az: az,
err: acme.NewErrorISE("error creating challenge: force"),
az: az,
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 {
Expand Down Expand Up @@ -646,8 +684,101 @@ func TestHandler_newAuthorization(t *testing.T) {
return errors.New("force")
},
},
az: az,
err: acme.NewErrorISE("error creating authorization: force"),
az: az,
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 {
Expand Down Expand Up @@ -816,25 +947,25 @@ func TestHandler_newAuthorization(t *testing.T) {
az: az,
}
},
"ok/wire": func(t *testing.T) test {
"ok/wireapp-user": func(t *testing.T) test {
az := &acme.Authorization{
AccountID: "accID",
Identifier: acme.Identifier{
Type: "wireapp",
Value: "wireapp://user!client@domain",
Type: "wireapp-user",
Value: "wireapp://%40alice.smith.qa@example.com",
},
Status: acme.StatusPending,
ExpiresAt: clock.Now(),
}
count := 0
var ch1 **acme.Challenge
return test{
prov: defaultProvisioner,
prov: wireProvisioner,
db: &acme.MockDB{
MockCreateChallenge: func(ctx context.Context, ch *acme.Challenge) error {
switch count {
case 0:
ch.ID = "wireapp"
ch.ID = "wireapp-user"
assert.Equals(t, ch.Type, acme.WIREOIDC01)
ch1 = &ch
default:
Expand Down Expand Up @@ -863,31 +994,73 @@ func TestHandler_newAuthorization(t *testing.T) {
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 {
t.Run(name, func(t *testing.T) {
if name == "ok/permanent-identifier-enabled" {
println(1)
}
tc := run(t)
ctx := newBaseContext(context.Background(), tc.db)
ctx = acme.NewProvisionerContext(ctx, tc.prov)
if err := newAuthorization(ctx, tc.az); err != nil {
if assert.NotNil(t, tc.err) {
var k *acme.Error
if assert.True(t, errors.As(err, &k)) {
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)
} else {
assert.FatalError(t, errors.New("unexpected error type"))
}
err := newAuthorization(ctx, tc.az)
if tc.err != nil {
sassert.Error(t, err)
var k *acme.Error
if sassert.True(t, errors.As(err, &k)) {
sassert.Equal(t, tc.err.Type, k.Type)
sassert.Equal(t, tc.err.Detail, k.Detail)
sassert.Equal(t, tc.err.Status, k.Status)
sassert.EqualError(t, k.Err, tc.err.Error())
}
} else {
assert.Nil(t, tc.err)
return
}

sassert.NoError(t, err)
})
}
}
Expand Down

0 comments on commit c6a6622

Please sign in to comment.