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)
Example #2
0
    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)
Example #4
0
    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
                                })
Example #5
0
    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.')
Example #6
0
    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))
Example #7
0
    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
                                           })