Skip to content

Commit 3a3032d

Browse files
authored
Discovery: DID registration by clients (#2709)
1 parent a5febda commit 3a3032d

33 files changed

+2519
-339
lines changed

README.rst

Lines changed: 77 additions & 77 deletions
Large diffs are not rendered by default.

auth/api/iam/generated.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func CreateSystem(shutdownCallback context.CancelFunc) *core.System {
196196
vdrInstance := vdr.NewVDR(cryptoInstance, networkInstance, didStore, eventManager, storageInstance)
197197
credentialInstance := vcr.NewVCRInstance(cryptoInstance, vdrInstance, networkInstance, jsonld, eventManager, storageInstance, pkiInstance)
198198
didmanInstance := didman.NewDidmanInstance(vdrInstance, credentialInstance, jsonld)
199-
discoveryInstance := discovery.New(storageInstance, credentialInstance)
199+
discoveryInstance := discovery.New(storageInstance, credentialInstance, vdrInstance)
200200
authInstance := auth.NewAuthInstance(auth.DefaultConfig(), vdrInstance, credentialInstance, cryptoInstance, didmanInstance, jsonld, pkiInstance)
201201
statusEngine := status.NewStatusEngine(system)
202202
metricsEngine := core.NewMetricsEngine()
@@ -224,7 +224,7 @@ func CreateSystem(shutdownCallback context.CancelFunc) *core.System {
224224
system.RegisterRoutes(authIAMAPI.New(authInstance, credentialInstance, vdrInstance, storageInstance, policyInstance))
225225
system.RegisterRoutes(&authMeansAPI.Wrapper{Auth: authInstance})
226226
system.RegisterRoutes(&didmanAPI.Wrapper{Didman: didmanInstance})
227-
system.RegisterRoutes(&discoveryAPI.Wrapper{Server: discoveryInstance})
227+
system.RegisterRoutes(&discoveryAPI.Wrapper{Server: discoveryInstance, Client: discoveryInstance})
228228

229229
// Register engines
230230
// without dependencies

discovery/api/v1/wrapper.go renamed to discovery/api/v1/api.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"context"
2323
"errors"
2424
"github.com/labstack/echo/v4"
25+
"github.com/nuts-foundation/go-did/did"
26+
"github.com/nuts-foundation/nuts-node/audit"
2527
"github.com/nuts-foundation/nuts-node/core"
2628
"github.com/nuts-foundation/nuts-node/discovery"
2729
"net/http"
@@ -56,6 +58,9 @@ func (w *Wrapper) Routes(router core.EchoRouter) {
5658
return f(ctx, request)
5759
}
5860
},
61+
func(f StrictHandlerFunc, operationID string) StrictHandlerFunc {
62+
return audit.StrictMiddleware(f, discovery.ModuleName, operationID)
63+
},
5964
}))
6065
}
6166

@@ -77,7 +82,7 @@ func (w *Wrapper) GetPresentations(_ context.Context, request GetPresentationsRe
7782
}
7883

7984
func (w *Wrapper) RegisterPresentation(_ context.Context, request RegisterPresentationRequestObject) (RegisterPresentationResponseObject, error) {
80-
err := w.Server.Add(request.ServiceID, *request.Body)
85+
err := w.Server.Register(request.ServiceID, *request.Body)
8186
if err != nil {
8287
return nil, err
8388
}
@@ -99,3 +104,40 @@ func (w *Wrapper) SearchPresentations(_ context.Context, request SearchPresentat
99104
}
100105
return SearchPresentations200JSONResponse(result), nil
101106
}
107+
108+
func (w *Wrapper) ActivateServiceForDID(ctx context.Context, request ActivateServiceForDIDRequestObject) (ActivateServiceForDIDResponseObject, error) {
109+
subjectDID, err := did.ParseDID(request.Did)
110+
if err != nil {
111+
return nil, err
112+
}
113+
err = w.Client.ActivateServiceForDID(ctx, request.ServiceID, *subjectDID)
114+
if errors.Is(err, discovery.ErrPresentationRegistrationFailed) {
115+
// registration failed, but will be retried
116+
return ActivateServiceForDID202JSONResponse{
117+
Reason: err.Error(),
118+
}, nil
119+
}
120+
if err != nil {
121+
// other error
122+
return nil, err
123+
}
124+
return ActivateServiceForDID200Response{}, nil
125+
}
126+
127+
func (w *Wrapper) DeactivateServiceForDID(ctx context.Context, request DeactivateServiceForDIDRequestObject) (DeactivateServiceForDIDResponseObject, error) {
128+
subjectDID, err := did.ParseDID(request.Did)
129+
if err != nil {
130+
return nil, err
131+
}
132+
err = w.Client.DeactivateServiceForDID(ctx, request.ServiceID, *subjectDID)
133+
if errors.Is(err, discovery.ErrPresentationRegistrationFailed) {
134+
// deactivation succeeded, but Verifiable Presentation couldn't be removed from remote Discovery Server.
135+
return DeactivateServiceForDID202JSONResponse{
136+
Reason: err.Error(),
137+
}, nil
138+
}
139+
if err != nil {
140+
return nil, err
141+
}
142+
return DeactivateServiceForDID200Response{}, nil
143+
}

discovery/api/v1/wrapper_test.go renamed to discovery/api/v1/api_test.go

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package v1
2121
import (
2222
"errors"
2323
ssi "github.com/nuts-foundation/go-did"
24+
"github.com/nuts-foundation/go-did/did"
2425
"github.com/nuts-foundation/go-did/vc"
2526
"github.com/nuts-foundation/nuts-node/discovery"
2627
"github.com/nuts-foundation/nuts-node/vcr/credential"
@@ -80,7 +81,7 @@ func TestWrapper_RegisterPresentation(t *testing.T) {
8081
t.Run("ok", func(t *testing.T) {
8182
test := newMockContext(t)
8283
presentation := vc.VerifiablePresentation{}
83-
test.server.EXPECT().Add(serviceID, presentation).Return(nil)
84+
test.server.EXPECT().Register(serviceID, presentation).Return(nil)
8485

8586
response, err := test.wrapper.RegisterPresentation(nil, RegisterPresentationRequestObject{
8687
ServiceID: serviceID,
@@ -93,7 +94,7 @@ func TestWrapper_RegisterPresentation(t *testing.T) {
9394
t.Run("error", func(t *testing.T) {
9495
test := newMockContext(t)
9596
presentation := vc.VerifiablePresentation{}
96-
test.server.EXPECT().Add(serviceID, presentation).Return(discovery.ErrInvalidPresentation)
97+
test.server.EXPECT().Register(serviceID, presentation).Return(discovery.ErrInvalidPresentation)
9798

9899
_, err := test.wrapper.RegisterPresentation(nil, RegisterPresentationRequestObject{
99100
ServiceID: serviceID,
@@ -104,6 +105,75 @@ func TestWrapper_RegisterPresentation(t *testing.T) {
104105
})
105106
}
106107

108+
func TestWrapper_ActivateServiceForDID(t *testing.T) {
109+
t.Run("ok", func(t *testing.T) {
110+
test := newMockContext(t)
111+
expectedDID := "did:web:example.com"
112+
test.client.EXPECT().ActivateServiceForDID(gomock.Any(), serviceID, did.MustParseDID(expectedDID)).Return(nil)
113+
114+
response, err := test.wrapper.ActivateServiceForDID(nil, ActivateServiceForDIDRequestObject{
115+
ServiceID: serviceID,
116+
Did: expectedDID,
117+
})
118+
119+
assert.NoError(t, err)
120+
assert.IsType(t, ActivateServiceForDID200Response{}, response)
121+
})
122+
t.Run("ok, but registration failed", func(t *testing.T) {
123+
test := newMockContext(t)
124+
expectedDID := "did:web:example.com"
125+
test.client.EXPECT().ActivateServiceForDID(gomock.Any(), gomock.Any(), gomock.Any()).Return(discovery.ErrPresentationRegistrationFailed)
126+
127+
response, err := test.wrapper.ActivateServiceForDID(nil, ActivateServiceForDIDRequestObject{
128+
ServiceID: serviceID,
129+
Did: expectedDID,
130+
})
131+
132+
assert.NoError(t, err)
133+
assert.IsType(t, ActivateServiceForDID202JSONResponse{}, response)
134+
})
135+
t.Run("other error", func(t *testing.T) {
136+
test := newMockContext(t)
137+
expectedDID := "did:web:example.com"
138+
test.client.EXPECT().ActivateServiceForDID(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("foo"))
139+
140+
_, err := test.wrapper.ActivateServiceForDID(nil, ActivateServiceForDIDRequestObject{
141+
ServiceID: serviceID,
142+
Did: expectedDID,
143+
})
144+
145+
assert.Error(t, err)
146+
})
147+
}
148+
149+
func TestWrapper_DeactivateServiceForDID(t *testing.T) {
150+
t.Run("ok", func(t *testing.T) {
151+
test := newMockContext(t)
152+
expectedDID := "did:web:example.com"
153+
test.client.EXPECT().DeactivateServiceForDID(gomock.Any(), serviceID, did.MustParseDID(expectedDID)).Return(nil)
154+
155+
response, err := test.wrapper.DeactivateServiceForDID(nil, DeactivateServiceForDIDRequestObject{
156+
ServiceID: serviceID,
157+
Did: expectedDID,
158+
})
159+
160+
assert.NoError(t, err)
161+
assert.IsType(t, DeactivateServiceForDID200Response{}, response)
162+
})
163+
t.Run("error", func(t *testing.T) {
164+
test := newMockContext(t)
165+
expectedDID := "did:web:example.com"
166+
test.client.EXPECT().DeactivateServiceForDID(gomock.Any(), serviceID, did.MustParseDID(expectedDID)).Return(errors.New("foo"))
167+
168+
_, err := test.wrapper.DeactivateServiceForDID(nil, DeactivateServiceForDIDRequestObject{
169+
ServiceID: serviceID,
170+
Did: expectedDID,
171+
})
172+
173+
assert.Error(t, err)
174+
})
175+
}
176+
107177
func TestWrapper_ResolveStatusCode(t *testing.T) {
108178
expected := map[error]int{
109179
discovery.ErrServerModeDisabled: http.StatusBadRequest,

0 commit comments

Comments
 (0)