def test_callback_url_success(self): # create a state state = generate_nonce() AnonUserState.objects.create( state=state, next_uri= "http://www.google.com?client_id=test&redirect_uri=test.com&response_type=token&state=test" ) # mock sls token endpoint @urlmatch(netloc='dev.accounts.cms.gov', path='/v1/oauth/token') def sls_token_mock(url, request): return { 'status_code': 200, 'content': { 'access_token': 'works' }, } # mock sls user info endpoint @urlmatch(netloc='dev.accounts.cms.gov', path='/v1/oauth/userinfo') def sls_user_info_mock(url, request): return { 'status_code': 200, 'content': { 'sub': '00112233-4455-6677-8899-aabbccddeeff', 'given_name': '', 'family_name': '', 'email': '*****@*****.**', 'hicn': '1234567890A', }, } # mock fhir user info endpoint @urlmatch(netloc='bogus.com', path='/Patient/') def fhir_patient_info_mock(url, request): return { 'status_code': 200, 'content': patient_response, } @all_requests def catchall(url, request): raise Exception(url) with HTTMock(sls_token_mock, sls_user_info_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'code': 'test', 'state': state }) # assert http redirect self.assertEqual(response.status_code, 302) self.assertIn("client_id=test", response.url) self.assertIn("redirect_uri=test.com", response.url) # self.assertRedirects(response, "http://www.google.com", fetch_redirect_response=False) # assert login self.assertNotIn('_auth_user_id', self.client.session)
def test_callback_url_success(self): # create a state state = generate_nonce() AnonUserState.objects.create( state=state, next_uri= "http://www.google.com?client_id=test&redirect_uri=test.com&response_type=token&state=test" ) # mock fhir user info endpoint @urlmatch(netloc='fhir.backend.bluebutton.hhsdevcloud.us', path='/v1/fhir/Patient/') def fhir_patient_info_mock(url, request): return { 'status_code': status.HTTP_200_OK, 'content': patient_response, } @all_requests def catchall(url, request): raise Exception(url) with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): # need to fake an auth flow context to pass # validation of Request.prepare(...) in # apps.fhir.server.authentication.py->search_fhir_id_by_identifier(...) s = self.client.session s.update({ "auth_uuid": "84b4afdc-d85d-4ea4-b44c-7bde77634429", "auth_app_id": "2", "auth_app_name": "TestApp-001", "auth_client_id": "uouIr1mnblrv3z0PJHgmeHiYQmGVgmk5DZPDNfop" }) s.save() response = self.client.get(self.callback_url, data={ 'req_token': '0000-test_req_token-0000', 'relay': state }) # assert http redirect self.assertEqual(response.status_code, status.HTTP_302_FOUND) self.assertIn("client_id=test", response.url) self.assertIn("redirect_uri=test.com", response.url) self.assertIn("response_type=token", response.url) self.assertIn("http://www.google.com/v1/o/authorize/", response.url) # assert login self.assertNotIn('_auth_user_id', self.client.session)
def test_callback_url_failure(self): # create a state state = generate_nonce() AnonUserState.objects.create(state=state, next_uri="http://www.google.com") @all_requests def catchall(url, request): return { 'status_code': 403, 'content': {'error': 'nope'}, } with HTTMock(catchall): response = self.client.get(self.callback_url, data={'code': 'test', 'state': state}) # assert http redirect self.assertEqual(response.status_code, 502)
def test_callback_url_failure(self): # create a state state = generate_nonce() AnonUserState.objects.create(state=state, next_uri="http://www.google.com") @all_requests def catchall(url, request): return { 'status_code': status.HTTP_403_FORBIDDEN, 'content': { 'error': 'nope' }, } with HTTMock(catchall): with self.assertRaises(HTTPError): self.client.get(self.callback_url, data={ 'req_token': '0000-test_req_token-0000', 'relay': state })
def _callback_url_slsx_userinfo_error_logger(self, v2=False): state = generate_nonce() AnonUserState.objects.create( state=state, next_uri= "http://www.google.com?client_id=test&redirect_uri=test.com&response_type=token&state=test" ) # mock fhir user info endpoint @urlmatch(netloc='fhir.backend.bluebutton.hhsdevcloud.us', path=r'/v[12]/fhir/Patient/') def fhir_patient_info_mock(url, request): return { 'status_code': 200, 'content': patient_response, } @all_requests def catchall(url, request): raise Exception(url) with HTTMockWithResponseHook( MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_non_json_response_mock, fhir_patient_info_mock, catchall): s = self.client.session s.update({ "auth_uuid": "84b4afdc-d85d-4ea4-b44c-7bde77634429", "auth_app_id": "2", "version": 2 if v2 else 1, "auth_app_name": "TestApp-001", "auth_client_id": "uouIr1mnblrv3z0PJHgmeHiYQmGVgmk5DZPDNfop" }) s.save() try: self.client.get(self.callback_url, data={ 'req_token': 'xxxx-request-token-xxxx', 'relay': state }) self.fail("HTTP Error 403 expected.") except requests.exceptions.HTTPError as err: self.assertEqual(err.response.status_code, status.HTTP_403_FORBIDDEN) slsx_log_content = self.get_log_content('audit.authorization.sls') quoted_strings = re.findall("{[^{}]+}", slsx_log_content) self.assertEqual(len(quoted_strings), 2) log_entry_dict = json.loads(quoted_strings[1]) self.assertIsNotNone(log_entry_dict.get('message')) self.assertEqual( log_entry_dict.get('message'), 'JSONDecodeError thrown when parsing response text.')
def _callback_url_success_slsx_logger(self, v2=False): # copy and adapted for SLS logger test state = generate_nonce() AnonUserState.objects.create( state=state, next_uri= "http://www.google.com?client_id=test&redirect_uri=test.com&response_type=token&state=test" ) # mock fhir user info endpoint @urlmatch(netloc='fhir.backend.bluebutton.hhsdevcloud.us', path=r'/v[12]/fhir/Patient/') def fhir_patient_info_mock(url, request): return { 'status_code': status.HTTP_200_OK, 'content': patient_response, } @all_requests def catchall(url, request): raise Exception(url) with HTTMockWithResponseHook(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): s = self.client.session s.update({ "auth_uuid": "84b4afdc-d85d-4ea4-b44c-7bde77634429", "auth_app_id": "2", "version": 2 if v2 else 1, "auth_app_name": "TestApp-001", "auth_client_id": "uouIr1mnblrv3z0PJHgmeHiYQmGVgmk5DZPDNfop" }) s.save() self.client.get(self.callback_url, data={ 'req_token': 'xxxx-request-token-xxxx', 'relay': state }) slsx_log_content = self.get_log_content('audit.authorization.sls') quoted_strings = re.findall("{[^{}]+}", slsx_log_content) self.assertEqual(len(quoted_strings), 2) # Validate token response slsx_token_dict = json.loads(quoted_strings[0]) self.assertTrue( self._validateJsonSchema(SLSX_TOKEN_LOG_SCHEMA, slsx_token_dict)) # Validate userinfo response slsx_userinfo_dict = json.loads(quoted_strings[1]) self.assertTrue( self._validateJsonSchema(SLSX_USERINFO_LOG_SCHEMA, slsx_userinfo_dict)) authn_sls_log_content = self.get_log_content( 'audit.authenticate.sls') log_entries = authn_sls_log_content.splitlines() self.assertEqual(len(log_entries), 2) # Validate Authentication:start entry log_entry_dict = json.loads(log_entries[0]) self.assertTrue( self._validateJsonSchema(AUTHENTICATION_START_LOG_SCHEMA, log_entry_dict)) # Validate Authentication:success entry log_entry_dict = json.loads(log_entries[1]) self.assertTrue( self._validateJsonSchema(AUTHENTICATION_SUCCESS_LOG_SCHEMA, log_entry_dict)) mymedicare_cb_log_content = self.get_log_content( 'audit.authenticate.mymedicare_cb') log_entries = mymedicare_cb_log_content.splitlines() self.assertEqual(len(log_entries), 2) # Validate mymedicare_cb:create_beneficiary_record entry log_entry_dict = json.loads(log_entries[0]) self.assertTrue( self._validateJsonSchema(MYMEDICARE_CB_CREATE_BENE_LOG_SCHEMA, log_entry_dict)) # Validate mymedicare_cb:get_and_update_user entry log_entry_dict = json.loads(log_entries[1]) self.assertTrue( self._validateJsonSchema( MYMEDICARE_CB_GET_UPDATE_BENE_LOG_SCHEMA, log_entry_dict)) fhir_log_content = self.get_log_content('audit.data.fhir') log_entries = fhir_log_content.splitlines() self.assertEqual(len(log_entries), 2) # Validate fhir_auth_pre_fetch entry log_entry_dict = json.loads(log_entries[0]) self.assertTrue( self._validateJsonSchema(FHIR_AUTH_PRE_FETCH_LOG_SCHEMA, log_entry_dict)) # Validate fhir_auth_post_fetch entry log_entry_dict = json.loads(log_entries[1]) self.assertTrue( self._validateJsonSchema(FHIR_AUTH_POST_FETCH_LOG_SCHEMA, log_entry_dict)) match_fhir_id_log_content = self.get_log_content( 'audit.authenticate.match_fhir_id') log_entries = match_fhir_id_log_content.splitlines() self.assertGreater(len(log_entries), 0) # Validate fhir.server.authentication.match_fhir_id entry log_entry_dict = json.loads(log_entries[0]) self.assertTrue( self._validateJsonSchema(MATCH_FHIR_ID_LOG_SCHEMA, log_entry_dict)) hhs_oauth_server_log_content = self.get_log_content( 'audit.hhs_oauth_server.request_logging') log_entries = hhs_oauth_server_log_content.splitlines() self.assertGreater(len(log_entries), 0) # Validate hhs_oauth_server request/response custom middleware log entry log_entry_dict = json.loads(log_entries[0]) self.assertTrue( self._validateJsonSchema( REQUEST_RESPONSE_MIDDLEWARE_LOG_SCHEMA, log_entry_dict))
def test_callback_exceptions(self): # BB2-237: Added to test ASSERTS replaced with exceptions. # These are typically for conditions that should never be reached, so generate a 500. ERROR_MSG_MYMEDICARE = "An error occurred connecting to account.mymedicare.gov" # create a state state = generate_nonce() AnonUserState.objects.create( state=state, next_uri= "http://www.google.com?client_id=test&redirect_uri=test.com&response_type=token&state=test" ) # mock fhir user info endpoint @urlmatch(netloc='fhir.backend.bluebutton.hhsdevcloud.us', path='/v1/fhir/Patient/') def fhir_patient_info_mock(url, request): return { 'status_code': status.HTTP_200_OK, 'content': patient_response, } @all_requests def catchall(url, request): raise Exception(url) with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # assert http redirect self.assertEqual(response.status_code, status.HTTP_302_FOUND) # Change existing hash prior to test cw = Crosswalk.objects.get(id=1) saved_hicn_hash = cw._user_id_hash saved_mbi_hash = cw._user_mbi_hash saved_fhir_id = cw.fhir_id cw._user_id_hash = "XXX" cw.save() with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # assert 500 exception self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) content = json.loads(response.content) self.assertEqual(content['error'], "Found user's hicn did not match") # Restore hicn hash and change existing mbi hash prior to next test cw = Crosswalk.objects.get(id=1) cw._user_id_hash = saved_hicn_hash cw._user_mbi_hash = "XXX" cw.save() with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # assert 500 exception self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) content = json.loads(response.content) self.assertEqual(content['error'], "Found user's mbi did not match") # Restore mbi hash and change existing fhir_id prior to next test cw = Crosswalk.objects.get(id=1) cw._user_mbi_hash = saved_mbi_hash cw._fhir_id = "XXX" cw.save() with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # assert 500 exception self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) content = json.loads(response.content) self.assertEqual(content['error'], "Found user's fhir_id did not match") # Restore fhir_id cw = Crosswalk.objects.get(id=1) cw._fhir_id = saved_fhir_id cw.save() # With HTTMock sls_user_info_no_sub_mock that has no sub/username with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_no_username_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): with self.assertRaises(BBMyMedicareSLSxUserinfoException): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # With HTTMock sls_user_info_empty_hicn_mock test User info HICN cannot be empty. with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_empty_hicn_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # assert 500 exception self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) content = json.loads(response.content) self.assertEqual(content['error'], ERROR_MSG_MYMEDICARE) # With HTTMock sls_user_info_invalid_mbi_mock test User info MBI is not in valid format. with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_invalid_mbi_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # assert 500 exception self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) content = json.loads(response.content) self.assertEqual(content['error'], ERROR_MSG_MYMEDICARE) # With HTTMock sls_token_http_error_mock with HTTMock(MockUrlSLSxResponses.slsx_token_http_error_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): with self.assertRaises(HTTPError): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) content = json.loads(response.content) self.assertEqual(content['error'], ERROR_MSG_MYMEDICARE) # With HTTMock sls_user_info_http_error_mock with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_http_error_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_ok_mock, fhir_patient_info_mock, catchall): with self.assertRaises(HTTPError): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # With HTTMock MockUrlSLSxResponses.slsx_signout_fail_mock has exception with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_fail_mock, fhir_patient_info_mock, catchall): with self.assertRaises(HTTPError): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state }) # With HTTMock MockUrlSLSxResponses.slsx_signout_fail2_mock has exception with HTTMock(MockUrlSLSxResponses.slsx_token_mock, MockUrlSLSxResponses.slsx_user_info_mock, MockUrlSLSxResponses.slsx_health_ok_mock, MockUrlSLSxResponses.slsx_signout_fail2_mock, fhir_patient_info_mock, catchall): with self.assertRaises(BBMyMedicareSLSxSignoutException): response = self.client.get(self.callback_url, data={ 'req_token': 'test', 'relay': state })