From c39b68c8542d781ce3cf961676a87eaa38e1862b Mon Sep 17 00:00:00 2001 From: reinkrul Date: Fri, 4 Oct 2024 10:27:38 +0200 Subject: [PATCH] Discovery: fix GetActivationStatus on MS SQL Server (#3443) --- discovery/store.go | 11 +++++++++-- e2e-tests/oauth-flow/rfc021/do-test.sh | 13 +++++++++++++ .../rfc021/shared/discovery/definition.json | 6 ++++-- vcr/revocation/statuslist2021_issuer.go | 2 ++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/discovery/store.go b/discovery/store.go index 87bb94089..9e0b3780e 100644 --- a/discovery/store.go +++ b/discovery/store.go @@ -89,7 +89,9 @@ type presentationRefreshRecord struct { // Parameters is a serialized JSON object containing parameters that should be used when registering the subject on the service. Parameters []byte // PresentationRefreshError is the error message that occurred during the refresh attempt. - PresentationRefreshError presentationRefreshError `gorm:"foreignKey:ServiceID,SubjectID"` + // It's loaded using a spearate query instead of using GORM's Preload, which fails on MS SQL Server if it spans multiple columns + // See https://github.com/nuts-foundation/nuts-node/issues/3442 + PresentationRefreshError presentationRefreshError `gorm:"-"` } // TableName returns the table name for this DTO. @@ -353,12 +355,17 @@ func (s *sqlStore) updatePresentationRefreshTime(serviceID string, subjectID str func (s *sqlStore) getPresentationRefreshRecord(serviceID string, subjectID string) (*presentationRefreshRecord, error) { var row presentationRefreshRecord - if err := s.db.Preload("PresentationRefreshError").Find(&row, "service_id = ? AND subject_id = ?", serviceID, subjectID).Error; err != nil { + if err := s.db.Find(&row, "service_id = ? AND subject_id = ?", serviceID, subjectID).Error; err != nil { return nil, err } if row.NextRefresh == 0 { return nil, nil } + // Load presentationRefreshError using a spearate query instead of using GORM's Preload, which fails on MS SQL Server if it spans multiple columns + // See https://github.com/nuts-foundation/nuts-node/issues/3442 + if err := s.db.Find(&row.PresentationRefreshError, "service_id = ? AND subject_id = ?", serviceID, subjectID).Error; err != nil { + return nil, err + } return &row, nil } diff --git a/e2e-tests/oauth-flow/rfc021/do-test.sh b/e2e-tests/oauth-flow/rfc021/do-test.sh index 86c7273d7..c28fce6bf 100755 --- a/e2e-tests/oauth-flow/rfc021/do-test.sh +++ b/e2e-tests/oauth-flow/rfc021/do-test.sh @@ -75,6 +75,19 @@ else exitWithDockerLogs 1 fi +# Test regression for https://github.com/nuts-foundation/nuts-node/issues/3442 +# (Discovery: GetActivationStatus fails on MS SQL Server) +echo "Getting activation status from Discovery Service..." +RESPONSE=$(curl -s http://localhost:28081/internal/discovery/v1/e2e-test/vendorB) +echo $RESPONSE +if echo $RESPONSE | grep -q "true"; then + echo "Activation status OK" +else + echo "FAILED: Could not get activation status of vendor B on Discovery Service" 1>&2 + echo $RESPONSE + exitWithDockerLogs 1 +fi + echo "---------------------------------------" echo "Perform OAuth 2.0 rfc021 flow..." echo "---------------------------------------" diff --git a/e2e-tests/oauth-flow/rfc021/shared/discovery/definition.json b/e2e-tests/oauth-flow/rfc021/shared/discovery/definition.json index e7b38ad1c..f43a88422 100644 --- a/e2e-tests/oauth-flow/rfc021/shared/discovery/definition.json +++ b/e2e-tests/oauth-flow/rfc021/shared/discovery/definition.json @@ -27,7 +27,8 @@ }, { "path": [ - "$.credentialSubject.organization.name" + "$.credentialSubject.organization.name", + "$.credentialSubject[0].organization.name" ], "filter": { "type": "string" @@ -35,7 +36,8 @@ }, { "path": [ - "$.credentialSubject.organization.city" + "$.credentialSubject.organization.city", + "$.credentialSubject[0].organization.city" ], "filter": { "type": "string" diff --git a/vcr/revocation/statuslist2021_issuer.go b/vcr/revocation/statuslist2021_issuer.go index d8946eb1b..9ea538a11 100644 --- a/vcr/revocation/statuslist2021_issuer.go +++ b/vcr/revocation/statuslist2021_issuer.go @@ -121,6 +121,7 @@ func (cs *StatusList2021) isManaged(subjectID string) bool { var exists bool cs.db.Model(new(credentialIssuerRecord)). Select("count(*) > 0"). + Group("subject_id"). Where("subject_id = ?", subjectID). First(&exists) return exists @@ -423,6 +424,7 @@ func (cs *StatusList2021) Revoke(ctx context.Context, credentialID ssi.URI, entr err = tx.Model(new(credentialRecord)). Clauses(clause.Locking{Strength: clause.LockingStrengthUpdate}). Select("count(*) > 0"). + Group("subject_id"). Where("subject_id = ?", entry.StatusListCredential). First(new(bool)). Error