From ccd894aeb9632e218332b897dcd15662193fdbb8 Mon Sep 17 00:00:00 2001 From: sb-cecilialiu Date: Mon, 9 Dec 2024 08:33:32 -0600 Subject: [PATCH] MAT-4169 UMLS logout --- pom.xml | 4 +-- .../TerminologyServiceApplication.java | 2 +- .../controller/VsacController.java | 9 ++++++ .../repositories/UmlsUserRepository.java | 2 ++ .../terminology/service/VsacService.java | 9 ++++++ .../controller/VsacControllerTest.java | 22 ++++++++++++++ .../service/FhirTerminologyServiceTest.java | 12 ++++---- .../terminology/service/VsacServiceTest.java | 30 +++++++++++++++++++ .../FhirTerminologyServiceWebClientTest.java | 4 ++- 9 files changed, 84 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 87938d1..a776509 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent 3.2.11 - + gov.cms.madie.terminologyservice @@ -167,7 +167,7 @@ - + diff --git a/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java b/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java index 0832521..2dfad47 100644 --- a/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java +++ b/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java @@ -25,7 +25,7 @@ public WebMvcConfigurer corsConfigurer() { public void addCorsMappings(CorsRegistry registry) { registry .addMapping("/**") - .allowedMethods("PUT", "POST", "GET") + .allowedMethods("PUT", "POST", "GET", "DELETE") .allowedOrigins( "http://localhost:9000", "https://dev-madie.hcqis.org", diff --git a/src/main/java/gov/cms/madie/terminology/controller/VsacController.java b/src/main/java/gov/cms/madie/terminology/controller/VsacController.java index a73fc16..19b80a8 100644 --- a/src/main/java/gov/cms/madie/terminology/controller/VsacController.java +++ b/src/main/java/gov/cms/madie/terminology/controller/VsacController.java @@ -8,6 +8,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -134,4 +135,12 @@ public ResponseEntity checkUserLogin(Principal principal) { ? ResponseEntity.ok().body(Boolean.TRUE) : new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } + + @DeleteMapping("/umls-credentials") + public ResponseEntity umlsLogout(Principal principal) { + log.info("Entering: umlsLogout(): username = " + principal.getName()); + return vsacService.logoutUMLSUser(principal.getName()) + ? ResponseEntity.ok().body(Boolean.TRUE) + : new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } } diff --git a/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java b/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java index a13a69f..eb4aaf7 100644 --- a/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java +++ b/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java @@ -10,4 +10,6 @@ public interface UmlsUserRepository extends MongoRepository { Optional findByHarpId(String harpId); Optional findByHarpIdAndApiKey(String harpId, String apiKey); + + Optional deleteByHarpId(String harpId); } diff --git a/src/main/java/gov/cms/madie/terminology/service/VsacService.java b/src/main/java/gov/cms/madie/terminology/service/VsacService.java index fa17250..084cc52 100644 --- a/src/main/java/gov/cms/madie/terminology/service/VsacService.java +++ b/src/main/java/gov/cms/madie/terminology/service/VsacService.java @@ -358,4 +358,13 @@ private List getValueSetConcepts(DescribedValueSet valueSet public Optional findByHarpId(String harpId) { return umlsUserRepository.findByHarpId(harpId); } + + public boolean logoutUMLSUser(String userName) { + UmlsUser user = verifyUmlsAccess(userName); + boolean deleted = false; + Optional deletedUser = umlsUserRepository.deleteByHarpId(userName); + deleted = deletedUser.isPresent(); + log.info("Log out UMLS User:{} : {}.", user.getHarpId(), deleted); + return deleted; + } } diff --git a/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java b/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java index a155cd1..f2d9c50 100644 --- a/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java +++ b/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java @@ -133,4 +133,26 @@ void testInvalidUserUmlsLogin() { assertEquals(response.getStatusCode(), HttpStatus.UNAUTHORIZED); } + + @Test + void testUserUmlsLogout() { + Principal principal = mock(Principal.class); + when(principal.getName()).thenReturn(TEST_USER); + + when(vsacService.logoutUMLSUser(anyString())).thenReturn(true); + ResponseEntity response = vsacController.umlsLogout(principal); + + assertEquals(response.getBody(), Boolean.TRUE); + } + + @Test + void testUserUmlsLogoutFailed() { + Principal principal = mock(Principal.class); + when(principal.getName()).thenReturn(TEST_USER); + + when(vsacService.logoutUMLSUser(anyString())).thenReturn(false); + ResponseEntity response = vsacController.umlsLogout(principal); + + assertEquals(response.getStatusCode(), HttpStatus.UNAUTHORIZED); + } } diff --git a/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java b/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java index f3b6ca1..1fd0f67 100644 --- a/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java +++ b/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java @@ -219,12 +219,12 @@ void getsValueSetsExpansionsForQdm_withNoCodes_When_ManifestExpansionIsProvided( .build(); when(fhirContext.newJsonParser()).thenReturn(FhirContext.forR4().newJsonParser()); when(fhirTerminologyServiceWebClient.getValueSetResource( - anyString(), - any(ValueSetsSearchCriteria.ValueSetParams.class), - anyString(), - anyString(), - anyString(), - any(ManifestExpansion.class))) + anyString(), + any(ValueSetsSearchCriteria.ValueSetParams.class), + anyString(), + anyString(), + anyString(), + any(ManifestExpansion.class))) .thenReturn(mockValueSetResourceWithNoCodes); when(mappingService.getCodeSystemEntries()).thenReturn(codeSystemEntries); List result = diff --git a/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java b/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java index b0148d9..e9f515c 100644 --- a/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java +++ b/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java @@ -592,4 +592,34 @@ void testGetCodeStatusIfCodeNotFoundInSvs() { CodeStatus status = vsacService.getCodeStatus(code, TEST_API_KEY); assertThat(status, is(equalTo(CodeStatus.NA))); } + + @Test + void testUserUmlsLogout() { + when(umlsUserRepository.findByHarpId(anyString())).thenReturn(Optional.of(umlsUser)); + UmlsUser user = vsacService.verifyUmlsAccess(TEST_API_KEY); + when(umlsUserRepository.deleteByHarpId(anyString())).thenReturn(Optional.of(umlsUser)); + boolean loggedOut = vsacService.logoutUMLSUser(umlsUser.getHarpId()); + assertThat(user.getHarpId(), is(equalTo(TEST_HARP_ID))); + assertThat(user.getApiKey(), is(equalTo(TEST_API_KEY))); + assertThat(loggedOut, is(equalTo(true))); + } + + @Test + void testUserUmlsLogoutUserNotFound() { + when(umlsUserRepository.findByHarpId(anyString())).thenReturn(Optional.empty()); + Exception exception = + assertThrows( + VsacUnauthorizedException.class, () -> vsacService.logoutUMLSUser(TEST_API_KEY)); + assertThat(exception.getMessage(), is(equalTo("Please login to UMLS before proceeding"))); + } + + @Test + void testUserUmlsLogoutUserApiKeyIsMissing() { + UmlsUser umlsUserCopy = umlsUser.toBuilder().apiKey(null).build(); + when(umlsUserRepository.findByHarpId(anyString())).thenReturn(Optional.of(umlsUserCopy)); + Exception exception = + assertThrows( + VsacUnauthorizedException.class, () -> vsacService.logoutUMLSUser(TEST_API_KEY)); + assertThat(exception.getMessage(), is(equalTo("Please login to UMLS before proceeding"))); + } } diff --git a/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java b/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java index 6e9bef5..06cc5c2 100644 --- a/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java +++ b/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java @@ -112,7 +112,9 @@ void getDraftValueSetResourceSuccessfully_when_noCustomSearchCriteriaIsProvided( assertNotNull(actualResponse); assertEquals(MOCK_RESPONSE_STRING, actualResponse); RecordedRequest recordedRequest = mockBackEnd.takeRequest(); - assertEquals("/ValueSet/test-vs-id/$expand?includeDraft=true&activeOnly=false", recordedRequest.getPath()); + assertEquals( + "/ValueSet/test-vs-id/$expand?includeDraft=true&activeOnly=false", + recordedRequest.getPath()); } @Test