Skip to content

Commit

Permalink
Add config for VDR (#3254)
Browse files Browse the repository at this point in the history
* just keep 3 packages to prevent deleting them all

* add supported methods to vdr config

* doc update
  • Loading branch information
woutslakhorst authored Jul 17, 2024
1 parent 89387c2 commit 8404439
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 56 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/e2e-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ jobs:
package: nuts-node-ci
# NOTE: using Personal Access Token
token: ${{ secrets.PACKAGE_SECRET }}
tags: ${{ env.SHA }}
keep-n-tagged: 3

- name: package cleanup dependabot
Expand All @@ -98,5 +97,4 @@ jobs:
package: nuts-node-ci
# NOTE: using Personal Access Token
token: ${{ secrets.GITHUB_TOKEN }}
tags: ${{ env.SHA }}
keep-n-tagged: 3
88 changes: 44 additions & 44 deletions README.rst

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/pages/deployment/cli-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The following options apply to the server commands below:
--crypto.vault.timeout duration Timeout of client calls to Vault, in Golang time.Duration string format (e.g. 1s). (default 5s)
--crypto.vault.token string The Vault token. If set it overwrites the VAULT_TOKEN env var.
--datadir string Directory where the node stores its files. (default "./data")
--didmethods strings Comma-separated list of DID methods (without did: prefix). (default [web,nuts])
--discovery.client.refresh_interval duration Interval at which the client synchronizes with the Discovery Server; refreshing Verifiable Presentations of local DIDs and loading changes, updating the local copy. It only will actually refresh registrations of local DIDs that about to expire (less than 1/4th of their lifetime left). Specified as Golang duration (e.g. 1m, 1h30m). (default 10m0s)
--discovery.definitions.directory string Directory to load Discovery Service Definitions from. If not set, the discovery service will be disabled. If the directory contains JSON files that can't be parsed as service definition, the node will fail to start. (default "./config/discovery")
--discovery.server.ids strings IDs of the Discovery Service for which to act as server. If an ID does not map to a loaded service definition, the node will fail to start.
Expand Down Expand Up @@ -62,8 +63,7 @@ The following options apply to the server commands below:
--network.v2.gossipinterval int Interval (in milliseconds) that specifies how often the node should gossip its new hashes to other nodes. (default 5000)
--pki.maxupdatefailhours int Maximum number of hours that a denylist update can fail (default 4)
--pki.softfail Do not reject certificates if their revocation status cannot be established when softfail is true (default true)
--policy.address string The address of a remote policy server. Mutual exclusive with policy.directory.
--policy.directory string Directory to read policy files from. Policy files are JSON files that contain a scope to PresentationDefinition mapping. Mutual exclusive with policy.address. (default "./config/policy")
--policy.directory string Directory to read policy files from. Policy files are JSON files that contain a scope to PresentationDefinition mapping. (default "./config/policy")
--storage.bbolt.backup.directory string Target directory for BBolt database backups.
--storage.bbolt.backup.interval duration Interval, formatted as Golang duration (e.g. 10m, 1h) at which BBolt database backups will be performed.
--storage.redis.address string Redis database server address. This can be a simple 'host:port' or a Redis connection URL with scheme, auth and other options.
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/deployment/server_options.rst

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions vdr/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/nuts-foundation/nuts-node/vdr"
"io"
"os"
"strings"
Expand All @@ -41,6 +42,10 @@ import (
// FlagSet contains flags relevant for the VDR instance
func FlagSet() *pflag.FlagSet {
flagSet := pflag.NewFlagSet("vdr", pflag.ContinueOnError)

defs := vdr.DefaultConfig()

flagSet.StringSlice("didmethods", defs.DIDMethods, "Comma-separated list of DID methods (without did: prefix).")
return flagSet
}

Expand Down
29 changes: 29 additions & 0 deletions vdr/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 Nuts community
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

package vdr

type Config struct {
DIDMethods []string `koanf:"didmethods"`
}

func DefaultConfig() Config {
return Config{
DIDMethods: []string{"web", "nuts"},
}
}
2 changes: 2 additions & 0 deletions vdr/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type VDR interface {
ResolveManaged(id did.DID) (*did.Document, error)
// Resolver returns the resolver for getting the DID document for a DID.
Resolver() resolver.DIDResolver
// SupportedMethods returns the activated DID methods.
SupportedMethods() []string
// ConflictedDocuments returns the DID Document and metadata of all documents with a conflict.
ConflictedDocuments() ([]did.Document, []resolver.DocumentMetadata, error)
}
14 changes: 14 additions & 0 deletions vdr/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 34 additions & 5 deletions vdr/vdr.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"

ssi "github.com/nuts-foundation/go-did"
"github.com/nuts-foundation/go-did/did"
Expand Down Expand Up @@ -62,6 +63,7 @@ var _ core.Configurable = (*Module)(nil)
// It connects the Resolve, Create and Update DID methods to the network, and receives events back from the network which are processed in the store.
// It is also a Runnable, Diagnosable and Configurable Nuts Engine.
type Module struct {
config Config
store didnutsStore.Store
network network.Transactions
networkAmbassador didnuts.Ambassador
Expand Down Expand Up @@ -97,11 +99,16 @@ func (r *Module) Resolver() resolver.DIDResolver {
return r.didResolver
}

func (r *Module) SupportedMethods() []string {
return r.config.DIDMethods
}

// NewVDR creates a new Module with provided params
func NewVDR(cryptoClient crypto.KeyStore, networkClient network.Transactions,
didStore didnutsStore.Store, eventManager events.Event, storageInstance storage.Engine) *Module {
didResolver := &resolver.DIDResolverRouter{}
return &Module{
module := Module{
config: DefaultConfig(),
network: networkClient,
eventManager: eventManager,
didResolver: didResolver,
Expand All @@ -110,14 +117,33 @@ func NewVDR(cryptoClient crypto.KeyStore, networkClient network.Transactions,
keyStore: cryptoClient,
storageInstance: storageInstance,
}
return &module
}

func (r *Module) Name() string {
return ModuleName
}

func (r *Module) Config() interface{} {
return &r.config
}

// Configure configures the Module engine.
func (r *Module) Configure(config core.ServerConfig) error {
// at least one method should be configured
if len(r.config.DIDMethods) == 0 {
return errors.New("no DID methods configured")
}
// check if all configured methods are supported
for _, method := range r.config.DIDMethods {
switch method {
case didnuts.MethodName, didweb.MethodName:
continue
default:
return fmt.Errorf("unsupported DID method: %s", method)
}
}

r.networkAmbassador = didnuts.NewAmbassador(r.network, r.store, r.eventManager)
r.db = r.storageInstance.GetSQLDatabase()

Expand All @@ -132,16 +158,17 @@ func (r *Module) Configure(config core.ServerConfig) error {
},
// deprecated
newCachingDocumentOwner(privateKeyDocumentOwner{keyResolver: r.keyStore}, r.didResolver))
r.documentManagers = map[string]management.DocumentManager{
didnuts.MethodName: nutsManager,
}
r.documentManagers = map[string]management.DocumentManager{}
r.documentOwner = &MultiDocumentOwner{
DocumentOwners: []didsubject.DocumentOwner{
newCachingDocumentOwner(DBDocumentOwner{DB: r.db}, r.didResolver),
// if the DB doesn't know, we check the private keys (legacy)
newCachingDocumentOwner(privateKeyDocumentOwner{keyResolver: r.keyStore}, r.didResolver),
},
}
if slices.Contains(r.config.DIDMethods, didnuts.MethodName) {
r.documentManagers[didnuts.MethodName] = nutsManager
}

// did:web
publicURL, err := config.ServerURL()
Expand All @@ -153,7 +180,9 @@ func (r *Module) Configure(config core.ServerConfig) error {
return err
}
manager := didweb.NewManager(*rootDID, "iam", r.keyStore, r.storageInstance.GetSQLDatabase())
r.documentManagers[didweb.MethodName] = manager
if slices.Contains(r.config.DIDMethods, didweb.MethodName) {
r.documentManagers[didweb.MethodName] = manager
}
// did:web resolver should first look in own database, then resolve over the web
webResolver := resolver.ChainedDIDResolver{
Resolvers: []resolver.DIDResolver{
Expand Down

0 comments on commit 8404439

Please sign in to comment.