From 514f4448bbf748eb53c215b34252dc09d7c4e5bd Mon Sep 17 00:00:00 2001 From: Rein Krul Date: Thu, 28 Mar 2024 14:44:57 +0100 Subject: [PATCH] fixes --- api/collaboration.go | 2 ++ domain/episode/service.go | 6 +++--- domain/fhir/client.go | 7 ++++--- domain/zorginzage.go | 18 ++++++++++-------- main.go | 13 +++++-------- nuts/client/iam.go | 9 +++++++-- 6 files changed, 31 insertions(+), 24 deletions(-) diff --git a/api/collaboration.go b/api/collaboration.go index 4d909955..6e745784 100644 --- a/api/collaboration.go +++ b/api/collaboration.go @@ -2,6 +2,7 @@ package api import ( "errors" + "github.com/nuts-foundation/nuts-demo-ehr/domain/fhir" "github.com/nuts-foundation/nuts-demo-ehr/domain/types" "net/http" @@ -48,6 +49,7 @@ func (w Wrapper) CreateCollaboration(ctx echo.Context, dossierID string) error { dossierID, *patient.Ssn, request.Sender.Did, + w.FHIRService.ClientFactory(fhir.WithTenant(customer.Id)), ); err != nil { return err } diff --git a/domain/episode/service.go b/domain/episode/service.go index 68b1392e..a460f054 100644 --- a/domain/episode/service.go +++ b/domain/episode/service.go @@ -23,7 +23,7 @@ type Service interface { Create(ctx context.Context, customerID int, patientID string, request types.CreateEpisodeRequest) (*types.Episode, error) Get(ctx context.Context, customerID int, dossierID string) (*types.Episode, error) GetReports(ctx context.Context, customerDID, patientSSN string) ([]types.Report, error) - CreateCollaboration(ctx context.Context, customerDID, dossierID, patientSSN, senderDID string) error + CreateCollaboration(ctx context.Context, customerDID, dossierID, patientSSN, senderDID string, client fhir.Client) error GetCollaborations(ctx context.Context, customerDID, dossierID, patientSSN string) ([]types.Collaboration, error) } @@ -91,7 +91,7 @@ func (service *service) Get(ctx context.Context, customerID int, dossierID strin return zorginzage.ToEpisode(episode), nil } -func (service *service) CreateCollaboration(ctx context.Context, customerDID, dossierID, patientSSN, senderDID string) error { +func (service *service) CreateCollaboration(ctx context.Context, customerDID, dossierID, patientSSN, senderDID string, client fhir.Client) error { // TODO: Need to formalize this in a use case specification authorizedResources := []registry.Resource{ { @@ -110,7 +110,7 @@ func (service *service) CreateCollaboration(ctx context.Context, customerDID, do } for _, resource := range authorizedResources { for _, op := range resource.Operations { - if err := service.aclRepository.GrantAccess(ctx, customerDID, senderDID, op, resource.Path); err != nil { + if err := service.aclRepository.GrantAccess(ctx, customerDID, senderDID, op, client.BuildRequestURI(resource.Path)); err != nil { return err } } diff --git a/domain/fhir/client.go b/domain/fhir/client.go index 3d98c1a4..e551b164 100644 --- a/domain/fhir/client.go +++ b/domain/fhir/client.go @@ -65,6 +65,7 @@ type Client interface { CreateOrUpdate(ctx context.Context, resource interface{}) error ReadMultiple(ctx context.Context, path string, params map[string]string, results interface{}) error ReadOne(ctx context.Context, path string, result interface{}) error + BuildRequestURI(fhirResourcePath string) string } type httpClient struct { @@ -80,7 +81,7 @@ func (h httpClient) CreateOrUpdate(ctx context.Context, resource interface{}) er if err != nil { return fmt.Errorf("unable to determine resource path: %w", err) } - requestURI := h.buildRequestURI(resourcePath) + requestURI := h.BuildRequestURI(resourcePath) resp, err := h.restClient.R().SetBody(resource).SetContext(ctx).Put(requestURI) if err != nil { return fmt.Errorf("unable to write FHIR resource (path=%s): %w", requestURI, err) @@ -123,7 +124,7 @@ func (h httpClient) ReadOne(ctx context.Context, path string, result interface{} } func (h httpClient) getResource(ctx context.Context, path string, params map[string]string) (gjson.Result, error) { - url := h.buildRequestURI(path) + url := h.BuildRequestURI(path) logrus.Debugf("Performing FHIR request with url: %s", url) resp, err := h.restClient.R().SetQueryParams(params).SetContext(ctx).SetHeader("Cache-Control", "no-cache").Get(url) if err != nil { @@ -140,7 +141,7 @@ func (h httpClient) getResource(ctx context.Context, path string, params map[str return gjson.ParseBytes(body), nil } -func (h httpClient) buildRequestURI(fhirResourcePath string) string { +func (h httpClient) BuildRequestURI(fhirResourcePath string) string { if !h.multiTenancyEnabled { return buildRequestURI(h.url, "", fhirResourcePath) } diff --git a/domain/zorginzage.go b/domain/zorginzage.go index 57c34055..0890abf5 100644 --- a/domain/zorginzage.go +++ b/domain/zorginzage.go @@ -12,8 +12,7 @@ import ( ) type ZorginzageService struct { - NutsClient *nutsClient.HTTPClient - FHIRFactory fhir.Factory + NutsClient *nutsClient.HTTPClient } func (z ZorginzageService) RemotePatient(ctx context.Context, localDID, remotePartyDID string, patientSSN string) (*types.Patient, error) { @@ -22,7 +21,7 @@ func (z ZorginzageService) RemotePatient(ctx context.Context, localDID, remotePa return nil, err } patient := resources.Patient{} - if err = fhirClient.ReadOne(ctx, "/Patient?identifier="+url.QueryEscape(patientSSN), &patient); err != nil { + if err = fhirClient.ReadOne(ctx, "Patient?identifier="+url.QueryEscape(patientSSN), &patient); err != nil { return nil, fmt.Errorf("unable to read remote patient: %w", err) } result := patients.ToDomainPatient(patient) @@ -34,15 +33,18 @@ func (z ZorginzageService) fhirClient(ctx context.Context, localDID string, remo if err != nil { return nil, fmt.Errorf("resolve DID service (DID=%s, service=%s): %w", remotePartyDID, serviceName, err) } - endpoints := endpointsInterf.(map[string]string) - fhirEndpoint := endpoints["fhir"] - if fhirEndpoint == "" { + endpoints := endpointsInterf.(map[string]interface{}) + fhirEndpointInterf := endpoints["fhir"] + if fhirEndpointInterf == nil { return nil, fmt.Errorf("remote XIS does not have its FHIR endpoint registered (DID=%s)", remotePartyDID) } + fhirEndpoint, ok := fhirEndpointInterf.(string) + if !ok { + return nil, fmt.Errorf("FHIR endpoint is not a string (DID=%s)", remotePartyDID) + } accessToken, err := z.NutsClient.RequestServiceAccessToken(ctx, localDID, remotePartyDID, scope) if err != nil { return nil, fmt.Errorf("unable to get access token (DID=%s,scope=%s): %w", remotePartyDID, scope, err) } - fhirClient := z.FHIRFactory(fhir.WithURL(fhirEndpoint), fhir.WithAuthToken(accessToken)) - return fhirClient, nil + return fhir.NewFactory(fhir.WithURL(fhirEndpoint), fhir.WithAuthToken(accessToken))(), nil } diff --git a/main.go b/main.go index 3c79c79b..322a9959 100644 --- a/main.go +++ b/main.go @@ -249,14 +249,11 @@ func registerEHR(server *echo.Echo, config Config, customerRepository customers. TransferSenderService: transferSenderService, TransferReceiverService: transferReceiverService, TransferReceiverRepo: transferReceiverRepo, - ZorginzageService: domain.ZorginzageService{ - NutsClient: nodeClient, - FHIRFactory: fhirClientFactory, - }, - FHIRService: fhir.Service{ClientFactory: fhirClientFactory}, - EpisodeService: episode.NewService(fhirClientFactory, authService, orgRegistry, vcRegistry, aclRepository), - TenantInitializer: tenantInitializer, - NotificationHandler: notification.NewHandler(authService, fhirClientFactory, transferReceiverService, orgRegistry, vcRegistry), + ZorginzageService: domain.ZorginzageService{NutsClient: nodeClient}, + FHIRService: fhir.Service{ClientFactory: fhirClientFactory}, + EpisodeService: episode.NewService(fhirClientFactory, authService, orgRegistry, vcRegistry, aclRepository), + TenantInitializer: tenantInitializer, + NotificationHandler: notification.NewHandler(authService, fhirClientFactory, transferReceiverService, orgRegistry, vcRegistry), } // JWT checking for correct claims diff --git a/nuts/client/iam.go b/nuts/client/iam.go index 98faa07e..fe316c61 100644 --- a/nuts/client/iam.go +++ b/nuts/client/iam.go @@ -3,7 +3,7 @@ package client import ( "context" "encoding/json" - "errors" + "fmt" nutsIamClient "github.com/nuts-foundation/nuts-demo-ehr/nuts/client/iam" "net/http" "time" @@ -76,8 +76,13 @@ func (c HTTPClient) RequestServiceAccessToken(ctx context.Context, relyingPartyD if err != nil { return "", err } + if tokenResponse.JSON200 == nil { - return "", errors.New("unable to get access token") + var detail string + if tokenResponse.ApplicationproblemJSONDefault != nil { + detail = tokenResponse.ApplicationproblemJSONDefault.Detail + } + return "", fmt.Errorf("unable to get access token: %s", detail) } return tokenResponse.JSON200.AccessToken, nil