diff --git a/discovery/api/v1/wapper.go b/discovery/api/v1/wapper.go index c7c9e94976..62b00bde60 100644 --- a/discovery/api/v1/wapper.go +++ b/discovery/api/v1/wapper.go @@ -36,7 +36,6 @@ type Wrapper struct { } func (w *Wrapper) ResolveStatusCode(err error) int { - // todo switch { case errors.Is(err, discovery.ErrServerModeDisabled): return http.StatusBadRequest diff --git a/discovery/interface.go b/discovery/interface.go index 4167a99cc7..207138dc0a 100644 --- a/discovery/interface.go +++ b/discovery/interface.go @@ -26,6 +26,7 @@ import ( "strings" ) +// Tag is value that references a point in the list. // It is opaque for clients: they should not try to interpret it. // The server who issued the tag can interpret it as Lamport timestamp. type Tag string @@ -97,5 +98,5 @@ type Client interface { type SearchResult struct { VP vc.VerifiablePresentation - Fields map[string]string + Fields map[string]interface{} } diff --git a/discovery/module.go b/discovery/module.go index b37ca5ff37..43e26e4005 100644 --- a/discovery/module.go +++ b/discovery/module.go @@ -24,6 +24,7 @@ import ( ssi "github.com/nuts-foundation/go-did" "github.com/nuts-foundation/go-did/vc" "github.com/nuts-foundation/nuts-node/core" + "github.com/nuts-foundation/nuts-node/discovery/log" "github.com/nuts-foundation/nuts-node/storage" "github.com/nuts-foundation/nuts-node/vcr" "github.com/nuts-foundation/nuts-node/vcr/credential" @@ -260,7 +261,8 @@ func loadDefinitions(directory string) (map[string]ServiceDefinition, error) { } func (m *Module) Search(serviceID string, query map[string]string) ([]SearchResult, error) { - if _, exists := m.serverDefinitions[serviceID]; !exists { + serviceDefinition, exists := m.serverDefinitions[serviceID] + if !exists { return nil, ErrServerModeDisabled } matchingVPs, err := m.store.search(serviceID, query) @@ -269,10 +271,25 @@ func (m *Module) Search(serviceID string, query map[string]string) ([]SearchResu } var result []SearchResult for _, matchingVP := range matchingVPs { + // Match credentials to Presentation Definition, to resolve map with InputDescriptorId -> CredentialValue + submissionVCs, inputDescriptorMappingObjects, err := serviceDefinition.PresentationDefinition.Match(matchingVP.VerifiableCredential) + var fields map[string]interface{} + if err != nil { + log.Logger().Infof("Search() is unable to build submission for VP '%s': %s", matchingVP.ID, err) + } else { + credentialMap := make(map[string]vc.VerifiableCredential) + for i := 0; i < len(inputDescriptorMappingObjects); i++ { + credentialMap[inputDescriptorMappingObjects[i].Id] = submissionVCs[i] + } + fields, err = serviceDefinition.PresentationDefinition.ResolveConstraintsFields(credentialMap) + if err != nil { + log.Logger().Infof("Search() is unable to resolve Input Descriptor Constraints Fields map for VP '%s': %s", matchingVP.ID, err) + } + } + result = append(result, SearchResult{ - VP: matchingVP, - // TODO: TokenIntrospection is also missing map[InputDescriptorId]CredentialValue ? - //Fields: matchingVP.Fields, + VP: matchingVP, + Fields: fields, }) } return result, nil diff --git a/discovery/module_test.go b/discovery/module_test.go index ec819c34b8..e19a7317cc 100644 --- a/discovery/module_test.go +++ b/discovery/module_test.go @@ -19,6 +19,7 @@ package discovery import ( + "encoding/json" "errors" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/nuts-foundation/go-did/vc" @@ -297,12 +298,14 @@ func TestModule_Search(t *testing.T) { "credentialSubject.id": aliceDID.String(), }) assert.NoError(t, err) - assert.Equal(t, []SearchResult{ + expectedJSON, _ := json.Marshal([]SearchResult{ { VP: vpAlice, - Fields: nil, + Fields: map[string]interface{}{"issuer_field": authorityDID}, }, - }, results) + }) + actualJSON, _ := json.Marshal(results) + assert.JSONEq(t, string(expectedJSON), string(actualJSON)) }) t.Run("not a client for this service ID", func(t *testing.T) { m, _ := setupModule(t, storageEngine) diff --git a/discovery/test.go b/discovery/test.go index a97ba1ea7d..8be0a792e3 100644 --- a/discovery/test.go +++ b/discovery/test.go @@ -50,6 +50,7 @@ var testServiceID = "usecase_v1" func testDefinitions() map[string]ServiceDefinition { issuerPattern := "did:example:*" + issuerFieldID := "issuer_field" return map[string]ServiceDefinition{ testServiceID: { ID: testServiceID, @@ -61,6 +62,7 @@ func testDefinitions() map[string]ServiceDefinition { Constraints: &pe.Constraints{ Fields: []pe.Field{ { + Id: &issuerFieldID, Path: []string{"$.issuer"}, Filter: &pe.Filter{ Type: "string", diff --git a/docs/_static/discovery/v1.yaml b/docs/_static/discovery/v1.yaml index 76eeecf636..a7715563a8 100644 --- a/docs/_static/discovery/v1.yaml +++ b/docs/_static/discovery/v1.yaml @@ -154,9 +154,6 @@ components: fields: type: object description: Input descriptor IDs and their mapped values that from the Verifiable Credential. - additionalProperties: - type: string - description: The value of the field that matched the query. securitySchemes: jwtBearerAuth: type: http