Skip to content

Commit

Permalink
fix: did web resolver (#36)
Browse files Browse the repository at this point in the history
* fix: did web resolver

* fix: mocks

* fix: lint

* fix: test

* fix: path

* fix: bin

* fix :gen

* feat: add debug log

* feat: base install

* fix: gen

* fix: gen
  • Loading branch information
skynet2 authored Nov 22, 2024
1 parent 0c5631a commit c010226
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 24 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Go 1.22
uses: actions/setup-go@v4
with:
Expand All @@ -51,7 +51,7 @@ jobs:
go-version: '1.22'
id: go

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Run unit test
timeout-minutes: 15
Expand All @@ -61,4 +61,4 @@ jobs:
timeout-minutes: 10
uses: codecov/[email protected]
with:
file: ./coverage.out
file: ./coverage.out
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ dist
build
umd

# Auto-generated mock files
*_mocks_test.go
gomocks_test.go
24 changes: 19 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,43 @@
# Tool commands (overridable)
DOCKER_CMD ?= docker

GOBIN_PATH=$(abspath .)/.build/bin
OS := $(shell uname)
ifeq ($(OS),$(filter $(OS),Darwin Linux))
PATH:=$(PATH):$(GOBIN_PATH)
else
PATH:=$(PATH);$(subst /,\\,$(GOBIN_PATH))
endif

GOBIN_PATH=$(abspath .)/build/bin
MOCKGEN=$(GOBIN_PATH)/mockgen
GOMOCKS=pkg/internal/gomocks
MOCK_VERSION ?=v1.7.0-rc.1

.PHONY: all
all: clean checks unit-test
all: clean generate checks unit-test

.PHONY: checks
checks: license lint
checks: generate license lint

.PHONY: lint
lint:
lint: generate
@scripts/check_lint.sh

.PHONY: license
license:
@scripts/check_license.sh

.PHONY: unit-test
unit-test:
unit-test: generate
@scripts/check_unit.sh

.PHONY: clean
clean:
@rm -rf ./.build
@rm -rf coverage*.out
@rm -rf coverage*.out

.PHONY: generate
generate:
@go install github.com/golang/mock/mockgen@$(MOCK_VERSION)
@go generate ./...
51 changes: 43 additions & 8 deletions doc/did/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,38 @@ type rawDoc struct {
Proof []interface{} `json:"proof,omitempty"`
}

// UnmarshalJSON handles the custom unmarshaling logic for the rawDoc struct.
func (r *rawDoc) UnmarshalJSON(data []byte) error {
type Alias rawDoc

temp := &struct {
Proof json.RawMessage `json:"proof,omitempty"`
*Alias
}{
Alias: (*Alias)(r),
}

if err := json.Unmarshal(data, temp); err != nil {
return err
}

var proofArray []interface{}

if temp.Proof != nil {
var proofSingle interface{}

if err := json.Unmarshal(temp.Proof, &proofArray); err != nil {
if err = json.Unmarshal(temp.Proof, &proofSingle); err == nil {
proofArray = []interface{}{proofSingle}
}
}
}

r.Proof = proofArray

return nil
}

// Proof is cryptographic proof of the integrity of the DID Document.
type Proof struct {
Type string
Expand Down Expand Up @@ -601,13 +633,6 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([]
return nil, errors.New("rawProofs is not map[string]interface{}")
}

created := stringEntry(emap[jsonldCreated])

timeValue, err := time.Parse(time.RFC3339, created)
if err != nil {
return nil, err
}

proofKey := jsonldProofValue

if context == contextV011 {
Expand Down Expand Up @@ -635,7 +660,6 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([]

proof := Proof{
Type: stringEntry(emap[jsonldType]),
Created: &timeValue,
Creator: creator,
ProofValue: proofValue,
ProofPurpose: stringEntry(emap[jsonldProofPurpose]),
Expand All @@ -644,6 +668,17 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([]
relativeURL: isRelative,
}

created := stringEntry(emap[jsonldCreated])
if created != "" {
timeValue, errTime := time.Parse(time.RFC3339, created)

if errTime != nil {
return nil, errTime
}

proof.Created = &timeValue
}

proofs = append(proofs, proof)
}

Expand Down
8 changes: 5 additions & 3 deletions doc/did/doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import (
"github.com/btcsuite/btcutil/base58"
gojose "github.com/go-jose/go-jose/v3"
"github.com/stretchr/testify/require"

"github.com/trustbloc/did-go/doc/internal/mock/signature"

"github.com/trustbloc/kms-go/doc/jose/jwk"

"github.com/trustbloc/did-go/doc/did/endpoint"
"github.com/trustbloc/did-go/doc/ld/testutil"
"github.com/trustbloc/did-go/doc/signature/api"
"github.com/trustbloc/did-go/doc/signature/signer"
"github.com/trustbloc/kms-go/doc/jose/jwk"
)

const pemPK = `-----BEGIN PUBLIC KEY-----
Expand Down Expand Up @@ -1120,7 +1122,7 @@ func TestValidateDidDocProof(t *testing.T) {
})

t.Run("test did doc proof without created", func(t *testing.T) {
docs := []string{validDocWithProof, validDocV011WithProof}
docs := []string{validDocV011WithProof}
for _, d := range docs {
raw := &rawDoc{}
require.NoError(t, json.Unmarshal([]byte(d), &raw))
Expand All @@ -1136,7 +1138,7 @@ func TestValidateDidDocProof(t *testing.T) {
})

t.Run("test did doc proof without creator", func(t *testing.T) {
docs := []string{validDocWithProof, validDocV011WithProof}
docs := []string{validDocV011WithProof}
for _, d := range docs {
raw := &rawDoc{}
require.NoError(t, json.Unmarshal([]byte(d), &raw))
Expand Down
17 changes: 12 additions & 5 deletions doc/did/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,24 @@ const (
"updated": {
"type": "string"
},
"proof": {
"type": "array",
"items": {
"proof": {
"oneOf": [
{
"type": "array",
"items": {
"$ref": "#/definitions/proof"
}
},
{
"$ref": "#/definitions/proof"
}
}
]
}
},
"definitions": {
"proof": {
"type": "object",
"required": [ "type", "creator", "created", "proofValue"],
"required": [ "type", "proofValue"],
"properties": {
"type": {
"type": "string",
Expand Down
8 changes: 8 additions & 0 deletions doc/ld/proof/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"encoding/base64"
"errors"
"fmt"
"strings"

"github.com/multiformats/go-multibase"

Expand Down Expand Up @@ -158,6 +159,13 @@ func DecodeProofValue(s, proofType string) ([]byte, error) {
return nil, errors.New("unsupported encoding")
}

if strings.HasPrefix(s, "z") { // maybe base58
_, value, err := multibase.Decode(s)
if err == nil {
return value, nil
}
}

return decodeBase64(s)
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cenkalti/backoff/v4 v4.1.3
github.com/go-jose/go-jose/v3 v3.0.1
github.com/golang/mock v1.4.4
github.com/google/uuid v1.3.0
github.com/mitchellh/mapstructure v1.5.0
github.com/multiformats/go-multibase v0.1.1
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
Expand Down Expand Up @@ -104,15 +106,18 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
Expand Down
15 changes: 15 additions & 0 deletions method/web/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package web

import "net/http"

//go:generate mockgen -destination interfaces_mocks_test.go -package web -source=interfaces.go

type roundTripper interface { //nolint
http.RoundTripper
}
34 changes: 34 additions & 0 deletions method/web/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ SPDX-License-Identifier: Apache-2.0
package web

import (
"bytes"
_ "embed"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
urlapi "net/url"
"strings"
"testing"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"

didapi "github.com/trustbloc/did-go/doc/did"
Expand Down Expand Up @@ -42,6 +46,9 @@ const (
invalidDoc = `{}`
)

//go:embed testdata/uscis.json
var uscisDid []byte

func TestParseDID(t *testing.T) {
t.Run("test parse did success", func(t *testing.T) {
address, host, err := parseDIDWeb(validDID, false)
Expand Down Expand Up @@ -219,3 +226,30 @@ func TestResolveWebFixtures(t *testing.T) {
require.Equal(t, expectedDoc, docResolution.DIDDocument)
})
}

func TestResolveUscisDid(t *testing.T) {
cl := &http.Client{}
trip := NewMockroundTripper(gomock.NewController(t))
cl.Transport = trip

trip.EXPECT().RoundTrip(gomock.Any()).
DoAndReturn(func(request *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader(uscisDid)),
}, nil
})

v := New()

docResolution, err := v.Read("did:web:dhs-svip.github.io:ns:uscis:oidp",
vdrapi.WithOption(HTTPClientOpt, cl))

require.NoError(t, err)
require.NotNil(t, docResolution)

require.Len(t, docResolution.DIDDocument.Proof, 1)
require.Len(t, docResolution.DIDDocument.VerificationMethod, 2)
require.EqualValues(t, "did:web:dhs-svip.github.io:ns:uscis:oidp", docResolution.DIDDocument.ID)
require.NotEmpty(t, docResolution.DIDDocument.Proof[0].ProofValue)
}
Loading

0 comments on commit c010226

Please sign in to comment.