diff --git a/README.rst b/README.rst index f6316b814b..81ecce4964 100644 --- a/README.rst +++ b/README.rst @@ -224,7 +224,7 @@ The following options can be configured on the server: http.default.auth.type Whether to enable authentication for the default interface, specify 'token_v2' for bearer token mode or 'token' for legacy bearer token mode. http.default.cors.origin [] When set, enables CORS from the specified origins on the default HTTP interface. **JSONLD** - jsonld.contexts.localmapping [https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json=assets/contexts/lds-jws2020-v1.ldjson,https://schema.org=assets/contexts/schema-org-v13.ldjson,https://nuts.nl/credentials/v1=assets/contexts/nuts.ldjson,https://www.w3.org/2018/credentials/v1=assets/contexts/w3c-credentials-v1.ldjson] This setting allows mapping external URLs to local files for e.g. preventing external dependencies. These mappings have precedence over those in remoteallowlist. + jsonld.contexts.localmapping [https://www.w3.org/2018/credentials/v1=assets/contexts/w3c-credentials-v1.ldjson,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json=assets/contexts/lds-jws2020-v1.ldjson,https://schema.org=assets/contexts/schema-org-v13.ldjson,https://nuts.nl/credentials/v1=assets/contexts/nuts.ldjson] This setting allows mapping external URLs to local files for e.g. preventing external dependencies. These mappings have precedence over those in remoteallowlist. jsonld.contexts.remoteallowlist [https://schema.org,https://www.w3.org/2018/credentials/v1,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json] In strict mode, fetching external JSON-LD contexts is not allowed except for context-URLs listed here. **Network** network.bootstrapnodes [] List of bootstrap nodes (':') which the node initially connect to. diff --git a/auth/api/iam/api_test.go b/auth/api/iam/api_test.go index 771e4090de..fb5edb0b4b 100644 --- a/auth/api/iam/api_test.go +++ b/auth/api/iam/api_test.go @@ -22,7 +22,6 @@ import ( "context" "encoding/json" "errors" - "net/http" "net/http/httptest" "net/url" @@ -178,7 +177,6 @@ func TestWrapper_PresentationDefinition(t *testing.T) { t.Run("ok", func(t *testing.T) { test := newTestClient(t) - test.authnServices.EXPECT().PresentationDefinitions().Return(&definitionResolver) response, err := test.client.PresentationDefinition(ctx, PresentationDefinitionRequestObject{Did: webDID.ID, Params: PresentationDefinitionParams{Scope: "eOverdracht-overdrachtsbericht"}}) @@ -201,7 +199,6 @@ func TestWrapper_PresentationDefinition(t *testing.T) { t.Run("error - unknown scope", func(t *testing.T) { test := newTestClient(t) - test.authnServices.EXPECT().PresentationDefinitions().Return(&definitionResolver) response, err := test.client.PresentationDefinition(ctx, PresentationDefinitionRequestObject{Did: webDID.ID, Params: PresentationDefinitionParams{Scope: "unknown"}}) diff --git a/auth/api/iam/s2s_vptoken.go b/auth/api/iam/s2s_vptoken.go index 311e0d1a0f..e8cdc87b5a 100644 --- a/auth/api/iam/s2s_vptoken.go +++ b/auth/api/iam/s2s_vptoken.go @@ -23,22 +23,18 @@ import ( "encoding/json" "errors" "fmt" - "github.com/nuts-foundation/nuts-node/auth/oauth" - "github.com/nuts-foundation/nuts-node/crypto" + "net/url" "time" - "github.com/lestrrat-go/jwx/jws" - "github.com/lestrrat-go/jwx/jwt" "github.com/nuts-foundation/go-did/did" "github.com/nuts-foundation/go-did/vc" + "github.com/nuts-foundation/nuts-node/auth/oauth" "github.com/nuts-foundation/nuts-node/core" + "github.com/nuts-foundation/nuts-node/crypto" "github.com/nuts-foundation/nuts-node/storage" "github.com/nuts-foundation/nuts-node/vcr/credential" "github.com/nuts-foundation/nuts-node/vcr/pe" "github.com/nuts-foundation/nuts-node/vdr/resolver" - "net/url" - "strings" - "time" ) // accessTokenValidity defines how long access tokens are valid. @@ -147,26 +143,6 @@ func (s Wrapper) handleS2SAccessTokenRequest(issuer did.DID, params map[string]s return HandleTokenRequest200JSONResponse(*response), nil } -func (s Wrapper) createAccessToken(issuer did.DID, issueTime time.Time, presentation vc.VerifiablePresentation, scope string) (*TokenResponse, error) { - accessToken := AccessToken{ - Token: generateCode(), - Issuer: issuer.String(), - Expiration: issueTime.Add(accessTokenValidity), - Presentation: presentation, - } - err := s.storageInstance.GetSessionDatabase().GetStore(accessTokenValidity, "s2s", issuer.String(), "accesstoken").Put(accessToken.Token, accessToken) - if err != nil { - return nil, fmt.Errorf("unable to store access token: %w", err) - } - expiresIn := int(accessTokenValidity.Seconds()) - return &TokenResponse{ - AccessToken: accessToken.Token, - ExpiresIn: &expiresIn, - Scope: &scope, - TokenType: "bearer", - }, nil -} - func (r Wrapper) RequestAccessToken(ctx context.Context, request RequestAccessTokenRequestObject) (RequestAccessTokenResponseObject, error) { if request.Body == nil { // why did oapi-codegen generate a pointer for the body?? diff --git a/auth/api/iam/types.go b/auth/api/iam/types.go index 141a4fbce3..a0f9e48897 100644 --- a/auth/api/iam/types.go +++ b/auth/api/iam/types.go @@ -24,7 +24,6 @@ import ( "github.com/nuts-foundation/nuts-node/auth/oauth" "github.com/nuts-foundation/nuts-node/vcr/pe" "github.com/nuts-foundation/nuts-node/vdr/resolver" - "time" ) // DIDDocument is an alias diff --git a/docs/pages/deployment/cli-reference.rst b/docs/pages/deployment/cli-reference.rst index 0bf3c272ea..ea99046b26 100755 --- a/docs/pages/deployment/cli-reference.rst +++ b/docs/pages/deployment/cli-reference.rst @@ -44,7 +44,7 @@ The following options apply to the server commands below: --http.default.log string What to log about HTTP requests. Options are 'nothing', 'metadata' (log request method, URI, IP and response code), and 'metadata-and-body' (log the request and response body, in addition to the metadata). (default "metadata") --http.default.tls string Whether to enable TLS for the default interface, options are 'disabled', 'server', 'server-client'. Leaving it empty is synonymous to 'disabled', --internalratelimiter When set, expensive internal calls are rate-limited to protect the network. Always enabled in strict mode. (default true) - --jsonld.contexts.localmapping stringToString This setting allows mapping external URLs to local files for e.g. preventing external dependencies. These mappings have precedence over those in remoteallowlist. (default [https://schema.org=assets/contexts/schema-org-v13.ldjson,https://nuts.nl/credentials/v1=assets/contexts/nuts.ldjson,https://www.w3.org/2018/credentials/v1=assets/contexts/w3c-credentials-v1.ldjson,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json=assets/contexts/lds-jws2020-v1.ldjson]) + --jsonld.contexts.localmapping stringToString This setting allows mapping external URLs to local files for e.g. preventing external dependencies. These mappings have precedence over those in remoteallowlist. (default [https://nuts.nl/credentials/v1=assets/contexts/nuts.ldjson,https://www.w3.org/2018/credentials/v1=assets/contexts/w3c-credentials-v1.ldjson,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json=assets/contexts/lds-jws2020-v1.ldjson,https://schema.org=assets/contexts/schema-org-v13.ldjson]) --jsonld.contexts.remoteallowlist strings In strict mode, fetching external JSON-LD contexts is not allowed except for context-URLs listed here. (default [https://schema.org,https://www.w3.org/2018/credentials/v1,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json]) --loggerformat string Log format (text, json) (default "text") --network.bootstrapnodes strings List of bootstrap nodes (':') which the node initially connect to. diff --git a/docs/pages/deployment/server_options.rst b/docs/pages/deployment/server_options.rst index 03b274bb46..944cf3b97b 100755 --- a/docs/pages/deployment/server_options.rst +++ b/docs/pages/deployment/server_options.rst @@ -50,7 +50,7 @@ http.default.auth.type Whether to enable authentication for the default interface, specify 'token_v2' for bearer token mode or 'token' for legacy bearer token mode. http.default.cors.origin [] When set, enables CORS from the specified origins on the default HTTP interface. **JSONLD** - jsonld.contexts.localmapping [https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json=assets/contexts/lds-jws2020-v1.ldjson,https://schema.org=assets/contexts/schema-org-v13.ldjson,https://nuts.nl/credentials/v1=assets/contexts/nuts.ldjson,https://www.w3.org/2018/credentials/v1=assets/contexts/w3c-credentials-v1.ldjson] This setting allows mapping external URLs to local files for e.g. preventing external dependencies. These mappings have precedence over those in remoteallowlist. + jsonld.contexts.localmapping [https://www.w3.org/2018/credentials/v1=assets/contexts/w3c-credentials-v1.ldjson,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json=assets/contexts/lds-jws2020-v1.ldjson,https://schema.org=assets/contexts/schema-org-v13.ldjson,https://nuts.nl/credentials/v1=assets/contexts/nuts.ldjson] This setting allows mapping external URLs to local files for e.g. preventing external dependencies. These mappings have precedence over those in remoteallowlist. jsonld.contexts.remoteallowlist [https://schema.org,https://www.w3.org/2018/credentials/v1,https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json] In strict mode, fetching external JSON-LD contexts is not allowed except for context-URLs listed here. **Network** network.bootstrapnodes [] List of bootstrap nodes (':') which the node initially connect to. diff --git a/vcr/assets/test_assets.go b/vcr/assets/test_assets.go index 39ce28e2ef..bdf0e1e490 100644 --- a/vcr/assets/test_assets.go +++ b/vcr/assets/test_assets.go @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2023 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 . + * + */ + package assets import ( diff --git a/vcr/pe/submission.go b/vcr/pe/submission.go deleted file mode 100644 index e73b3f8ca2..0000000000 --- a/vcr/pe/submission.go +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2023 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 . - * - */ - -package pe - -import ( - "encoding/json" - "fmt" - "github.com/PaesslerAG/jsonpath" - "github.com/nuts-foundation/go-did/vc" -) - -// Credentials returns the credential from the Verifiable Presentation mapped by the submission's InputDescriptors. -// If one or more InputDescriptors can't be mapped to a Verifiable Credential, it returns an error. -// It will never return more credentials than mapped by the submission. -// The credentials will be returned as map with the InputDescriptor.Id as key. -func (s PresentationSubmission) Credentials(presentation vc.VerifiablePresentation) (map[string]vc.VerifiableCredential, error) { - presentationJSON, err := presentation.MarshalJSON() - if err != nil { - return nil, err - } - var presentationAsMap map[string]interface{} - _ = json.Unmarshal(presentationJSON, &presentationAsMap) - // Handle compacted array of JSON-LD VP: presentation submission indexes VerifiablePresentation.credentialSubject, - // which only works if it's actually an array. - verifiableCredentials := presentationAsMap["verifiableCredential"] - if verifiableCredentials != nil { - _, isSlice := verifiableCredentials.([]interface{}) - if !isSlice { - presentationAsMap["verifiableCredential"] = []interface{}{verifiableCredentials} - } - } - - var credentials = make(map[string]vc.VerifiableCredential, len(s.DescriptorMap)) - for _, inputDescriptor := range s.DescriptorMap { - // Note: path_nested is not supported. Do we need it? - credentialAsInterf, err := jsonpath.Get(inputDescriptor.Path, presentationAsMap) - if err != nil { - return nil, fmt.Errorf("descriptor '%s' evaluation failed: %w", inputDescriptor.Id, err) - } - if credentialAsInterf == nil || err != nil { - return nil, fmt.Errorf("descriptor '%s' does not evaluate to a VC in the VP", inputDescriptor.Id) - } - credentialAsJSON, _ := json.Marshal(credentialAsInterf) // can only fail when credentialAsInterf is a func(), which is impossible - var credential vc.VerifiableCredential - if err = json.Unmarshal(credentialAsJSON, &credential); err != nil { - return nil, fmt.Errorf("descriptor '%s' evaluates to an invalid VC in the VP: %w", inputDescriptor.Id, err) - } - credentials[inputDescriptor.Id] = credential - } - return credentials, nil -} diff --git a/vcr/pe/submission_test.go b/vcr/pe/submission_test.go deleted file mode 100644 index fe8d8c36e6..0000000000 --- a/vcr/pe/submission_test.go +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2023 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 . - * - */ - -package pe - -import ( - "encoding/json" - ssi "github.com/nuts-foundation/go-did" - "github.com/nuts-foundation/go-did/vc" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "testing" -) - -func TestPresentationSubmission_Credentials(t *testing.T) { - credential1ID := ssi.MustParseURI("cred-1") - credential1 := vc.VerifiableCredential{ - ID: &credential1ID, - } - credential2ID := ssi.MustParseURI("cred-2") - credential2 := vc.VerifiableCredential{ - ID: &credential2ID, - } - - t.Run("1 input descriptor", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - VerifiableCredential: []vc.VerifiableCredential{credential1}, - } - submissionJSON := ` -{ - "descriptor_map": [ - { - "id": "1", - "path": "$.verifiableCredential[0]", - "format": "ldp_vc" - } - ] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - require.NoError(t, err) - assert.Equal(t, []vc.VerifiableCredential{credential1}, credentials) - }) - t.Run("2 input descriptors", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - VerifiableCredential: []vc.VerifiableCredential{credential1, credential2}, - } - submissionJSON := ` -{ - "descriptor_map": [ - { - "id": "1", - "path": "$.verifiableCredential[0]", - "format": "ldp_vc" - }, - { - "id": "2", - "path": "$.verifiableCredential[1]", - "format": "ldp_vc" - } - ] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - require.NoError(t, err) - assert.Equal(t, []vc.VerifiableCredential{credential1, credential2}, credentials) - }) - t.Run("input descriptor does not match", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - VerifiableCredential: []vc.VerifiableCredential{credential1}, - } - submissionJSON := ` -{ - "descriptor_map": [ - { - "id": "1", - "path": "$.verifiableCredential[1]", - "format": "ldp_vc" - } - ] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - assert.EqualError(t, err, "descriptor '1' does not evaluate to a VC in the VP") - assert.Nil(t, credentials) - }) - t.Run("input descriptors with the same path", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - VerifiableCredential: []vc.VerifiableCredential{credential1, credential2}, - } - submissionJSON := ` -{ - "descriptor_map": [ - { - "id": "1", - "path": "$.verifiableCredential[0]", - "format": "ldp_vc" - }, - { - "id": "2", - "path": "$.verifiableCredential[0]", - "format": "ldp_vc" - } - ] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - require.NoError(t, err) - assert.Equal(t, []vc.VerifiableCredential{credential1}, credentials) - }) - t.Run("no input descriptors", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - VerifiableCredential: []vc.VerifiableCredential{credential1, credential2}, - } - submissionJSON := ` -{ - "descriptor_map": [] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - assert.NoError(t, err) - assert.Empty(t, credentials) - }) - t.Run("invalid input descriptor path (empty)", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - VerifiableCredential: []vc.VerifiableCredential{credential1, credential2}, - } - submissionJSON := ` -{ - "descriptor_map": [ - { - "id": "1", - "path": "", - "format": "ldp_vc" - } - ] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - assert.EqualError(t, err, "descriptor '1' evaluation failed: parsing error: \t - 1:1 unexpected EOF while scanning extensions") - assert.Empty(t, credentials) - }) - t.Run("input descriptor does not point to a verifiable credential", func(t *testing.T) { - vp := vc.VerifiablePresentation{ - Proof: []interface{}{ - "test", - }, - VerifiableCredential: []vc.VerifiableCredential{credential1, credential2}, - } - submissionJSON := ` -{ - "descriptor_map": [ - { - "id": "1", - "path": "$.proof", - "format": "ldp_vc" - } - ] -}` - var submission PresentationSubmission - _ = json.Unmarshal([]byte(submissionJSON), &submission) - - credentials, err := submission.Credentials(vp) - - assert.EqualError(t, err, "descriptor '1' evaluates to an invalid VC in the VP: json: cannot unmarshal string into Go value of type map[string]interface {}") - assert.Empty(t, credentials) - }) -} diff --git a/vcr/pe/types.go b/vcr/pe/types.go index 6d58f9702c..c0cadfbdef 100644 --- a/vcr/pe/types.go +++ b/vcr/pe/types.go @@ -22,10 +22,6 @@ package pe // PresentationDefinitionClaimFormatDesignations (replaces generated one) type PresentationDefinitionClaimFormatDesignations map[string]map[string][]string -func (pdcfd PresentationDefinitionClaimFormatDesignations) Supports(format string) bool { - return pdcfd[format] != nil -} - // PresentationSubmission describes how the VCs in the VP match the input descriptors in the PD type PresentationSubmission struct { // Id is the id of the presentation submission, which is a UUID diff --git a/vcr/pe/util.go b/vcr/pe/util.go index ce57902c82..5b418aab6f 100644 --- a/vcr/pe/util.go +++ b/vcr/pe/util.go @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2023 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 . + * + */ + package pe import ( diff --git a/vcr/pe/util_test.go b/vcr/pe/util_test.go index 398bb7e994..244b183167 100644 --- a/vcr/pe/util_test.go +++ b/vcr/pe/util_test.go @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2023 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 . + * + */ + package pe import ( diff --git a/vcr/test/test.go b/vcr/test/test.go index 02b6e8e721..96d887579c 100644 --- a/vcr/test/test.go +++ b/vcr/test/test.go @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2023 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 . + * + */ + package test import (