Skip to content

Commit

Permalink
re-enable did:web migration (#3473)
Browse files Browse the repository at this point in the history
  • Loading branch information
gerardsn authored Oct 9, 2024
1 parent 793592a commit 3590c1e
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 42 deletions.
3 changes: 1 addition & 2 deletions docs/pages/deployment/migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Nuts node v6 runs several migrations on startup for DID documents that are manag

1. Remove controllers and add self-control to ``did:nuts`` documents,
2. Import ``did:nuts`` documents into the new SQL database under a ``subject`` with the same name, and
3. Add a ``did:web`` document with the same services to the same ``subject``.
3. Add a ``did:web`` document to the same ``subject``.

**Migration: convert did:nuts to self-control**
Requires ``didmethods`` to contain ``nuts``.
Expand All @@ -34,6 +34,5 @@ See ``/status/diagnostics`` if you own any DIDs with a document conflict. If so,
Requires ``didmethods`` to contain ``web`` and ``nuts`` (default).

This migration adds a new ``did:web`` DID Document to owned subjects that do not already have one.
All services from the ``did:nuts`` DID Document are copied to the new document.
A new verification method is created for the document and added to all verification relationships except KeyAgreement.
This means did:web cannot be used for encryption (yet).
15 changes: 15 additions & 0 deletions docs/pages/integrating/version-incompatibilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,18 @@ There are basically two options.

Do not use the VDR V1 and VDR V2 API at the same time. This will lead to unexpected behavior.
Once you use the VDR V2 API, you cannot go back to the VDR V1 API. The VDR V1 API has also been marked as deprecated.

Publishing Services for use-cases
*********************************

V5 use-cases define service endpoints or a collection of endpoints that should be registered in the Services on DID Documents.
The concrete endpoints are usually on the DID Document of the vendor, and then referenced by all DID Documents managed by that vendor.
And ``did:nuts`` for example, requires the registration of a ``NutsComm`` endpoint to authenticate the connection.
Use-cases built on V5 should keep using the DIDMan API to manage and resolve Services on DID Documents.
Any Service change made using the DIDMan API will only update ``did:nuts`` DID Documents.

For use-cases built on V6, any endpoint needed for the use-case should be listed in the registration on the Discovery Service for that use-case, see :ref:`discovery` Registration.
This means that ``did:web`` DID Documents (or non-did:nuts if we look further ahead) will contain very few Services, if any.
If there is a need to add a Service for V6 use-cases, they should be added using the VDR v2 API, which will then add the Service to _all_ DIDs that are part of the Subject.
Note that resolving Services using the VDR v2 API will return the Service from the document as is.
So, it resolves Services without following any references in the Service to a concrete endpoint as is done by DIDMan.
5 changes: 3 additions & 2 deletions docs/pages/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Breaking changes
- The VDR v1 ``createDID`` (``POST /internal/vdr/v1/did``) no longer supports the ``controller`` and ``selfControl`` fields. All did:nuts documents are now self controlled. All existing documents will be migrated to self controlled at startup.
- Managed ``did:nuts`` DIDs are migrated to the new SQL storage. Unresolved DID document conflicts may contain an incorrect state after migrating to v6. See ``/status/diagnostics`` if you own any DIDs with a document conflict; use ``/internal/vdr/v1/did/conflicted`` to find the specific DIDs.
- Removed legacy API authentication tokens.
- See caveats in :ref:`version-incompatibilities`.

============
New Features
Expand Down Expand Up @@ -52,7 +53,7 @@ Changes
- Removed support for the UZI authentication means.
- Documentation of ``did:nuts``-related features have been removed (refer to v5 documentation).
- Documentation of specific use cases (e.g. health care in general or eOverdracht) has been moved to the `Nuts wiki <https://wiki.nuts.nl>`_.
- Node can now be run without configuring TLS when the gRPC network isn't used (no bootstrap node configured and no network state), to cater use cases that don't use ``did:nuts``.
- Node can now be run without configuring TLS when the gRPC network isn't used (``didmethods`` does not contain ``nuts``), to cater use cases that don't use ``did:nuts``.
- Crypto backends store keys under a key name and are linked to the kid via the ``key_reference`` SQL table.

The following features have also been changed:
Expand All @@ -63,7 +64,7 @@ DID management
You no longer manage changes to DIDs but to Subjects. Each subject has multiple DIDs, one for each enabled DID method.
You're free to choose an ID for a Subject. This feature enables forwards compatibility with new DID methods.
DID methods can be enabled and disabled via the ``didmethods`` config parameter. (Default: ``['web','nuts']``).
Existing ``did:nuts`` documents will be migrated to self-controlled at startup and the DID will be added as SubjectID.
Existing ``did:nuts`` documents will be migrated to self-controlled at startup and the DID will be added as SubjectID together with a new ``did:web`` DID.
See :ref:`nuts-node-migrations` for more information.

HTTP interface
Expand Down
17 changes: 5 additions & 12 deletions e2e-tests/migration/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func Test_Migrations(t *testing.T) {

DIDs, err := man.DID.All()
require.NoError(t, err)
require.Len(t, DIDs, 4) // 4 did:nuts, 3 did:web
require.Len(t, DIDs, 7) // 4 did:nuts, 3 did:web

t.Run("vendor", func(t *testing.T) {
// versions for did:nuts:
Expand All @@ -67,7 +67,7 @@ func Test_Migrations(t *testing.T) {
assert.Len(t, doc.VerificationMethods, 2)

// migration: add did:web
EqualServices(t, man, doc)
hasDIDWeb(t, man, doc)
})
t.Run("org1", func(t *testing.T) {
// versions for did:nuts:
Expand All @@ -89,7 +89,7 @@ func Test_Migrations(t *testing.T) {
assert.Empty(t, didDoc.Controller)

// migration: add did:web
EqualServices(t, man, doc)
hasDIDWeb(t, man, doc)
})
t.Run("org2", func(t *testing.T) {
// versions for did:nuts:
Expand Down Expand Up @@ -133,14 +133,11 @@ func Test_Migrations(t *testing.T) {
assert.Empty(t, didDoc.Controller)

// migration: add did:web
EqualServices(t, man, doc)
hasDIDWeb(t, man, doc)
})
}

func EqualServices(t *testing.T, man *manager, nutsDoc *orm.DidDocument) {
return // disable until there is a fix for https://github.com/nuts-foundation/nuts-node/issues/3444
didWebPrefix := "did:web:nodeA%3A8080"

func hasDIDWeb(t *testing.T, man *manager, nutsDoc *orm.DidDocument) {
dids, err := man.DID.FindBySubject(nutsDoc.DID.Subject) // migrated documents have subject == did:nuts:...
require.NoError(t, err)
assert.Len(t, dids, 2)
Expand All @@ -152,8 +149,4 @@ func EqualServices(t *testing.T, man *manager, nutsDoc *orm.DidDocument) {
}
}
assert.Equal(t, 0, webDoc.Version)
assert.Equal(t, len(nutsDoc.Services), len(webDoc.Services))
for _, service := range webDoc.Services {
assert.True(t, strings.HasPrefix(service.ID, didWebPrefix))
}
}
22 changes: 2 additions & 20 deletions vdr/didsubject/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -769,26 +769,8 @@ func (r *SqlManager) MigrateAddWebToNuts(ctx context.Context, id did.DID) error
ID: webDoc.DID.ID,
Subject: subject,
}
// rename services. only the DID part of the service.ID needs to be updates
webDoc.Services = make([]orm.Service, len(nutsDoc.Services))
for i, ormService := range nutsDoc.Services {
service := new(did.Service)
err = json.Unmarshal(ormService.Data, service)
if err != nil {
return err
}
service.ID = ssi.MustParseURI(webDID.ID + "#" + service.ID.Fragment)
rawService, err := json.Marshal(service)
if err != nil {
return err
}
webDoc.Services[i] = orm.Service{
ID: service.ID.String(),
Data: rawService,
}
}
// store did:web
_, err = sqlDIDDocumentManager.CreateOrUpdate(webDID, webDoc.VerificationMethods, webDoc.Services)
// store did:web; don't migrate services
_, err = sqlDIDDocumentManager.CreateOrUpdate(webDID, webDoc.VerificationMethods, nil)
if err != nil {
return err
}
Expand Down
4 changes: 1 addition & 3 deletions vdr/didsubject/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,12 +627,10 @@ func TestSqlManager_MigrateAddWebToNuts(t *testing.T) {
assert.Equal(t, didNuts.String(), dids[0].ID)
assert.Equal(t, didWeb.String(), dids[1].ID)

docNuts, err := NewDIDDocumentManager(db).Latest(didNuts, nil)
require.NoError(t, err)
docWeb, err := NewDIDDocumentManager(db).Latest(didWeb, nil)
require.NoError(t, err)
assert.Equal(t, len(docNuts.Services), len(docWeb.Services))
assert.Equal(t, didWeb.String()+"#service-1", docWeb.Services[0].ID)
assert.Len(t, docWeb.Services, 0)
})
t.Run("ok - already has did:web", func(t *testing.T) {
db := testDB(t)
Expand Down
3 changes: 1 addition & 2 deletions vdr/vdr.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ func (r *Module) allMigrations() []migration {
return []migration{ // key will be printed as description of the migration
{r.migrateRemoveControllerFromDIDNuts, "remove controller"}, // must come before migrateHistoryOwnedDIDNuts so controller removal is also migrated.
{r.migrateHistoryOwnedDIDNuts, "document history"},
// Disable migration until we have a fix for: https://github.com/nuts-foundation/nuts-node/issues/3444
//{r.migrateAddDIDWebToOwnedDIDNuts, "add did:web to subject"}, // must come after migrateHistoryOwnedDIDNuts since it acts on the SQL store.
{r.migrateAddDIDWebToOwnedDIDNuts, "add did:web to subject"}, // must come after migrateHistoryOwnedDIDNuts since it acts on the SQL store.
}
}

Expand Down
2 changes: 1 addition & 1 deletion vdr/vdr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ func TestVDR_Migrate(t *testing.T) {
ctx.mockDocumentOwner.EXPECT().ListOwned(gomock.Any()).Return([]did.DID{testDIDWeb}, nil)
err := ctx.vdr.Migrate()
assert.NoError(t, err)
assert.Len(t, ctx.vdr.migrations, 2) // confirm its running allMigrations() that currently is only did:nuts
assert.Len(t, ctx.vdr.migrations, 3) // confirm its running allMigrations() that currently is only did:nuts
})
t.Run("controller migration", func(t *testing.T) {
controllerMigrationSetup := func(t *testing.T) vdrTestCtx {
Expand Down

0 comments on commit 3590c1e

Please sign in to comment.