From f1b7e80e13babbcac2a419397d98d03e63b6baf6 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Thu, 20 Jul 2023 21:43:37 -0700 Subject: [PATCH] make sure that we print the error response body if we can. Added an update source method. After sync, if sourcecredential access token/refresh token has been updated make sure we store it int he database. --- backend/pkg/database/interface.go | 1 + backend/pkg/database/mock/mock_database.go | 14 +++++++++++ backend/pkg/database/sqlite_repository.go | 23 ++++++++++++++++++ backend/pkg/jwk/jwk_utils_test.go | 3 --- backend/pkg/models/source_credential.go | 4 ++-- backend/pkg/web/handler/source.go | 27 +++++++++++++--------- 6 files changed, 56 insertions(+), 16 deletions(-) diff --git a/backend/pkg/database/interface.go b/backend/pkg/database/interface.go index ddcc9c8b..87d22e14 100644 --- a/backend/pkg/database/interface.go +++ b/backend/pkg/database/interface.go @@ -36,6 +36,7 @@ type DatabaseRepository interface { GetSource(context.Context, string) (*models.SourceCredential, error) GetSourceSummary(context.Context, string) (*models.SourceSummary, error) GetSources(context.Context) ([]models.SourceCredential, error) + UpdateSource(ctx context.Context, sourceCreds *models.SourceCredential) error CreateGlossaryEntry(ctx context.Context, glossaryEntry *models.Glossary) error GetGlossaryEntry(ctx context.Context, code string, codeSystem string) (*models.Glossary, error) diff --git a/backend/pkg/database/mock/mock_database.go b/backend/pkg/database/mock/mock_database.go index 8c020a17..879185b0 100644 --- a/backend/pkg/database/mock/mock_database.go +++ b/backend/pkg/database/mock/mock_database.go @@ -359,6 +359,20 @@ func (mr *MockDatabaseRepositoryMockRecorder) RemoveResourceAssociation(ctx, sou return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveResourceAssociation", reflect.TypeOf((*MockDatabaseRepository)(nil).RemoveResourceAssociation), ctx, source, resourceType, resourceId, relatedSource, relatedResourceType, relatedResourceId) } +// UpdateSource mocks base method. +func (m *MockDatabaseRepository) UpdateSource(ctx context.Context, sourceCreds *models0.SourceCredential) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateSource", ctx, sourceCreds) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateSource indicates an expected call of UpdateSource. +func (mr *MockDatabaseRepositoryMockRecorder) UpdateSource(ctx, sourceCreds interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSource", reflect.TypeOf((*MockDatabaseRepository)(nil).UpdateSource), ctx, sourceCreds) +} + // UpsertRawResource mocks base method. func (m *MockDatabaseRepository) UpsertRawResource(ctx context.Context, sourceCredentials models.SourceCredential, rawResource models.RawResourceFhir) (bool, error) { m.ctrl.T.Helper() diff --git a/backend/pkg/database/sqlite_repository.go b/backend/pkg/database/sqlite_repository.go index eafc3ca2..c2803f84 100644 --- a/backend/pkg/database/sqlite_repository.go +++ b/backend/pkg/database/sqlite_repository.go @@ -775,6 +775,29 @@ func (sr *SqliteRepository) CreateSource(ctx context.Context, sourceCreds *model Assign(*sourceCreds).FirstOrCreate(sourceCreds).Error } +func (sr *SqliteRepository) UpdateSource(ctx context.Context, sourceCreds *models.SourceCredential) error { + currentUser, currentUserErr := sr.GetCurrentUser(ctx) + if currentUserErr != nil { + return currentUserErr + } + sourceCreds.UserID = currentUser.ID + + //Assign will **always** update the source credential in the DB with data passed into this function. + return sr.GormClient.WithContext(ctx). + Where(models.SourceCredential{ + ModelBase: models.ModelBase{ID: sourceCreds.ID}, + UserID: sourceCreds.UserID, + SourceType: sourceCreds.SourceType, + }).Updates(models.SourceCredential{ + AccessToken: sourceCreds.AccessToken, + RefreshToken: sourceCreds.RefreshToken, + ExpiresAt: sourceCreds.ExpiresAt, + DynamicClientId: sourceCreds.DynamicClientId, + DynamicClientRegistrationMode: sourceCreds.DynamicClientRegistrationMode, + DynamicClientJWKS: sourceCreds.DynamicClientJWKS, + }).Error +} + func (sr *SqliteRepository) GetSource(ctx context.Context, sourceId string) (*models.SourceCredential, error) { currentUser, currentUserErr := sr.GetCurrentUser(ctx) if currentUserErr != nil { diff --git a/backend/pkg/jwk/jwk_utils_test.go b/backend/pkg/jwk/jwk_utils_test.go index 3cc472a1..fd5f67e3 100644 --- a/backend/pkg/jwk/jwk_utils_test.go +++ b/backend/pkg/jwk/jwk_utils_test.go @@ -23,9 +23,6 @@ func TestJWKSerialize(t *testing.T) { require.NotEmpty(t, keypair.KeyID()) require.ElementsMatch(t, []string{"d", "dp", "dq", "e", "kty", "n", "p", "q", "qi", "kid"}, keys) require.Equal(t, "RSA", dict["kty"]) - //require.Equal(t, map[string]string{}, dict) - - require.Equal(t, string(keypair.N()), dict["n"]) } func TestJWKDeserialize(t *testing.T) { diff --git a/backend/pkg/models/source_credential.go b/backend/pkg/models/source_credential.go index 0a9e8fe0..9061c9f0 100644 --- a/backend/pkg/models/source_credential.go +++ b/backend/pkg/models/source_credential.go @@ -185,8 +185,8 @@ func (s *SourceCredential) RefreshDynamicClientAccessToken() error { if tokenResp.StatusCode >= 300 || tokenResp.StatusCode < 200 { b, err := io.ReadAll(tokenResp.Body) - if err != nil { - log.Printf("Response body: %s", string(b)) + if err == nil { + log.Printf("Error Response body: %s", string(b)) } return fmt.Errorf("an error occurred while reading dynamic client token response, status code was not 200: %d", tokenResp.StatusCode) diff --git a/backend/pkg/web/handler/source.go b/backend/pkg/web/handler/source.go index 3227675c..42f5cb96 100644 --- a/backend/pkg/web/handler/source.go +++ b/backend/pkg/web/handler/source.go @@ -105,8 +105,8 @@ func CreateSource(c *gin.Context) { if registrationResponse.StatusCode >= 300 || registrationResponse.StatusCode < 200 { logger.Errorln("An error occurred while reading dynamic client registration response, status code was not 200", registrationResponse.StatusCode) b, err := io.ReadAll(registrationResponse.Body) - if err != nil { - logger.Printf("Response body: %s", string(b)) + if err == nil { + logger.Printf("Error Response body: %s", string(b)) } c.JSON(http.StatusBadRequest, gin.H{"success": false}) @@ -291,20 +291,25 @@ func SyncSourceResources(c context.Context, logger *logrus.Entry, databaseRepo d logger.Errorln("An error occurred while initializing hub client using source credential", err) return sourceModels.UpsertSummary{}, err } - //TODO: update source - //if updatedSource != nil { - // logger.Warnf("TODO: source credential has been updated, we should store it in the database: %v", updatedSource) - // //err := databaseRepo.CreateSource(c, updatedSource) - // //if err != nil { - // // logger.Errorln("An error occurred while updating source credential", err) - // // return err - // //} - //} summary, err := sourceClient.SyncAll(databaseRepo) if err != nil { logger.Errorln("An error occurred while bulk import of resources from source", err) return summary, err } + + //update source incase the access token/refresh token has been updated + sourceCredential := sourceClient.GetSourceCredential() + sourceCredentialConcrete, ok := sourceCredential.(*models.SourceCredential) + if !ok { + logger.Errorln("An error occurred while updating source credential, source credential is not of type *models.SourceCredential") + return summary, fmt.Errorf("source credential is not of type *models.SourceCredential") + } + err = databaseRepo.UpdateSource(c, sourceCredentialConcrete) + if err != nil { + logger.Errorf("An error occurred while updating source credential: %v", err) + return summary, err + } + return summary, nil }