mirror of
https://github.com/outbackdingo/certificates.git
synced 2026-01-27 10:18:34 +00:00
Merge pull request #1960 from smallstep/herman/wire-db-interface
Change `Wire` DB operations into using a runtime type assertion
This commit is contained in:
@@ -117,9 +117,17 @@ func (ch *Challenge) Validate(ctx context.Context, db DB, jwk *jose.JSONWebKey,
|
||||
case DEVICEATTEST01:
|
||||
return deviceAttest01Validate(ctx, ch, db, jwk, payload)
|
||||
case WIREOIDC01:
|
||||
return wireOIDC01Validate(ctx, ch, db, jwk, payload)
|
||||
wireDB, ok := db.(WireDB)
|
||||
if !ok {
|
||||
return NewErrorISE("db %T is not a WireDB", db)
|
||||
}
|
||||
return wireOIDC01Validate(ctx, ch, wireDB, jwk, payload)
|
||||
case WIREDPOP01:
|
||||
return wireDPOP01Validate(ctx, ch, db, jwk, payload)
|
||||
wireDB, ok := db.(WireDB)
|
||||
if !ok {
|
||||
return NewErrorISE("db %T is not a WireDB", db)
|
||||
}
|
||||
return wireDPOP01Validate(ctx, ch, wireDB, jwk, payload)
|
||||
default:
|
||||
return NewErrorISE("unexpected challenge type %q", ch.Type)
|
||||
}
|
||||
@@ -392,7 +400,7 @@ type wireOidcPayload struct {
|
||||
IDToken string `json:"id_token"`
|
||||
}
|
||||
|
||||
func wireOIDC01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebKey, payload []byte) error {
|
||||
func wireOIDC01Validate(ctx context.Context, ch *Challenge, db WireDB, jwk *jose.JSONWebKey, payload []byte) error {
|
||||
prov, ok := ProvisionerFromContext(ctx)
|
||||
if !ok {
|
||||
return NewErrorISE("missing provisioner")
|
||||
@@ -522,7 +530,7 @@ type wireDpopPayload struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
|
||||
func wireDPOP01Validate(ctx context.Context, ch *Challenge, db DB, accountJWK *jose.JSONWebKey, payload []byte) error {
|
||||
func wireDPOP01Validate(ctx context.Context, ch *Challenge, db WireDB, accountJWK *jose.JSONWebKey, payload []byte) error {
|
||||
prov, ok := ProvisionerFromContext(ctx)
|
||||
if !ok {
|
||||
return NewErrorISE("missing provisioner")
|
||||
|
||||
@@ -962,14 +962,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -984,6 +986,100 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
},
|
||||
}
|
||||
},
|
||||
"fail/wire-oidc-01-no-wire-db": func(t *testing.T) test {
|
||||
jwk, keyAuth := mustAccountAndKeyAuthorization(t, "token")
|
||||
signerJWK, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||
require.NoError(t, err)
|
||||
signer, err := jose.NewSigner(jose.SigningKey{
|
||||
Algorithm: jose.SignatureAlgorithm(signerJWK.Algorithm),
|
||||
Key: signerJWK,
|
||||
}, new(jose.SignerOptions))
|
||||
require.NoError(t, err)
|
||||
srv := mustJWKServer(t, signerJWK.Public())
|
||||
tokenBytes, err := json.Marshal(struct {
|
||||
jose.Claims
|
||||
Name string `json:"name,omitempty"`
|
||||
PreferredUsername string `json:"preferred_username,omitempty"`
|
||||
KeyAuth string `json:"keyauth"`
|
||||
ACMEAudience string `json:"acme_aud"`
|
||||
}{
|
||||
Claims: jose.Claims{
|
||||
Issuer: srv.URL,
|
||||
Audience: []string{"test"},
|
||||
Expiry: jose.NewNumericDate(time.Now().Add(1 * time.Minute)),
|
||||
},
|
||||
Name: "Alice Smith",
|
||||
PreferredUsername: "wireapp://%40alice_wire@wire.com",
|
||||
KeyAuth: keyAuth,
|
||||
ACMEAudience: "https://ca.example.com/acme/wire/challenge/azID/chID",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
signed, err := signer.Sign(tokenBytes)
|
||||
require.NoError(t, err)
|
||||
idToken, err := signed.CompactSerialize()
|
||||
require.NoError(t, err)
|
||||
payload, err := json.Marshal(struct {
|
||||
IDToken string `json:"id_token"`
|
||||
}{
|
||||
IDToken: idToken,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
valueBytes, err := json.Marshal(struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
ClientID string `json:"client-id,omitempty"`
|
||||
Handle string `json:"handle,omitempty"`
|
||||
}{
|
||||
Name: "Alice Smith",
|
||||
Domain: "wire.com",
|
||||
ClientID: "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com",
|
||||
Handle: "wireapp://%40alice_wire@wire.com",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
ctx := NewProvisionerContext(context.Background(), newWireProvisionerWithOptions(t, &provisioner.Options{
|
||||
Wire: &wireprovisioner.Options{
|
||||
OIDC: &wireprovisioner.OIDCOptions{
|
||||
Provider: &wireprovisioner.Provider{
|
||||
IssuerURL: srv.URL,
|
||||
JWKSURL: srv.URL + "/keys",
|
||||
Algorithms: []string{"ES256"},
|
||||
},
|
||||
Config: &wireprovisioner.Config{
|
||||
ClientID: "test",
|
||||
SignatureAlgorithms: []string{"ES256"},
|
||||
Now: time.Now,
|
||||
},
|
||||
TransformTemplate: "",
|
||||
},
|
||||
DPOP: &wireprovisioner.DPOPOptions{
|
||||
SigningKey: []byte(fakeKey),
|
||||
},
|
||||
},
|
||||
}))
|
||||
ctx = NewLinkerContext(ctx, NewLinker("ca.example.com", "acme"))
|
||||
return test{
|
||||
ch: &Challenge{
|
||||
ID: "chID",
|
||||
AuthorizationID: "azID",
|
||||
AccountID: "accID",
|
||||
Token: "token",
|
||||
Type: "wire-oidc-01",
|
||||
Status: StatusPending,
|
||||
Value: string(valueBytes),
|
||||
},
|
||||
srv: srv,
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{},
|
||||
err: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
Status: 500,
|
||||
Err: errors.New("db *acme.MockDB is not a WireDB"),
|
||||
},
|
||||
}
|
||||
},
|
||||
"ok/wire-dpop-01": func(t *testing.T) test {
|
||||
jwk, keyAuth := mustAccountAndKeyAuthorization(t, "token")
|
||||
_ = keyAuth // TODO(hs): keyAuth (not) required for DPoP? Or needs to be added to validation?
|
||||
@@ -1111,14 +1207,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -1134,6 +1232,141 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
},
|
||||
}
|
||||
},
|
||||
"fail/wire-dpop-01-no-wire-db": func(t *testing.T) test {
|
||||
jwk, _ := mustAccountAndKeyAuthorization(t, "token")
|
||||
dpopSigner, err := jose.NewSigner(jose.SigningKey{
|
||||
Algorithm: jose.SignatureAlgorithm(jwk.Algorithm),
|
||||
Key: jwk,
|
||||
}, new(jose.SignerOptions))
|
||||
require.NoError(t, err)
|
||||
signerJWK, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||
require.NoError(t, err)
|
||||
signer, err := jose.NewSigner(jose.SigningKey{
|
||||
Algorithm: jose.SignatureAlgorithm(signerJWK.Algorithm),
|
||||
Key: signerJWK,
|
||||
}, new(jose.SignerOptions))
|
||||
require.NoError(t, err)
|
||||
signerPEMBlock, err := pemutil.Serialize(signerJWK.Public().Key)
|
||||
require.NoError(t, err)
|
||||
signerPEMBytes := pem.EncodeToMemory(signerPEMBlock)
|
||||
dpopBytes, err := json.Marshal(struct {
|
||||
jose.Claims
|
||||
Challenge string `json:"chal,omitempty"`
|
||||
Handle string `json:"handle,omitempty"`
|
||||
Nonce string `json:"nonce,omitempty"`
|
||||
HTU string `json:"htu,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}{
|
||||
Claims: jose.Claims{
|
||||
Subject: "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com",
|
||||
Audience: jose.Audience{"https://ca.example.com/acme/wire/challenge/azID/chID"},
|
||||
},
|
||||
Challenge: "token",
|
||||
Handle: "wireapp://%40alice_wire@wire.com",
|
||||
Nonce: "nonce",
|
||||
HTU: "http://issuer.example.com",
|
||||
Name: "Alice Smith",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
dpop, err := dpopSigner.Sign(dpopBytes)
|
||||
require.NoError(t, err)
|
||||
proof, err := dpop.CompactSerialize()
|
||||
require.NoError(t, err)
|
||||
tokenBytes, err := json.Marshal(struct {
|
||||
jose.Claims
|
||||
Challenge string `json:"chal,omitempty"`
|
||||
Nonce string `json:"nonce,omitempty"`
|
||||
Cnf struct {
|
||||
Kid string `json:"kid,omitempty"`
|
||||
} `json:"cnf"`
|
||||
Proof string `json:"proof,omitempty"`
|
||||
ClientID string `json:"client_id"`
|
||||
APIVersion int `json:"api_version"`
|
||||
Scope string `json:"scope"`
|
||||
}{
|
||||
Claims: jose.Claims{
|
||||
Issuer: "http://issuer.example.com",
|
||||
Audience: jose.Audience{"https://ca.example.com/acme/wire/challenge/azID/chID"},
|
||||
Expiry: jose.NewNumericDate(time.Now().Add(1 * time.Minute)),
|
||||
},
|
||||
Challenge: "token",
|
||||
Nonce: "nonce",
|
||||
Cnf: struct {
|
||||
Kid string `json:"kid,omitempty"`
|
||||
}{
|
||||
Kid: jwk.KeyID,
|
||||
},
|
||||
Proof: proof,
|
||||
ClientID: "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com",
|
||||
APIVersion: 5,
|
||||
Scope: "wire_client_id",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
signed, err := signer.Sign(tokenBytes)
|
||||
require.NoError(t, err)
|
||||
accessToken, err := signed.CompactSerialize()
|
||||
require.NoError(t, err)
|
||||
payload, err := json.Marshal(struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}{
|
||||
AccessToken: accessToken,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
valueBytes, err := json.Marshal(struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
ClientID string `json:"client-id,omitempty"`
|
||||
Handle string `json:"handle,omitempty"`
|
||||
}{
|
||||
Name: "Alice Smith",
|
||||
Domain: "wire.com",
|
||||
ClientID: "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com",
|
||||
Handle: "wireapp://%40alice_wire@wire.com",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
ctx := NewProvisionerContext(context.Background(), newWireProvisionerWithOptions(t, &provisioner.Options{
|
||||
Wire: &wireprovisioner.Options{
|
||||
OIDC: &wireprovisioner.OIDCOptions{
|
||||
Provider: &wireprovisioner.Provider{
|
||||
IssuerURL: "http://issuerexample.com",
|
||||
Algorithms: []string{"ES256"},
|
||||
},
|
||||
Config: &wireprovisioner.Config{
|
||||
ClientID: "test",
|
||||
SignatureAlgorithms: []string{"ES256"},
|
||||
Now: time.Now,
|
||||
},
|
||||
TransformTemplate: "",
|
||||
},
|
||||
DPOP: &wireprovisioner.DPOPOptions{
|
||||
Target: "http://issuer.example.com",
|
||||
SigningKey: signerPEMBytes,
|
||||
},
|
||||
},
|
||||
}))
|
||||
ctx = NewLinkerContext(ctx, NewLinker("ca.example.com", "acme"))
|
||||
return test{
|
||||
ch: &Challenge{
|
||||
ID: "chID",
|
||||
AuthorizationID: "azID",
|
||||
AccountID: "accID",
|
||||
Token: "token",
|
||||
Type: "wire-dpop-01",
|
||||
Status: StatusPending,
|
||||
Value: string(valueBytes),
|
||||
},
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{},
|
||||
err: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
Status: 500,
|
||||
Err: errors.New("db *acme.MockDB is not a WireDB"),
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
for name, run := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
|
||||
@@ -29,7 +29,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
type test struct {
|
||||
ch *Challenge
|
||||
jwk *jose.JSONWebKey
|
||||
db DB
|
||||
db WireDB
|
||||
payload []byte
|
||||
ctx context.Context
|
||||
expectedErr *Error
|
||||
@@ -38,6 +38,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
"fail/no-provisioner": func(t *testing.T) test {
|
||||
return test{
|
||||
ctx: context.Background(),
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -68,6 +69,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
}))
|
||||
return test{
|
||||
ctx: ctx,
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -109,6 +111,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
Status: StatusPending,
|
||||
Value: "1234",
|
||||
},
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:malformed",
|
||||
Detail: "The request message was malformed",
|
||||
@@ -150,6 +153,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
Status: StatusPending,
|
||||
Value: "1234",
|
||||
},
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -203,6 +207,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
Status: StatusPending,
|
||||
Value: string(valueBytes),
|
||||
},
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -259,25 +264,27 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
Status: StatusPending,
|
||||
Value: string(valueBytes),
|
||||
},
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, ch *Challenge) error {
|
||||
assert.Equal(t, "chID", ch.ID)
|
||||
assert.Equal(t, "azID", ch.AuthorizationID)
|
||||
assert.Equal(t, "accID", ch.AccountID)
|
||||
assert.Equal(t, "token", ch.Token)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), ch.Type)
|
||||
assert.Equal(t, StatusInvalid, ch.Status)
|
||||
assert.Equal(t, string(valueBytes), ch.Value)
|
||||
if assert.NotNil(t, ch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(ch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Equal(t, `failed validating Wire access token: failed parsing token: go-jose/go-jose: compact JWS format must have three parts`, k.Err.Error())
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, ch *Challenge) error {
|
||||
assert.Equal(t, "chID", ch.ID)
|
||||
assert.Equal(t, "azID", ch.AuthorizationID)
|
||||
assert.Equal(t, "accID", ch.AccountID)
|
||||
assert.Equal(t, "token", ch.Token)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), ch.Type)
|
||||
assert.Equal(t, StatusInvalid, ch.Status)
|
||||
assert.Equal(t, string(valueBytes), ch.Value)
|
||||
if assert.NotNil(t, ch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(ch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Equal(t, `failed validating Wire access token: failed parsing token: go-jose/go-jose: compact JWS format must have three parts`, k.Err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -410,14 +417,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return errors.New("fail")
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return errors.New("fail")
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: &Error{
|
||||
@@ -556,14 +565,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -706,14 +717,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -856,14 +869,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -1012,14 +1027,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-dpop-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -1065,7 +1082,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
type test struct {
|
||||
ch *Challenge
|
||||
jwk *jose.JSONWebKey
|
||||
db DB
|
||||
db WireDB
|
||||
payload []byte
|
||||
srv *httptest.Server
|
||||
ctx context.Context
|
||||
@@ -1075,6 +1092,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
"fail/no-provisioner": func(t *testing.T) test {
|
||||
return test{
|
||||
ctx: context.Background(),
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -1105,6 +1123,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
}))
|
||||
return test{
|
||||
ctx: ctx,
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -1146,10 +1165,12 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
Status: StatusPending,
|
||||
Value: "1234",
|
||||
},
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, ch *Challenge) error {
|
||||
assert.Equal(t, "chID", ch.ID)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, ch *Challenge) error {
|
||||
assert.Equal(t, "chID", ch.ID)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: &Error{
|
||||
@@ -1193,6 +1214,7 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
Status: StatusPending,
|
||||
Value: "1234",
|
||||
},
|
||||
db: &MockWireDB{},
|
||||
expectedErr: &Error{
|
||||
Type: "urn:ietf:params:acme:error:serverInternal",
|
||||
Detail: "The server experienced an internal error",
|
||||
@@ -1288,23 +1310,25 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusInvalid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
if assert.NotNil(t, updch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(updch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Equal(t, `error verifying ID token signature: failed to verify signature: failed to verify id token signature`, k.Err.Error())
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusInvalid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
if assert.NotNil(t, updch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(updch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Equal(t, `error verifying ID token signature: failed to verify signature: failed to verify id token signature`, k.Err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1394,23 +1418,25 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusInvalid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
if assert.NotNil(t, updch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(updch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Contains(t, k.Err.Error(), "keyAuthorization does not match")
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusInvalid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
if assert.NotNil(t, updch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(updch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Contains(t, k.Err.Error(), "keyAuthorization does not match")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1500,23 +1526,25 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusInvalid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
if assert.NotNil(t, updch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(updch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Equal(t, `claims in OIDC ID token don't match: invalid 'preferred_username' "wireapp://%40bob@wire.com" after transformation`, k.Err.Error())
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusInvalid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
if assert.NotNil(t, updch.Error) {
|
||||
var k *Error // NOTE: the error is not returned up, but stored with the challenge instead
|
||||
if errors.As(updch.Error, &k) {
|
||||
assert.Equal(t, "urn:ietf:params:acme:error:rejectedIdentifier", k.Type)
|
||||
assert.Equal(t, "The server will not issue certificates for the identifier", k.Detail)
|
||||
assert.Equal(t, 400, k.Status)
|
||||
assert.Equal(t, `claims in OIDC ID token don't match: invalid 'preferred_username' "wireapp://%40bob@wire.com" after transformation`, k.Err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1606,14 +1634,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return errors.New("fail")
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return errors.New("fail")
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: &Error{
|
||||
@@ -1709,14 +1739,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -1816,14 +1848,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -1923,14 +1957,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
@@ -2036,14 +2072,16 @@ MCowBQYDK2VwAyEA5c+4NKZSNQcR1T8qN6SjwgdPZQ0Ge12Ylx/YeGAJ35k=
|
||||
payload: payload,
|
||||
ctx: ctx,
|
||||
jwk: jwk,
|
||||
db: &MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
db: &MockWireDB{
|
||||
MockDB: MockDB{
|
||||
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
|
||||
assert.Equal(t, "chID", updch.ID)
|
||||
assert.Equal(t, "token", updch.Token)
|
||||
assert.Equal(t, StatusValid, updch.Status)
|
||||
assert.Equal(t, ChallengeType("wire-oidc-01"), updch.Type)
|
||||
assert.Equal(t, string(valueBytes), updch.Value)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
MockGetAllOrdersByAccountID: func(ctx context.Context, accountID string) ([]string, error) {
|
||||
assert.Equal(t, "accID", accountID)
|
||||
|
||||
30
acme/db.go
30
acme/db.go
@@ -54,8 +54,14 @@ type DB interface {
|
||||
GetOrder(ctx context.Context, id string) (*Order, error)
|
||||
GetOrdersByAccountID(ctx context.Context, accountID string) ([]string, error)
|
||||
UpdateOrder(ctx context.Context, o *Order) error
|
||||
}
|
||||
|
||||
// TODO(hs): put in a different interface
|
||||
// WireDB is the interface used for operations on ACME Orders for Wire identifiers. This
|
||||
// is not a general purpose interface, and it should only be used when Wire identifiers
|
||||
// are enabled in the CA configuration. Currently it provides a runtime assertion only;
|
||||
// not at compile time.
|
||||
type WireDB interface {
|
||||
DB
|
||||
GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error)
|
||||
CreateDpopToken(ctx context.Context, orderID string, dpop map[string]interface{}) error
|
||||
GetDpopToken(ctx context.Context, orderID string) (map[string]interface{}, error)
|
||||
@@ -126,14 +132,20 @@ type MockDB struct {
|
||||
MockGetOrdersByAccountID func(ctx context.Context, accountID string) ([]string, error)
|
||||
MockUpdateOrder func(ctx context.Context, o *Order) error
|
||||
|
||||
MockRet1 interface{}
|
||||
MockError error
|
||||
}
|
||||
|
||||
// MockWireDB is an implementation of the WireDB interface that should only be used as
|
||||
// a mock in tests. It embeds the MockDB, as it is an extension of the existing database
|
||||
// methods.
|
||||
type MockWireDB struct {
|
||||
MockDB
|
||||
MockGetAllOrdersByAccountID func(ctx context.Context, accountID string) ([]string, error)
|
||||
MockGetDpopToken func(ctx context.Context, orderID string) (map[string]interface{}, error)
|
||||
MockCreateDpopToken func(ctx context.Context, orderID string, dpop map[string]interface{}) error
|
||||
MockGetOidcToken func(ctx context.Context, orderID string) (map[string]interface{}, error)
|
||||
MockCreateOidcToken func(ctx context.Context, orderID string, idToken map[string]interface{}) error
|
||||
|
||||
MockRet1 interface{}
|
||||
MockError error
|
||||
}
|
||||
|
||||
// CreateAccount mock.
|
||||
@@ -407,7 +419,7 @@ func (m *MockDB) GetOrdersByAccountID(ctx context.Context, accID string) ([]stri
|
||||
}
|
||||
|
||||
// GetAllOrdersByAccountID returns a list of any order IDs owned by the account.
|
||||
func (m *MockDB) GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error) {
|
||||
func (m *MockWireDB) GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error) {
|
||||
if m.MockGetAllOrdersByAccountID != nil {
|
||||
return m.MockGetAllOrdersByAccountID(ctx, accountID)
|
||||
} else if m.MockError != nil {
|
||||
@@ -417,7 +429,7 @@ func (m *MockDB) GetAllOrdersByAccountID(ctx context.Context, accountID string)
|
||||
}
|
||||
|
||||
// GetDpop retrieves a DPoP from the database.
|
||||
func (m *MockDB) GetDpopToken(ctx context.Context, orderID string) (map[string]any, error) {
|
||||
func (m *MockWireDB) GetDpopToken(ctx context.Context, orderID string) (map[string]any, error) {
|
||||
if m.MockGetDpopToken != nil {
|
||||
return m.MockGetDpopToken(ctx, orderID)
|
||||
} else if m.MockError != nil {
|
||||
@@ -427,7 +439,7 @@ func (m *MockDB) GetDpopToken(ctx context.Context, orderID string) (map[string]a
|
||||
}
|
||||
|
||||
// CreateDpop creates DPoP resources and saves them to the DB.
|
||||
func (m *MockDB) CreateDpopToken(ctx context.Context, orderID string, dpop map[string]any) error {
|
||||
func (m *MockWireDB) CreateDpopToken(ctx context.Context, orderID string, dpop map[string]any) error {
|
||||
if m.MockCreateDpopToken != nil {
|
||||
return m.MockCreateDpopToken(ctx, orderID, dpop)
|
||||
}
|
||||
@@ -435,7 +447,7 @@ func (m *MockDB) CreateDpopToken(ctx context.Context, orderID string, dpop map[s
|
||||
}
|
||||
|
||||
// GetOidcToken retrieves an oidc token from the database.
|
||||
func (m *MockDB) GetOidcToken(ctx context.Context, orderID string) (map[string]any, error) {
|
||||
func (m *MockWireDB) GetOidcToken(ctx context.Context, orderID string) (map[string]any, error) {
|
||||
if m.MockGetOidcToken != nil {
|
||||
return m.MockGetOidcToken(ctx, orderID)
|
||||
} else if m.MockError != nil {
|
||||
@@ -445,7 +457,7 @@ func (m *MockDB) GetOidcToken(ctx context.Context, orderID string) (map[string]a
|
||||
}
|
||||
|
||||
// CreateOidcToken creates oidc token resources and saves them to the DB.
|
||||
func (m *MockDB) CreateOidcToken(ctx context.Context, orderID string, idToken map[string]any) error {
|
||||
func (m *MockWireDB) CreateOidcToken(ctx context.Context, orderID string, idToken map[string]any) error {
|
||||
if m.MockCreateOidcToken != nil {
|
||||
return m.MockCreateOidcToken(ctx, orderID, idToken)
|
||||
}
|
||||
|
||||
@@ -208,6 +208,10 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
|
||||
// Template data
|
||||
data := x509util.NewTemplateData()
|
||||
if o.containsWireIdentifiers() {
|
||||
wireDB, ok := db.(WireDB)
|
||||
if !ok {
|
||||
return fmt.Errorf("db %T is not a WireDB", db)
|
||||
}
|
||||
subject, err := createWireSubject(o, csr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating Wire subject: %w", err)
|
||||
@@ -215,13 +219,13 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
|
||||
data.SetSubject(subject)
|
||||
|
||||
// Inject Wire's custom challenges into the template once they have been validated
|
||||
dpop, err := db.GetDpopToken(ctx, o.ID)
|
||||
dpop, err := wireDB.GetDpopToken(ctx, o.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed getting Wire DPoP token: %w", err)
|
||||
}
|
||||
data.Set("Dpop", dpop)
|
||||
|
||||
oidc, err := db.GetOidcToken(ctx, o.ID)
|
||||
oidc, err := wireDB.GetOidcToken(ctx, o.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed getting Wire OIDC token: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user