From 41e60cd7d654e3dede492adc3a1cec2ae763e79a Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Thu, 25 Aug 2022 21:57:29 -0700 Subject: [PATCH] working frontend, after token swap store credential in SQLite db. --- backend/pkg/config/config.go | 1 + backend/pkg/database/sqlite_repository.go | 12 ++++- backend/pkg/models/provider_credential.go | 24 +++++----- backend/pkg/models/response_wrapper.go | 7 +++ .../handler/create_provider_credentials.go | 2 + backend/pkg/web/server.go | 2 +- frontend/src/app/app.component.ts | 48 ++++++++++++------- .../models/fasten/provider-credential.spec.ts | 7 +++ .../app/models/fasten/provider-credential.ts | 16 +++++++ .../src/app/services/fasten-api.service.ts | 24 +++++++++- 10 files changed, 112 insertions(+), 31 deletions(-) create mode 100644 backend/pkg/models/response_wrapper.go create mode 100644 frontend/src/app/models/fasten/provider-credential.spec.ts create mode 100644 frontend/src/app/models/fasten/provider-credential.ts diff --git a/backend/pkg/config/config.go b/backend/pkg/config/config.go index 4b8902a7..19faebac 100644 --- a/backend/pkg/config/config.go +++ b/backend/pkg/config/config.go @@ -25,6 +25,7 @@ func (c *configuration) Init() error { c.SetDefault("web.listen.host", "0.0.0.0") c.SetDefault("web.listen.basepath", "") c.SetDefault("web.src.frontend.path", "/opt/fasten/web") + c.SetDefault("web.database.location", "fasten.db") //TODO: should be /opt/fasten/fasten.db c.SetDefault("log.level", "INFO") c.SetDefault("log.file", "") diff --git a/backend/pkg/database/sqlite_repository.go b/backend/pkg/database/sqlite_repository.go index 2833a96c..00849025 100644 --- a/backend/pkg/database/sqlite_repository.go +++ b/backend/pkg/database/sqlite_repository.go @@ -41,6 +41,16 @@ func NewRepository(appConfig config.Interface, globalLogger logrus.FieldLogger) } globalLogger.Infof("Successfully connected to scrutiny sqlite db: %s\n", appConfig.GetString("web.database.location")) + //TODO: automigrate for now + err = database.AutoMigrate(&models.User{}) + if err != nil { + return nil, fmt.Errorf("Failed to automigrate! - %v", err) + } + err = database.AutoMigrate(&models.ProviderCredential{}) + if err != nil { + return nil, fmt.Errorf("Failed to automigrate! - %v", err) + } + deviceRepo := sqliteRepository{ appConfig: appConfig, logger: globalLogger, @@ -65,7 +75,7 @@ func (sr *sqliteRepository) Close() error { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// func (sr *sqliteRepository) CreateProviderCredentials(ctx context.Context, providerCreds models.ProviderCredential) error { - return sr.gormClient.WithContext(ctx).Create(providerCreds).Error + return sr.gormClient.WithContext(ctx).Create(&providerCreds).Error } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/backend/pkg/models/provider_credential.go b/backend/pkg/models/provider_credential.go index 1e61bb88..60fe67f4 100644 --- a/backend/pkg/models/provider_credential.go +++ b/backend/pkg/models/provider_credential.go @@ -5,18 +5,18 @@ import "gorm.io/gorm" type ProviderCredential struct { gorm.Model - OauthEndpointBaseUrl string `json:"oauth_endpoint_base_url"` - ApiEndpointBaseUrl string `json:"api_endpoint_base_url"` - ClientId string `json:"client_id"` - RedirectUri string `json:"redirect_uri"` - Scopes []string `json:"scopes"` - PatientId string `json:"patient"` - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - IdToken string `json:"id_token"` - ExpiresAt string `json:"expires_at"` - CodeChallenge string `json:"code_challenge"` - CodeVerifier string `json:"code_verifier"` + OauthEndpointBaseUrl string `json:"oauth_endpoint_base_url"` + ApiEndpointBaseUrl string `json:"api_endpoint_base_url"` + ClientId string `json:"client_id"` + RedirectUri string `json:"redirect_uri"` + Scopes string `json:"scopes"` + PatientId string `json:"patient"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + IdToken string `json:"id_token"` + ExpiresAt int64 `json:"expires_at"` + CodeChallenge string `json:"code_challenge"` + CodeVerifier string `json:"code_verifier"` } /* diff --git a/backend/pkg/models/response_wrapper.go b/backend/pkg/models/response_wrapper.go new file mode 100644 index 00000000..e5d076ce --- /dev/null +++ b/backend/pkg/models/response_wrapper.go @@ -0,0 +1,7 @@ +package models + +type ResponseWrapper struct { + Success bool `json:"success"` + Error string `json:"error"` + Data interface{} `json:"data"` +} diff --git a/backend/pkg/web/handler/create_provider_credentials.go b/backend/pkg/web/handler/create_provider_credentials.go index c98991bb..fcd039e9 100644 --- a/backend/pkg/web/handler/create_provider_credentials.go +++ b/backend/pkg/web/handler/create_provider_credentials.go @@ -19,6 +19,8 @@ func CreateProviderCredentials(c *gin.Context) { return } + logger.Infof("Parsed Create Provider Credentials Payload: %v", providerCred) + err := databaseRepo.CreateProviderCredentials(c, providerCred) if err != nil { logger.Errorln("An error occurred while storing provider credential", err) diff --git a/backend/pkg/web/server.go b/backend/pkg/web/server.go index a1867b4f..c3c63387 100644 --- a/backend/pkg/web/server.go +++ b/backend/pkg/web/server.go @@ -39,7 +39,7 @@ func (ae *AppEngine) Setup(logger *logrus.Entry) *gin.Engine { "success": true, }) }) - api.POST("/provider_credentials", handler.CreateProviderCredentials) //used to save settings + api.POST("/provider_credential", handler.CreateProviderCredentials) //used to save settings } } diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 717f6976..4abad5fc 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -8,6 +8,8 @@ import BrowserAdapter from 'fhirclient/lib/adapters/BrowserAdapter'; import {PassportService} from './services/passport.service'; import {ProviderConfig} from './models/passport/provider-config'; import {AuthorizeClaim} from './models/passport/authorize-claim'; +import {FastenApiService} from './services/fasten-api.service'; +import {ProviderCredential} from './models/fasten/provider-credential'; export const retryCount = 24; //wait 2 minutes (5 * 24 = 120) export const retryWaitMilliSeconds = 5000; //wait 5 seconds @@ -20,7 +22,10 @@ export class AppComponent { title = 'fastenhealth'; - constructor(private passportApi: PassportService) { } + constructor( + private passportApi: PassportService, + private fastenApi: FastenApiService, + ) { } connect(provider: string) { this.passportApi.getProviderConfig(provider) @@ -81,23 +86,34 @@ export class AppComponent { //Create FHIR Client - const clientState = { - serverUrl: connectData.api_endpoint_base_url, - clientId: connectData.client_id, - redirectUri: connectData.redirect_uri, - tokenUri: `${connectData.oauth_endpoint_base_url}/token`, - scope: connectData.scopes.join(' '), - tokenResponse: payload, - expiresAt: getAccessTokenExpiration(payload, new BrowserAdapter()), - codeChallenge: codeChallenge, - codeVerifier: codeVerifier + const providerCredential: ProviderCredential = { + oauth_endpoint_base_url: connectData.oauth_endpoint_base_url, + api_endpoint_base_url: connectData.api_endpoint_base_url, + client_id: connectData.client_id, + redirect_uri: connectData.redirect_uri, + scopes: connectData.scopes.join(' '), + patient: payload.patient, + access_token: payload.access_token, + refresh_token: payload.refresh_token, + id_token: payload.id_token, + expires_at: getAccessTokenExpiration(payload, new BrowserAdapter()), + code_challenge: codeChallenge, + code_verifier: codeVerifier, } - console.log("STARTING--- FHIR.client(clientState)", clientState) - const fhirClient = FHIR.client(clientState); - console.log("STARTING--- client.request(Patient)") - const patientResponse = await fhirClient.request("PatientAccess/v1/$userinfo") - console.log(patientResponse) + this.fastenApi.createProviderCredential(providerCredential).subscribe( (respData) => { + console.log("provider credential create response:", respData) + }) + + + + + // console.log("STARTING--- FHIR.client(clientState)", clientState) + // const fhirClient = FHIR.client(clientState); + // + // console.log("STARTING--- client.request(Patient)") + // const patientResponse = await fhirClient.request("PatientAccess/v1/$userinfo") + // console.log(patientResponse) diff --git a/frontend/src/app/models/fasten/provider-credential.spec.ts b/frontend/src/app/models/fasten/provider-credential.spec.ts new file mode 100644 index 00000000..5699af3c --- /dev/null +++ b/frontend/src/app/models/fasten/provider-credential.spec.ts @@ -0,0 +1,7 @@ +import { ProviderCredential } from './provider-credential'; + +describe('ProviderCredential', () => { + it('should create an instance', () => { + expect(new ProviderCredential()).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/models/fasten/provider-credential.ts b/frontend/src/app/models/fasten/provider-credential.ts new file mode 100644 index 00000000..8b4ca632 --- /dev/null +++ b/frontend/src/app/models/fasten/provider-credential.ts @@ -0,0 +1,16 @@ +export class ProviderCredential { + id?: number + + oauth_endpoint_base_url: string + api_endpoint_base_url: string + client_id: string + redirect_uri: string + scopes: string //space seperated string + patient: string + access_token: string + refresh_token: string + id_token: string + expires_at: number + code_challenge: string + code_verifier: string +} diff --git a/frontend/src/app/services/fasten-api.service.ts b/frontend/src/app/services/fasten-api.service.ts index b9538b43..3a482336 100644 --- a/frontend/src/app/services/fasten-api.service.ts +++ b/frontend/src/app/services/fasten-api.service.ts @@ -1,9 +1,31 @@ import { Injectable } from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {ProviderConfig} from '../models/passport/provider-config'; +import {environment} from '../../environments/environment'; +import {map} from 'rxjs/operators'; +import {ResponseWrapper} from '../models/response-wrapper'; +import {ProviderCredential} from '../models/fasten/provider-credential'; @Injectable({ providedIn: 'root' }) export class FastenApiService { - constructor() { } + constructor(private _httpClient: HttpClient) { + } + + getBasePath(): string { + return window.location.pathname.split('/web').slice(0, 1)[0]; + } + + createProviderCredential(providerCredential: ProviderCredential): Observable { + return this._httpClient.post(`${this.getBasePath()}/api/provider_credential`, providerCredential) + .pipe( + map((response: ResponseWrapper) => { + console.log("PROVIDER CREDENTIAL RESPONSE", response) + return response.data as ProviderCredential + }) + ); + } }