Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: update bdd tests to use mock attestation server #1568

Merged
merged 1 commit into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ mock-trustregistry-docker:

.PHONY: mock-attestation-docker
mock-attestation-docker:
@echo "Building mock Trust Registry server"
@echo "Building mock attestation server"
@docker build -f ./images/mocks/attestation/Dockerfile --no-cache -t vcs/mock-attestation:latest \
--build-arg GO_VER=$(GO_VER) \
--build-arg ALPINE_VER=$(GO_ALPINE_VER) \
Expand Down
4 changes: 2 additions & 2 deletions component/wallet-cli/cmd/oidc4vci_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func NewOIDC4VCICommand() *cobra.Command {
return err
}

if err = flow.Run(context.Background()); err != nil {
if _, err = flow.Run(context.Background()); err != nil {
return err
}
case preAuthorizedCodeGrantType:
Expand All @@ -240,7 +240,7 @@ func NewOIDC4VCICommand() *cobra.Command {
return err
}

if err = flow.Run(context.Background()); err != nil {
if _, err = flow.Run(context.Background()); err != nil {
return err
}
default:
Expand Down
4 changes: 3 additions & 1 deletion component/wallet-cli/pkg/attestation/attestation_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"

Expand Down Expand Up @@ -191,7 +192,8 @@ func (c *Client) doRequest(ctx context.Context, policyURL string, body []byte, r
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
b, _ := io.ReadAll(resp.Body)
return fmt.Errorf("unexpected status code: %d; response: %s", resp.StatusCode, string(b))
}

if err = json.NewDecoder(resp.Body).Decode(response); err != nil {
Expand Down
61 changes: 33 additions & 28 deletions component/wallet-cli/pkg/oidc4vci/oidc4vci_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func NewFlow(p provider, opts ...Opt) (*Flow, error) {
}, nil
}

func (f *Flow) Run(ctx context.Context) error {
func (f *Flow) Run(ctx context.Context) (*verifiable.Credential, error) {
slog.Info("Running OIDC4VCI flow",
"flow_type", f.flowType,
"credential_offer_uri", f.credentialOffer,
Expand All @@ -233,7 +233,7 @@ func (f *Flow) Run(ctx context.Context) error {

credentialOfferResponse, err = f.parseCredentialOfferURI(f.credentialOffer)
if err != nil {
return err
return nil, err
}

credentialIssuer = credentialOfferResponse.CredentialIssuer
Expand All @@ -252,15 +252,15 @@ func (f *Flow) Run(ctx context.Context) error {

openIDConfig, err := f.wellKnownService.GetWellKnownOpenIDConfiguration(credentialIssuer)
if err != nil {
return err
return nil, err
}

requireWalletAttestation := openIDConfig.TokenEndpointAuthMethodsSupported != nil &&
lo.Contains(openIDConfig.TokenEndpointAuthMethodsSupported, attestJWTClientAuthType)

if f.trustRegistryURL != "" {
if credentialOfferResponse == nil || len(credentialOfferResponse.Credentials) == 0 {
return fmt.Errorf("credential offer is empty")
return nil, fmt.Errorf("credential offer is empty")
}

slog.Info("Validating issuer", "url", f.trustRegistryURL)
Expand All @@ -286,7 +286,7 @@ func (f *Flow) Run(ctx context.Context) error {
credentialFormat,
lo.Contains(openIDConfig.TokenEndpointAuthMethodsSupported, attestJWTClientAuthType),
); err != nil {
return fmt.Errorf("validate issuer: %w", err)
return nil, fmt.Errorf("validate issuer: %w", err)
}
}

Expand All @@ -307,14 +307,14 @@ func (f *Flow) Run(ctx context.Context) error {

authCode, err = f.getAuthorizationCode(oauthClient, issuerState)
if err != nil {
return err
return nil, err
}

ctx = context.WithValue(ctx, oauth2.HTTPClient, f.httpClient)

token, err = f.exchangeAuthorizationCodeForAccessToken(ctx, oauthClient, authCode)
if err != nil {
return err
return nil, err
}
} else if f.flowType == FlowTypePreAuthorizedCode {
slog.Info("Getting access token",
Expand Down Expand Up @@ -346,7 +346,7 @@ func (f *Flow) Run(ctx context.Context) error {

jwtVP, err = f.getAttestationVP()
if err != nil {
return fmt.Errorf("get attestation vp: %w", err)
return nil, fmt.Errorf("get attestation vp: %w", err)
}

tokenValues.Add("client_assertion_type", attestJWTClientAuthType)
Expand All @@ -356,16 +356,16 @@ func (f *Flow) Run(ctx context.Context) error {
var resp *http.Response

if resp, err = f.httpClient.PostForm(openIDConfig.TokenEndpoint, tokenValues); err != nil {
return err
return nil, err
}

if resp.StatusCode != http.StatusOK {
b, readErr := io.ReadAll(resp.Body)
if readErr != nil {
return readErr
return nil, readErr
}

return fmt.Errorf(
return nil, fmt.Errorf(
"get access token: status %s and body %s",
resp.Status,
string(b),
Expand All @@ -375,7 +375,7 @@ func (f *Flow) Run(ctx context.Context) error {
var tokenResp oidc4civ1.AccessTokenResponse

if err = json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {
return err
return nil, err
}
_ = resp.Body.Close()

Expand All @@ -392,11 +392,16 @@ func (f *Flow) Run(ctx context.Context) error {
)
}

if err = f.receiveVC(token, openIDConfig, credentialIssuer); err != nil {
return err
vc, err := f.receiveVC(token, openIDConfig, credentialIssuer)
if err != nil {
return nil, err
}

return nil
return vc, nil
}

func (f *Flow) Signer() jose.Signer {
return f.signer
}

func (f *Flow) parseCredentialOfferURI(uri string) (*oidc4ci.CredentialOfferResponse, error) {
Expand Down Expand Up @@ -670,7 +675,7 @@ func (f *Flow) receiveVC(
token *oauth2.Token,
wellKnown *issuerv1.WellKnownOpenIDIssuerConfiguration,
credentialIssuer string,
) error {
) (*verifiable.Credential, error) {
credentialEndpoint := wellKnown.CredentialEndpoint

slog.Info("Getting credential",
Expand All @@ -691,7 +696,7 @@ func (f *Flow) receiveVC(

jws, err := f.proofBuilder(claims, headers, f.signer)
if err != nil {
return fmt.Errorf("build proof: %w", err)
return nil, fmt.Errorf("build proof: %w", err)
}

b, err := json.Marshal(CredentialRequest{
Expand All @@ -703,20 +708,20 @@ func (f *Flow) receiveVC(
},
})
if err != nil {
return fmt.Errorf("marshal credential request: %w", err)
return nil, fmt.Errorf("marshal credential request: %w", err)
}

req, err := http.NewRequest(http.MethodPost, credentialEndpoint, bytes.NewBuffer(b))
if err != nil {
return fmt.Errorf("new credential request: %w", err)
return nil, fmt.Errorf("new credential request: %w", err)
}

req.Header.Add("content-type", "application/json")
req.Header.Add("authorization", "Bearer "+token.AccessToken)

resp, err := f.httpClient.Do(req)
if err != nil {
return fmt.Errorf("post to credential endpoint: %w", err)
return nil, fmt.Errorf("post to credential endpoint: %w", err)
}

defer func() {
Expand All @@ -727,10 +732,10 @@ func (f *Flow) receiveVC(

if resp.StatusCode != http.StatusOK {
if b, err = io.ReadAll(resp.Body); err != nil {
return err
return nil, err
}

return fmt.Errorf(
return nil, fmt.Errorf(
"get credential: status %s and body %s",
resp.Status,
string(b),
Expand All @@ -740,24 +745,24 @@ func (f *Flow) receiveVC(
var credentialResp CredentialResponse

if err = json.NewDecoder(resp.Body).Decode(&credentialResp); err != nil {
return fmt.Errorf("decode credential response: %w", err)
return nil, fmt.Errorf("decode credential response: %w", err)
}

vcBytes, err := json.Marshal(credentialResp.Credential)
if err != nil {
return fmt.Errorf("marshal credential response: %w", err)
return nil, fmt.Errorf("marshal credential response: %w", err)
}

parsedVC, err := verifiable.ParseCredential(vcBytes,
verifiable.WithJSONLDDocumentLoader(f.documentLoader),
verifiable.WithDisabledProofCheck(),
)
if err != nil {
return fmt.Errorf("parse credential: %w", err)
return nil, fmt.Errorf("parse credential: %w", err)
}

if err = f.wallet.Add(vcBytes); err != nil {
return fmt.Errorf("add credential to wallet: %w", err)
return nil, fmt.Errorf("add credential to wallet: %w", err)
}

var cslURL, statusListIndex, statusListType string
Expand Down Expand Up @@ -790,10 +795,10 @@ func (f *Flow) receiveVC(
)

if err = f.handleIssuanceAck(wellKnown, &credentialResp, token); err != nil {
return err
return nil, err
}

return nil
return parsedVC, nil
}

func (f *Flow) handleIssuanceAck(
Expand Down
24 changes: 24 additions & 0 deletions test/bdd/attestation/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,56 @@ go 1.21
require (
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
github.com/trustbloc/cmdutil-go v1.0.0
github.com/trustbloc/did-go v1.1.0
github.com/trustbloc/vc-go v1.1.0
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
)

require (
github.com/IBM/mathlib v0.0.3-0.20231011094432-44ee0eb539da // indirect
github.com/VictoriaMetrics/fastcache v1.5.7 // indirect
github.com/bits-and-blooms/bitset v1.7.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/go-jose/go-jose/v3 v3.0.1-0.20221117193127-916db76e8214 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/tink/go v1.7.0 // indirect
github.com/hyperledger/fabric-amcl v0.0.0-20230602173724-9e02669dceb2 // indirect
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multibase v0.1.1 // indirect
github.com/piprate/json-gold v0.5.1-0.20230111113000-6ddbe6e6f19f // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 // indirect
github.com/tidwall/gjson v1.14.3 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/sjson v1.1.4 // indirect
github.com/trustbloc/bbs-signature-go v1.0.1 // indirect
github.com/trustbloc/kms-go v1.1.0 // indirect
github.com/trustbloc/logutil-go v0.0.0-20221124174025-c46110e3ea42 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.23.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.11.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
Loading
Loading