From 9a0bdea4700327c1d1b9c9bad597dd0f812ee167 Mon Sep 17 00:00:00 2001 From: gabe Date: Wed, 29 Mar 2023 17:24:58 -0700 Subject: [PATCH 01/22] temp --- config/compose.toml | 1 + config/config.go | 1 + go.mod | 7 +++ go.sum | 19 +++++++- pkg/service/did/handler.go | 3 +- pkg/service/did/ion.go | 98 ++++++++++++++++++++++++++++++++++++++ pkg/service/did/key.go | 26 ++++++---- pkg/service/did/service.go | 22 +++++++-- pkg/service/did/web.go | 31 +++++++----- 9 files changed, 179 insertions(+), 29 deletions(-) create mode 100644 pkg/service/did/ion.go diff --git a/config/compose.toml b/config/compose.toml index 6e2a7acc5..8441717f8 100644 --- a/config/compose.toml +++ b/config/compose.toml @@ -42,6 +42,7 @@ methods = ["key", "web"] resolution_methods = ["key", "web", "pkh", "peer"] universal_resolver_url = "http://uni-resolver-web:8080" universal_resolver_methods = ["ion"] +ion_resolver_url = "https://tbdwebsiteonline.com" [services.schema] name = "schema" diff --git a/config/config.go b/config/config.go index c94e2f778..4360b1042 100644 --- a/config/config.go +++ b/config/config.go @@ -108,6 +108,7 @@ type DIDServiceConfig struct { ResolutionMethods []string `toml:"resolution_methods"` UniversalResolverURL string `toml:"universal_resolver_url"` UniversalResolverMethods []string `toml:"universal_resolver_methods"` + IONResolverURL string `toml:"ion_resolver_url"` } func (d *DIDServiceConfig) IsEmpty() bool { diff --git a/go.mod b/go.mod index 45a86e123..bf16e8c7e 100644 --- a/go.mod +++ b/go.mod @@ -46,6 +46,7 @@ require ( github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/bits-and-blooms/bitset v1.5.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect @@ -54,9 +55,11 @@ require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/validator/v10 v10.12.0 // indirect + github.com/gowebpki/jcs v1.0.0 // indirect github.com/hyperledger/aries-framework-go v0.1.9 // indirect github.com/hyperledger/aries-framework-go/spi v0.0.0-20221025204933-b807371b6f1e // indirect github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/leodido/go-urn v1.2.2 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect @@ -65,14 +68,17 @@ require ( github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/jwx/v2 v2.0.9 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multicodec v0.8.1 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect github.com/piprate/json-gold v0.5.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.2 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.2.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stoewer/go-strcase v1.2.1 // indirect github.com/yuin/gopher-lua v1.1.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect @@ -83,4 +89,5 @@ require ( google.golang.org/protobuf v1.28.1 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/blake3 v1.1.6 // indirect ) diff --git a/go.sum b/go.sum index aa9fbb0c3..8d9330fd6 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328165935-a9e587d94ba5 h1:dWIS0axYmcuSa+4xK0W5hoqINoqjC1Vh4DL4sxfUEYE= -github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328165935-a9e587d94ba5/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262 h1:mMd9kTYtqEHAbiYwtnH94qyY4Meanp0mWkOktrZyVv4= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= @@ -21,6 +19,9 @@ github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ= github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8= github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= +github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= @@ -32,6 +33,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= @@ -66,6 +68,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gowebpki/jcs v1.0.0 h1:0pZtOgGetfH/L7yXb4KWcJqIyZNA43WXFyMd7ftZACw= +github.com/gowebpki/jcs v1.0.0/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/hyperledger/aries-framework-go v0.1.9 h1:qwfjV/zGaH745AMyQwpL3296uRCbM3sJPVFzgW7EBWk= github.com/hyperledger/aries-framework-go v0.1.9/go.mod h1:qrOxEGVsu8M2RahaJgM8nz9AcAHjR/dKd1JIJ3ieJhY= @@ -76,6 +80,9 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI= github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4= @@ -101,6 +108,8 @@ github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNB github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= @@ -111,6 +120,8 @@ github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivnc github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= @@ -136,6 +147,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.2.0 h1:WCcC4vZDS1tYNxjWlwRJZQy28r8CM github.com/santhosh-tekuri/jsonschema/v5 v5.2.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stoewer/go-strcase v1.2.1 h1:/1JWd+AcWPzkcGLEmjUCka99YqGOtTnp1H/wcP+uap4= github.com/stoewer/go-strcase v1.2.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -237,3 +250,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= +lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/pkg/service/did/handler.go b/pkg/service/did/handler.go index 7ff548277..3b2994041 100644 --- a/pkg/service/did/handler.go +++ b/pkg/service/did/handler.go @@ -13,8 +13,9 @@ import ( // https://github.com/TBD54566975/ssi-service/issues/362 type MethodHandler interface { CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) + // TODO(gabe): support query parameters to get soft deleted and other DIDs https://github.com/TBD54566975/ssi-service/issues/364 GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) - GetDIDs(ctx context.Context, method didsdk.Method) (*GetDIDsResponse, error) + GetDIDs(ctx context.Context) (*GetDIDsResponse, error) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error } diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go new file mode 100644 index 000000000..a594f0029 --- /dev/null +++ b/pkg/service/did/ion.go @@ -0,0 +1,98 @@ +package did + +import ( + "context" + "fmt" + "net/http" + + "github.com/TBD54566975/ssi-sdk/did" + "github.com/TBD54566975/ssi-sdk/did/ion" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "github.com/tbd54566975/ssi-service/pkg/service/keystore" +) + +func NewIONHandler(baseURL string, s *Storage, ks *keystore.Service) (MethodHandler, error) { + if baseURL == "" { + return nil, errors.New("baseURL cannot be empty") + } + if s == nil { + return nil, errors.New("storage cannot be empty") + } + if ks == nil { + return nil, errors.New("keystore cannot be empty") + } + r, err := ion.NewIONResolver(http.DefaultClient, baseURL) + if err != nil { + return nil, errors.Wrap(err, "creating ion resolver") + } + return &ionHandler{resolver: r, storage: s, keyStore: ks}, nil +} + +type ionHandler struct { + resolver *ion.Resolver + storage *Storage + keyStore *keystore.Service +} + +func (i *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { + // TODO implement me + panic("implement me") +} + +func (i *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { + id := request.ID + + // TODO(gabe) as we are fully custodying ION DIDs this is fine; as we move to a more decentralized model we will + // need to either remove local storage or treat it as a cache with a TTL + + // first check if the DID is in the storage + gotDID, err := i.storage.GetDID(ctx, id) + if err == nil { + return &GetDIDResponse{DID: gotDID.DID}, nil + } + logrus.WithError(err).Warnf("error getting DID from storage: %s", id) + + // if not, resolve it from the network + resolved, err := i.resolver.Resolve(ctx, request.ID, nil) + if err != nil { + return nil, errors.Wrap(err, "resolving DID from network") + } + return &GetDIDResponse{DID: resolved.Document}, nil +} + +// GetDIDs returns all DIDs we have in storage for ION, it is not feasible to get all DIDs from the network +func (i *ionHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { + logrus.Debug("getting stored did:ion DIDs") + + gotDIDs, err := i.storage.GetDIDs(ctx, did.KeyMethod.String()) + if err != nil { + return nil, fmt.Errorf("error getting did:ion DIDs") + } + dids := make([]did.Document, 0, len(gotDIDs)) + for _, gotDID := range gotDIDs { + if !gotDID.SoftDeleted { + dids = append(dids, gotDID.DID) + } + } + return &GetDIDsResponse{DIDs: dids}, nil +} + +// SoftDeleteDID soft deletes a DID from storage but has no effect on the DID's state on the network +func (i *ionHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { + logrus.Debugf("soft deleting DID: %+v", request) + + id := request.ID + gotStoredDID, err := i.storage.GetDID(ctx, id) + if err != nil { + return fmt.Errorf("error getting DID: %s", id) + } + if gotStoredDID == nil { + return fmt.Errorf("did with id<%s> could not be found", id) + } + + gotStoredDID.SoftDeleted = true + + return i.storage.StoreDID(ctx, *gotStoredDID) +} diff --git a/pkg/service/did/key.go b/pkg/service/did/key.go index a3e959235..a64b2a403 100644 --- a/pkg/service/did/key.go +++ b/pkg/service/did/key.go @@ -13,16 +13,22 @@ import ( "github.com/tbd54566975/ssi-service/pkg/service/keystore" ) -func NewKeyDIDHandler(s *Storage, ks *keystore.Service) MethodHandler { - return &keyDIDHandler{storage: s, keyStore: ks} +func NewKeyHandler(s *Storage, ks *keystore.Service) (MethodHandler, error) { + if s == nil { + return nil, errors.New("storage cannot be empty") + } + if ks == nil { + return nil, errors.New("keystore cannot be empty") + } + return &keyHandler{storage: s, keyStore: ks}, nil } -type keyDIDHandler struct { +type keyHandler struct { storage *Storage keyStore *keystore.Service } -func (h *keyDIDHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { +func (h *keyHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { logrus.Debugf("creating DID: %+v", request) // create the DID @@ -74,7 +80,7 @@ func (h *keyDIDHandler) CreateDID(ctx context.Context, request CreateDIDRequest) }, nil } -func (h *keyDIDHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { +func (h *keyHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { logrus.Debugf("getting DID: %+v", request) id := request.ID @@ -88,12 +94,12 @@ func (h *keyDIDHandler) GetDID(ctx context.Context, request GetDIDRequest) (*Get return &GetDIDResponse{DID: gotDID.DID}, nil } -func (h *keyDIDHandler) GetDIDs(ctx context.Context, method did.Method) (*GetDIDsResponse, error) { - logrus.Debugf("getting DIDs for method: %s", method) +func (h *keyHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { + logrus.Debug("getting did:key DIDs") - gotDIDs, err := h.storage.GetDIDs(ctx, string(method)) + gotDIDs, err := h.storage.GetDIDs(ctx, did.KeyMethod.String()) if err != nil { - return nil, fmt.Errorf("error getting DIDs for method: %s", method) + return nil, fmt.Errorf("error getting did:key DIDs") } dids := make([]did.Document, 0, len(gotDIDs)) for _, gotDID := range gotDIDs { @@ -104,7 +110,7 @@ func (h *keyDIDHandler) GetDIDs(ctx context.Context, method did.Method) (*GetDID return &GetDIDsResponse{DIDs: dids}, nil } -func (h *keyDIDHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { +func (h *keyHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { logrus.Debugf("soft deleting DID: %+v", request) id := request.ID diff --git a/pkg/service/did/service.go b/pkg/service/did/service.go index 42bbc48d1..5238a7e5d 100644 --- a/pkg/service/did/service.go +++ b/pkg/service/did/service.go @@ -105,12 +105,28 @@ func NewDIDService(config config.DIDServiceConfig, s storage.ServiceStorage, key return &service, nil } +// instantiateHandlerForMethod instantiates a handler for the given DID method. All handlers supported by the DID +// service must be instantiated here. func (s *Service) instantiateHandlerForMethod(method didsdk.Method) error { switch method { case didsdk.KeyMethod: - s.handlers[method] = NewKeyDIDHandler(s.storage, s.keyStore) + kh, err := NewKeyHandler(s.storage, s.keyStore) + if err != nil { + return errors.Wrap(err, "instantiating key handler") + } + s.handlers[method] = kh case didsdk.WebMethod: - s.handlers[method] = NewWebDIDHandler(s.storage, s.keyStore) + wh, err := NewWebHandler(s.storage, s.keyStore) + if err != nil { + return errors.Wrap(err, "instantiating web handler") + } + s.handlers[method] = wh + case didsdk.IONMethod: + ih, err := NewIONHandler(s.Config().IONResolverURL, s.storage, s.keyStore) + if err != nil { + return errors.Wrap(err, "instantiating ion handler") + } + s.handlers[method] = ih default: return util.LoggingNewErrorf("unsupported DID method: %s", method) } @@ -184,7 +200,7 @@ func (s *Service) GetDIDsByMethod(ctx context.Context, request GetDIDsRequest) ( if err != nil { return nil, util.LoggingErrorMsgf(err, "could not get handler for method<%s>", method) } - return handler.GetDIDs(ctx, method) + return handler.GetDIDs(ctx) } func (s *Service) SoftDeleteDIDByMethod(ctx context.Context, request DeleteDIDRequest) error { diff --git a/pkg/service/did/web.go b/pkg/service/did/web.go index 173f4363f..1991145e2 100644 --- a/pkg/service/did/web.go +++ b/pkg/service/did/web.go @@ -13,16 +13,22 @@ import ( "github.com/tbd54566975/ssi-service/pkg/service/keystore" ) -func NewWebDIDHandler(s *Storage, ks *keystore.Service) MethodHandler { - return &webDIDHandler{storage: s, keyStore: ks} +func NewWebHandler(s *Storage, ks *keystore.Service) (MethodHandler, error) { + if s == nil { + return nil, errors.New("storage cannot be empty") + } + if ks == nil { + return nil, errors.New("keystore cannot be empty") + } + return &webHandler{storage: s, keyStore: ks}, nil } -type webDIDHandler struct { +type webHandler struct { storage *Storage keyStore *keystore.Service } -func (h *webDIDHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { +func (h *webHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { logrus.Debugf("creating DID: %+v", request) if request.DIDWebID == "" { @@ -87,14 +93,13 @@ func (h *webDIDHandler) CreateDID(ctx context.Context, request CreateDIDRequest) }, nil } -func (h *webDIDHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { - +func (h *webHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { logrus.Debugf("getting DID: %+v", request) id := request.ID gotDID, err := h.storage.GetDID(ctx, id) if err != nil { - return nil, fmt.Errorf("error getting DID: %s", id) + return nil, errors.Wrapf(err, "error getting DID: %s", id) } if gotDID == nil { return nil, fmt.Errorf("did with id<%s> could not be found", id) @@ -102,12 +107,12 @@ func (h *webDIDHandler) GetDID(ctx context.Context, request GetDIDRequest) (*Get return &GetDIDResponse{DID: gotDID.DID}, nil } -func (h *webDIDHandler) GetDIDs(ctx context.Context, method did.Method) (*GetDIDsResponse, error) { - logrus.Debugf("getting DIDs for method: %s", method) +func (h *webHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { + logrus.Debug("getting did:web DID") - gotDIDs, err := h.storage.GetDIDs(ctx, string(method)) + gotDIDs, err := h.storage.GetDIDs(ctx, did.WebMethod.String()) if err != nil { - return nil, fmt.Errorf("error getting DIDs for method: %s", method) + return nil, errors.Wrap(err, "getting did:web DIDs") } dids := make([]did.Document, 0, len(gotDIDs)) for _, gotDID := range gotDIDs { @@ -118,13 +123,13 @@ func (h *webDIDHandler) GetDIDs(ctx context.Context, method did.Method) (*GetDID return &GetDIDsResponse{DIDs: dids}, nil } -func (h *webDIDHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { +func (h *webHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { logrus.Debugf("soft deleting DID: %+v", request) id := request.ID gotStoredDID, err := h.storage.GetDID(ctx, id) if err != nil { - return fmt.Errorf("error getting DID: %s", id) + return errors.Wrapf(err, "getting DID: %s", id) } if gotStoredDID == nil { return fmt.Errorf("did with id<%s> could not be found", id) From 48aa7362f668c58aa4eb6729e5326ec565f9a1a4 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 16:45:21 -0700 Subject: [PATCH 02/22] ion did progress --- go.mod | 2 +- go.sum | 2 + pkg/server/router/did.go | 23 +++- pkg/server/router/did_test.go | 8 +- pkg/server/router/keystore.go | 8 +- pkg/service/did/handler.go | 1 + pkg/service/did/ion.go | 149 +++++++++++++++++++-- pkg/service/did/key.go | 7 +- pkg/service/did/model.go | 18 ++- pkg/service/did/storage.go | 6 +- pkg/service/did/web.go | 33 ++++- pkg/service/keystore/model.go | 1 + pkg/service/keystore/service.go | 4 +- pkg/service/keystore/storage.go | 1 + pkg/testutil/well_known_generation_test.go | 4 +- 15 files changed, 228 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index bf16e8c7e..2de9758da 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/BurntSushi/toml v1.2.1 - github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262 + github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504 github.com/alicebob/miniredis/v2 v2.30.1 github.com/ardanlabs/conf v1.5.0 github.com/benbjohnson/clock v1.3.0 diff --git a/go.sum b/go.sum index 8d9330fd6..f6b66c9d5 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262 h1:mMd9kTYtqEHAbiYwtnH94qyY4Meanp0mWkOktrZyVv4= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= +github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504 h1:SsKoZkq5U3sWDEPozRJiOCUl/p1gR1YPnzzg/nY764Y= +github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= diff --git a/pkg/server/router/did.go b/pkg/server/router/did.go index 94c22c0d9..55e1c3a52 100644 --- a/pkg/server/router/did.go +++ b/pkg/server/router/did.go @@ -60,11 +60,11 @@ func (dr DIDRouter) GetDIDMethods(ctx context.Context, w http.ResponseWriter, _ type CreateDIDByMethodRequest struct { // Identifies the cryptographic algorithm family to use when generating this key. - // One of the following: `"Ed25519","X25519","secp256k1","P-224","P-256","P-384","P-521","RSA"`. + // One of the following: "Ed25519", "X25519", "secp256k1", "P-224","P-256","P-384", "P-521", "RSA" KeyType crypto.KeyType `json:"keyType" validate:"required"` - // Required when creating a DID with the `web` did method. E.g. `did:web:identity.foundation`. - DIDWebID string `json:"didWebId"` + // Options for creating the DID. Implementation dependent on the method. + Options any `json:"options,omitempty"` } type CreateDIDByMethodResponse struct { @@ -110,8 +110,23 @@ func (dr DIDRouter) CreateDIDByMethod(ctx context.Context, w http.ResponseWriter return framework.NewRequestError(errors.Wrap(err, errMsg), http.StatusBadRequest) } + // method wrapper + m := didsdk.Method(*method) + + // make sure we have a valid option type + var opts did.CreateDIDRequestOptions + if request.Options != nil { + var ok bool + opts, ok = request.Options.(did.CreateDIDRequestOptions) + if !ok { + errMsg := fmt.Sprintf("invalid options for method<%s>", *method) + logrus.Error(errMsg) + return framework.NewRequestErrorMsg(errMsg, http.StatusBadRequest) + } + } + // TODO(gabe) check if the key type is supported for the method, to tell whether this is a bad req or internal error - createDIDRequest := did.CreateDIDRequest{Method: didsdk.Method(*method), KeyType: request.KeyType, DIDWebID: request.DIDWebID} + createDIDRequest := did.CreateDIDRequest{Method: m, KeyType: request.KeyType, Options: opts} createDIDResponse, err := dr.service.CreateDIDByMethod(ctx, createDIDRequest) if err != nil { errMsg := fmt.Sprintf("could not create DID for method<%s> with key type: %s", *method, request.KeyType) diff --git a/pkg/server/router/did_test.go b/pkg/server/router/did_test.go index 5e053c8c9..7ff01c775 100644 --- a/pkg/server/router/did_test.go +++ b/pkg/server/router/did_test.go @@ -138,12 +138,13 @@ func TestDIDRouter(t *testing.T) { assert.ElementsMatch(tt, supported.Methods, []didsdk.Method{didsdk.KeyMethod, didsdk.WebMethod}) // bad key type - _, err = didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: "bad", DIDWebID: "did:web:example.com"}) + createOpts := did.CreateWebDIDOptions{URL: "did:web:example.com"} + _, err = didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: "bad", Options: createOpts}) assert.Error(tt, err) assert.Contains(tt, err.Error(), "could not generate key for did:web") // good key type - createDIDResponse, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: crypto.Ed25519, DIDWebID: "did:web:example.com"}) + createDIDResponse, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: crypto.Ed25519, Options: createOpts}) assert.NoError(tt, err) assert.NotEmpty(tt, createDIDResponse) @@ -159,7 +160,8 @@ func TestDIDRouter(t *testing.T) { assert.Equal(tt, createDIDResponse.DID.ID, getDIDResponse.DID.ID) // create a second DID - createDIDResponse2, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: crypto.Ed25519, DIDWebID: "did:web:tbd.website"}) + createOpts = did.CreateWebDIDOptions{URL: "did:web:tbd.website"} + createDIDResponse2, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: crypto.Ed25519, Options: createOpts}) assert.NoError(tt, err) assert.NotEmpty(tt, createDIDResponse2) diff --git a/pkg/server/router/keystore.go b/pkg/server/router/keystore.go index c59f8815d..1f4ae4712 100644 --- a/pkg/server/router/keystore.go +++ b/pkg/server/router/keystore.go @@ -37,14 +37,17 @@ type StoreKeyRequest struct { ID string `json:"id" validate:"required"` // Identifies the cryptographic algorithm family used with the key. - // One of the following: `"Ed25519","X25519","secp256k1","P-224","P-256","P-384","P-521","RSA"`. + // One of the following: "Ed25519", "X25519", "secp256k1", "P-224", "P-256", "P-384", "P-521", "RSA". Type crypto.KeyType `json:"type,omitempty" validate:"required"` // See https://www.w3.org/TR/did-core/#did-controller Controller string `json:"controller,omitempty" validate:"required"` // Base58 encoding of the bytes that result from marshalling the private key using golang's implementation. - PrivateKeyBase58 string `json:"base58PrivateKey,omitempty" validate:"required"` + PrivateKeyBase58 string `json:"base58PrivateKey,omitempty"` + + // JSON Web Key (JWK) representation of the private key. + PrivateKeyJWK crypto.PrivateKeyJWK `json:"jwkPrivateKey,omitempty"` } func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) { @@ -61,6 +64,7 @@ func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) Type: sk.Type, Controller: sk.Controller, PrivateKeyBase58: sk.PrivateKeyBase58, + PrivateKeyJWK: sk.PrivateKeyJWK, }, nil } diff --git a/pkg/service/did/handler.go b/pkg/service/did/handler.go index 3b2994041..100c2485b 100644 --- a/pkg/service/did/handler.go +++ b/pkg/service/did/handler.go @@ -12,6 +12,7 @@ import ( // TODO(gabe) consider smaller/more composable interfaces and promoting reusability across methods // https://github.com/TBD54566975/ssi-service/issues/362 type MethodHandler interface { + GetMethod() didsdk.Method CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) // TODO(gabe): support query parameters to get soft deleted and other DIDs https://github.com/TBD54566975/ssi-service/issues/364 GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index a594f0029..013d4e38a 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -5,14 +5,23 @@ import ( "fmt" "net/http" + "github.com/TBD54566975/ssi-sdk/crypto" "github.com/TBD54566975/ssi-sdk/did" "github.com/TBD54566975/ssi-sdk/did/ion" + "github.com/TBD54566975/ssi-sdk/util" + "github.com/google/uuid" + "github.com/mr-tron/base58" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/tbd54566975/ssi-service/pkg/service/keystore" ) +const ( + updateKeySuffix string = "update" + recoverKeySuffix string = "recover" +) + func NewIONHandler(baseURL string, s *Storage, ks *keystore.Service) (MethodHandler, error) { if baseURL == "" { return nil, errors.New("baseURL cannot be empty") @@ -27,35 +36,151 @@ func NewIONHandler(baseURL string, s *Storage, ks *keystore.Service) (MethodHand if err != nil { return nil, errors.Wrap(err, "creating ion resolver") } - return &ionHandler{resolver: r, storage: s, keyStore: ks}, nil + return &ionHandler{method: did.IONMethod, resolver: r, storage: s, keyStore: ks}, nil } type ionHandler struct { + method did.Method resolver *ion.Resolver storage *Storage keyStore *keystore.Service } -func (i *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { - // TODO implement me - panic("implement me") +type CreateIONDIDOptions struct { + // TODO(gabe) for now we only allow adding service endpoints upon creation. + // we do not allow adding external keys or other properties. + // Related: + // - https://github.com/TBD54566975/ssi-sdk/issues/336 + // - https://github.com/TBD54566975/ssi-sdk/issues/335 + ServiceEndpoints []ion.Service `json:"serviceEndpoints"` +} + +func (c CreateIONDIDOptions) Method() did.Method { + return did.IONMethod +} + +func (h *ionHandler) GetMethod() did.Method { + return h.method +} + +func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { + // process options + if request.Options == nil { + return nil, errors.New("options cannot be empty") + } + opts, ok := request.Options.(CreateIONDIDOptions) + if !ok || request.Options.Method() != did.IONMethod { + return nil, fmt.Errorf("invalid options for method, expected %s, got %s", did.IONMethod, request.Options.Method()) + } + if err := util.IsValidStruct(opts); err != nil { + return nil, errors.Wrap(err, "processing options") + } + + // create a key for the doc + _, privKey, err := crypto.GenerateKeyByKeyType(request.KeyType) + if err != nil { + return nil, errors.Wrap(err, "could not generate key for ion DID") + } + pubKeyJWK, privKeyJWK, err := crypto.PrivateKeyToPrivateKeyJWK(privKey) + if err != nil { + return nil, errors.Wrap(err, "could not convert key to JWK") + } + keyID := uuid.NewString() + pubKeys := []ion.PublicKey{ + { + ID: keyID, + Type: request.KeyType.String(), + PublicKeyJWK: *pubKeyJWK, + // TODO(gabe): configurable purposes + Purposes: []ion.PublicKeyPurpose{ion.Authentication, ion.AssertionMethod}, + }, + } + + // generate the did document's initial state + doc := ion.Document{PublicKeys: pubKeys, Services: opts.ServiceEndpoints} + ionDID, createOp, err := ion.NewIONDID(doc) + if err != nil { + return nil, errors.Wrap(err, "creating new ION DID") + } + + // submit the create operation to the ION service + if err = h.resolver.Anchor(ctx, createOp); err != nil { + return nil, errors.Wrap(err, "anchoring create operation") + } + + // store the did document and associated keys + // 1. update key + // 2. recovery key + // 3. key(s) in the did doc + updateStoreRequest, err := keyToStoreRequest(ionDID.ID()+"#"+updateKeySuffix, ionDID.GetUpdatePrivateKey(), ionDID.ID()) + if err != nil { + return nil, errors.Wrap(err, "converting update private key to store request") + } + if err = h.keyStore.StoreKey(ctx, *updateStoreRequest); err != nil { + return nil, errors.Wrap(err, "could not store did:ion update private key") + } + + recoveryStoreRequest, err := keyToStoreRequest(ionDID.ID()+"#"+recoverKeySuffix, ionDID.GetRecoveryPrivateKey(), ionDID.ID()) + if err != nil { + return nil, errors.Wrap(err, "converting recovery private key to store request") + } + if err = h.keyStore.StoreKey(ctx, *recoveryStoreRequest); err != nil { + return nil, errors.Wrap(err, "could not store did:ion recovery private key") + } + + keyStoreRequest, err := keyToStoreRequest(ionDID.ID()+"#"+keyID, *privKeyJWK, ionDID.ID()) + if err != nil { + return nil, errors.Wrap(err, "converting private key to store request") + } + if err = h.keyStore.StoreKey(ctx, *keyStoreRequest); err != nil { + return nil, errors.Wrap(err, "could not store did:ion private key") + } + + return &CreateDIDResponse{ + DID: storedDID.DID, + PrivateKeyBase58: privKeyBase58, + KeyType: request.KeyType, + }, nil +} + +func keyToStoreRequest(kid string, privateKeyJWK crypto.PrivateKeyJWK, controller string) (*keystore.StoreKeyRequest, error) { + privateKey, err := privateKeyJWK.ToKey() + if err != nil { + return nil, errors.Wrap(err, "getting private private key from JWK") + } + keyType, err := crypto.GetKeyTypeFromPrivateKey(privateKey) + if err != nil { + return nil, errors.Wrap(err, "getting private key type from private privateKeyJWK") + } + // convert to a serialized format + privateKeyBytes, err := crypto.PrivKeyToBytes(privateKey) + if err != nil { + return nil, errors.Wrap(err, "could not encode private key as base58 string") + } + privateKeyBase58 := base58.Encode(privateKeyBytes) + return &keystore.StoreKeyRequest{ + ID: kid, + Type: keyType, + Controller: controller, + PrivateKeyBase58: privateKeyBase58, + }, nil } -func (i *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { +func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { id := request.ID // TODO(gabe) as we are fully custodying ION DIDs this is fine; as we move to a more decentralized model we will // need to either remove local storage or treat it as a cache with a TTL // first check if the DID is in the storage - gotDID, err := i.storage.GetDID(ctx, id) + gotDID, err := h.storage.GetDID(ctx, id) if err == nil { return &GetDIDResponse{DID: gotDID.DID}, nil } logrus.WithError(err).Warnf("error getting DID from storage: %s", id) // if not, resolve it from the network - resolved, err := i.resolver.Resolve(ctx, request.ID, nil) + resolved, err := h.resolver.Resolve(ctx, request.ID, nil) if err != nil { return nil, errors.Wrap(err, "resolving DID from network") } @@ -63,10 +188,10 @@ func (i *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID } // GetDIDs returns all DIDs we have in storage for ION, it is not feasible to get all DIDs from the network -func (i *ionHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { +func (h *ionHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { logrus.Debug("getting stored did:ion DIDs") - gotDIDs, err := i.storage.GetDIDs(ctx, did.KeyMethod.String()) + gotDIDs, err := h.storage.GetDIDs(ctx, did.KeyMethod.String()) if err != nil { return nil, fmt.Errorf("error getting did:ion DIDs") } @@ -80,11 +205,11 @@ func (i *ionHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { } // SoftDeleteDID soft deletes a DID from storage but has no effect on the DID's state on the network -func (i *ionHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { +func (h *ionHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest) error { logrus.Debugf("soft deleting DID: %+v", request) id := request.ID - gotStoredDID, err := i.storage.GetDID(ctx, id) + gotStoredDID, err := h.storage.GetDID(ctx, id) if err != nil { return fmt.Errorf("error getting DID: %s", id) } @@ -94,5 +219,5 @@ func (i *ionHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest gotStoredDID.SoftDeleted = true - return i.storage.StoreDID(ctx, *gotStoredDID) + return h.storage.StoreDID(ctx, *gotStoredDID) } diff --git a/pkg/service/did/key.go b/pkg/service/did/key.go index a64b2a403..34b653172 100644 --- a/pkg/service/did/key.go +++ b/pkg/service/did/key.go @@ -20,14 +20,19 @@ func NewKeyHandler(s *Storage, ks *keystore.Service) (MethodHandler, error) { if ks == nil { return nil, errors.New("keystore cannot be empty") } - return &keyHandler{storage: s, keyStore: ks}, nil + return &keyHandler{method: did.KeyMethod, storage: s, keyStore: ks}, nil } type keyHandler struct { + method did.Method storage *Storage keyStore *keystore.Service } +func (h *keyHandler) GetMethod() did.Method { + return h.method +} + func (h *keyHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { logrus.Debugf("creating DID: %+v", request) diff --git a/pkg/service/did/model.go b/pkg/service/did/model.go index 23456446b..14073311c 100644 --- a/pkg/service/did/model.go +++ b/pkg/service/did/model.go @@ -21,18 +21,24 @@ type ResolveDIDResponse struct { DIDDocumentMetadata *didsdk.DocumentMetadata `json:"didDocumentMetadata,omitempty"` } +type CreateDIDRequestOptions interface { + Method() didsdk.Method +} + // CreateDIDRequest is the JSON-serializable request for creating a DID across DID method type CreateDIDRequest struct { - Method didsdk.Method `json:"method" validate:"required"` - KeyType crypto.KeyType `validate:"required"` - DIDWebID string `json:"didWebId"` + Method didsdk.Method `json:"method" validate:"required"` + KeyType crypto.KeyType `validate:"required"` + Options CreateDIDRequestOptions `json:"options"` } // CreateDIDResponse is the JSON-serializable response for creating a DID type CreateDIDResponse struct { - DID didsdk.Document `json:"did"` - PrivateKeyBase58 string `json:"base58PrivateKey"` - KeyType crypto.KeyType `json:"keyType"` + DID didsdk.Document `json:"did"` + // TODO(gabe): change to returning a set of public keys. private keys should be stored in the keystore, + // and stay within the service boundary. This will unify the solution for both custodial and non-custodial keys. + PrivateKeyBase58 string `json:"base58PrivateKey"` + KeyType crypto.KeyType `json:"keyType"` } type GetDIDRequest struct { diff --git a/pkg/service/did/storage.go b/pkg/service/did/storage.go index 283ee50ca..affe7589a 100644 --- a/pkg/service/did/storage.go +++ b/pkg/service/did/storage.go @@ -17,12 +17,14 @@ const ( namespace = "did" keyNamespace = "key" webNamespace = "web" + ionNamespace = "ion" ) var ( didMethodToNamespace = map[string]string{ - "key": storage.MakeNamespace(namespace, keyNamespace), - "web": storage.MakeNamespace(namespace, webNamespace), + keyNamespace: storage.MakeNamespace(namespace, keyNamespace), + webNamespace: storage.MakeNamespace(namespace, webNamespace), + ionNamespace: storage.MakeNamespace(namespace, ionNamespace), } ) diff --git a/pkg/service/did/web.go b/pkg/service/did/web.go index 1991145e2..fb1d52149 100644 --- a/pkg/service/did/web.go +++ b/pkg/service/did/web.go @@ -6,6 +6,7 @@ import ( "github.com/TBD54566975/ssi-sdk/crypto" "github.com/TBD54566975/ssi-sdk/did" + "github.com/TBD54566975/ssi-sdk/util" "github.com/mr-tron/base58" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -20,22 +21,43 @@ func NewWebHandler(s *Storage, ks *keystore.Service) (MethodHandler, error) { if ks == nil { return nil, errors.New("keystore cannot be empty") } - return &webHandler{storage: s, keyStore: ks}, nil + return &webHandler{method: did.WebMethod, storage: s, keyStore: ks}, nil } type webHandler struct { + method did.Method storage *Storage keyStore *keystore.Service } +type CreateWebDIDOptions struct { + URL string `json:"url" validate:"required"` +} + +func (c CreateWebDIDOptions) Method() did.Method { + return did.WebMethod +} + +func (h *webHandler) GetMethod() did.Method { + return h.method +} + func (h *webHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { logrus.Debugf("creating DID: %+v", request) - if request.DIDWebID == "" { - return nil, errors.New("url is empty, cannot create did:web") + // process options + if request.Options == nil { + return nil, errors.New("options cannot be empty") + } + opts, ok := request.Options.(CreateWebDIDOptions) + if !ok || request.Options.Method() != did.WebMethod { + return nil, fmt.Errorf("invalid options for method, expected %s, got %s", did.WebMethod, request.Options.Method()) + } + if err := util.IsValidStruct(opts); err != nil { + return nil, errors.Wrap(err, "processing options") } - didWeb := did.DIDWeb(request.DIDWebID) + didWeb := did.DIDWeb(opts.URL) if !didWeb.IsValid() { return nil, fmt.Errorf("did:web is not valid, could not resolve did:web DID: %s", didWeb) @@ -76,6 +98,7 @@ func (h *webHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* // store private key in key storage keyStoreRequest := keystore.StoreKeyRequest{ + // TODO(gabe): this should be a unique ID for the key ID: id, Type: request.KeyType, Controller: id, @@ -83,7 +106,7 @@ func (h *webHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* } if err = h.keyStore.StoreKey(ctx, keyStoreRequest); err != nil { - return nil, errors.Wrap(err, "could not store did:key private key") + return nil, errors.Wrap(err, "could not store did:web private key") } return &CreateDIDResponse{ diff --git a/pkg/service/keystore/model.go b/pkg/service/keystore/model.go index 879944afc..3a0c6ba87 100644 --- a/pkg/service/keystore/model.go +++ b/pkg/service/keystore/model.go @@ -11,6 +11,7 @@ type StoreKeyRequest struct { Type crypto.KeyType Controller string PrivateKeyBase58 string + PrivateKeyJWK crypto.PrivateKeyJWK } type GetKeyRequest struct { diff --git a/pkg/service/keystore/service.go b/pkg/service/keystore/service.go index 32ce7daad..fdffb147a 100644 --- a/pkg/service/keystore/service.go +++ b/pkg/service/keystore/service.go @@ -10,9 +10,10 @@ import ( "github.com/mr-tron/base58" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/tbd54566975/ssi-service/internal/keyaccess" "golang.org/x/crypto/chacha20poly1305" + "github.com/tbd54566975/ssi-service/internal/keyaccess" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/service/framework" @@ -73,7 +74,6 @@ func NewKeyStoreService(config config.KeyStoreServiceConfig, s storage.ServiceSt } func (s Service) StoreKey(ctx context.Context, request StoreKeyRequest) error { - logrus.Debugf("storing key: %+v", request) // check if the provided key type is supported. support entails being able to serialize/deserialize, in addition diff --git a/pkg/service/keystore/storage.go b/pkg/service/keystore/storage.go index 7ece85558..d16523215 100644 --- a/pkg/service/keystore/storage.go +++ b/pkg/service/keystore/storage.go @@ -106,6 +106,7 @@ func (kss *Storage) getAndSetServiceKey(ctx context.Context) ([]byte, error) { } func (kss *Storage) StoreKey(ctx context.Context, key StoredKey) error { + // TODO(gabe): conflict checking on key id id := key.ID if id == "" { return util.LoggingNewError("could not store key without an ID") diff --git a/pkg/testutil/well_known_generation_test.go b/pkg/testutil/well_known_generation_test.go index 307480196..3600fd508 100644 --- a/pkg/testutil/well_known_generation_test.go +++ b/pkg/testutil/well_known_generation_test.go @@ -14,6 +14,7 @@ import ( "github.com/lestrrat-go/jwx/jwt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/internal/keyaccess" "github.com/tbd54566975/ssi-service/pkg/service/did" @@ -44,7 +45,8 @@ func TestWellKnownGenerationTest(t *testing.T) { createWellKnownDIDConfiguration(tt, didKey, gotKey, origin) - didWeb, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: "web", DIDWebID: "did:web:tbd.website", KeyType: "Ed25519"}) + createOpts := did.CreateWebDIDOptions{URL: "did:web:tbd.website"} + didWeb, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: "web", KeyType: "Ed25519", Options: createOpts}) assert.NoError(tt, err) assert.NotEmpty(tt, didWeb) From a37cbced503b6afd6fee8f9b3e7c6acc5c4d534d Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 17:57:24 -0700 Subject: [PATCH 03/22] generic DID storage --- pkg/server/router/keystore.go | 4 - pkg/service/did/ion.go | 11 +- pkg/service/did/key.go | 12 +- pkg/service/did/storage.go | 104 ++++++++++++++--- pkg/service/did/storage_test.go | 198 ++++++++++++++++++++++++++++++++ pkg/service/did/web.go | 14 +-- pkg/service/keystore/model.go | 1 - 7 files changed, 303 insertions(+), 41 deletions(-) create mode 100644 pkg/service/did/storage_test.go diff --git a/pkg/server/router/keystore.go b/pkg/server/router/keystore.go index 1f4ae4712..47b0ab804 100644 --- a/pkg/server/router/keystore.go +++ b/pkg/server/router/keystore.go @@ -45,9 +45,6 @@ type StoreKeyRequest struct { // Base58 encoding of the bytes that result from marshalling the private key using golang's implementation. PrivateKeyBase58 string `json:"base58PrivateKey,omitempty"` - - // JSON Web Key (JWK) representation of the private key. - PrivateKeyJWK crypto.PrivateKeyJWK `json:"jwkPrivateKey,omitempty"` } func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) { @@ -64,7 +61,6 @@ func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) Type: sk.Type, Controller: sk.Controller, PrivateKeyBase58: sk.PrivateKeyBase58, - PrivateKeyJWK: sk.PrivateKeyJWK, }, nil } diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index 013d4e38a..018011897 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -137,9 +137,8 @@ func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* } return &CreateDIDResponse{ - DID: storedDID.DID, - PrivateKeyBase58: privKeyBase58, - KeyType: request.KeyType, + DID: did.Document{ID: ionDID.ID()}, + KeyType: request.KeyType, }, nil } @@ -173,7 +172,7 @@ func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID // need to either remove local storage or treat it as a cache with a TTL // first check if the DID is in the storage - gotDID, err := h.storage.GetDID(ctx, id) + gotDID, err := h.storage.GetDIDDefault(ctx, id) if err == nil { return &GetDIDResponse{DID: gotDID.DID}, nil } @@ -191,7 +190,7 @@ func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID func (h *ionHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { logrus.Debug("getting stored did:ion DIDs") - gotDIDs, err := h.storage.GetDIDs(ctx, did.KeyMethod.String()) + gotDIDs, err := h.storage.GetDIDsDefault(ctx, did.KeyMethod.String()) if err != nil { return nil, fmt.Errorf("error getting did:ion DIDs") } @@ -209,7 +208,7 @@ func (h *ionHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest logrus.Debugf("soft deleting DID: %+v", request) id := request.ID - gotStoredDID, err := h.storage.GetDID(ctx, id) + gotStoredDID, err := h.storage.GetDIDDefault(ctx, id) if err != nil { return fmt.Errorf("error getting DID: %s", id) } diff --git a/pkg/service/did/key.go b/pkg/service/did/key.go index 34b653172..dfb52a4f2 100644 --- a/pkg/service/did/key.go +++ b/pkg/service/did/key.go @@ -50,7 +50,7 @@ func (h *keyHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* // store metadata in DID storage id := doc.String() - storedDID := StoredDID{ + storedDID := DefaultStoredDID{ ID: id, DID: *expanded, SoftDeleted: false, @@ -89,7 +89,7 @@ func (h *keyHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID logrus.Debugf("getting DID: %+v", request) id := request.ID - gotDID, err := h.storage.GetDID(ctx, id) + gotDID, err := h.storage.GetDIDDefault(ctx, id) if err != nil { return nil, fmt.Errorf("error getting DID: %s", id) } @@ -102,14 +102,14 @@ func (h *keyHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID func (h *keyHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { logrus.Debug("getting did:key DIDs") - gotDIDs, err := h.storage.GetDIDs(ctx, did.KeyMethod.String()) + gotDIDs, err := h.storage.GetDIDsDefault(ctx, did.KeyMethod.String()) if err != nil { return nil, fmt.Errorf("error getting did:key DIDs") } dids := make([]did.Document, 0, len(gotDIDs)) for _, gotDID := range gotDIDs { - if !gotDID.SoftDeleted { - dids = append(dids, gotDID.DID) + if !gotDID.IsSoftDeleted() { + dids = append(dids, gotDID.GetDocument()) } } return &GetDIDsResponse{DIDs: dids}, nil @@ -119,7 +119,7 @@ func (h *keyHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest logrus.Debugf("soft deleting DID: %+v", request) id := request.ID - gotStoredDID, err := h.storage.GetDID(ctx, id) + gotStoredDID, err := h.storage.GetDIDDefault(ctx, id) if err != nil { return fmt.Errorf("error getting DID: %s", id) } diff --git a/pkg/service/did/storage.go b/pkg/service/did/storage.go index affe7589a..2c39de597 100644 --- a/pkg/service/did/storage.go +++ b/pkg/service/did/storage.go @@ -3,6 +3,7 @@ package did import ( "context" "fmt" + "reflect" "github.com/TBD54566975/ssi-sdk/did" "github.com/goccy/go-json" @@ -28,12 +29,33 @@ var ( } ) -type StoredDID struct { +// StoredDID is a DID that has been stored in the database. It is an interface to allow +// for different implementations of DID storage based on the DID method. +type StoredDID interface { + GetID() string + GetDocument() did.Document + IsSoftDeleted() bool +} + +// DefaultStoredDID is the default implementation of StoredDID if no other implementation requirements are needed. +type DefaultStoredDID struct { ID string `json:"id"` DID did.Document `json:"did"` SoftDeleted bool `json:"softDeleted"` } +func (d DefaultStoredDID) GetID() string { + return d.ID +} + +func (d DefaultStoredDID) GetDocument() did.Document { + return d.DID +} + +func (d DefaultStoredDID) IsSoftDeleted() bool { + return d.SoftDeleted +} + type Storage struct { db storage.ServiceStorage } @@ -46,8 +68,8 @@ func NewDIDStorage(db storage.ServiceStorage) (*Storage, error) { } func (ds *Storage) StoreDID(ctx context.Context, did StoredDID) error { - couldNotStoreDIDErr := fmt.Sprintf("could not store DID: %s", did.ID) - ns, err := getNamespaceForDID(did.ID) + couldNotStoreDIDErr := fmt.Sprintf("could not store DID: %s", did.GetID()) + ns, err := getNamespaceForDID(did.GetID()) if err != nil { return util.LoggingErrorMsg(err, couldNotStoreDIDErr) } @@ -55,32 +77,50 @@ func (ds *Storage) StoreDID(ctx context.Context, did StoredDID) error { if err != nil { return util.LoggingErrorMsg(err, couldNotStoreDIDErr) } - return ds.db.Write(ctx, ns, did.ID, didBytes) + return ds.db.Write(ctx, ns, did.GetID(), didBytes) } -func (ds *Storage) GetDID(ctx context.Context, id string) (*StoredDID, error) { +// GetDID attempts to get a DID from the database. It will return an error if it cannot. +// The out parameter must be a pointer to a struct that implements the StoredDID interface. +func (ds *Storage) GetDID(ctx context.Context, id string, out StoredDID) error { + if err := validateOut(out); err != nil { + return errors.Wrap(err, "validating out") + } couldNotGetDIDErr := fmt.Sprintf("could not get DID: %s", id) ns, err := getNamespaceForDID(id) if err != nil { - return nil, util.LoggingErrorMsg(err, couldNotGetDIDErr) + return util.LoggingErrorMsg(err, couldNotGetDIDErr) } docBytes, err := ds.db.Read(ctx, ns, id) if err != nil { - return nil, util.LoggingErrorMsg(err, couldNotGetDIDErr) + return util.LoggingErrorMsg(err, couldNotGetDIDErr) } if len(docBytes) == 0 { err = fmt.Errorf("did not found: %s", id) - return nil, util.LoggingErrorMsg(err, couldNotGetDIDErr) + return util.LoggingErrorMsg(err, couldNotGetDIDErr) } - var stored StoredDID - if err = json.Unmarshal(docBytes, &stored); err != nil { - return nil, util.LoggingErrorMsgf(err, "could not ummarshal stored DID: %s", id) + if err = json.Unmarshal(docBytes, out); err != nil { + return util.LoggingErrorMsgf(err, "could not ummarshal stored DID: %s", id) } - return &stored, nil + return nil +} + +// GetDIDDefault is a convenience method for getting a DID that is stored as a DefaultStoredDID. +func (ds *Storage) GetDIDDefault(ctx context.Context, id string) (*DefaultStoredDID, error) { + outType := new(DefaultStoredDID) + if err := ds.GetDID(ctx, id, outType); err != nil { + return nil, err + } + return outType, nil } // GetDIDs attempts to get all DIDs for a given method. It will return those it can even if it has trouble with some. -func (ds *Storage) GetDIDs(ctx context.Context, method string) ([]StoredDID, error) { +// The out parameter must be a pointer to a struct for a type that implement the StoredDID interface. +// The result is a slice of the type of the out parameter (an array of pointers to the type of the out parameter).) +func (ds *Storage) GetDIDs(ctx context.Context, method string, outType StoredDID) ([]StoredDID, error) { + if err := validateOut(outType); err != nil { + return nil, errors.Wrap(err, "validating the out type") + } couldNotGetDIDsErr := fmt.Sprintf("could not get DIDs for method: %s", method) ns, err := getNamespaceForMethod(method) if err != nil { @@ -94,14 +134,27 @@ func (ds *Storage) GetDIDs(ctx context.Context, method string) ([]StoredDID, err logrus.Infof("no DIDs found for method: %s", method) return nil, nil } - var stored []StoredDID + + out := make([]StoredDID, 0, len(gotDIDs)) for _, didBytes := range gotDIDs { - var nextDID StoredDID + nextDID := reflect.New(reflect.TypeOf(outType).Elem()).Interface() if err = json.Unmarshal(didBytes, &nextDID); err == nil { - stored = append(stored, nextDID) + out = append(out, nextDID.(StoredDID)) } } - return stored, nil + return out, nil +} + +func (ds *Storage) GetDIDsDefault(ctx context.Context, method string) ([]DefaultStoredDID, error) { + gotDIDs, err := ds.GetDIDs(ctx, method, new(DefaultStoredDID)) + if err != nil { + return nil, err + } + typedDIDs := make([]DefaultStoredDID, len(gotDIDs)) + for i, gotDID := range gotDIDs { + typedDIDs[i] = *gotDID.(*DefaultStoredDID) + } + return typedDIDs, nil } func (ds *Storage) DeleteDID(ctx context.Context, id string) error { @@ -116,6 +169,23 @@ func (ds *Storage) DeleteDID(ctx context.Context, id string) error { return nil } +func validateOut(out StoredDID) error { + if out == nil { + return errors.New("cannot be nil") + } + // make sure out is a ptr to a struct + outVal := reflect.ValueOf(out) + if outVal.Kind() != reflect.Ptr { + return fmt.Errorf("must be ptr to a struct; is %T", out) + } + // dereference the pointer + outValDeref := outVal.Elem() + if outValDeref.Kind() != reflect.Struct { + return fmt.Errorf("must be ptr to a struct; is %T", out) + } + return nil +} + func getNamespaceForDID(id string) (string, error) { method, err := util.GetMethodForDID(id) if err != nil { diff --git a/pkg/service/did/storage_test.go b/pkg/service/did/storage_test.go new file mode 100644 index 000000000..2471d87f1 --- /dev/null +++ b/pkg/service/did/storage_test.go @@ -0,0 +1,198 @@ +package did + +import ( + "context" + "os" + "testing" + + didsdk "github.com/TBD54566975/ssi-sdk/did" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/tbd54566975/ssi-service/pkg/storage" +) + +func TestStorage(t *testing.T) { + t.Run("Create bad DID - no namespace", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // create a did + toStore := DefaultStoredDID{ + ID: "did:bad:test", + DID: didsdk.Document{ + ID: "did:bad:test", + }, + SoftDeleted: false, + } + + // store + err = ds.StoreDID(context.Background(), toStore) + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "could not store DID") + }) + + t.Run("Get bad DID - namespace does not exist", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // store + gotDID, err := ds.GetDIDDefault(context.Background(), "did:test:bad") + assert.Error(tt, err) + assert.Empty(tt, gotDID) + assert.Contains(tt, err.Error(), "could not get DID: did:test:bad: no namespace found for DID method: test") + }) + + t.Run("Get bad DID - does not exist", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // store + gotDID, err := ds.GetDIDDefault(context.Background(), "did:key:bad") + assert.Error(tt, err) + assert.Empty(tt, gotDID) + assert.Contains(tt, err.Error(), "could not get DID: did:key:bad") + }) + + t.Run("Create and Get DID", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // create a did + toStore := DefaultStoredDID{ + ID: "did:key:test", + DID: didsdk.Document{ + ID: "did:key:test", + }, + SoftDeleted: false, + } + + // store + err = ds.StoreDID(context.Background(), toStore) + assert.NoError(tt, err) + + // get it back as a default + got, err := ds.GetDIDDefault(context.Background(), "did:key:test") + assert.NoError(tt, err) + assert.Equal(tt, toStore, *got) + + // get it back as a did + outDID := new(DefaultStoredDID) + err = ds.GetDID(context.Background(), "did:key:test", outDID) + assert.NoError(tt, err) + assert.Equal(tt, toStore, *outDID) + }) + + t.Run("Create and Get Multiple DIDs", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // create two dids + toStore1 := DefaultStoredDID{ + ID: "did:key:test-1", + DID: didsdk.Document{ + ID: "did:key:test-1", + }, + SoftDeleted: false, + } + + toStore2 := DefaultStoredDID{ + ID: "did:key:test-2", + DID: didsdk.Document{ + ID: "did:key:test-2", + }, + SoftDeleted: false, + } + + // store + err = ds.StoreDID(context.Background(), toStore1) + assert.NoError(tt, err) + + err = ds.StoreDID(context.Background(), toStore2) + assert.NoError(tt, err) + + // get both back as default + got, err := ds.GetDIDsDefault(context.Background(), didsdk.KeyMethod.String()) + assert.NoError(tt, err) + assert.Len(tt, got, 2) + assert.Contains(tt, got, toStore1) + assert.Contains(tt, got, toStore2) + + // get back as did + gotDIDs, err := ds.GetDIDs(context.Background(), didsdk.KeyMethod.String(), new(DefaultStoredDID)) + assert.NoError(tt, err) + assert.Len(tt, gotDIDs, 2) + assert.Contains(tt, gotDIDs, &toStore1) + assert.Contains(tt, gotDIDs, &toStore2) + }) + + t.Run("Soft delete DID", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // create two dids + toStore1 := DefaultStoredDID{ + ID: "did:key:test-1", + DID: didsdk.Document{ + ID: "did:key:test-1", + }, + SoftDeleted: false, + } + + toStore2 := DefaultStoredDID{ + ID: "did:key:test-2", + DID: didsdk.Document{ + ID: "did:key:test-2", + }, + SoftDeleted: false, + } + + // store + err = ds.StoreDID(context.Background(), toStore1) + assert.NoError(tt, err) + + err = ds.StoreDID(context.Background(), toStore2) + assert.NoError(tt, err) + + // get both and verify there are two + gotDIDs, err := ds.GetDIDsDefault(context.Background(), didsdk.KeyMethod.String()) + assert.NoError(tt, err) + assert.Len(tt, gotDIDs, 2) + + // soft delete one + err = ds.DeleteDID(context.Background(), "did:key:test-1") + assert.NoError(tt, err) + + // get it back + _, err = ds.GetDIDDefault(context.Background(), "did:key:test-1") + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "could not get DID: did:key:test-1") + + // get both and verify there is one + gotDIDs, err = ds.GetDIDsDefault(context.Background(), didsdk.KeyMethod.String()) + assert.NoError(tt, err) + assert.Len(tt, gotDIDs, 1) + assert.Contains(tt, gotDIDs, toStore2) + }) +} + +func setupTestDB(t *testing.T) storage.ServiceStorage { + file, err := os.CreateTemp("", "bolt") + require.NoError(t, err) + name := file.Name() + err = file.Close() + require.NoError(t, err) + s, err := storage.NewStorage(storage.Bolt, name) + require.NoError(t, err) + t.Cleanup(func() { + _ = s.Close() + _ = os.Remove(s.URI()) + }) + return s +} diff --git a/pkg/service/did/web.go b/pkg/service/did/web.go index fb1d52149..e89e3aaf5 100644 --- a/pkg/service/did/web.go +++ b/pkg/service/did/web.go @@ -80,7 +80,7 @@ func (h *webHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* // store metadata in DID storage id := didWeb.String() - storedDID := StoredDID{ + storedDID := DefaultStoredDID{ ID: id, DID: *doc, SoftDeleted: false, @@ -120,27 +120,27 @@ func (h *webHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID logrus.Debugf("getting DID: %+v", request) id := request.ID - gotDID, err := h.storage.GetDID(ctx, id) + gotDID, err := h.storage.GetDIDDefault(ctx, id) if err != nil { return nil, errors.Wrapf(err, "error getting DID: %s", id) } if gotDID == nil { return nil, fmt.Errorf("did with id<%s> could not be found", id) } - return &GetDIDResponse{DID: gotDID.DID}, nil + return &GetDIDResponse{DID: gotDID.GetDocument()}, nil } func (h *webHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { logrus.Debug("getting did:web DID") - gotDIDs, err := h.storage.GetDIDs(ctx, did.WebMethod.String()) + gotDIDs, err := h.storage.GetDIDsDefault(ctx, did.WebMethod.String()) if err != nil { return nil, errors.Wrap(err, "getting did:web DIDs") } dids := make([]did.Document, 0, len(gotDIDs)) for _, gotDID := range gotDIDs { - if !gotDID.SoftDeleted { - dids = append(dids, gotDID.DID) + if !gotDID.IsSoftDeleted() { + dids = append(dids, gotDID.GetDocument()) } } return &GetDIDsResponse{DIDs: dids}, nil @@ -150,7 +150,7 @@ func (h *webHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest logrus.Debugf("soft deleting DID: %+v", request) id := request.ID - gotStoredDID, err := h.storage.GetDID(ctx, id) + gotStoredDID, err := h.storage.GetDIDDefault(ctx, id) if err != nil { return errors.Wrapf(err, "getting DID: %s", id) } diff --git a/pkg/service/keystore/model.go b/pkg/service/keystore/model.go index 3a0c6ba87..879944afc 100644 --- a/pkg/service/keystore/model.go +++ b/pkg/service/keystore/model.go @@ -11,7 +11,6 @@ type StoreKeyRequest struct { Type crypto.KeyType Controller string PrivateKeyBase58 string - PrivateKeyJWK crypto.PrivateKeyJWK } type GetKeyRequest struct { From 3c4a4265217fc3e907d03d383d753efa9e0dbca7 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 18:04:36 -0700 Subject: [PATCH 04/22] merge' --- go.mod | 10 +- go.sum | 1264 ++++++++++++++++++++++++++++- pkg/authorizationserver/oauth2.go | 1 + 3 files changed, 1269 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index f09942dca..dd26e76cd 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/bits-and-blooms/bitset v1.5.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cristalhq/jwt/v4 v4.0.2 // indirect github.com/dave/jennifer v1.4.0 // indirect @@ -63,7 +64,14 @@ require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/validator/v10 v10.12.0 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/gorilla/websocket v1.4.2 // indirect github.com/gowebpki/jcs v1.0.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/hashicorp/go-retryablehttp v0.6.8 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/hyperledger/aries-framework-go v0.1.9 // indirect github.com/hyperledger/aries-framework-go/spi v0.0.0-20221025204933-b807371b6f1e // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -77,9 +85,9 @@ require ( github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/jwx/v2 v2.0.9 // indirect github.com/lestrrat-go/option v1.0.1 // indirect - github.com/minio/sha256-simd v1.0.0 // indirect github.com/magiconair/properties v1.8.1 // indirect github.com/mattn/goveralls v0.0.6 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect diff --git a/go.sum b/go.sum index f6b66c9d5..a3e5e3d64 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,38 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262 h1:mMd9kTYtqEHAbiYwtnH94qyY4Meanp0mWkOktrZyVv4= -github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230328175208-0ce55b2b0262/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v4.0.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504 h1:SsKoZkq5U3sWDEPozRJiOCUl/p1gR1YPnzzg/nY764Y= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= +github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= @@ -13,25 +42,75 @@ github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrG github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/ardanlabs/conf v1.5.0 h1:5TwP6Wu9Xi07eLFEpiCUF3oQXh9UzHMDVnD3u/I5d5c= github.com/ardanlabs/conf v1.5.0/go.mod h1:ILsMo9dMqYzCxDjDXTiwMI0IgxOJd0MOiucbQY2wlJw= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/aws/aws-sdk-go v1.23.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-xray-sdk-go v0.9.4/go.mod h1:XtMKdBQfpVut+tJEwI7+dJFRxxRdxHDyVNp2tHXRq04= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bmatcuk/doublestar/v2 v2.0.3/go.mod h1:QMmcs3H2AUQICWhfzLXz+IYln8lRQmTZRptLie8RgRw= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ= github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8= github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= +github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= +github.com/cockroachdb/cockroach-go v0.0.0-20200312223839-f565e4789405/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= +github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cristalhq/jwt/v4 v4.0.2 h1:g/AD3h0VicDamtlM70GWGElp8kssQEv+5wYd7L9WOhU= +github.com/cristalhq/jwt/v4 v4.0.2/go.mod h1:HnYraSNKDRag1DZP92rYHyrjyQHnVEHPNqesmzs+miQ= +github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= +github.com/dave/jennifer v1.4.0 h1:tNJFJmLDVTLu+v05mVZ88RINa3vQqnyyWkTKWYz0CwE= +github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -40,17 +119,115 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimfeld/httptreemux/v5 v5.5.0 h1:p8jkiMrCuZ0CmhwYLcbNbl7DDo21fozhKHQ2PccwOFQ= github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu93CKPnTLbsidvSw= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v17.12.0-ce-rc1.0.20201201034508-7d75c1d40d88+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/ecordell/optgen v0.0.6 h1:aSknPe6ZUBrjwHGp2+6XfmfCGYGD6W0ZDfCmmsrS7s4= +github.com/ecordell/optgen v0.0.6/go.mod h1:bAPkLVWcBlTX5EkXW0UTPRj3+yjq2I6VLgH8OasuQEM= +github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= +github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= +github.com/elazarl/goproxy v0.0.0-20181003060214-f58a169a71a5/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -58,35 +235,452 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI= github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/attrs v0.1.0/go.mod h1:fmNpaWyHM0tRm8gCZWKx8yY9fvaNLo2PyzBNSrBZ5Hw= +github.com/gobuffalo/buffalo v0.12.8-0.20181004233540-fac9bb505aa8/go.mod h1:sLyT7/dceRXJUxSsE813JTQtA3Eb1vjxWfo/N//vXIY= +github.com/gobuffalo/buffalo v0.13.0/go.mod h1:Mjn1Ba9wpIbpbrD+lIDMy99pQ0H0LiddMIIDGse7qT4= +github.com/gobuffalo/buffalo-plugins v1.0.2/go.mod h1:pOp/uF7X3IShFHyobahTkTLZaeUXwb0GrUTb9ngJWTs= +github.com/gobuffalo/buffalo-plugins v1.0.4/go.mod h1:pWS1vjtQ6uD17MVFWf7i3zfThrEKWlI5+PYLw/NaDB4= +github.com/gobuffalo/buffalo-plugins v1.4.3/go.mod h1:uCzTY0woez4nDMdQjkcOYKanngeUVRO2HZi7ezmAjWY= +github.com/gobuffalo/buffalo-plugins v1.5.1/go.mod h1:jbmwSZK5+PiAP9cC09VQOrGMZFCa/P0UMlIS3O12r5w= +github.com/gobuffalo/buffalo-plugins v1.6.4/go.mod h1:/+N1aophkA2jZ1ifB2O3Y9yGwu6gKOVMtUmJnbg+OZI= +github.com/gobuffalo/buffalo-plugins v1.6.5/go.mod h1:0HVkbgrVs/MnPZ/FOseDMVanCTm2RNcdM0PuXcL1NNI= +github.com/gobuffalo/buffalo-plugins v1.6.7/go.mod h1:ZGZRkzz2PiKWHs0z7QsPBOTo2EpcGRArMEym6ghKYgk= +github.com/gobuffalo/buffalo-plugins v1.6.9/go.mod h1:yYlYTrPdMCz+6/+UaXg5Jm4gN3xhsvsQ2ygVatZV5vw= +github.com/gobuffalo/buffalo-plugins v1.6.11/go.mod h1:eAA6xJIL8OuynJZ8amXjRmHND6YiusVAaJdHDN1Lu8Q= +github.com/gobuffalo/buffalo-plugins v1.8.2/go.mod h1:9te6/VjEQ7pKp7lXlDIMqzxgGpjlKoAcAANdCgoR960= +github.com/gobuffalo/buffalo-plugins v1.8.3/go.mod h1:IAWq6vjZJVXebIq2qGTLOdlXzmpyTZ5iJG5b59fza5U= +github.com/gobuffalo/buffalo-plugins v1.9.4/go.mod h1:grCV6DGsQlVzQwk6XdgcL3ZPgLm9BVxlBmXPMF8oBHI= +github.com/gobuffalo/buffalo-plugins v1.10.0/go.mod h1:4osg8d9s60txLuGwXnqH+RCjPHj9K466cDFRl3PErHI= +github.com/gobuffalo/buffalo-plugins v1.11.0/go.mod h1:rtIvAYRjYibgmWhnjKmo7OadtnxuMG5ZQLr25ozAzjg= +github.com/gobuffalo/buffalo-plugins v1.15.0/go.mod h1:BqSx01nwgKUQr/MArXzFkSD0QvdJidiky1OKgyfgrK8= +github.com/gobuffalo/buffalo-pop v1.0.5/go.mod h1:Fw/LfFDnSmB/vvQXPvcXEjzP98Tc+AudyNWUBWKCwQ8= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.4/go.mod h1:Abh+Jfw475/NWtYMEt+hnJWRiC8INKWibIMyNt1w2Mc= +github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.6/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.7/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.8/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.9/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.10/go.mod h1:X0CFllQjTV5ogsnUrg+Oks2yTI+PU2dGYBJOEI2D1Uo= +github.com/gobuffalo/envy v1.6.11/go.mod h1:Fiq52W7nrHGDggFPhn2ZCcHw4u/rqXkqo+i7FB6EAcg= +github.com/gobuffalo/envy v1.6.12/go.mod h1:qJNrJhKkZpEW0glh5xP2syQHH5kgdmgsKss2Kk8PTP0= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= +github.com/gobuffalo/envy v1.8.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= +github.com/gobuffalo/envy v1.9.0/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= +github.com/gobuffalo/events v1.0.3/go.mod h1:Txo8WmqScapa7zimEQIwgiJBvMECMe9gJjsKNPN3uZw= +github.com/gobuffalo/events v1.0.7/go.mod h1:z8txf6H9jWhQ5Scr7YPLWg/cgXBRj8Q4uYI+rsVCCSQ= +github.com/gobuffalo/events v1.0.8/go.mod h1:A5KyqT1sA+3GJiBE4QKZibse9mtOcI9nw8gGrDdqYGs= +github.com/gobuffalo/events v1.1.3/go.mod h1:9yPGWYv11GENtzrIRApwQRMYSbUgCsZ1w6R503fCfrk= +github.com/gobuffalo/events v1.1.4/go.mod h1:09/YRRgZHEOts5Isov+g9X2xajxdvOAcUuAHIX/O//A= +github.com/gobuffalo/events v1.1.5/go.mod h1:3YUSzgHfYctSjEjLCWbkXP6djH2M+MLaVRzb4ymbAK0= +github.com/gobuffalo/events v1.1.7/go.mod h1:6fGqxH2ing5XMb3EYRq9LEkVlyPGs4oO/eLzh+S8CxY= +github.com/gobuffalo/events v1.1.8/go.mod h1:UFy+W6X6VbCWS8k2iT81HYX65dMtiuVycMy04cplt/8= +github.com/gobuffalo/events v1.1.9/go.mod h1:/0nf8lMtP5TkgNbzYxR6Bl4GzBy5s5TebgNTdRfRbPM= +github.com/gobuffalo/events v1.3.1/go.mod h1:9JOkQVoyRtailYVE/JJ2ZQ/6i4gTjM5t2HsZK4C1cSA= +github.com/gobuffalo/events v1.4.1/go.mod h1:SjXgWKpeSuvQDvGhgMz5IXx3Czu+IbL+XPLR41NvVQY= +github.com/gobuffalo/fizz v1.0.12/go.mod h1:C0sltPxpYK8Ftvf64kbsQa2yiCZY4RZviurNxXdAKwc= +github.com/gobuffalo/fizz v1.9.8/go.mod h1:w1FEn1yKNVCc49KnADGyYGRPH7jFON3ak4Bj1yUudHo= +github.com/gobuffalo/fizz v1.10.0/go.mod h1:J2XGPO0AfJ1zKw7+2BA+6FEGAkyEsdCOLvN93WCT2WI= +github.com/gobuffalo/flect v0.0.0-20180907193754-dc14d8acaf9f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181002182613-4571df4b1daf/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181007231023-ae7ed6bfe683/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181018182602-fd24a256709f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181019110701-3d6f0b585514/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181024204909-8f6be1a8c6c2/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181104133451-1f6e9779237a/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181114183036-47375f6d8328/go.mod h1:0HvNbHdfh+WOvDSIASqJOSxTOWSxCCUF++k/Y53v9rI= +github.com/gobuffalo/flect v0.0.0-20181210151238-24a2b68e0316/go.mod h1:en58vff74S9b99Eg42Dr+/9yPu437QjlNsO/hBYPuOk= +github.com/gobuffalo/flect v0.0.0-20190104192022-4af577e09bf2/go.mod h1:en58vff74S9b99Eg42Dr+/9yPu437QjlNsO/hBYPuOk= +github.com/gobuffalo/flect v0.0.0-20190117212819-a62e61d96794/go.mod h1:397QT6v05LkZkn07oJXXT6y9FCfwC8Pug0WA2/2mE9k= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= +github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= +github.com/gobuffalo/flect v0.2.1/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= +github.com/gobuffalo/genny v0.0.0-20180924032338-7af3a40f2252/go.mod h1:tUTQOogrr7tAQnhajMSH6rv1BVev34H2sa1xNHMy94g= +github.com/gobuffalo/genny v0.0.0-20181003150629-3786a0744c5d/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM= +github.com/gobuffalo/genny v0.0.0-20181005145118-318a41a134cc/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM= +github.com/gobuffalo/genny v0.0.0-20181007153042-b8de7d566757/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA= +github.com/gobuffalo/genny v0.0.0-20181012161047-33e5f43d83a6/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA= +github.com/gobuffalo/genny v0.0.0-20181017160347-90a774534246/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA= +github.com/gobuffalo/genny v0.0.0-20181024195656-51392254bf53/go.mod h1:o9GEH5gn5sCKLVB5rHFC4tq40rQ3VRUzmx6WwmaqISE= +github.com/gobuffalo/genny v0.0.0-20181025145300-af3f81d526b8/go.mod h1:uZ1fFYvdcP8mu0B/Ynarf6dsGvp7QFIpk/QACUuFUVI= +github.com/gobuffalo/genny v0.0.0-20181027191429-94d6cfb5c7fc/go.mod h1:x7SkrQQBx204Y+O9EwRXeszLJDTaWN0GnEasxgLrQTA= +github.com/gobuffalo/genny v0.0.0-20181027195209-3887b7171c4f/go.mod h1:JbKx8HSWICu5zyqWOa0dVV1pbbXOHusrSzQUprW6g+w= +github.com/gobuffalo/genny v0.0.0-20181106193839-7dcb0924caf1/go.mod h1:x61yHxvbDCgQ/7cOAbJCacZQuHgB0KMSzoYcw5debjU= +github.com/gobuffalo/genny v0.0.0-20181107223128-f18346459dbe/go.mod h1:utQD3aKKEsdb03oR+Vi/6ztQb1j7pO10N3OBoowRcSU= +github.com/gobuffalo/genny v0.0.0-20181114215459-0a4decd77f5d/go.mod h1:kN2KZ8VgXF9VIIOj/GM0Eo7YK+un4Q3tTreKOf0q1ng= +github.com/gobuffalo/genny v0.0.0-20181119162812-e8ff4adce8bb/go.mod h1:BA9htSe4bZwBDJLe8CUkoqkypq3hn3+CkoHqVOW718E= +github.com/gobuffalo/genny v0.0.0-20181127225641-2d959acc795b/go.mod h1:l54xLXNkteX/PdZ+HlgPk1qtcrgeOr3XUBBPDbH+7CQ= +github.com/gobuffalo/genny v0.0.0-20181128191930-77e34f71ba2a/go.mod h1:FW/D9p7cEEOqxYA71/hnrkOWm62JZ5ZNxcNIVJEaWBU= +github.com/gobuffalo/genny v0.0.0-20181203165245-fda8bcce96b1/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM= +github.com/gobuffalo/genny v0.0.0-20181203201232-849d2c9534ea/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM= +github.com/gobuffalo/genny v0.0.0-20181206121324-d6fb8a0dbe36/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM= +github.com/gobuffalo/genny v0.0.0-20181207164119-84844398a37d/go.mod h1:y0ysCHGGQf2T3vOhCrGHheYN54Y/REj0ayd0Suf4C/8= +github.com/gobuffalo/genny v0.0.0-20181211165820-e26c8466f14d/go.mod h1:sHnK+ZSU4e2feXP3PA29ouij6PUEiN+RCwECjCTB3yM= +github.com/gobuffalo/genny v0.0.0-20190104222617-a71664fc38e7/go.mod h1:QPsQ1FnhEsiU8f+O0qKWXz2RE4TiDqLVChWkBuh1WaY= +github.com/gobuffalo/genny v0.0.0-20190112155932-f31a84fcacf5/go.mod h1:CIaHCrSIuJ4il6ka3Hub4DR4adDrGoXGEEt2FbBxoIo= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/genny v0.2.0/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.3.0/go.mod h1:ywJ2CoXrTZj7rbS8HTbzv7uybnLKlsNSBhEQ+yFI3E8= +github.com/gobuffalo/genny v0.6.0/go.mod h1:Vigx9VDiNscYpa/LwrURqGXLSIbzTfapt9+K6gF1kTA= +github.com/gobuffalo/genny/v2 v2.0.5/go.mod h1:kRkJuAw9mdI37AiEYjV4Dl+TgkBDYf8HZVjLkqe5eBg= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/github_flavored_markdown v1.0.4/go.mod h1:uRowCdK+q8d/RF0Kt3/DSalaIXbb0De/dmTqMQdkQ4I= +github.com/gobuffalo/github_flavored_markdown v1.0.5/go.mod h1:U0643QShPF+OF2tJvYNiYDLDGDuQmJZXsf/bHOJPsMY= +github.com/gobuffalo/github_flavored_markdown v1.0.7/go.mod h1:w93Pd9Lz6LvyQXEG6DktTPHkOtCbr+arAD5mkwMzXLI= +github.com/gobuffalo/github_flavored_markdown v1.1.0/go.mod h1:TSpTKWcRTI0+v7W3x8dkSKMLJSUpuVitlptCkpeY8ic= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/gogen v0.2.0/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/helpers v0.2.2/go.mod h1:xYbzUdCUpVzLwLnqV8HIjT6hmG0Cs7YIBCJkNM597jw= +github.com/gobuffalo/helpers v0.2.4/go.mod h1:NX7v27yxPDOPTgUFYmJ5ow37EbxdoLraucOGvMNawyk= +github.com/gobuffalo/helpers v0.5.0/go.mod h1:stpgxJ2C7T99NLyAxGUnYMM2zAtBk5NKQR0SIbd05j4= +github.com/gobuffalo/helpers v0.6.0/go.mod h1:pncVrer7x/KRvnL5aJABLAuT/RhKRR9klL6dkUOhyv8= +github.com/gobuffalo/helpers v0.6.1/go.mod h1:wInbDi0vTJKZBviURTLRMFLE4+nF2uRuuL2fnlYo7w4= +github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= +github.com/gobuffalo/httptest v1.0.2/go.mod h1:7T1IbSrg60ankme0aDLVnEY0h056g9M1/ZvpVThtB7E= +github.com/gobuffalo/licenser v0.0.0-20180924033006-eae28e638a42/go.mod h1:Ubo90Np8gpsSZqNScZZkVXXAo5DGhTb+WYFIjlnog8w= +github.com/gobuffalo/licenser v0.0.0-20181025145548-437d89de4f75/go.mod h1:x3lEpYxkRG/XtGCUNkio+6RZ/dlOvLzTI9M1auIwFcw= +github.com/gobuffalo/licenser v0.0.0-20181027200154-58051a75da95/go.mod h1:BzhaaxGd1tq1+OLKObzgdCV9kqVhbTulxOpYbvMQWS0= +github.com/gobuffalo/licenser v0.0.0-20181109171355-91a2a7aac9a7/go.mod h1:m+Ygox92pi9bdg+gVaycvqE8RVSjZp7mWw75+K5NPHk= +github.com/gobuffalo/licenser v0.0.0-20181128165715-cc7305f8abed/go.mod h1:oU9F9UCE+AzI/MueCKZamsezGOOHfSirltllOVeRTAE= +github.com/gobuffalo/licenser v0.0.0-20181203160806-fe900bbede07/go.mod h1:ph6VDNvOzt1CdfaWC+9XwcBnlSTBz2j49PBwum6RFaU= +github.com/gobuffalo/licenser v0.0.0-20181211173111-f8a311c51159/go.mod h1:ve/Ue99DRuvnTaLq2zKa6F4KtHiYf7W046tDjuGYPfM= +github.com/gobuffalo/licenser v1.1.0/go.mod h1:ZVWE6uKUE3rGf7sedUHWVjNWrEgxaUQLVFL+pQiWpfY= +github.com/gobuffalo/logger v0.0.0-20181022175615-46cfb361fc27/go.mod h1:8sQkgyhWipz1mIctHF4jTxmJh1Vxhp7mP8IqbljgJZo= +github.com/gobuffalo/logger v0.0.0-20181027144941-73d08d2bb969/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8= +github.com/gobuffalo/logger v0.0.0-20181027193913-9cf4dd0efe46/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8= +github.com/gobuffalo/logger v0.0.0-20181109185836-3feeab578c17/go.mod h1:oNErH0xLe+utO+OW8ptXMSA5DkiSEDW1u3zGIt8F9Ew= +github.com/gobuffalo/logger v0.0.0-20181117211126-8e9b89b7c264/go.mod h1:5etB91IE0uBlw9k756fVKZJdS+7M7ejVhmpXXiSFj0I= +github.com/gobuffalo/logger v0.0.0-20181127160119-5b956e21995c/go.mod h1:+HxKANrR9VGw9yN3aOAppJKvhO05ctDi63w4mDnKv2U= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM= +github.com/gobuffalo/makr v1.1.5/go.mod h1:Y+o0btAH1kYAMDJW/TX3+oAXEu0bmSLLoC9mIFxtzOw= +github.com/gobuffalo/mapi v1.0.0/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.1.0/go.mod h1:pqQ1XAqvpy/JYtRwoieNps2yU8MFiMxBUpAm2FBtQ50= +github.com/gobuffalo/mapi v1.2.1/go.mod h1:giGJ2AUESRepOFYAzWpq8Gf/s/QDryxoEHisQtFN3cY= +github.com/gobuffalo/meta v0.0.0-20181018155829-df62557efcd3/go.mod h1:XTTOhwMNryif3x9LkTTBO/Llrveezd71u3quLd0u7CM= +github.com/gobuffalo/meta v0.0.0-20181018192820-8c6cef77dab3/go.mod h1:E94EPzx9NERGCY69UWlcj6Hipf2uK/vnfrF4QD0plVE= +github.com/gobuffalo/meta v0.0.0-20181025145500-3a985a084b0a/go.mod h1:YDAKBud2FP7NZdruCSlmTmDOZbVSa6bpK7LJ/A/nlKg= +github.com/gobuffalo/meta v0.0.0-20181114191255-b130ebedd2f7/go.mod h1:K6cRZ29ozr4Btvsqkjvg5nDFTLOgTqf03KA70Ks0ypE= +github.com/gobuffalo/meta v0.0.0-20181127070345-0d7e59dd540b/go.mod h1:RLO7tMvE0IAKAM8wny1aN12pvEKn7EtkBLkUZR00Qf8= +github.com/gobuffalo/meta v0.0.0-20190120163247-50bbb1fa260d/go.mod h1:KKsH44nIK2gA8p0PJmRT9GvWJUdphkDUA8AJEvFWiqM= +github.com/gobuffalo/meta v0.0.0-20190329152330-e161e8a93e3b/go.mod h1:mCRSy5F47tjK8yaIDcJad4oe9fXxY5gLrx3Xx2spK+0= +github.com/gobuffalo/meta v0.3.0/go.mod h1:cpr6mrUX5H/B4wEP86Gdq568TK4+dKUD8oRPl698RUw= +github.com/gobuffalo/mw-basicauth v1.0.3/go.mod h1:dg7+ilMZOKnQFHDefUzUHufNyTswVUviCBgF244C1+0= +github.com/gobuffalo/mw-contenttype v0.0.0-20180802152300-74f5a47f4d56/go.mod h1:7EvcmzBbeCvFtQm5GqF9ys6QnCxz2UM1x0moiWLq1No= +github.com/gobuffalo/mw-csrf v0.0.0-20180802151833-446ff26e108b/go.mod h1:sbGtb8DmDZuDUQoxjr8hG1ZbLtZboD9xsn6p77ppcHo= +github.com/gobuffalo/mw-forcessl v0.0.0-20180802152810-73921ae7a130/go.mod h1:JvNHRj7bYNAMUr/5XMkZaDcw3jZhUZpsmzhd//FFWmQ= +github.com/gobuffalo/mw-i18n v0.0.0-20180802152014-e3060b7e13d6/go.mod h1:91AQfukc52A6hdfIfkxzyr+kpVYDodgAeT5cjX1UIj4= +github.com/gobuffalo/mw-paramlogger v0.0.0-20181005191442-d6ee392ec72e/go.mod h1:6OJr6VwSzgJMqWMj7TYmRUqzNe2LXu/W1rRW4MAz/ME= +github.com/gobuffalo/mw-tokenauth v0.0.0-20181001105134-8545f626c189/go.mod h1:UqBF00IfKvd39ni5+yI5MLMjAf4gX7cDKN/26zDOD6c= +github.com/gobuffalo/nulls v0.2.0/go.mod h1:w4q8RoSCEt87Q0K0sRIZWYeIxkxog5mh3eN3C/n+dUc= +github.com/gobuffalo/nulls v0.3.0/go.mod h1:UP49vd/k+bcaz6m0cHMyuk8oQ7XgLnkfxeiVoPAvBSs= +github.com/gobuffalo/packd v0.0.0-20181027182251-01ad393492c8/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc= +github.com/gobuffalo/packd v0.0.0-20181027190505-aafc0d02c411/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc= +github.com/gobuffalo/packd v0.0.0-20181027194105-7ae579e6d213/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc= +github.com/gobuffalo/packd v0.0.0-20181031195726-c82734870264/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181104210303-d376b15f8e96/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181111195323-b2e760a5f0ff/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181114190715-f25c5d2471d7/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181124090624-311c6248e5fb/go.mod h1:Foenia9ZvITEvG05ab6XpiD5EfBHPL8A6hush8SJ0o8= +github.com/gobuffalo/packd v0.0.0-20181207120301-c49825f8f6f4/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA= +github.com/gobuffalo/packd v0.0.0-20181212173646-eca3b8fd6687/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.2.0/go.mod h1:k2CkHP3bjbqL2GwxwhxUy1DgnlbW644hkLC9iIUvZwY= +github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI= +github.com/gobuffalo/packr v1.13.7/go.mod h1:KkinLIn/n6+3tVXMwg6KkNvWwVsrRAz4ph+jgpk3Z24= +github.com/gobuffalo/packr v1.15.0/go.mod h1:t5gXzEhIviQwVlNx/+3SfS07GS+cZ2hn76WLzPp6MGI= +github.com/gobuffalo/packr v1.15.1/go.mod h1:IeqicJ7jm8182yrVmNbM6PR4g79SjN9tZLH8KduZZwE= +github.com/gobuffalo/packr v1.19.0/go.mod h1:MstrNkfCQhd5o+Ct4IJ0skWlxN8emOq8DsoT1G98VIU= +github.com/gobuffalo/packr v1.20.0/go.mod h1:JDytk1t2gP+my1ig7iI4NcVaXr886+N0ecUga6884zw= +github.com/gobuffalo/packr v1.21.0/go.mod h1:H00jGfj1qFKxscFJSw8wcL4hpQtPe1PfU2wa6sg/SR0= +github.com/gobuffalo/packr v1.22.0/go.mod h1:Qr3Wtxr3+HuQEwWqlLnNW4t1oTvK+7Gc/Rnoi/lDFvA= +github.com/gobuffalo/packr/v2 v2.0.0-rc.8/go.mod h1:y60QCdzwuMwO2R49fdQhsjCPv7tLQFR0ayzxxla9zes= +github.com/gobuffalo/packr/v2 v2.0.0-rc.9/go.mod h1:fQqADRfZpEsgkc7c/K7aMew3n4aF1Kji7+lIZeR98Fc= +github.com/gobuffalo/packr/v2 v2.0.0-rc.10/go.mod h1:4CWWn4I5T3v4c1OsJ55HbHlUEKNWMITG5iIkdr4Px4w= +github.com/gobuffalo/packr/v2 v2.0.0-rc.11/go.mod h1:JoieH/3h3U4UmatmV93QmqyPUdf4wVM9HELaHEu+3fk= +github.com/gobuffalo/packr/v2 v2.0.0-rc.12/go.mod h1:FV1zZTsVFi1DSCboO36Xgs4pzCZBjB/tDV9Cz/lSaR8= +github.com/gobuffalo/packr/v2 v2.0.0-rc.13/go.mod h1:2Mp7GhBFMdJlOK8vGfl7SYtfMP3+5roE39ejlfjw0rA= +github.com/gobuffalo/packr/v2 v2.0.0-rc.14/go.mod h1:06otbrNvDKO1eNQ3b8hst+1010UooI2MFg+B2Ze4MV8= +github.com/gobuffalo/packr/v2 v2.0.0-rc.15/go.mod h1:IMe7H2nJvcKXSF90y4X1rjYIRlNMJYCxEhssBXNZwWs= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/packr/v2 v2.4.0/go.mod h1:ra341gygw9/61nSjAbfwcwh8IrYL4WmR4IsPkPBhQiY= +github.com/gobuffalo/packr/v2 v2.5.2/go.mod h1:sgEE1xNZ6G0FNN5xn9pevVu4nywaxHvgup67xisti08= +github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobuffalo/packr/v2 v2.8.0/go.mod h1:PDk2k3vGevNE3SwVyVRgQCCXETC9SaONCNSXT1Q8M1g= +github.com/gobuffalo/plush v3.7.16+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.20+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.21+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.22+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.23+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.30+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.31+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.32+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.8.2+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.8.3+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush/v4 v4.0.0/go.mod h1:ErFS3UxKqEb8fpFJT7lYErfN/Nw6vHGiDMTjxpk5bQ0= +github.com/gobuffalo/plushgen v0.0.0-20181128164830-d29dcb966cb2/go.mod h1:r9QwptTFnuvSaSRjpSp4S2/4e2D3tJhARYbvEBcKSb4= +github.com/gobuffalo/plushgen v0.0.0-20181203163832-9fc4964505c2/go.mod h1:opEdT33AA2HdrIwK1aibqnTJDVVKXC02Bar/GT1YRVs= +github.com/gobuffalo/plushgen v0.0.0-20181207152837-eedb135bd51b/go.mod h1:Lcw7HQbEVm09sAQrCLzIxuhFbB3nAgp4c55E+UlynR0= +github.com/gobuffalo/plushgen v0.0.0-20190104222512-177cd2b872b3/go.mod h1:tYxCozi8X62bpZyKXYHw1ncx2ZtT2nFvG42kuLwYjoc= +github.com/gobuffalo/plushgen v0.1.2/go.mod h1:3U71v6HWZpVER1nInTXeAwdoRNsRd4W8aeIa1Lyp+Bk= +github.com/gobuffalo/pop v4.8.2+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/pop v4.8.3+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/pop v4.8.4+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/pop v4.13.1+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/pop/v5 v5.0.11/go.mod h1:mZJHJbA3cy2V18abXYuVop2ldEJ8UZ2DK6qOekC5u5g= +github.com/gobuffalo/pop/v5 v5.3.1/go.mod h1:vcEDhh6cJ3WVENqJDFt/6z7zNb7lLnlN8vj3n5G9rYA= +github.com/gobuffalo/release v1.0.35/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4= +github.com/gobuffalo/release v1.0.38/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4= +github.com/gobuffalo/release v1.0.42/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug= +github.com/gobuffalo/release v1.0.52/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug= +github.com/gobuffalo/release v1.0.53/go.mod h1:FdF257nd8rqhNaqtDWFGhxdJ/Ig4J7VcS3KL7n/a+aA= +github.com/gobuffalo/release v1.0.54/go.mod h1:Pe5/RxRa/BE8whDpGfRqSI7D1a0evGK1T4JDm339tJc= +github.com/gobuffalo/release v1.0.61/go.mod h1:mfIO38ujUNVDlBziIYqXquYfBF+8FDHUjKZgYC1Hj24= +github.com/gobuffalo/release v1.0.72/go.mod h1:NP5NXgg/IX3M5XmHmWR99D687/3Dt9qZtTK/Lbwc1hU= +github.com/gobuffalo/release v1.1.1/go.mod h1:Sluak1Xd6kcp6snkluR1jeXAogdJZpFFRzTYRs/2uwg= +github.com/gobuffalo/release v1.1.3/go.mod h1:CuXc5/m+4zuq8idoDt1l4va0AXAn/OSs08uHOfMVr8E= +github.com/gobuffalo/release v1.1.6/go.mod h1:18naWa3kBsqO0cItXZNJuefCKOENpbbUIqRL1g+p6z0= +github.com/gobuffalo/release v1.7.0/go.mod h1:xH2NjAueVSY89XgC4qx24ojEQ4zQ9XCGVs5eXwJTkEs= +github.com/gobuffalo/shoulders v1.0.1/go.mod h1:V33CcVmaQ4gRUmHKwq1fiTXuf8Gp/qjQBUL5tHPmvbA= +github.com/gobuffalo/shoulders v1.0.4/go.mod h1:LqMcHhKRuBPMAYElqOe3POHiZ1x7Ry0BE8ZZ84Bx+k4= +github.com/gobuffalo/syncx v0.0.0-20181120191700-98333ab04150/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobuffalo/syncx v0.0.0-20181120194010-558ac7de985f/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobuffalo/syncx v0.1.0/go.mod h1:Mg/s+5pv7IgxEp6sA+NFpqS4o2x+R9dQNwbwT0iuOGQ= +github.com/gobuffalo/tags v2.0.11+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/tags v2.0.14+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/tags v2.0.15+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/tags v2.1.0+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/tags v2.1.7+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/tags/v3 v3.0.2/go.mod h1:ZQeN6TCTiwAFnS0dNcbDtSgZDwNKSpqajvVtt6mlYpA= +github.com/gobuffalo/tags/v3 v3.1.0/go.mod h1:ZQeN6TCTiwAFnS0dNcbDtSgZDwNKSpqajvVtt6mlYpA= +github.com/gobuffalo/uuid v2.0.3+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE= +github.com/gobuffalo/uuid v2.0.4+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE= +github.com/gobuffalo/uuid v2.0.5+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE= +github.com/gobuffalo/validate v2.0.3+incompatible/go.mod h1:N+EtDe0J8252BgfzQUChBgfd6L93m9weay53EWFVsMM= +github.com/gobuffalo/validate v2.0.4+incompatible/go.mod h1:N+EtDe0J8252BgfzQUChBgfd6L93m9weay53EWFVsMM= +github.com/gobuffalo/validate/v3 v3.0.0/go.mod h1:HFpjq+AIiA2RHoQnQVTFKF/ZpUPXwyw82LgyDPxQ9r0= +github.com/gobuffalo/validate/v3 v3.1.0/go.mod h1:HFpjq+AIiA2RHoQnQVTFKF/ZpUPXwyw82LgyDPxQ9r0= +github.com/gobuffalo/validate/v3 v3.2.0/go.mod h1:PrhDOdDHxtN8KUgMvF3TDL0r1YZXV4sQnyFX/EmeETY= +github.com/gobuffalo/x v0.0.0-20181003152136-452098b06085/go.mod h1:WevpGD+5YOreDJznWevcn8NTmQEW5STSBgIkpkjzqXc= +github.com/gobuffalo/x v0.0.0-20181007152206-913e47c59ca7/go.mod h1:9rDPXaB3kXdKWzMc4odGQQdG2e2DIEmANy5aSJ9yesY= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gofrs/uuid v3.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid/v3 v3.1.2/go.mod h1:xPwMqoocQ1L5G6pXX5BcE7N5jlzn2o19oqAKxwZW/kI= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/gddo v0.0.0-20180828051604-96d2a289f41e/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= +github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/cel-go v0.13.0 h1:z+8OBOcmh7IeKyqwT/6IlnMvy621fYUqnTVPEdegGlU= github.com/google/cel-go v0.13.0/go.mod h1:K2hpQgEjDp18J76a2DKFRlPBPpgRZgi6EbnpDgIhJ8s= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-jsonnet v0.16.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.1.2/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gotestyourself/gotestyourself v1.3.0/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/gowebpki/jcs v1.0.0 h1:0pZtOgGetfH/L7yXb4KWcJqIyZNA43WXFyMd7ftZACw= github.com/gowebpki/jcs v1.0.0/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs= +github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hyperledger/aries-framework-go v0.1.9 h1:qwfjV/zGaH745AMyQwpL3296uRCbM3sJPVFzgW7EBWk= github.com/hyperledger/aries-framework-go v0.1.9/go.mod h1:qrOxEGVsu8M2RahaJgM8nz9AcAHjR/dKd1JIJ3ieJhY= github.com/hyperledger/aries-framework-go/spi v0.0.0-20221025204933-b807371b6f1e h1:SxbXlF39661T9w/L9PhVdtbJfJ51Pm4JYEEW6XfZHEQ= github.com/hyperledger/aries-framework-go/spi v0.0.0-20221025204933-b807371b6f1e/go.mod h1:oryUyWb23l/a3tAP9KW+GBbfcfqp9tZD4y5hSkFrkqI= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inhies/go-bytesize v0.0.0-20201103132853-d0aed0d254f8/go.mod h1:KrtyD5PFj++GKkFS/7/RRrfnRhAMGQwy75GLCHWrCNs= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.3.2/go.mod h1:LvCquS3HbBKwgl7KbX9KyqEIumJAbm1UMcTvGaIf3bM= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.6.0/go.mod h1:yeseQo4xhQbgyJs2c87RAXOH2i624N0Fh1KSPJya7qo= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik= +github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.4.1/go.mod h1:6iSW+JznC0YT+SgBn7rNxoEBsBgSmnC5FwyCekOGUiE= +github.com/jackc/pgx/v4 v4.6.0/go.mod h1:vPh43ZzxijXUVJ+t/EmXBtFmbFVO72cuneCT9oAlxAg= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jandelgado/gcov2lcov v1.0.4-0.20210120124023-b83752c6dc08/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= +github.com/karrick/godirwalk v1.7.7/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= +github.com/karrick/godirwalk v1.7.8/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/karrick/godirwalk v1.10.9/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/karrick/godirwalk v1.15.5/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI= github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/knadh/koanf v0.14.1-0.20201201075439-e0853799f9ec/go.mod h1:H5mEFsTeWizwFXHKtsITL5ipsLTuAMQoGuQpp+1JL9U= +github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4= github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= @@ -108,10 +702,86 @@ github.com/lestrrat-go/jwx/v2 v2.0.9/go.mod h1:K68euYaR95FnL0hIQB8VvzL70vB7pSifb github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/luna-duclos/instrumentedsql v0.0.0-20181127104832-b7d587d28109/go.mod h1:PWUIzhtavmOR965zfawVsHXbEuU1G29BPZ/CB3C7jXk= +github.com/luna-duclos/instrumentedsql v1.1.2/go.mod h1:4LGbEqDnopzNAiyxPPDXhLspyunZxgPTMJBKtC6U0BQ= +github.com/luna-duclos/instrumentedsql v1.1.3/go.mod h1:9J1njvFds+zN7y85EDhN9XNQLANWwZt2ULeIC8yMNYs= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/markbates/deplist v1.0.4/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM= +github.com/markbates/deplist v1.0.5/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM= +github.com/markbates/deplist v1.1.3/go.mod h1:BF7ioVzAJYEtzQN/os4rt8H8Ti3h0T7EoN+7eyALktE= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/going v1.0.2/go.mod h1:UWCk3zm0UKefHZ7l8BNqi26UyiEMniznk8naLdTcy6c= +github.com/markbates/grift v1.0.4/go.mod h1:wbmtW74veyx+cgfwFhlnnMWqhoz55rnHR47oMXzsyVs= +github.com/markbates/hmax v1.0.0/go.mod h1:cOkR9dktiESxIMu+65oc/r/bdY4bE8zZw3OLhLx0X2c= +github.com/markbates/inflect v1.0.0/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88= +github.com/markbates/inflect v1.0.1/go.mod h1:uv3UVNBe5qBIfCm8O8Q+DW+S1EopeyINj+Ikhc7rnCk= +github.com/markbates/inflect v1.0.3/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= +github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= +github.com/markbates/oncer v0.0.0-20180924031910-e862a676800b/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v0.0.0-20180924034138-723ad0170a46/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= +github.com/markbates/refresh v1.4.10/go.mod h1:NDPHvotuZmTmesXxr95C9bjlw1/0frJwtME2dzcVKhc= +github.com/markbates/safe v1.0.0/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/markbates/sigtx v1.0.0/go.mod h1:QF1Hv6Ic6Ca6W+T+DL0Y/ypborFKyvUY9HmuCD4VeTc= +github.com/markbates/willie v1.0.9/go.mod h1:fsrFVWl91+gXpx/6dv715j7i11fYPfZ9ZGfH0DQzY7w= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mattn/goveralls v0.0.6 h1:cr8Y0VMo/MnEZBjxNN/vh6G90SZ7IMb6lms1dzMoO+Y= +github.com/mattn/goveralls v0.0.6/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2/go.mod h1:TjQg8pa4iejrUrjiz0MCtMV38jdMNW4doKSiBrEvCQQ= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/monoculum/formam v0.0.0-20180901015400-4e68be1d79ba/go.mod h1:RKgILGEJq24YyJ2ban8EO0RUVSJlF1pGsEvoLEACr/Q= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/moul/http2curl v0.0.0-20170919181001-9ac6cf4d929b/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= @@ -126,37 +796,225 @@ github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w= +github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.6.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/analytics-go/v4 v4.0.0/go.mod h1:FMx9cLRD9xN+XevPvZ5FDMfignpmcqPP6FUKnJ9/MmE= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/ory/dockertest/v3 v3.5.4/go.mod h1:J8ZUbNB2FOhm1cFZW9xBpDsODqsSWcyYgtJYVPcnF70= +github.com/ory/dockertest/v3 v3.6.3/go.mod h1:EFLcVUOl8qCwp9NyDAcCDtq/QviLtYswW/VbWzUnTNE= +github.com/ory/fosite v0.29.0/go.mod h1:0atSZmXO7CAcs6NPMI/Qtot8tmZYj04Nddoold4S2h0= +github.com/ory/fosite v0.44.0 h1:Z3UjyO11/wlIoa3BotOqcTkfm7kUNA8F7dd8mOMfx0o= +github.com/ory/fosite v0.44.0/go.mod h1:o/G4kAeNn65l6MCod2+KmFfU6JQBSojS7eXys6lKGzM= +github.com/ory/go-acc v0.0.0-20181118080137-ddc355013f90/go.mod h1:sxnvPCxChFuSmTJGj8FdMupeq1BezCiEpDjTUXQ4hf4= +github.com/ory/go-acc v0.2.6 h1:YfI+L9dxI7QCtWn2RbawqO0vXhiThdXu/RgizJBbaq0= +github.com/ory/go-acc v0.2.6/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= +github.com/ory/go-convenience v0.1.0 h1:zouLKfF2GoSGnJwGq+PE/nJAE6dj2Zj5QlTgmMTsTS8= +github.com/ory/go-convenience v0.1.0/go.mod h1:uEY/a60PL5c12nYz4V5cHY03IBmwIAEm8TWB0yn9KNs= +github.com/ory/gojsonreference v0.0.0-20190720135523-6b606c2d8ee8/go.mod h1:wsH1C4nIeeQClDtD5AH7kF1uTS6zWyqfjVDTmB0Em7A= +github.com/ory/gojsonschema v1.1.1-0.20190919112458-f254ca73d5e9/go.mod h1:BNZpdJgB74KOLSsWFvzw6roXg1I6O51WO8roMmW+T7Y= +github.com/ory/herodot v0.6.2/go.mod h1:3BOneqcyBsVybCPAJoi92KN2BpJHcmDqAMcAAaJiJow= +github.com/ory/herodot v0.7.0/go.mod h1:YXKOfAXYdQojDP5sD8m0ajowq3+QXNdtxA+QiUXBwn0= +github.com/ory/herodot v0.8.3/go.mod h1:rvLjxOAlU5omtmgjCfazQX2N82EpMfl3BytBWc1jjsk= +github.com/ory/herodot v0.9.2/go.mod h1:Da2HXR8mpwPbPrH+Gv9qV8mM5gI3v+PoJ69BA4l2RAk= +github.com/ory/jsonschema/v3 v3.0.1/go.mod h1:jgLHekkFk0uiGdEWGleC+tOm6JSSP8cbf17PnBuGXlw= +github.com/ory/ristretto v0.1.1-0.20211108053508-297c39e6640f h1:P3stZofIZ2D+tjaPCrwLAPd2FJa1wmmyMI7phSbZU98= +github.com/ory/ristretto v0.1.1-0.20211108053508-297c39e6640f/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/ory/viper v1.5.6/go.mod h1:TYmpFpKLxjQwvT4f0QPpkOn4sDXU1kDgAwJpgLYiQ28= +github.com/ory/viper v1.7.4/go.mod h1:T6sodNZKNGPpashUOk7EtXz2isovz8oCd57GNVkkNmE= +github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE= +github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM= +github.com/ory/x v0.0.84/go.mod h1:RXLPBG7B+hAViONVg0sHwK+U/ie1Y/NeXrq1JcARfoE= +github.com/ory/x v0.0.93/go.mod h1:lfcTaGXpTZs7IEQAW00r9EtTCOxD//SiP5uWtNiz31g= +github.com/ory/x v0.0.110/go.mod h1:DJfkE3GdakhshNhw4zlKoRaL/ozg/lcTahA9OCih2BE= +github.com/ory/x v0.0.127/go.mod h1:FwUujfFuCj5d+xgLn4fGMYPnzriR5bdAIulFXMtnK0M= +github.com/ory/x v0.0.214 h1:nz5ijvm5MVhYxWsQSuUrW1hj9F5QLZvPn/nLo5s06T4= +github.com/ory/x v0.0.214/go.mod h1:aRl57gzyD4GF0HQCekovXhv0xTZgAgiht3o8eVhsm9Q= +github.com/parnurzeal/gorequest v0.2.15/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= +github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM= github.com/piprate/json-gold v0.5.0/go.mod h1:WZ501QQMbZZ+3pXFPhQKzNwS1+jls0oqov3uQ2WasLs= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.2 h1:RImcxeEeyrbUSm8vE/CGwrBVfaHoWw67n12tv4uXTJw= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.2/go.mod h1:Q8gKWKQVtBG6qkzIozBCE4ZPtuWtr2NTHZbcBf0UIfo= github.com/redis/go-redis/extra/redisotel/v9 v9.0.2 h1:M7X7ZJFESh919eIhL8Rj8fNVlY9LGcsIpE+jFZMyblw= github.com/redis/go-redis/extra/redisotel/v9 v9.0.2/go.mod h1:/uqUz3T+1j2U4Z+hVlN00KI5dluwXY0JzthPxDhjjj4= github.com/redis/go-redis/v9 v9.0.2 h1:BA426Zqe/7r56kCcvxYLWe1mkaz71LKF77GwgFzSxfE= github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= +github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rhnvrm/simples3 v0.5.0/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rubenv/sql-migrate v0.0.0-20190212093014-1007f53448d7/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ= +github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= +github.com/santhosh-tekuri/jsonschema/v2 v2.1.0/go.mod h1:yzJzKUGV4RbWqWIBBP4wSOBqavX5saE02yirLS0OTyg= github.com/santhosh-tekuri/jsonschema/v5 v5.2.0 h1:WCcC4vZDS1tYNxjWlwRJZQy28r8CMoggKnxNzxsVDMQ= github.com/santhosh-tekuri/jsonschema/v5 v5.2.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/seatgeek/logrus-gelf-formatter v0.0.0-20210219220335-367fa274be2c/go.mod h1:/THDZYi7F/BsVEcYzYPqdcWFQ+1C2InkawTKfLOAnzg= +github.com/segmentio/analytics-go v3.0.1+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48= +github.com/segmentio/analytics-go v3.1.0+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48= +github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M= +github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3/go.mod h1:9/Rh6yILuLysoQnZ2oNooD2g7aBnvM7r/fNVxRNWfBc= +github.com/segmentio/conf v1.2.0/go.mod h1:Y3B9O/PqqWqjyxyWWseyj/quPEtMu1zDp/kVbSWWaB0= +github.com/segmentio/go-snakecase v1.1.0/go.mod h1:jk1miR5MS7Na32PZUykG89Arm+1BUSYhuGR6b7+hJto= +github.com/segmentio/objconv v1.0.1/go.mod h1:auayaH5k3137Cl4SoXTgrzQcuQDmvuVtZgS0fb1Ahys= +github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20170515013102-78fb10f4a5f8/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/octicon v0.0.0-20180602230221-c42b0e3b24d9/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.1.0/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= +github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.0/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.2 h1:GDarE4TJQI52kYSbSAmLiId1Elfj+xgSDqrUZxFhxlU= +github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.2-0.20200723214538-8d17101741c8 h1:GbJaXkBXPYlxE45H4g2wo0Hb4TGzv/YbHVA1OGqx+mo= +github.com/spf13/cast v1.3.2-0.20200723214538-8d17101741c8/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI= +github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= +github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693/go.mod h1:6hSY48PjDm4UObWmGLyJE9DxYVKTgR9kbCspXXJEhcU= github.com/stoewer/go-strcase v1.2.1 h1:/1JWd+AcWPzkcGLEmjUCka99YqGOtTnp1H/wcP+uap4= github.com/stoewer/go-strcase v1.2.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -165,50 +1023,275 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.1.1/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/gjson v1.7.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y= +github.com/tidwall/sjson v1.1.5/go.mod h1:VuJzsZnTowhSxWdOgsAnb886i4AjEyTkk7tNtsL7EYE= +github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= +github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/unrolled/secure v0.0.0-20180918153822-f340ee86eb8b/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA= +github.com/unrolled/secure v0.0.0-20181005190816-ff9db2ff917f/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.einride.tech/aip v0.60.0 h1:h6bgabZ5BCfAptbGex8jbh3VvPBRLa6xq+pQ1CAjHYw= go.einride.tech/aip v0.60.0/go.mod h1:SdLbSbgSU60Xkb4TMkmsZEQPHeEWx0ikBoq5QnqZvdg= +go.elastic.co/apm v1.8.0/go.mod h1:tCw6CkOJgkWnzEthFN9HUP1uL3Gjc/Ur6m7gRPLaoH0= +go.elastic.co/apm/module/apmhttp v1.8.0/go.mod h1:9LPFlEON51/lRbnWDfqAWErihIiAFDUMfMV27YjoWQ8= +go.elastic.co/apm/module/apmot v1.8.0/go.mod h1:Q5Xzabte8G/fkvDjr1jlDuOSUt9hkVWNZEHh6ZNaTjI= +go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= +go.opentelemetry.io/contrib v0.18.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.18.0/go.mod h1:iK1G0FgHurSJ/aYLg5LpnPI0pqdanM73S3dhyDp0Lk4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 h1:lE9EJyw3/JhrjWH/hEy9FptnalDQgj7vpbgC2KCCCxE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0/go.mod h1:pcQ3MM3SWvrA71U4GDqv9UFDJ3HQsW7y5ZO3tDTlUdI= +go.opentelemetry.io/otel v0.18.0/go.mod h1:PT5zQj4lTsR1YeARt8YNKcFb88/c2IKoSABK9mX0r78= go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= +go.opentelemetry.io/otel/metric v0.18.0/go.mod h1:kEH2QtzAyBy3xDVQfGZKIcok4ZZFvd5xyKPfPcuK6pE= go.opentelemetry.io/otel/metric v0.35.0/go.mod h1:qAcbhaTRFU6uG8QM7dDo7XvFsWcugziq/5YI065TokQ= go.opentelemetry.io/otel/metric v0.37.0 h1:pHDQuLQOZwYD+Km0eb657A25NaRzy0a+eLyKfDXedEs= go.opentelemetry.io/otel/metric v0.37.0/go.mod h1:DmdaHfGt54iV6UKxsV9slj2bBRJcKC1B1uvDLIioc1s= +go.opentelemetry.io/otel/oteltest v0.18.0/go.mod h1:NyierCU3/G8DLTva7KRzGii2fdxdR89zXKH1bNWY7Bo= go.opentelemetry.io/otel/sdk v1.12.0/go.mod h1:WYcvtgquYvgODEvxOry5owO2y9MyciW7JqMz6cpXShE= go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= +go.opentelemetry.io/otel/trace v0.18.0/go.mod h1:FzdUu3BPwZSZebfQ1vl5/tAa8LyMLXSJN57AXIt/iDk= go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181024171144-74cb1d3d52f4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190102171810-8d7daa0c54b3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180816102801-aaf60122140d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200219183655-46282727080f/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180921163948-d47a0f339242/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180927150500-dad3d9fb7b6e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181011152604-fa43e7bc11ba/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181022134430-8a28ead16f52/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181024145615-5cd93ef61a7c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026064943-731415f00dce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181106135930-3a76605856fd/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -223,34 +1306,205 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181003024731-2f84ea8ef872/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181006002542-f60d9635b16a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181013182035-5e66757b835f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181017214349-06f26fdaaa28/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181024171208-a2dc47679d30/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181105230042-78dc5bac0cac/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181107215632-34b416bd17b3/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181114190951-94339b83286c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181119130350-139d099f6620/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181127195227-b4e97c0ed882/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181127232545-e782529d0ddd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181203210056-e5f3ab76ea4b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181205224935-3576414c54a4/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181206194817-bcd4e47d0288/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181207183836-8bc39b988060/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181212172921-837e80568c09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190102213336-ca9055ed7d04/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190104182027-498d95493402/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190111214448-fc1d57b08d7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190118193359-16909d206f00/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190613204242-ed0dc450797f/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190711191110-9a621aea19f8/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191224055732-dd894d0a8a40/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200203215610-ab391d50b528/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20191229114700-bbb4dff026f8/go.mod h1:2IgXn/sJaRbePPBA1wRj8OE+QLvVaH0q8SK6TSTKlnk= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.0.0-20200111075622-4abb28f724d5/go.mod h1:+HbaZVpsa73UwN7kXGCECULRHovLRJjH+t5cFPgxErs= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20230221151758-ace64dc21148 h1:muK+gVBJBfFb4SejshDBlN2/UgxCCOKH9Y34ljqEGOc= google.golang.org/genproto v0.0.0-20230221151758-ace64dc21148/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc/examples v0.0.0-20210304020650-930c79186c99/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/DataDog/dd-trace-go.v1 v1.27.0/go.mod h1:Sp1lku8WJMvNV0kjDI4Ni/T7J/U3BO5ct5kEaoVU8+I= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/mold.v2 v2.2.0/go.mod h1:XMyyRsGtakkDPbxXbrA5VODo6bUXyvoDjLd5l3T0XoA= gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= +gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.1.9/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614 h1:lwJmuuJQGclcankpPJwh8rorzB0bNbVALv8phDGh8TQ= +gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/validator.v2 v2.0.0-20180514200540-135c24b11c19/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= +modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= +modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= +modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/pkg/authorizationserver/oauth2.go b/pkg/authorizationserver/oauth2.go index 72d60f600..2544a2287 100644 --- a/pkg/authorizationserver/oauth2.go +++ b/pkg/authorizationserver/oauth2.go @@ -16,6 +16,7 @@ import ( "github.com/ory/fosite/storage" "github.com/ory/fosite/token/jwt" "github.com/sirupsen/logrus" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/server/framework" "github.com/tbd54566975/ssi-service/pkg/server/middleware" From 2759457aba5f81b2a0d4e2d131b8374e09e4508d Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 18:48:28 -0700 Subject: [PATCH 05/22] ion logic --- pkg/service/did/ion.go | 85 ++++++++++++++++++++++++++++----- pkg/service/did/storage_test.go | 47 ++++++++++++++++++ 2 files changed, 120 insertions(+), 12 deletions(-) diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index 018011897..b1176247d 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -63,6 +63,26 @@ func (h *ionHandler) GetMethod() did.Method { return h.method } +type ionStoredDID struct { + ID string `json:"id"` + DID did.Document `json:"did"` + SoftDeleted bool `json:"softDeleted"` + LongFormDID string `json:"longFormDID"` + Operations []any `json:"operations"` +} + +func (i ionStoredDID) GetID() string { + return i.ID +} + +func (i ionStoredDID) GetDocument() did.Document { + return i.DID +} + +func (i ionStoredDID) IsSoftDeleted() bool { + return i.SoftDeleted +} + func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { // process options if request.Options == nil { @@ -108,7 +128,47 @@ func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* return nil, errors.Wrap(err, "anchoring create operation") } - // store the did document and associated keys + // construct first document state + ldKeyType, err := did.KeyTypeToLDKeyType(request.KeyType) + if err != nil { + return nil, errors.Wrap(err, "converting key type to LD key type") + } + + // TODO(gabe): move this to the SDK + didDoc := did.Document{ + ID: ionDID.ID(), + VerificationMethod: []did.VerificationMethod{ + { + ID: keyID, + Type: ldKeyType, + Controller: ionDID.ID(), + PublicKeyJWK: pubKeyJWK, + }, + }, + Authentication: []did.VerificationMethodSet{map[string]any{"id": keyID}}, + AssertionMethod: []did.VerificationMethodSet{map[string]any{"id": keyID}}, + } + for _, s := range opts.ServiceEndpoints { + didDoc.Services = append(didDoc.Services, did.Service{ + ID: s.ID, + Type: s.Type, + ServiceEndpoint: s.ServiceEndpoint, + }) + } + + // store the did document + storedDID := ionStoredDID{ + ID: ionDID.ID(), + DID: didDoc, + SoftDeleted: false, + LongFormDID: ionDID.LongForm(), + Operations: ionDID.Operations(), + } + if err = h.storage.StoreDID(ctx, storedDID); err != nil { + return nil, errors.Wrap(err, "storing ion did document") + } + + // store associated keys // 1. update key // 2. recovery key // 3. key(s) in the did doc @@ -137,7 +197,7 @@ func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* } return &CreateDIDResponse{ - DID: did.Document{ID: ionDID.ID()}, + DID: didDoc, KeyType: request.KeyType, }, nil } @@ -172,8 +232,9 @@ func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID // need to either remove local storage or treat it as a cache with a TTL // first check if the DID is in the storage - gotDID, err := h.storage.GetDIDDefault(ctx, id) - if err == nil { + gotDID := new(ionStoredDID) + err := h.storage.GetDID(ctx, id, gotDID) + if err != nil { return &GetDIDResponse{DID: gotDID.DID}, nil } logrus.WithError(err).Warnf("error getting DID from storage: %s", id) @@ -190,14 +251,14 @@ func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID func (h *ionHandler) GetDIDs(ctx context.Context) (*GetDIDsResponse, error) { logrus.Debug("getting stored did:ion DIDs") - gotDIDs, err := h.storage.GetDIDsDefault(ctx, did.KeyMethod.String()) + gotDIDs, err := h.storage.GetDIDs(ctx, did.KeyMethod.String(), new(ionStoredDID)) if err != nil { return nil, fmt.Errorf("error getting did:ion DIDs") } dids := make([]did.Document, 0, len(gotDIDs)) for _, gotDID := range gotDIDs { - if !gotDID.SoftDeleted { - dids = append(dids, gotDID.DID) + if !gotDID.IsSoftDeleted() { + dids = append(dids, gotDID.GetDocument()) } } return &GetDIDsResponse{DIDs: dids}, nil @@ -208,15 +269,15 @@ func (h *ionHandler) SoftDeleteDID(ctx context.Context, request DeleteDIDRequest logrus.Debugf("soft deleting DID: %+v", request) id := request.ID - gotStoredDID, err := h.storage.GetDIDDefault(ctx, id) - if err != nil { + gotDID := new(ionStoredDID) + if err := h.storage.GetDID(ctx, id, gotDID); err != nil { return fmt.Errorf("error getting DID: %s", id) } - if gotStoredDID == nil { + if gotDID.GetID() == "" { return fmt.Errorf("did with id<%s> could not be found", id) } - gotStoredDID.SoftDeleted = true + gotDID.SoftDeleted = true - return h.storage.StoreDID(ctx, *gotStoredDID) + return h.storage.StoreDID(ctx, *gotDID) } diff --git a/pkg/service/did/storage_test.go b/pkg/service/did/storage_test.go index 2471d87f1..a2b6c3f9a 100644 --- a/pkg/service/did/storage_test.go +++ b/pkg/service/did/storage_test.go @@ -87,6 +87,33 @@ func TestStorage(t *testing.T) { assert.Equal(tt, toStore, *outDID) }) + t.Run("Create and Get DID of a custom type", func(tt *testing.T) { + ds, err := NewDIDStorage(setupTestDB(tt)) + assert.NoError(tt, err) + assert.NotEmpty(tt, ds) + + // create a did + toStore := customStoredDID{ + ID: "did:key:test", + Party: false, + } + + // store + err = ds.StoreDID(context.Background(), toStore) + assert.NoError(tt, err) + + // get it back as a default - which won't be equal + got, err := ds.GetDIDDefault(context.Background(), "did:key:test") + assert.NoError(tt, err) + assert.NotEqual(tt, toStore, *got) + + // get it back as a custom did + outDID := new(customStoredDID) + err = ds.GetDID(context.Background(), "did:key:test", outDID) + assert.NoError(tt, err) + assert.Equal(tt, toStore, *outDID) + }) + t.Run("Create and Get Multiple DIDs", func(tt *testing.T) { ds, err := NewDIDStorage(setupTestDB(tt)) assert.NoError(tt, err) @@ -196,3 +223,23 @@ func setupTestDB(t *testing.T) storage.ServiceStorage { }) return s } + +// new stored DID type +type customStoredDID struct { + ID string `json:"id,omitempty"` + Party bool `json:"party,omitempty"` +} + +func (d customStoredDID) GetID() string { + return d.ID +} + +func (d customStoredDID) GetDocument() didsdk.Document { + return didsdk.Document{ + ID: d.ID, + } +} + +func (d customStoredDID) IsSoftDeleted() bool { + return d.Party +} From d671331782d87b2df5749b88e6231cc34cb42bac Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 21:57:50 -0700 Subject: [PATCH 06/22] temp: --- go.mod | 2 + go.sum | 4 ++ pkg/service/did/ion.go | 25 +++++++---- pkg/service/did/ion_test.go | 87 +++++++++++++++++++++++++++++++++++++ pkg/service/did/storage.go | 1 + 5 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 pkg/service/did/ion_test.go diff --git a/go.mod b/go.mod index dd26e76cd..43fae4f03 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( go.opentelemetry.io/otel/trace v1.14.0 golang.org/x/crypto v0.7.0 gopkg.in/go-playground/validator.v9 v9.31.0 + gopkg.in/h2non/gock.v1 v1.1.2 ) replace github.com/dgraph-io/ristretto => github.com/ory/ristretto v0.1.1-0.20211108053508-297c39e6640f @@ -69,6 +70,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/gowebpki/jcs v1.0.0 // indirect + github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/hashicorp/go-cleanhttp v0.5.1 // indirect github.com/hashicorp/go-retryablehttp v0.6.8 // indirect github.com/hashicorp/hcl v1.0.0 // indirect diff --git a/go.sum b/go.sum index a3e5e3d64..18b20816c 100644 --- a/go.sum +++ b/go.sum @@ -573,6 +573,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= @@ -797,6 +798,8 @@ github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -1464,6 +1467,7 @@ gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWd gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index b1176247d..8ff74ca24 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -2,8 +2,10 @@ package did import ( "context" + gocrypto "crypto" "fmt" "net/http" + "reflect" "github.com/TBD54566975/ssi-sdk/crypto" "github.com/TBD54566975/ssi-sdk/did" @@ -85,15 +87,16 @@ func (i ionStoredDID) IsSoftDeleted() bool { func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (*CreateDIDResponse, error) { // process options - if request.Options == nil { - return nil, errors.New("options cannot be empty") - } - opts, ok := request.Options.(CreateIONDIDOptions) - if !ok || request.Options.Method() != did.IONMethod { - return nil, fmt.Errorf("invalid options for method, expected %s, got %s", did.IONMethod, request.Options.Method()) - } - if err := util.IsValidStruct(opts); err != nil { - return nil, errors.Wrap(err, "processing options") + var opts CreateIONDIDOptions + var ok bool + if request.Options != nil { + opts, ok = request.Options.(CreateIONDIDOptions) + if !ok || request.Options.Method() != did.IONMethod { + return nil, fmt.Errorf("invalid options for method, expected %s, got %s", did.IONMethod, request.Options.Method()) + } + if err := util.IsValidStruct(opts); err != nil { + return nil, errors.Wrap(err, "processing options") + } } // create a key for the doc @@ -207,6 +210,10 @@ func keyToStoreRequest(kid string, privateKeyJWK crypto.PrivateKeyJWK, controlle if err != nil { return nil, errors.Wrap(err, "getting private private key from JWK") } + if reflect.ValueOf(privateKey).Kind() == reflect.Ptr { + // dereference the ptr + privateKey = reflect.ValueOf(privateKey).Elem().Interface().(gocrypto.PrivateKey) + } keyType, err := crypto.GetKeyTypeFromPrivateKey(privateKey) if err != nil { return nil, errors.Wrap(err, "getting private key type from private privateKeyJWK") diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go new file mode 100644 index 000000000..3bc216084 --- /dev/null +++ b/pkg/service/did/ion_test.go @@ -0,0 +1,87 @@ +package did + +import ( + "context" + "testing" + + "github.com/TBD54566975/ssi-sdk/crypto" + "github.com/TBD54566975/ssi-sdk/did" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/h2non/gock.v1" + + "github.com/tbd54566975/ssi-service/config" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" + "github.com/tbd54566975/ssi-service/pkg/storage" +) + +func TestIONHandler(t *testing.T) { + t.Run("Test Create ION Handler", func(tt *testing.T) { + handler, err := NewIONHandler("", nil, nil) + assert.Error(tt, err) + assert.Empty(tt, handler) + assert.Contains(tt, err.Error(), "baseURL cannot be empty") + + s := setupTestDB(tt) + keystoreService := testKeyStoreService(tt, s) + didStorage, err := NewDIDStorage(s) + assert.NoError(tt, err) + handler, err = NewIONHandler("bad", nil, keystoreService) + assert.Error(tt, err) + assert.Empty(tt, handler) + assert.Contains(tt, err.Error(), "storage cannot be empty") + + handler, err = NewIONHandler("bad", didStorage, nil) + assert.Error(tt, err) + assert.Empty(tt, handler) + assert.Contains(tt, err.Error(), "keystore cannot be empty") + + handler, err = NewIONHandler("bad", didStorage, keystoreService) + assert.Error(tt, err) + assert.Empty(tt, handler) + assert.Contains(tt, err.Error(), "invalid resolver URL") + + handler, err = NewIONHandler("https://example.com", didStorage, keystoreService) + assert.NoError(tt, err) + assert.NotEmpty(tt, handler) + + assert.Equal(tt, handler.GetMethod(), did.IONMethod) + }) + + t.Run("Test Create DIDs", func(tt *testing.T) { + // create a handler + s := setupTestDB(tt) + keystoreService := testKeyStoreService(tt, s) + didStorage, err := NewDIDStorage(s) + assert.NoError(tt, err) + handler, err := NewIONHandler("https://test-ion-resolver.com", didStorage, keystoreService) + assert.NoError(tt, err) + assert.NotEmpty(tt, handler) + + gock.New("https://test-ion-resolver.com"). + Post("/operations"). + Reply(200) + defer gock.Off() + + // create a did + created, err := handler.CreateDID(context.Background(), CreateDIDRequest{ + Method: did.IONMethod, + KeyType: crypto.Ed25519, + }) + assert.NoError(tt, err) + assert.NotEmpty(tt, created) + }) +} + +func testKeyStoreService(t *testing.T, db storage.ServiceStorage) *keystore.Service { + serviceConfig := config.KeyStoreServiceConfig{ + BaseServiceConfig: &config.BaseServiceConfig{Name: "test-keystore"}, + ServiceKeyPassword: "test-password", + } + + // create a keystore service + keystoreService, err := keystore.NewKeyStoreService(serviceConfig, db) + require.NoError(t, err) + require.NotEmpty(t, keystoreService) + return keystoreService +} diff --git a/pkg/service/did/storage.go b/pkg/service/did/storage.go index 2c39de597..49f848f68 100644 --- a/pkg/service/did/storage.go +++ b/pkg/service/did/storage.go @@ -178,6 +178,7 @@ func validateOut(out StoredDID) error { if outVal.Kind() != reflect.Ptr { return fmt.Errorf("must be ptr to a struct; is %T", out) } + // dereference the pointer outValDeref := outVal.Elem() if outValDeref.Kind() != reflect.Struct { From dc4e6cd4655b917eed50195569be26f0a7a95441 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 22:28:12 -0700 Subject: [PATCH 07/22] test ion did handler in unit test --- go.mod | 2 +- go.sum | 2 ++ pkg/service/did/ion.go | 10 ++---- pkg/service/did/ion_test.go | 66 +++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 43fae4f03..f24cf8d59 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/BurntSushi/toml v1.2.1 - github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504 + github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230401051839-bca28f8b0fea github.com/alicebob/miniredis/v2 v2.30.1 github.com/ardanlabs/conf v1.5.0 github.com/benbjohnson/clock v1.3.0 diff --git a/go.sum b/go.sum index 18b20816c..b9e2f7247 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,8 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504 h1:SsKoZkq5U3sWDEPozRJiOCUl/p1gR1YPnzzg/nY764Y= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= +github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230401051839-bca28f8b0fea h1:+0dl8nqYYkewqiiYKxhk3RK7ivOOzweeYa08DFOU3fE= +github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230401051839-bca28f8b0fea/go.mod h1:9SNGqEkRihpNbgilFDRRmgi8Gi/l7/l0eyO+3Prubro= github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index 8ff74ca24..74cfc7292 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -2,10 +2,8 @@ package did import ( "context" - gocrypto "crypto" "fmt" "net/http" - "reflect" "github.com/TBD54566975/ssi-sdk/crypto" "github.com/TBD54566975/ssi-sdk/did" @@ -206,14 +204,10 @@ func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* } func keyToStoreRequest(kid string, privateKeyJWK crypto.PrivateKeyJWK, controller string) (*keystore.StoreKeyRequest, error) { - privateKey, err := privateKeyJWK.ToKey() + privateKey, err := privateKeyJWK.ToPrivateKey() if err != nil { return nil, errors.Wrap(err, "getting private private key from JWK") } - if reflect.ValueOf(privateKey).Kind() == reflect.Ptr { - // dereference the ptr - privateKey = reflect.ValueOf(privateKey).Elem().Interface().(gocrypto.PrivateKey) - } keyType, err := crypto.GetKeyTypeFromPrivateKey(privateKey) if err != nil { return nil, errors.Wrap(err, "getting private key type from private privateKeyJWK") @@ -241,7 +235,7 @@ func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID // first check if the DID is in the storage gotDID := new(ionStoredDID) err := h.storage.GetDID(ctx, id, gotDID) - if err != nil { + if err == nil { return &GetDIDResponse{DID: gotDID.DID}, nil } logrus.WithError(err).Warnf("error getting DID from storage: %s", id) diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go index 3bc216084..a5bff21c1 100644 --- a/pkg/service/did/ion_test.go +++ b/pkg/service/did/ion_test.go @@ -2,6 +2,7 @@ package did import ( "context" + "fmt" "testing" "github.com/TBD54566975/ssi-sdk/crypto" @@ -70,6 +71,71 @@ func TestIONHandler(t *testing.T) { }) assert.NoError(tt, err) assert.NotEmpty(tt, created) + assert.Equal(tt, crypto.Ed25519, created.KeyType) + }) + + t.Run("Test Get DID from storage", func(tt *testing.T) { + // create a handler + s := setupTestDB(tt) + keystoreService := testKeyStoreService(tt, s) + didStorage, err := NewDIDStorage(s) + assert.NoError(tt, err) + handler, err := NewIONHandler("https://test-ion-resolver.com", didStorage, keystoreService) + assert.NoError(tt, err) + assert.NotEmpty(tt, handler) + + gock.New("https://test-ion-resolver.com"). + Post("/operations"). + Reply(200) + defer gock.Off() + + // create a did + created, err := handler.CreateDID(context.Background(), CreateDIDRequest{ + Method: did.IONMethod, + KeyType: crypto.Ed25519, + }) + assert.NoError(tt, err) + assert.NotEmpty(tt, created) + assert.Equal(tt, crypto.Ed25519, created.KeyType) + + gock.New("https://test-ion-resolver.com"). + Get("/identifiers/" + created.DID.ID). + Reply(200).BodyString(fmt.Sprintf(`{"didDocument": {"id": "%s"}}`, created.DID.ID)) + defer gock.Off() + + // get the did + gotDID, err := handler.GetDID(context.Background(), GetDIDRequest{ + Method: did.IONMethod, + ID: created.DID.ID, + }) + assert.NoError(tt, err) + assert.NotEmpty(tt, gotDID) + assert.Equal(tt, created.DID.ID, gotDID.DID.ID) + }) + + t.Run("Test Get DID from resolver", func(tt *testing.T) { + // create a handler + s := setupTestDB(tt) + keystoreService := testKeyStoreService(tt, s) + didStorage, err := NewDIDStorage(s) + assert.NoError(tt, err) + handler, err := NewIONHandler("https://test-ion-resolver.com", didStorage, keystoreService) + assert.NoError(tt, err) + assert.NotEmpty(tt, handler) + + gock.New("https://test-ion-resolver.com"). + Get("/identifiers/did:ion:test"). + Reply(200).BodyString(`{"didDocument": {"id": "did:ion:test"}}`) + defer gock.Off() + + // get the did + gotDID, err := handler.GetDID(context.Background(), GetDIDRequest{ + Method: did.IONMethod, + ID: "did:ion:test", + }) + assert.NoError(tt, err) + assert.NotEmpty(tt, gotDID) + assert.Equal(tt, "did:ion:test", gotDID.DID.ID) }) } From 982128a2e0867b74efea1375896fcf0670adddd7 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 22:35:18 -0700 Subject: [PATCH 08/22] integration test --- integration/common.go | 11 + .../credential_revocation_integration_test.go | 1 - integration/didion_integration_test.go | 188 ++++++++++++++++++ integration/didweb_integration_test.go | 3 +- integration/testdata/did-ion-input.json | 3 + pkg/server/server_did_test.go | 1 + 6 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 integration/didion_integration_test.go create mode 100644 integration/testdata/did-ion-input.json diff --git a/integration/common.go b/integration/common.go index e861850b5..303f142bb 100644 --- a/integration/common.go +++ b/integration/common.go @@ -17,6 +17,7 @@ import ( "github.com/oliveagle/jsonpath" "github.com/pkg/errors" "github.com/sirupsen/logrus" + credmodel "github.com/tbd54566975/ssi-service/internal/credential" "github.com/tbd54566975/ssi-service/internal/keyaccess" ) @@ -53,6 +54,16 @@ func CreateDIDWeb() (string, error) { return output, nil } +func CreateDIDION() (string, error) { + logrus.Println("\n\nCreate a did:ion") + output, err := put(endpoint+version+"dids/ion", getJSONFromFile("did-ion-input.json")) + if err != nil { + return "", errors.Wrapf(err, "did endpoint with output: %s", output) + } + + return output, nil +} + func ResolveDID(did string) (string, error) { logrus.Println("\n\nResolve a did") output, err := get(endpoint + version + "dids/resolver/" + did) diff --git a/integration/credential_revocation_integration_test.go b/integration/credential_revocation_integration_test.go index 5488e3fbc..acb3fabaa 100644 --- a/integration/credential_revocation_integration_test.go +++ b/integration/credential_revocation_integration_test.go @@ -24,7 +24,6 @@ func TestRevocationCreateIssuerDIDKeyIntegration(t *testing.T) { assert.NoError(t, err) assert.Contains(t, issuerDID, "did:key") - } func TestRevocationCreateSchemaIntegration(t *testing.T) { diff --git a/integration/didion_integration_test.go b/integration/didion_integration_test.go new file mode 100644 index 000000000..b2da7a27a --- /dev/null +++ b/integration/didion_integration_test.go @@ -0,0 +1,188 @@ +package integration + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/tbd54566975/ssi-service/pkg/service/operation/storage" +) + +var didIONContext = NewTestContext("DIDION") + +func TestCreateIssuerDIDIONIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + didIONOutput, err := CreateDIDION() + assert.NoError(t, err) + + issuerDID, err := getJSONElement(didIONOutput, "$.did.id") + SetValue(didIONContext, "issuerDID", issuerDID) + + assert.NoError(t, err) + assert.Contains(t, issuerDID, "did:ion") +} + +func TestCreateAliceDIDIONIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + didIONOutput, err := CreateDIDION() + assert.NoError(t, err) + assert.NotEmpty(t, didIONOutput) + + aliceDID, err := getJSONElement(didIONOutput, "$.did.id") + SetValue(didIONContext, "aliceDID", aliceDID) + + assert.NoError(t, err) + assert.Contains(t, aliceDID, "did:ion") + + aliceDIDPrivateKey, err := getJSONElement(didIONOutput, "$.privateKeyBase58") + SetValue(didIONContext, "aliceDIDPrivateKey", aliceDIDPrivateKey) + assert.NoError(t, err) + assert.NotEmpty(t, aliceDID) +} + +func TestDIDIONCreateSchemaIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + output, err := CreateKYCSchema() + assert.NoError(t, err) + + schemaID, err := getJSONElement(output, "$.id") + SetValue(didIONContext, "schemaID", schemaID) + + assert.NoError(t, err) + assert.NotEmpty(t, schemaID) +} + +func TestDIDIONCreateVerifiableCredentialIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + issuerDID, err := GetValue(didIONContext, "issuerDID") + assert.NoError(t, err) + assert.NotEmpty(t, issuerDID) + + schemaID, err := GetValue(didIONContext, "schemaID") + assert.NoError(t, err) + assert.NotEmpty(t, schemaID) + + vcOutput, err := CreateVerifiableCredential(credInputParams{ + IssuerID: issuerDID.(string), + SchemaID: schemaID.(string), + SubjectID: issuerDID.(string), + }, false) + assert.NoError(t, err) + assert.NotEmpty(t, vcOutput) + + credentialJWT, err := getJSONElement(vcOutput, "$.credentialJwt") + SetValue(didIONContext, "credentialJWT", credentialJWT) + assert.NoError(t, err) + assert.NotEmpty(t, credentialJWT) +} + +func TestDIDIONCreateCredentialManifestIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + issuerDID, err := GetValue(didIONContext, "issuerDID") + assert.NoError(t, err) + assert.NotEmpty(t, issuerDID) + + schemaID, err := GetValue(didIONContext, "schemaID") + assert.NoError(t, err) + assert.NotEmpty(t, schemaID) + + cmOutput, err := CreateCredentialManifest(credManifestParams{ + IssuerID: issuerDID.(string), + SchemaID: schemaID.(string), + }) + assert.NoError(t, err) + + presentationDefinitionID, err := getJSONElement(cmOutput, "$.credential_manifest.presentation_definition.id") + SetValue(didIONContext, "presentationDefinitionID", presentationDefinitionID) + assert.NoError(t, err) + assert.NotEmpty(t, presentationDefinitionID) + + manifestID, err := getJSONElement(cmOutput, "$.credential_manifest.id") + SetValue(didIONContext, "manifestID", manifestID) + assert.NoError(t, err) + assert.NotEmpty(t, manifestID) +} + +func TestDIDIONSubmitAndReviewApplicationIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + credentialJWT, err := GetValue(didIONContext, "credentialJWT") + assert.NoError(t, err) + assert.NotEmpty(t, credentialJWT) + + presentationDefinitionID, err := GetValue(didIONContext, "presentationDefinitionID") + assert.NoError(t, err) + assert.NotEmpty(t, presentationDefinitionID) + + manifestID, err := GetValue(didIONContext, "manifestID") + assert.NoError(t, err) + assert.NotEmpty(t, manifestID) + + aliceDID, err := GetValue(didIONContext, "aliceDID") + assert.NoError(t, err) + assert.NotEmpty(t, aliceDID) + + aliceDIDPrivateKey, err := GetValue(didIONContext, "aliceDIDPrivateKey") + assert.NoError(t, err) + assert.NotEmpty(t, aliceDIDPrivateKey) + + credAppJWT, err := CreateCredentialApplicationJWT(credApplicationParams{ + DefinitionID: presentationDefinitionID.(string), + ManifestID: manifestID.(string), + }, credentialJWT.(string), aliceDID.(string), aliceDIDPrivateKey.(string)) + assert.NoError(t, err) + assert.NotEmpty(t, credAppJWT) + + submitApplicationOutput, err := SubmitApplication(applicationParams{ + ApplicationJWT: credAppJWT, + }) + assert.NoError(t, err) + assert.NotEmpty(t, submitApplicationOutput) + + isDone, err := getJSONElement(submitApplicationOutput, "$.done") + assert.NoError(t, err) + assert.Equal(t, "false", isDone) + opID, err := getJSONElement(submitApplicationOutput, "$.id") + assert.NoError(t, err) + + reviewApplicationOutput, err := ReviewApplication(reviewApplicationParams{ + ID: storage.StatusObjectID(opID), + Approved: true, + Reason: "oh yeah im testing", + }) + assert.NoError(t, err) + crManifestID, err := getJSONElement(reviewApplicationOutput, "$.credential_response.manifest_id") + assert.NoError(t, err) + assert.Equal(t, manifestID, crManifestID) + + vc, err := getJSONElement(reviewApplicationOutput, "$.verifiableCredentials[0]") + assert.NoError(t, err) + assert.NotEmpty(t, vc) + + operationOutput, err := get(endpoint + version + "operations/" + opID) + assert.NoError(t, err) + isDone, err = getJSONElement(operationOutput, "$.done") + assert.NoError(t, err) + assert.Equal(t, "true", isDone) + + opCredentialResponse, err := getJSONElement(operationOutput, "$.result.response") + assert.NoError(t, err) + assert.JSONEq(t, reviewApplicationOutput, opCredentialResponse) +} diff --git a/integration/didweb_integration_test.go b/integration/didweb_integration_test.go index faa61240a..0d912e018 100644 --- a/integration/didweb_integration_test.go +++ b/integration/didweb_integration_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/tbd54566975/ssi-service/pkg/service/operation/storage" ) @@ -22,7 +23,6 @@ func TestCreateIssuerDIDWebIntegration(t *testing.T) { assert.NoError(t, err) assert.Contains(t, issuerDID, "did:web") - } func TestCreateAliceDIDWebIntegration(t *testing.T) { @@ -44,7 +44,6 @@ func TestCreateAliceDIDWebIntegration(t *testing.T) { SetValue(didWebContext, "aliceDIDPrivateKey", aliceDIDPrivateKey) assert.NoError(t, err) assert.NotEmpty(t, aliceDID) - } func TestDIDWebCreateSchemaIntegration(t *testing.T) { diff --git a/integration/testdata/did-ion-input.json b/integration/testdata/did-ion-input.json new file mode 100644 index 000000000..9d7bf8ea8 --- /dev/null +++ b/integration/testdata/did-ion-input.json @@ -0,0 +1,3 @@ +{ + "keyType":"Ed25519" +} \ No newline at end of file diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index 0f1497976..c2a8cf00b 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -121,6 +121,7 @@ func TestDIDAPI(t *testing.T) { // reset recorder between calls w.Flush() + // store a DID createDIDRequest := router.CreateDIDByMethodRequest{KeyType: crypto.Ed25519} requestReader := newRequestValue(tt, createDIDRequest) From fee399f01f5c9598601f4e5a7879321e8c8869e7 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 22:38:36 -0700 Subject: [PATCH 09/22] lint --- pkg/server/server_did_test.go | 2 +- pkg/service/did/ion.go | 2 +- pkg/service/did/ion_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index c2a8cf00b..131415cf0 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -121,7 +121,7 @@ func TestDIDAPI(t *testing.T) { // reset recorder between calls w.Flush() - + // store a DID createDIDRequest := router.CreateDIDByMethodRequest{KeyType: crypto.Ed25519} requestReader := newRequestValue(tt, createDIDRequest) diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index 74cfc7292..70cb8ad27 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -227,7 +227,7 @@ func keyToStoreRequest(kid string, privateKeyJWK crypto.PrivateKeyJWK, controlle } func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { - id := request.ID + // id := request.ID // TODO(gabe) as we are fully custodying ION DIDs this is fine; as we move to a more decentralized model we will // need to either remove local storage or treat it as a cache with a TTL diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go index a5bff21c1..dcdf75316 100644 --- a/pkg/service/did/ion_test.go +++ b/pkg/service/did/ion_test.go @@ -49,7 +49,7 @@ func TestIONHandler(t *testing.T) { assert.Equal(tt, handler.GetMethod(), did.IONMethod) }) - t.Run("Test Create DIDs", func(tt *testing.T) { + t.Run("Test Create DID", func(tt *testing.T) { // create a handler s := setupTestDB(tt) keystoreService := testKeyStoreService(tt, s) From 0f0d4292760fab24ba483f3c46f9f4fd48ebf8ba Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 22:38:53 -0700 Subject: [PATCH 10/22] whoops --- pkg/service/did/ion.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index 70cb8ad27..4d28b8c74 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -227,7 +227,7 @@ func keyToStoreRequest(kid string, privateKeyJWK crypto.PrivateKeyJWK, controlle } func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDIDResponse, error) { - // id := request.ID + id := request.ID // TODO(gabe) as we are fully custodying ION DIDs this is fine; as we move to a more decentralized model we will // need to either remove local storage or treat it as a cache with a TTL @@ -241,7 +241,7 @@ func (h *ionHandler) GetDID(ctx context.Context, request GetDIDRequest) (*GetDID logrus.WithError(err).Warnf("error getting DID from storage: %s", id) // if not, resolve it from the network - resolved, err := h.resolver.Resolve(ctx, request.ID, nil) + resolved, err := h.resolver.Resolve(ctx, id, nil) if err != nil { return nil, errors.Wrap(err, "resolving DID from network") } From ba47a2cbdc55d8c2079915f39657dd7daef75fdc Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 31 Mar 2023 23:05:50 -0700 Subject: [PATCH 11/22] add ion to config --- config/compose.toml | 4 ++-- config/config.toml | 4 ++-- pkg/service/did/ion_test.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/config/compose.toml b/config/compose.toml index 8441717f8..b53fcef8c 100644 --- a/config/compose.toml +++ b/config/compose.toml @@ -38,8 +38,8 @@ password = "default-password" [services.did] name = "did" -methods = ["key", "web"] -resolution_methods = ["key", "web", "pkh", "peer"] +methods = ["key", "web", "ion"] +resolution_methods = ["key", "web", "pkh", "peer", "ion"] universal_resolver_url = "http://uni-resolver-web:8080" universal_resolver_methods = ["ion"] ion_resolver_url = "https://tbdwebsiteonline.com" diff --git a/config/config.toml b/config/config.toml index 8d3027105..9d2ab626e 100644 --- a/config/config.toml +++ b/config/config.toml @@ -38,8 +38,8 @@ password = "default-password" [services.did] name = "did" -methods = ["key", "web"] -resolution_methods = ["key", "web", "pkh", "peer"] +methods = ["key", "web", "ion"] +resolution_methods = ["key", "web", "pkh", "peer", "ion"] universal_resolver_url = "http://localhost:8088" universal_resolver_methods = ["ion"] diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go index dcdf75316..48e4aef81 100644 --- a/pkg/service/did/ion_test.go +++ b/pkg/service/did/ion_test.go @@ -74,6 +74,34 @@ func TestIONHandler(t *testing.T) { assert.Equal(tt, crypto.Ed25519, created.KeyType) }) + t.Run("Test Create DID", func(tt *testing.T) { + // create a handler + s := setupTestDB(tt) + keystoreService := testKeyStoreService(tt, s) + didStorage, err := NewDIDStorage(s) + assert.NoError(tt, err) + handler, err := NewIONHandler("https://tbdwebsiteonline.com", didStorage, keystoreService) + assert.NoError(tt, err) + assert.NotEmpty(tt, handler) + + // create a did + created, err := handler.CreateDID(context.Background(), CreateDIDRequest{ + Method: did.IONMethod, + KeyType: crypto.Ed25519, + }) + assert.NoError(tt, err) + assert.NotEmpty(tt, created) + assert.Equal(tt, crypto.Ed25519, created.KeyType) + + // get the did + gotDID, err := handler.GetDID(context.Background(), GetDIDRequest{ + Method: did.IONMethod, + ID: created.DID.ID, + }) + assert.NoError(tt, err) + assert.NotEmpty(tt, gotDID) + }) + t.Run("Test Get DID from storage", func(tt *testing.T) { // create a handler s := setupTestDB(tt) From 422178db7b71bd5b9596b0a7fb3740fdde5ad86e Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 13:05:19 -0700 Subject: [PATCH 12/22] better tests --- config/compose.toml | 2 +- config/config.go | 8 +- config/config.toml | 2 +- config/config.toml.example | 2 +- integration/didion_integration_test.go | 1 + internal/did/resolver.go | 5 +- internal/util/util.go | 20 +++ pkg/authorizationserver/oauth2_test.go | 2 +- pkg/server/router/did.go | 80 +++++++--- pkg/server/router/did_test.go | 8 +- pkg/server/router/testutils_test.go | 5 +- pkg/server/server.go | 2 +- pkg/server/server_did_test.go | 168 ++++++++++++++++++++- pkg/server/server_test.go | 24 ++- pkg/service/did/ion_test.go | 2 +- pkg/service/did/resolution/resolver.go | 22 +-- pkg/service/did/service.go | 3 +- pkg/service/did/web.go | 7 +- pkg/service/webhook/model.go | 2 +- pkg/service/webhook/service.go | 2 +- pkg/testutil/well_known_generation_test.go | 6 +- 21 files changed, 301 insertions(+), 72 deletions(-) diff --git a/config/compose.toml b/config/compose.toml index b53fcef8c..1f53666de 100644 --- a/config/compose.toml +++ b/config/compose.toml @@ -39,7 +39,7 @@ password = "default-password" [services.did] name = "did" methods = ["key", "web", "ion"] -resolution_methods = ["key", "web", "pkh", "peer", "ion"] +local_resolution_methods = ["key", "web", "pkh", "peer"] universal_resolver_url = "http://uni-resolver-web:8080" universal_resolver_methods = ["ion"] ion_resolver_url = "https://tbdwebsiteonline.com" diff --git a/config/config.go b/config/config.go index 4360b1042..25a50a303 100644 --- a/config/config.go +++ b/config/config.go @@ -105,7 +105,7 @@ func (k *KeyStoreServiceConfig) IsEmpty() bool { type DIDServiceConfig struct { *BaseServiceConfig Methods []string `toml:"methods"` - ResolutionMethods []string `toml:"resolution_methods"` + LocalResolutionMethods []string `toml:"local_resolution_methods"` UniversalResolverURL string `toml:"universal_resolver_url"` UniversalResolverMethods []string `toml:"universal_resolver_methods"` IONResolverURL string `toml:"ion_resolver_url"` @@ -256,9 +256,9 @@ func loadDefaultServicesConfig(config *SSIServiceConfig) { ServiceKeyPassword: "default-password", }, DIDConfig: DIDServiceConfig{ - BaseServiceConfig: &BaseServiceConfig{Name: "did"}, - Methods: []string{"key", "web"}, - ResolutionMethods: []string{"key", "peer", "web", "pkh"}, + BaseServiceConfig: &BaseServiceConfig{Name: "did"}, + Methods: []string{"key", "web"}, + LocalResolutionMethods: []string{"key", "peer", "web", "pkh"}, }, SchemaConfig: SchemaServiceConfig{ BaseServiceConfig: &BaseServiceConfig{Name: "schema"}, diff --git a/config/config.toml b/config/config.toml index 9d2ab626e..7e928d268 100644 --- a/config/config.toml +++ b/config/config.toml @@ -39,7 +39,7 @@ password = "default-password" [services.did] name = "did" methods = ["key", "web", "ion"] -resolution_methods = ["key", "web", "pkh", "peer", "ion"] +local_resolution_methods = ["key", "web", "pkh", "peer"] universal_resolver_url = "http://localhost:8088" universal_resolver_methods = ["ion"] diff --git a/config/config.toml.example b/config/config.toml.example index d9ddc5a24..75ba0b993 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -42,7 +42,7 @@ password = "default-password" [services.did] name = "did" methods = ["key", "web"] -resolution_methods = ["key", "web", "pkh", "peer"] +local_resolution_methods = ["key", "web", "pkh", "peer"] [services.schema] name = "schema" diff --git a/integration/didion_integration_test.go b/integration/didion_integration_test.go index b2da7a27a..ea3802ad2 100644 --- a/integration/didion_integration_test.go +++ b/integration/didion_integration_test.go @@ -44,6 +44,7 @@ func TestCreateAliceDIDIONIntegration(t *testing.T) { SetValue(didIONContext, "aliceDIDPrivateKey", aliceDIDPrivateKey) assert.NoError(t, err) assert.NotEmpty(t, aliceDID) + } func TestDIDIONCreateSchemaIntegration(t *testing.T) { diff --git a/internal/did/resolver.go b/internal/did/resolver.go index 0b92845e4..fee47d49b 100644 --- a/internal/did/resolver.go +++ b/internal/did/resolver.go @@ -5,6 +5,7 @@ import ( didsdk "github.com/TBD54566975/ssi-sdk/did" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // BuildMultiMethodResolver builds a multi method DID resolver from a list of methods to support resolution for @@ -16,7 +17,9 @@ func BuildMultiMethodResolver(methods []string) (*didsdk.MultiMethodResolver, er for _, method := range methods { resolver, err := getKnownResolver(method) if err != nil { - return nil, err + // if we can't create a resolver for a method, we just skip it since not all methods are supported locally + logrus.WithError(err).Errorf("failed to create resolver for method %s", method) + continue } resolvers = append(resolvers, resolver) } diff --git a/internal/util/util.go b/internal/util/util.go index b8b2f1edd..270296c39 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -2,6 +2,7 @@ package util import ( "fmt" + "reflect" "strings" didsdk "github.com/TBD54566975/ssi-sdk/did" @@ -9,6 +10,25 @@ import ( "github.com/sirupsen/logrus" ) +// IsStructPtr checks if the given object is a pointer to a struct +func IsStructPtr(obj any) bool { + if obj == nil { + return false + } + // make sure out is a ptr to a struct + outVal := reflect.ValueOf(obj) + if outVal.Kind() != reflect.Ptr { + return false + } + + // dereference the pointer + outValDeref := outVal.Elem() + if outValDeref.Kind() != reflect.Struct { + return false + } + return true +} + // GetMethodForDID gets a DID method from a did, the second part of the did (e.g. did:test:abcd, the method is 'test') func GetMethodForDID(did string) (didsdk.Method, error) { split := strings.Split(did, ":") diff --git a/pkg/authorizationserver/oauth2_test.go b/pkg/authorizationserver/oauth2_test.go index bedc9da1b..6695de233 100644 --- a/pkg/authorizationserver/oauth2_test.go +++ b/pkg/authorizationserver/oauth2_test.go @@ -64,7 +64,7 @@ func TestCredentialIssuerMetadata(t *testing.T) { metadata, err := fetchMetadata(server.URL + "/oidc/issuer/.well-known/openid-credential-issuer") require.NoError(t, err) - // Check that the issuer matches the URL that was fetched + // Check that the issuer matches the DIDWebID that was fetched assert.JSONEq(t, string(expectedIssuerMetadata), string(metadata)) } diff --git a/pkg/server/router/did.go b/pkg/server/router/did.go index 55e1c3a52..db9b76973 100644 --- a/pkg/server/router/did.go +++ b/pkg/server/router/did.go @@ -7,9 +7,11 @@ import ( "github.com/TBD54566975/ssi-sdk/crypto" didsdk "github.com/TBD54566975/ssi-sdk/did" + "github.com/goccy/go-json" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/server/framework" "github.com/tbd54566975/ssi-service/pkg/service/did" svcframework "github.com/tbd54566975/ssi-service/pkg/service/framework" @@ -34,9 +36,7 @@ func NewDIDRouter(s svcframework.Service) (*DIDRouter, error) { if !ok { return nil, fmt.Errorf("could not create DID router with service type: %s", s.Type()) } - return &DIDRouter{ - service: didService, - }, nil + return &DIDRouter{service: didService}, nil } type GetDIDMethodsResponse struct { @@ -110,24 +110,14 @@ func (dr DIDRouter) CreateDIDByMethod(ctx context.Context, w http.ResponseWriter return framework.NewRequestError(errors.Wrap(err, errMsg), http.StatusBadRequest) } - // method wrapper - m := didsdk.Method(*method) - - // make sure we have a valid option type - var opts did.CreateDIDRequestOptions - if request.Options != nil { - var ok bool - opts, ok = request.Options.(did.CreateDIDRequestOptions) - if !ok { - errMsg := fmt.Sprintf("invalid options for method<%s>", *method) - logrus.Error(errMsg) - return framework.NewRequestErrorMsg(errMsg, http.StatusBadRequest) - } - } - // TODO(gabe) check if the key type is supported for the method, to tell whether this is a bad req or internal error - createDIDRequest := did.CreateDIDRequest{Method: m, KeyType: request.KeyType, Options: opts} - createDIDResponse, err := dr.service.CreateDIDByMethod(ctx, createDIDRequest) + createDIDRequest, err := toCreateDIDRequest(didsdk.Method(*method), request) + if err != nil { + errMsg := fmt.Sprintf("could not create DID for method<%s> with key type: %s", *method, request.KeyType) + logrus.WithError(err).Error(errMsg) + return framework.NewRequestError(errors.Wrap(err, invalidCreateDIDRequest), http.StatusBadRequest) + } + createDIDResponse, err := dr.service.CreateDIDByMethod(ctx, *createDIDRequest) if err != nil { errMsg := fmt.Sprintf("could not create DID for method<%s> with key type: %s", *method, request.KeyType) logrus.WithError(err).Error(errMsg) @@ -143,6 +133,56 @@ func (dr DIDRouter) CreateDIDByMethod(ctx context.Context, w http.ResponseWriter return framework.Respond(ctx, w, resp, http.StatusCreated) } +// toCreateDIDRequest converts CreateDIDByMethodRequest to did.CreateDIDRequest, parsing options according to method +func toCreateDIDRequest(m didsdk.Method, request CreateDIDByMethodRequest) (*did.CreateDIDRequest, error) { + createRequest := did.CreateDIDRequest{ + Method: m, + KeyType: request.KeyType, + } + + // check if options are present + if request.Options == nil { + return &createRequest, nil + } + + // parse options according to method + switch m { + case didsdk.IONMethod: + var opts did.CreateIONDIDOptions + if err := optionsToType(request.Options, &opts); err != nil { + return nil, errors.Wrap(err, "parsing ion options") + } + createRequest.Options = opts + case didsdk.WebMethod: + var opts did.CreateWebDIDOptions + if err := optionsToType(request.Options, &opts); err != nil { + return nil, errors.Wrap(err, "parsing web options") + } + createRequest.Options = opts + default: + if request.Options != nil { + return nil, fmt.Errorf("invalid options for method<%s>", m) + } + } + return &createRequest, nil +} + +// optionsToType converts options to the given type where options is a map[string]interface{} and optionType +// is a pointer to an empty struct of the desired type +func optionsToType(options any, out any) error { + if !util.IsStructPtr(out) { + return fmt.Errorf("output object must be a pointer to a struct") + } + optionBytes, err := json.Marshal(options) + if err != nil { + return errors.Wrap(err, "marshalling options") + } + if err = json.Unmarshal(optionBytes, out); err != nil { + return errors.Wrap(err, "unmarshalling options") + } + return nil +} + type GetDIDByMethodResponse struct { DID didsdk.Document `json:"did,omitempty"` } diff --git a/pkg/server/router/did_test.go b/pkg/server/router/did_test.go index 7ff01c775..a879f4e9b 100644 --- a/pkg/server/router/did_test.go +++ b/pkg/server/router/did_test.go @@ -35,7 +35,7 @@ func TestDIDRouter(t *testing.T) { keyStoreService := testKeyStoreService(tt, db) methods := []string{didsdk.KeyMethod.String()} - serviceConfig := config.DIDServiceConfig{Methods: methods, ResolutionMethods: methods} + serviceConfig := config.DIDServiceConfig{Methods: methods, LocalResolutionMethods: methods} didService, err := did.NewDIDService(serviceConfig, db, keyStoreService) assert.NoError(tt, err) assert.NotEmpty(tt, didService) @@ -117,7 +117,7 @@ func TestDIDRouter(t *testing.T) { keyStoreService := testKeyStoreService(tt, db) methods := []string{didsdk.KeyMethod.String(), didsdk.WebMethod.String()} - serviceConfig := config.DIDServiceConfig{Methods: methods, ResolutionMethods: methods} + serviceConfig := config.DIDServiceConfig{Methods: methods, LocalResolutionMethods: methods} didService, err := did.NewDIDService(serviceConfig, db, keyStoreService) assert.NoError(tt, err) assert.NotEmpty(tt, didService) @@ -138,7 +138,7 @@ func TestDIDRouter(t *testing.T) { assert.ElementsMatch(tt, supported.Methods, []didsdk.Method{didsdk.KeyMethod, didsdk.WebMethod}) // bad key type - createOpts := did.CreateWebDIDOptions{URL: "did:web:example.com"} + createOpts := did.CreateWebDIDOptions{DIDWebID: "did:web:example.com"} _, err = didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: "bad", Options: createOpts}) assert.Error(tt, err) assert.Contains(tt, err.Error(), "could not generate key for did:web") @@ -160,7 +160,7 @@ func TestDIDRouter(t *testing.T) { assert.Equal(tt, createDIDResponse.DID.ID, getDIDResponse.DID.ID) // create a second DID - createOpts = did.CreateWebDIDOptions{URL: "did:web:tbd.website"} + createOpts = did.CreateWebDIDOptions{DIDWebID: "did:web:tbd.website"} createDIDResponse2, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: didsdk.WebMethod, KeyType: crypto.Ed25519, Options: createOpts}) assert.NoError(tt, err) assert.NotEmpty(tt, createDIDResponse2) diff --git a/pkg/server/router/testutils_test.go b/pkg/server/router/testutils_test.go index f5e79ff15..23297f88f 100644 --- a/pkg/server/router/testutils_test.go +++ b/pkg/server/router/testutils_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/tbd54566975/ssi-service/pkg/testutil" "github.com/tbd54566975/ssi-service/config" @@ -35,8 +36,8 @@ func testDIDService(t *testing.T, db storage.ServiceStorage, keyStore *keystore. BaseServiceConfig: &config.BaseServiceConfig{ Name: "did", }, - Methods: []string{"key"}, - ResolutionMethods: []string{"key"}, + Methods: []string{"key"}, + LocalResolutionMethods: []string{"key"}, } // create a did service didService, err := did.NewDIDService(serviceConfig, db, keyStore) diff --git a/pkg/server/server.go b/pkg/server/server.go index c0c095b5f..1f2fe13ac 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -229,7 +229,7 @@ func (s *SSIServer) OperationAPI(service svcframework.Service) (err error) { s.Handle(http.MethodGet, handlerPath, operationRouter.GetOperations) // See https://github.com/dimfeld/httptreemux#routing-rules for details on how the `*` works. - // In this case, it's used so that the operation id matches `presentations/submissions/{submission_id}` for the URL + // In this case, it's used so that the operation id matches `presentations/submissions/{submission_id}` for the DIDWebID // path `/v1/operations/cancel/presentations/submissions/{id}` s.Handle(http.MethodPut, path.Join(handlerPath, "/cancel/*id"), operationRouter.CancelOperation) s.Handle(http.MethodGet, path.Join(handlerPath, "/*id"), operationRouter.GetOperation) diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index 131415cf0..f69e6ef3d 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -8,11 +8,14 @@ import ( "github.com/TBD54566975/ssi-sdk/crypto" didsdk "github.com/TBD54566975/ssi-sdk/did" + "github.com/TBD54566975/ssi-sdk/did/ion" "github.com/goccy/go-json" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "gopkg.in/h2non/gock.v1" "github.com/tbd54566975/ssi-service/pkg/server/router" + "github.com/tbd54566975/ssi-service/pkg/service/did" ) func TestDIDAPI(t *testing.T) { @@ -21,7 +24,7 @@ func TestDIDAPI(t *testing.T) { require.NotNil(tt, bolt) _, keyStoreService := testKeyStore(tt, bolt) - didService := testDIDRouter(tt, bolt, keyStoreService) + didService := testDIDRouter(tt, bolt, keyStoreService, []string{"key", "web", "ion"}) // get DID method req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids", nil) @@ -35,8 +38,10 @@ func TestDIDAPI(t *testing.T) { err = json.NewDecoder(w.Body).Decode(&resp) assert.NoError(tt, err) - assert.Len(tt, resp.DIDMethods, 1) - assert.Equal(tt, resp.DIDMethods[0], didsdk.KeyMethod) + assert.Len(tt, resp.DIDMethods, 3) + assert.Contains(tt, resp.DIDMethods, didsdk.KeyMethod) + assert.Contains(tt, resp.DIDMethods, didsdk.WebMethod) + assert.Contains(tt, resp.DIDMethods, didsdk.IONMethod) }) t.Run("Test Create DID By Method: Key", func(tt *testing.T) { @@ -44,7 +49,7 @@ func TestDIDAPI(t *testing.T) { require.NotNil(tt, bolt) _, keyStoreService := testKeyStore(tt, bolt) - didService := testDIDRouter(tt, bolt, keyStoreService) + didService := testDIDRouter(tt, bolt, keyStoreService, []string{"key"}) // create DID by method - key - missing body req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/key", nil) @@ -87,12 +92,159 @@ func TestDIDAPI(t *testing.T) { assert.Contains(tt, resp.DID.ID, didsdk.KeyMethod) }) + t.Run("Test Create DID By Method: Web", func(tt *testing.T) { + bolt := setupTestDB(tt) + require.NotNil(tt, bolt) + + _, keyStoreService := testKeyStore(tt, bolt) + didService := testDIDRouter(tt, bolt, keyStoreService, []string{"web"}) + + // create DID by method - web - missing body + req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/web", nil) + w := httptest.NewRecorder() + params := map[string]string{ + "method": "web", + } + + err := didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "invalid create DID request") + + // reset recorder between calls + w.Flush() + + // with body, good key type, missing options + createDIDRequest := router.CreateDIDByMethodRequest{KeyType: crypto.Ed25519} + requestReader := newRequestValue(tt, createDIDRequest) + req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/web", requestReader) + + err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "invalid create DID request: missing options for method") + + // reset recorder between calls + w.Flush() + + // good options + options := did.CreateWebDIDOptions{DIDWebID: "did:web:example.com"} + + // with body, bad key type + createDIDRequest = router.CreateDIDByMethodRequest{KeyType: "bad", Options: options} + requestReader = newRequestValue(tt, createDIDRequest) + req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/web", requestReader) + + err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "could not create DID for method with key type: bad") + + // reset recorder between calls + w.Flush() + + // with body, good key type with options + createDIDRequest = router.CreateDIDByMethodRequest{ + KeyType: crypto.Ed25519, + Options: options, + } + requestReader = newRequestValue(tt, createDIDRequest) + req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/web", requestReader) + + gock.New("https://example.com"). + Get("/.well-known/did.json"). + Reply(200). + BodyString(`{"didDocument": {"id": "did:web:example.com"}}`) + defer gock.Off() + + err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.NoError(tt, err) + + var resp router.CreateDIDByMethodResponse + err = json.NewDecoder(w.Body).Decode(&resp) + assert.NoError(tt, err) + + assert.Contains(tt, resp.DID.ID, didsdk.WebMethod) + }) + + t.Run("Test Create DID By Method: ION", func(tt *testing.T) { + bolt := setupTestDB(tt) + require.NotNil(tt, bolt) + + _, keyStoreService := testKeyStore(tt, bolt) + didService := testDIDRouter(tt, bolt, keyStoreService, []string{"ion"}) + + // create DID by method - ion - missing body + req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/ion", nil) + w := httptest.NewRecorder() + params := map[string]string{ + "method": "ion", + } + + err := didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "invalid create DID request") + + // reset recorder between calls + w.Flush() + + gock.New(testIONResolverURL). + Post("/operations"). + Reply(200) + defer gock.Off() + + // with body, good key type, no options + createDIDRequest := router.CreateDIDByMethodRequest{KeyType: crypto.Ed25519} + requestReader := newRequestValue(tt, createDIDRequest) + req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/ion", requestReader) + + err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.NoError(tt, err) + + // reset recorder between calls + w.Flush() + + // good options + options := did.CreateIONDIDOptions{ServiceEndpoints: []ion.Service{{ID: "test", Type: "test", ServiceEndpoint: "test"}}} + + // with body, bad key type + createDIDRequest = router.CreateDIDByMethodRequest{KeyType: "bad", Options: options} + requestReader = newRequestValue(tt, createDIDRequest) + req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/ion", requestReader) + + err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.Error(tt, err) + assert.Contains(tt, err.Error(), "could not create DID for method with key type: bad") + + // reset recorder between calls + w.Flush() + + // with body, good key type with options + createDIDRequest = router.CreateDIDByMethodRequest{ + KeyType: crypto.Ed25519, + Options: options, + } + requestReader = newRequestValue(tt, createDIDRequest) + req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/ion", requestReader) + + gock.New(testIONResolverURL). + Post("/operations"). + Reply(200) + defer gock.Off() + + err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) + assert.NoError(tt, err) + + var resp router.CreateDIDByMethodResponse + err = json.NewDecoder(w.Body).Decode(&resp) + assert.NoError(tt, err) + + assert.Contains(tt, resp.DID.ID, didsdk.IONMethod) + }) + t.Run("Test Get DID By Method", func(tt *testing.T) { bolt := setupTestDB(tt) require.NotNil(tt, bolt) _, keyStore := testKeyStore(tt, bolt) - didService := testDIDRouter(tt, bolt, keyStore) + didService := testDIDRouter(tt, bolt, keyStore, []string{"key"}) // get DID by method req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids/bad/worse", nil) @@ -162,7 +314,7 @@ func TestDIDAPI(t *testing.T) { require.NotNil(tt, bolt) _, keyStore := testKeyStore(tt, bolt) - didService := testDIDRouter(tt, bolt, keyStore) + didService := testDIDRouter(tt, bolt, keyStore, []string{"key"}) // soft delete DID by method req := httptest.NewRequest(http.MethodDelete, "https://ssi-service.com/v1/dids/bad/worse", nil) @@ -261,7 +413,7 @@ func TestDIDAPI(t *testing.T) { bolt := setupTestDB(tt) require.NotNil(tt, bolt) _, keyStore := testKeyStore(tt, bolt) - didService := testDIDRouter(tt, bolt, keyStore) + didService := testDIDRouter(tt, bolt, keyStore, []string{"key", "web"}) // get DIDs by method req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids/bad", nil) @@ -343,7 +495,7 @@ func TestDIDAPI(t *testing.T) { require.NotNil(tt, bolt) _, keyStore := testKeyStore(tt, bolt) - didService := testDIDRouter(tt, bolt, keyStore) + didService := testDIDRouter(tt, bolt, keyStore, []string{"key", "web"}) // bad resolution request req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids/resolver/bad", nil) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 136917d62..bdd93af63 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/TBD54566975/ssi-sdk/credential/exchange" + "github.com/tbd54566975/ssi-service/pkg/service/issuing" "github.com/tbd54566975/ssi-service/pkg/service/manifest/model" "github.com/tbd54566975/ssi-service/pkg/service/webhook" @@ -23,6 +24,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + credmodel "github.com/tbd54566975/ssi-service/internal/credential" "github.com/tbd54566975/ssi-service/config" @@ -37,6 +39,10 @@ import ( "github.com/tbd54566975/ssi-service/pkg/storage" ) +const ( + testIONResolverURL = "https://test-ion-resolver.com" +) + func TestMain(t *testing.M) { testutil.EnableSchemaCaching() os.Exit(t.Run()) @@ -53,7 +59,7 @@ func TestHealthCheckAPI(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/health", nil) w := httptest.NewRecorder() - err = router.Health(context.TODO(), w, req) + err = router.Health(context.Background(), w, req) assert.NoError(t, err) assert.Equal(t, http.StatusOK, w.Result().StatusCode) @@ -225,11 +231,15 @@ func testIssuanceService(t *testing.T, db storage.ServiceStorage) *issuing.Servi return s } -func testDIDService(t *testing.T, bolt storage.ServiceStorage, keyStore *keystore.Service) *did.Service { +func testDIDService(t *testing.T, bolt storage.ServiceStorage, keyStore *keystore.Service, methods ...string) *did.Service { + if methods == nil { + methods = []string{"key"} + } serviceConfig := config.DIDServiceConfig{ - BaseServiceConfig: &config.BaseServiceConfig{Name: "test-did"}, - Methods: []string{"key"}, - ResolutionMethods: []string{"key"}, + BaseServiceConfig: &config.BaseServiceConfig{Name: "test-did"}, + Methods: methods, + LocalResolutionMethods: []string{"key", "web", "peer", "pkh"}, + IONResolverURL: testIONResolverURL, } // create a did service @@ -239,8 +249,8 @@ func testDIDService(t *testing.T, bolt storage.ServiceStorage, keyStore *keystor return didService } -func testDIDRouter(t *testing.T, bolt storage.ServiceStorage, keyStore *keystore.Service) *router.DIDRouter { - didService := testDIDService(t, bolt, keyStore) +func testDIDRouter(t *testing.T, bolt storage.ServiceStorage, keyStore *keystore.Service, methods []string) *router.DIDRouter { + didService := testDIDService(t, bolt, keyStore, methods...) // create router for service didRouter, err := router.NewDIDRouter(didService) diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go index 48e4aef81..4d9a65f4b 100644 --- a/pkg/service/did/ion_test.go +++ b/pkg/service/did/ion_test.go @@ -40,7 +40,7 @@ func TestIONHandler(t *testing.T) { handler, err = NewIONHandler("bad", didStorage, keystoreService) assert.Error(tt, err) assert.Empty(tt, handler) - assert.Contains(tt, err.Error(), "invalid resolver URL") + assert.Contains(tt, err.Error(), "invalid resolver DIDWebID") handler, err = NewIONHandler("https://example.com", didStorage, keystoreService) assert.NoError(tt, err) diff --git a/pkg/service/did/resolution/resolver.go b/pkg/service/did/resolution/resolver.go index d8fca246a..f872a51d5 100644 --- a/pkg/service/did/resolution/resolver.go +++ b/pkg/service/did/resolution/resolver.go @@ -24,15 +24,15 @@ var _ didsdk.Resolver = (*ServiceResolver)(nil) // NewServiceResolver creates a new ServiceResolver instance which can resolve DIDs using a combination of local and // universal resolvers. -func NewServiceResolver(handlerResolver didsdk.Resolver, resolutionMethods []string, universalResolverURL string) (*ServiceResolver, error) { - if len(resolutionMethods) == 0 { - return nil, errors.New("no resolution methods configured") - } - - // instantiate sdk resolver - localResolver, err := didint.BuildMultiMethodResolver(resolutionMethods) - if err != nil { - return nil, errors.Wrap(err, "instantiating SDK DID resolver") +func NewServiceResolver(handlerResolver didsdk.Resolver, localResolutionMethods []string, universalResolverURL string) (*ServiceResolver, error) { + var lr didsdk.Resolver + var err error + if len(localResolutionMethods) > 0 { + // instantiate sdk resolver + lr, err = didint.BuildMultiMethodResolver(localResolutionMethods) + if err != nil { + return nil, errors.Wrap(err, "instantiating local DID resolver") + } } // instantiate universal resolver @@ -45,9 +45,9 @@ func NewServiceResolver(handlerResolver didsdk.Resolver, resolutionMethods []str } return &ServiceResolver{ - resolutionMethods: resolutionMethods, + resolutionMethods: localResolutionMethods, hr: handlerResolver, - lr: localResolver, + lr: lr, ur: ur, }, nil } diff --git a/pkg/service/did/service.go b/pkg/service/did/service.go index 5238a7e5d..90b5d51ff 100644 --- a/pkg/service/did/service.go +++ b/pkg/service/did/service.go @@ -74,6 +74,7 @@ func NewDIDService(config config.DIDServiceConfig, s storage.ServiceStorage, key } service := Service{ + config: config, storage: didStorage, handlers: make(map[didsdk.Method]MethodHandler), keyStore: keyStore, @@ -93,7 +94,7 @@ func NewDIDService(config config.DIDServiceConfig, s storage.ServiceStorage, key } // instantiate DID resolver - resolver, err := resolution.NewServiceResolver(hr, config.ResolutionMethods, config.UniversalResolverURL) + resolver, err := resolution.NewServiceResolver(hr, config.LocalResolutionMethods, config.UniversalResolverURL) if err != nil { return nil, errors.Wrap(err, "instantiating DID resolver") } diff --git a/pkg/service/did/web.go b/pkg/service/did/web.go index e89e3aaf5..83eaf5e55 100644 --- a/pkg/service/did/web.go +++ b/pkg/service/did/web.go @@ -31,7 +31,8 @@ type webHandler struct { } type CreateWebDIDOptions struct { - URL string `json:"url" validate:"required"` + // e.g. did:web:example.com + DIDWebID string `json:"didWebId" validate:"required"` } func (c CreateWebDIDOptions) Method() did.Method { @@ -57,10 +58,10 @@ func (h *webHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* return nil, errors.Wrap(err, "processing options") } - didWeb := did.DIDWeb(opts.URL) + didWeb := did.DIDWeb(opts.DIDWebID) if !didWeb.IsValid() { - return nil, fmt.Errorf("did:web is not valid, could not resolve did:web DID: %s", didWeb) + return nil, fmt.Errorf("could not resolve did:web DID: %s", didWeb) } pubKey, privKey, err := crypto.GenerateKeyByKeyType(request.KeyType) diff --git a/pkg/service/webhook/model.go b/pkg/service/webhook/model.go index f88896e00..46e87d887 100644 --- a/pkg/service/webhook/model.go +++ b/pkg/service/webhook/model.go @@ -109,7 +109,7 @@ func (v Verb) isValid() bool { return false } -// isValidURL checks if there were any errors during parsing and if the parsed URL has a non-empty Scheme and Host. +// isValidURL checks if there were any errors during parsing and if the parsed DIDWebID has a non-empty Scheme and Host. // currently we support any scheme including http, https, ftp ... func isValidURL(urlStr string) bool { parsedURL, err := url.Parse(urlStr) diff --git a/pkg/service/webhook/service.go b/pkg/service/webhook/service.go index b7b10f283..a38bb2580 100644 --- a/pkg/service/webhook/service.go +++ b/pkg/service/webhook/service.go @@ -127,7 +127,7 @@ func (s Service) GetWebhooks(ctx context.Context) (*GetWebhooksResponse, error) return &GetWebhooksResponse{Webhooks: webhooks}, nil } -// DeleteWebhook deletes a webhook from the storage by removing a given URL from the list of URLs associated with the webhook. +// DeleteWebhook deletes a webhook from the storage by removing a given DIDWebID from the list of URLs associated with the webhook. // If there are no URLs left in the list, the entire webhook is deleted from storage. func (s Service) DeleteWebhook(ctx context.Context, request DeleteWebhookRequest) error { logrus.Debugf("deleting webhook: %s-%s", request.Noun, request.Verb) diff --git a/pkg/testutil/well_known_generation_test.go b/pkg/testutil/well_known_generation_test.go index 3600fd508..9a6897468 100644 --- a/pkg/testutil/well_known_generation_test.go +++ b/pkg/testutil/well_known_generation_test.go @@ -45,7 +45,7 @@ func TestWellKnownGenerationTest(t *testing.T) { createWellKnownDIDConfiguration(tt, didKey, gotKey, origin) - createOpts := did.CreateWebDIDOptions{URL: "did:web:tbd.website"} + createOpts := did.CreateWebDIDOptions{DIDWebID: "did:web:tbd.website"} didWeb, err := didService.CreateDIDByMethod(context.Background(), did.CreateDIDRequest{Method: "web", KeyType: "Ed25519", Options: createOpts}) assert.NoError(tt, err) assert.NotEmpty(tt, didWeb) @@ -169,8 +169,8 @@ func testDIDService(t *testing.T, db storage.ServiceStorage, keyStore *keystore. BaseServiceConfig: &config.BaseServiceConfig{ Name: "did", }, - Methods: []string{"key", "web"}, - ResolutionMethods: []string{"key"}, + Methods: []string{"key", "web"}, + LocalResolutionMethods: []string{"key"}, } // create a did service didService, err := did.NewDIDService(serviceConfig, db, keyStore) From 01b44105dd3ed5a2fe05fa543ee476f799d32ee1 Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 13:12:21 -0700 Subject: [PATCH 13/22] fix tests --- internal/did/resolver_test.go | 2 +- pkg/server/server_did_test.go | 2 +- pkg/service/did/ion_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/did/resolver_test.go b/internal/did/resolver_test.go index 520aed2ac..2171a2ade 100644 --- a/internal/did/resolver_test.go +++ b/internal/did/resolver_test.go @@ -16,7 +16,7 @@ func TestResolver(t *testing.T) { // unsupported method _, err = BuildMultiMethodResolver([]string{"unsupported"}) assert.Error(t, err) - assert.Contains(t, err.Error(), "unsupported method: unsupported") + assert.Contains(t, err.Error(), "no resolvers created") // valid method resolver, err := BuildMultiMethodResolver([]string{"key"}) diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index f69e6ef3d..92cba53ac 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -120,7 +120,7 @@ func TestDIDAPI(t *testing.T) { err = didService.CreateDIDByMethod(newRequestContextWithParams(params), w, req) assert.Error(tt, err) - assert.Contains(tt, err.Error(), "invalid create DID request: missing options for method") + assert.Contains(tt, err.Error(), "could not create DID for method with key type: Ed25519: options cannot be empty") // reset recorder between calls w.Flush() diff --git a/pkg/service/did/ion_test.go b/pkg/service/did/ion_test.go index 4d9a65f4b..6a3dd1821 100644 --- a/pkg/service/did/ion_test.go +++ b/pkg/service/did/ion_test.go @@ -40,7 +40,7 @@ func TestIONHandler(t *testing.T) { handler, err = NewIONHandler("bad", didStorage, keystoreService) assert.Error(tt, err) assert.Empty(tt, handler) - assert.Contains(tt, err.Error(), "invalid resolver DIDWebID") + assert.Contains(tt, err.Error(), "invalid resolver URL: parse \"bad\": invalid URI for request") handler, err = NewIONHandler("https://example.com", didStorage, keystoreService) assert.NoError(tt, err) From 18344fcf8105d0da7461579ea629e4ab2cea09cd Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 13:17:56 -0700 Subject: [PATCH 14/22] return priv key bytes --- pkg/service/did/ion.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/service/did/ion.go b/pkg/service/did/ion.go index 4d28b8c74..fbbc16782 100644 --- a/pkg/service/did/ion.go +++ b/pkg/service/did/ion.go @@ -197,9 +197,14 @@ func (h *ionHandler) CreateDID(ctx context.Context, request CreateDIDRequest) (* return nil, errors.Wrap(err, "could not store did:ion private key") } + privKeyBytes, err := crypto.PrivKeyToBytes(privKey) + if err != nil { + return nil, errors.Wrap(err, "converting private key to bytes") + } return &CreateDIDResponse{ - DID: didDoc, - KeyType: request.KeyType, + DID: didDoc, + PrivateKeyBase58: base58.Encode(privKeyBytes), + KeyType: request.KeyType, }, nil } From 86607fcaa4b1a55bbf618340007b8d18d70d0088 Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 13:20:58 -0700 Subject: [PATCH 15/22] update comment --- pkg/service/did/model.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/service/did/model.go b/pkg/service/did/model.go index 14073311c..b9d1cb583 100644 --- a/pkg/service/did/model.go +++ b/pkg/service/did/model.go @@ -37,6 +37,7 @@ type CreateDIDResponse struct { DID didsdk.Document `json:"did"` // TODO(gabe): change to returning a set of public keys. private keys should be stored in the keystore, // and stay within the service boundary. This will unify the solution for both custodial and non-custodial keys. + // https://github.com/TBD54566975/ssi-service/issues/371 PrivateKeyBase58 string `json:"base58PrivateKey"` KeyType crypto.KeyType `json:"keyType"` } From 5ebd39075a69b92bfb57a1ed148ebade533b5b52 Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 14:01:51 -0700 Subject: [PATCH 16/22] refer to alice's key properly --- integration/didion_integration_test.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/integration/didion_integration_test.go b/integration/didion_integration_test.go index ea3802ad2..c5ea9d1e5 100644 --- a/integration/didion_integration_test.go +++ b/integration/didion_integration_test.go @@ -35,16 +35,22 @@ func TestCreateAliceDIDIONIntegration(t *testing.T) { assert.NotEmpty(t, didIONOutput) aliceDID, err := getJSONElement(didIONOutput, "$.did.id") + assert.NoError(t, err) + assert.NotEmpty(t, aliceDID) SetValue(didIONContext, "aliceDID", aliceDID) + aliceKeyID, err := getJSONElement(didIONOutput, "$.did.verificationMethod[0].id") + SetValue(didIONContext, "aliceKeyID", aliceKeyID) + assert.NoError(t, err) + assert.NotEmpty(t, aliceKeyID) + assert.NoError(t, err) assert.Contains(t, aliceDID, "did:ion") aliceDIDPrivateKey, err := getJSONElement(didIONOutput, "$.privateKeyBase58") - SetValue(didIONContext, "aliceDIDPrivateKey", aliceDIDPrivateKey) assert.NoError(t, err) - assert.NotEmpty(t, aliceDID) - + assert.NotEmpty(t, aliceDIDPrivateKey) + SetValue(didIONContext, "aliceDIDPrivateKey", aliceDIDPrivateKey) } func TestDIDIONCreateSchemaIntegration(t *testing.T) { @@ -140,6 +146,10 @@ func TestDIDIONSubmitAndReviewApplicationIntegration(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, aliceDID) + aliceKeyID, err := GetValue(didIONContext, "aliceKeyID") + assert.NoError(t, err) + assert.NotEmpty(t, aliceDID) + aliceDIDPrivateKey, err := GetValue(didIONContext, "aliceDIDPrivateKey") assert.NoError(t, err) assert.NotEmpty(t, aliceDIDPrivateKey) @@ -147,7 +157,7 @@ func TestDIDIONSubmitAndReviewApplicationIntegration(t *testing.T) { credAppJWT, err := CreateCredentialApplicationJWT(credApplicationParams{ DefinitionID: presentationDefinitionID.(string), ManifestID: manifestID.(string), - }, credentialJWT.(string), aliceDID.(string), aliceDIDPrivateKey.(string)) + }, credentialJWT.(string), aliceDID.(string)+"#"+aliceKeyID.(string), aliceDIDPrivateKey.(string)) assert.NoError(t, err) assert.NotEmpty(t, credAppJWT) From 7b9cb47da11b5c0a2806914c5a796bd53913f9e1 Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 14:34:22 -0700 Subject: [PATCH 17/22] fix int test --- integration/didion_integration_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/integration/didion_integration_test.go b/integration/didion_integration_test.go index c5ea9d1e5..22e0ea1cd 100644 --- a/integration/didion_integration_test.go +++ b/integration/didion_integration_test.go @@ -19,8 +19,12 @@ func TestCreateIssuerDIDIONIntegration(t *testing.T) { assert.NoError(t, err) issuerDID, err := getJSONElement(didIONOutput, "$.did.id") + assert.NoError(t, err) SetValue(didIONContext, "issuerDID", issuerDID) + issuerKeyID, err := getJSONElement(didIONOutput, "$.did.verificationMethod[0].id") + SetValue(didIONContext, "issuerKeyID", issuerKeyID) + assert.NoError(t, err) assert.Contains(t, issuerDID, "did:ion") } @@ -77,12 +81,16 @@ func TestDIDIONCreateVerifiableCredentialIntegration(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, issuerDID) + issuerKeyID, err := GetValue(didIONContext, "issuerKeyID") + assert.NoError(t, err) + assert.NotEmpty(t, issuerKeyID) + schemaID, err := GetValue(didIONContext, "schemaID") assert.NoError(t, err) assert.NotEmpty(t, schemaID) vcOutput, err := CreateVerifiableCredential(credInputParams{ - IssuerID: issuerDID.(string), + IssuerID: issuerDID.(string) + "#" + issuerKeyID.(string), SchemaID: schemaID.(string), SubjectID: issuerDID.(string), }, false) @@ -104,12 +112,16 @@ func TestDIDIONCreateCredentialManifestIntegration(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, issuerDID) + issuerKeyID, err := GetValue(didIONContext, "issuerKeyID") + assert.NoError(t, err) + assert.NotEmpty(t, issuerKeyID) + schemaID, err := GetValue(didIONContext, "schemaID") assert.NoError(t, err) assert.NotEmpty(t, schemaID) cmOutput, err := CreateCredentialManifest(credManifestParams{ - IssuerID: issuerDID.(string), + IssuerID: issuerDID.(string) + "#" + issuerKeyID.(string), SchemaID: schemaID.(string), }) assert.NoError(t, err) From 6c9804d3a2f75701268e7210bce186b259618e71 Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 15:07:25 -0700 Subject: [PATCH 18/22] options --- integration/testdata/did-web-input.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/integration/testdata/did-web-input.json b/integration/testdata/did-web-input.json index fcb7f09d2..824b099b2 100644 --- a/integration/testdata/did-web-input.json +++ b/integration/testdata/did-web-input.json @@ -1,4 +1,6 @@ { "keyType":"Ed25519", - "didWebId":"did:web:tbd.website" + "options": { + "didWebId": "did:web:tbd.website" + } } \ No newline at end of file From 13efea7ec4bef2cd5513731e7b65e38c1679c436 Mon Sep 17 00:00:00 2001 From: gabe Date: Sat, 1 Apr 2023 15:25:34 -0700 Subject: [PATCH 19/22] more test fix --- integration/common.go | 15 ++++++++++++++- integration/didweb_resolver_integration_test.go | 2 +- pkg/server/server_did_test.go | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/integration/common.go b/integration/common.go index 303f142bb..58eba7248 100644 --- a/integration/common.go +++ b/integration/common.go @@ -20,6 +20,7 @@ import ( credmodel "github.com/tbd54566975/ssi-service/internal/credential" "github.com/tbd54566975/ssi-service/internal/keyaccess" + "github.com/tbd54566975/ssi-service/pkg/server/router" ) const ( @@ -46,7 +47,19 @@ func CreateDIDKey() (string, error) { func CreateDIDWeb() (string, error) { logrus.Println("\n\nCreate a did:web") - output, err := put(endpoint+version+"dids/web", getJSONFromFile("did-web-input.json")) + + var createDIDWebRequest router.CreateDIDByMethodRequest + inputJSON := getJSONFromFile("did-web-input.json") + if err := json.Unmarshal([]byte(inputJSON), &createDIDWebRequest); err != nil { + return "", errors.Wrap(err, "unmarshalling did:web request") + } + + createdRequestJSONBytes, err := json.Marshal(createDIDWebRequest) + if err != nil { + return "", errors.Wrap(err, "creating did:web request") + } + + output, err := put(endpoint+version+"dids/web", string(createdRequestJSONBytes)) if err != nil { return "", errors.Wrapf(err, "did endpoint with output: %s", output) } diff --git a/integration/didweb_resolver_integration_test.go b/integration/didweb_resolver_integration_test.go index 4d6326189..224cec9c1 100644 --- a/integration/didweb_resolver_integration_test.go +++ b/integration/didweb_resolver_integration_test.go @@ -12,7 +12,7 @@ func TestResolveDIDWebIntegration(t *testing.T) { } // A .well-known file exists at https://tbd.website/.well-known/did.json - didWebOutput, err := put(endpoint+version+"dids/web", `{ "keyType":"Ed25519", "didWebId":"did:web:tbd.website"}`) + didWebOutput, err := put(endpoint+version+"dids/web", `{ "keyType":"Ed25519", "options": {"didWebId":"did:web:tbd.website"}}`) assert.NoError(t, err) did, err := getJSONElement(didWebOutput, "$.did.id") diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index 92cba53ac..c7f151ed5 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -145,6 +145,10 @@ func TestDIDAPI(t *testing.T) { KeyType: crypto.Ed25519, Options: options, } + + b, _ := json.Marshal(createDIDRequest) + fmt.Println(string(b)) + requestReader = newRequestValue(tt, createDIDRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/web", requestReader) From 4a0d02fb87b0239df60947f6c322e75db87742e4 Mon Sep 17 00:00:00 2001 From: gabe Date: Sun, 2 Apr 2023 09:54:25 -0700 Subject: [PATCH 20/22] lint --- integration/common.go | 2 +- pkg/server/server_did_test.go | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/integration/common.go b/integration/common.go index 58eba7248..8e9f3ee92 100644 --- a/integration/common.go +++ b/integration/common.go @@ -58,7 +58,7 @@ func CreateDIDWeb() (string, error) { if err != nil { return "", errors.Wrap(err, "creating did:web request") } - + output, err := put(endpoint+version+"dids/web", string(createdRequestJSONBytes)) if err != nil { return "", errors.Wrapf(err, "did endpoint with output: %s", output) diff --git a/pkg/server/server_did_test.go b/pkg/server/server_did_test.go index c7f151ed5..ce49ab23b 100644 --- a/pkg/server/server_did_test.go +++ b/pkg/server/server_did_test.go @@ -146,9 +146,6 @@ func TestDIDAPI(t *testing.T) { Options: options, } - b, _ := json.Marshal(createDIDRequest) - fmt.Println(string(b)) - requestReader = newRequestValue(tt, createDIDRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/web", requestReader) From 368a076ac094c7c36270eb55cf10bbccfa46fc1f Mon Sep 17 00:00:00 2001 From: gabe Date: Mon, 3 Apr 2023 10:52:21 -0700 Subject: [PATCH 21/22] pr comment --- pkg/server/router/keystore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/server/router/keystore.go b/pkg/server/router/keystore.go index 47b0ab804..00037ab6f 100644 --- a/pkg/server/router/keystore.go +++ b/pkg/server/router/keystore.go @@ -44,7 +44,7 @@ type StoreKeyRequest struct { Controller string `json:"controller,omitempty" validate:"required"` // Base58 encoding of the bytes that result from marshalling the private key using golang's implementation. - PrivateKeyBase58 string `json:"base58PrivateKey,omitempty"` + PrivateKeyBase58 string `json:"base58PrivateKey,omitempty" validate:"required"` } func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) { From 563992dd447db426d57a51df9301e6fd781dd7b9 Mon Sep 17 00:00:00 2001 From: gabe Date: Mon, 3 Apr 2023 11:47:57 -0700 Subject: [PATCH 22/22] fix go sum --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index b9e2f7247..84e08a167 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,6 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504 h1:SsKoZkq5U3sWDEPozRJiOCUl/p1gR1YPnzzg/nY764Y= -github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230331233052-9d44b158d504/go.mod h1:Ro9+HDADuYcLnCYKIL8pu92XWITKetTPOqfwLThplO0= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230401051839-bca28f8b0fea h1:+0dl8nqYYkewqiiYKxhk3RK7ivOOzweeYa08DFOU3fE= github.com/TBD54566975/ssi-sdk v0.0.3-alpha.0.20230401051839-bca28f8b0fea/go.mod h1:9SNGqEkRihpNbgilFDRRmgi8Gi/l7/l0eyO+3Prubro= github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=