Example #1
0
class ConnectionSettingsAuthManagerTests(TestCase):
    username = '******'
    password = '******'

    def setUp(self):
        self.connx = ConnectionSettings(
            domain='meaning-of-life',
            name='Mr. Creosote',
            url='https://restaurant.fr/api/',
            auth_type=BASIC_AUTH,
            username=self.username,
            notify_addresses_str='*****@*****.**',
        )
        self.connx.plaintext_password = self.password
        self.connx.save()

    def tearDown(self):
        self.connx.delete()

    def test_connection_settings_auth_manager(self):
        auth_manager = self.connx.get_auth_manager()
        self.assertIsInstance(auth_manager, BasicAuthManager)
        self.assertEqual(auth_manager.username, self.username)
        self.assertEqual(auth_manager.password, self.password)
        self.assertNotEqual(auth_manager.password, self.connx.password)
        self.assertTrue(self.connx.password.startswith(f'${ALGO_AES}$'))
class TestApiSettingsMigration(TestCase):
    username = '******'
    password = '******'

    def setUp(self):
        self.connx_dhis2 = ConnectionSettings(
            domain='meaning-of-life',
            name='Mr. Creosote',
            url='https://restaurant.fr/api/',
            auth_type=OAUTH2_PWD,
            username=self.username,
            notify_addresses_str='*****@*****.**',
            api_auth_settings='dhis2_auth_settings',
        )
        self.connx_dhis2.plaintext_password = self.password
        self.connx_dhis2.save()

    def test_dhis2_connection_updated(self):
        copy_api_auth_settings(self.connx_dhis2)
        self.assertEqual(self.connx_dhis2.token_url,
                         "https://restaurant.fr/api/uaa/oauth/token")
        self.assertEqual(
            self.connx_dhis2.refresh_url,
            "https://restaurant.fr/api/uaa/oauth/token",
        )
Example #3
0
    def _create_data(cls):
        conn = ConnectionSettings(domain=cls.domain,
                                  name="motech_conn",
                                  url="url",
                                  auth_type="Bearer Token",
                                  api_auth_settings="",
                                  username="",
                                  password="",
                                  client_id="",
                                  client_secret="",
                                  skip_cert_verify=False)
        conn.save()
        cls.connection_setting = conn

        sql_dsm = SQLDataSetMap(domain=cls.domain,
                                connection_settings=conn,
                                day_to_send=1,
                                description="This is a description",
                                ucr_id="1234")
        sql_dsm.save()
        cls.dataset_map = sql_dsm

        sql_dvm = SQLDataValueMap(dataset_map=sql_dsm,
                                  column="My column",
                                  data_element_id="D1234567891",
                                  comment="Testy comment")
        sql_dvm.save()
        cls.data_value_map = sql_dvm
Example #4
0
def handle_error(
    err: Exception,
    dhis2_server: ConnectionSettings,
    print_notifications: bool,
):
    message = f'Importing ONSE ISS facility cases from DHIS2 failed: {err}'
    if print_notifications:
        print(message, file=sys.stderr)
    else:
        dhis2_server.get_requests().notify_exception(message)
        raise err
Example #5
0
 def setUp(self):
     self.connx = ConnectionSettings(
         domain='meaning-of-life',
         name='Mr. Creosote',
         url='https://restaurant.fr/api/',
         auth_type=BASIC_AUTH,
         username=self.username,
         notify_addresses_str='*****@*****.**',
     )
     self.connx.plaintext_password = self.password
     self.connx.save()
Example #6
0
def handle_success(
    dhis2_server: ConnectionSettings,
    print_notifications: bool,
):
    message = 'Successfully imported ONSE ISS facility cases from DHIS2'
    if print_notifications:
        print(message, file=sys.stderr)
    else:
        # For most things we pass silently. But we can repurpose
        # `notify_error()` to tell admins that the import went through,
        # because it only happens once a quarter.
        dhis2_server.get_requests().notify_error(message)
def create_conn_settings(dhis2_conn: Dhis2Connection) -> ConnectionSettings:
    """
    Creates and returns a ConnectionSettings instance for ``dhis2_conn``.
    """
    url = strip_api(dhis2_conn.server_url)
    conn_settings = ConnectionSettings(
        domain=dhis2_conn.domain,
        name=url,
        url=url,
        auth_type=BASIC_AUTH,
        username=dhis2_conn.username,
        skip_cert_verify=dhis2_conn.skip_cert_verify,
        notify_addresses_str="")
    conn_settings.plaintext_password = dhis2_conn.plaintext_password
    conn_settings.save()
    return conn_settings
Example #8
0
    def setUpClass(cls):
        cls.domain_1 = 'caserepeater-migration'
        cls.domain_2 = 'migration-caserepeater'
        cls.date = datetime.utcnow().strftime('%Y-%m-%dT%H-%M-%S')
        cls.conn = ConnectionSettings(domain=cls.domain_1,
                                      url='http://url.com')
        cls.conn.save()
        cls.couch_repeater_1 = CaseRepeater(
            domain=cls.domain_1,
            connection_settings_id=cls.conn.id,
            format='case_json',
        )
        cls.couch_repeater_2 = CaseRepeater(
            domain=cls.domain_2,
            connection_settings_id=cls.conn.id,
            format='case_json',
        )
        cls.couch_repeater_3 = CaseRepeater(
            domain=cls.domain_1,
            connection_settings_id=cls.conn.id,
            format='case_json',
        )
        cls.repeaters = [
            cls.couch_repeater_1, cls.couch_repeater_2, cls.couch_repeater_3
        ]

        for repeater in cls.repeaters:
            repeater.save(sync_to_sql=False)
        return super(TestMigrationCommand, cls).setUpClass()
Example #9
0
 def setUpClass(cls):
     domain = 'caserepeater-migration'
     cls.conn = ConnectionSettings(domain=domain, url='http://url.com')
     cls.conn.save()
     cls.couch_repeater_obj = CaseRepeater(
         _id='id_1',
         domain=domain,
         connection_settings_id=cls.conn.id,
         white_listed_case_types=['white_case', 'black_case'],
         black_listed_users=['user1'],
         paused=False,
         format='case_json',
     )
     cls.sql_repeater_obj = SQLCaseRepeater(
         domain=domain,
         connection_settings=cls.conn,
         white_listed_case_types=['white_case', 'black_case'],
         black_listed_users=['user1'],
         is_paused=False,
         format='case_json',
         repeater_id='id_1',
     )
     cls.incorrect_sql_repeater_obj = SQLCaseRepeater(
         domain=domain,
         connection_settings=cls.conn,
         white_listed_case_types=['black_case'],
         black_listed_users=['user2'],
         is_paused=True,
         format='case_json',
         repeater_id='id_1',
     )
     super().setUpClass()
Example #10
0
class TestUpdateFromDhis2Task(TestCase):

    @patch('custom.onse.tasks.domain_exists', return_value=True)
    @patch('custom.onse.tasks.get_dhis2_server', return_value=ConnectionSettings())
    @patch('custom.onse.tasks.check_server_status', return_value={'ready': False, 'error': RequestException})
    def test_retry(self, *args):
        task = _update_facility_cases_from_dhis2_data_elements.delay(None, True)
        assert task.result.__class__ == MaxRetriesExceededError
Example #11
0
 def create_connection_settings(self):
     if self.connection_settings_id:
         return  # Nothing to do
     conn = ConnectionSettings(
         domain=self.domain,
         name=self.url,
         url=self.url,
         auth_type=self.auth_type,
         username=self.username,
         skip_cert_verify=self.skip_cert_verify,
         notify_addresses_str=self.notify_addresses_str or '',
     )
     # Allow ConnectionSettings to encrypt old Repeater passwords:
     conn.plaintext_password = self.plaintext_password
     conn.save()
     self.connection_settings_id = conn.id
     self.save()
     return conn
 def setUpClass(cls) -> None:
     cls.conn = ConnectionSettings(url="http://url.com", domain='rtest')
     cls.conn.save()
     cls.couch_repeaters = []
     for r in deepcopy(repeater_test_data):
         r = Repeater.wrap(r)
         r.connection_settings_id = cls.conn.id
         r.save(sync_to_sql=False)
         cls.couch_repeaters.append(r)
     return super().setUpClass()
Example #13
0
def connection_fixture(domain_name):
    connx = ConnectionSettings(
        domain=domain_name,
        name='example.com',
        url='https://example.com/forwarding',
    )
    connx.save()
    try:
        yield connx
    finally:
        connx.delete()
Example #14
0
 def test_connection_settings_auth_manager(self):
     connx = ConnectionSettings(
         domain=DOMAIN,
         name='Mr. Creosote',
         url=URL,
         auth_type=BASIC_AUTH,
         username=USERNAME,
         password='',
         notify_addresses_str=ADMIN,
     )
     connx.plaintext_password = PASSWORD
     connx.save()
     try:
         auth_manager = connx.get_auth_manager()
         self.assertIsInstance(auth_manager, BasicAuthManager)
         self.assertEqual(auth_manager.username, USERNAME)
         self.assertEqual(auth_manager.password, PASSWORD)
         self.assertNotEqual(auth_manager.password, connx.password)
         self.assertTrue(connx.password.startswith(f'${ALGO_AES}$'))
     finally:
         connx.delete()
Example #15
0
    def setUpClass(cls):
        super(TestRepeatersDBAccessors, cls).setUpClass()
        cls.conn = ConnectionSettings(domain=cls.domain_1,
                                      url='http://url.com')
        cls.conn.save()
        repeater_1 = CaseRepeater(
            domain=cls.domain_1,
            format='case_json',
            connection_settings_id=cls.conn.id,
        )
        repeater_2 = CaseRepeater(
            domain=cls.domain_2,
            connection_settings_id=cls.conn.id,
            format='case_json',
        )
        cls.repeaters = [repeater_1, repeater_2]

        for repeater in cls.repeaters:
            repeater.save()
Example #16
0
def fetch_data_set(
    dhis2_server: ConnectionSettings,
    data_set_id: str,
    org_unit_id: str,
    period: str,
) -> Optional[List[dict]]:
    """
    Returns a list of `DHIS2 data values`_, or ``None`` if the the given
    org unit has no data collected for the last quarter.

    Raises exceptions on connection timeout or non-200 response status.


    .. _DHIS2 data values: https://docs.dhis2.org/master/en/developer/html/webapi_data_values.html

    """
    max_attempts = 3
    backoff_seconds = 3 * 60

    requests = dhis2_server.get_requests()
    endpoint = '/dataValueSets' if DROP_API_PREFIX else '/api/dataValueSets'
    params = {
        'period': period,
        'dataSet': data_set_id,
        'orgUnit': org_unit_id,
    }
    attempt = 0
    while True:
        attempt += 1
        try:
            response = requests.get(endpoint, params, raise_for_status=True)
        except (RequestException, HTTPError):
            if attempt < max_attempts:
                sleep(backoff_seconds * attempt)
            else:
                raise
        else:
            break
    return response.json().get('dataValues', None)
Example #17
0
    def test_registration_payload(self, payload_doc_mock, connection_settings_mock):
        connection_settings_mock.return_value = ConnectionSettings(password="******")

        case_id = uuid.uuid4().hex
        case_json = {
            'beneficiary_name': 'Nitish Dube',
            'birth_year': '2000',
            'gender_id': '1',
            'mobile_number': '9999999999',
            'photo_id_type': '1',
            'photo_id_number': '1234',
            'consent_version': "1"
        }
        case = CommCareCase(domain=self.domain, type='cowin_api_data', case_id=case_id, case_json=case_json,
                            server_modified_on=datetime.datetime.utcnow())
        payload_doc_mock.return_value = case

        repeater = BeneficiaryRegistrationRepeater()
        generator = BeneficiaryRegistrationPayloadGenerator(repeater)
        repeat_record = RepeatRecord()

        self.assertEqual(repeater.get_headers(repeat_record)['X-Api-Key'], "secure-api-key")

        payload = generator.get_payload(repeat_record=None, cowin_api_data_registration_case=case)
        self.assertDictEqual(
            json.loads(payload),
            {
                'name': 'Nitish Dube',
                'birth_year': '2000',
                'gender_id': 1,
                'mobile_number': '9999999999',
                "photo_id_type": 1,
                'photo_id_number': '1234',
                "consent_version": "1"
            }
        )
Example #18
0
def fetch_data_set(
    dhis2_server: ConnectionSettings,
    data_set_id: str,
    org_unit_id: str,
) -> Optional[List[dict]]:
    """
    Returns a list of `DHIS2 data values`_, or ``None`` if the the given
    org unit has no data collected for the last quarter.

    Raises exceptions on connection timeout or non-200 response status.


    .. _DHIS2 data values: https://docs.dhis2.org/master/en/developer/html/webapi_data_values.html

    """
    requests = dhis2_server.get_requests()
    endpoint = '/dataValueSets' if DROP_API_PREFIX else '/api/dataValueSets'
    params = {
        'period': get_last_quarter(),
        'dataSet': data_set_id,
        'orgUnit': org_unit_id,
    }
    response = requests.get(endpoint, params, raise_for_status=True)
    return response.json().get('dataValues', None)
Example #19
0
 def test_client_secret_getter_returns(self):
     cs = ConnectionSettings()
     cs.client_secret = 'secret'
     self.assertEqual(cs.plaintext_client_secret, 'secret')
Example #20
0
    def test_vaccination_payload(self, payload_doc_mock, connection_settings_mock):
        connection_settings_mock.return_value = ConnectionSettings(password="******")

        case_id = uuid.uuid4().hex
        case = CommCareCase(domain=self.domain, type='cowin_api_data', case_id=case_id,
                            server_modified_on=datetime.datetime.utcnow())
        payload_doc_mock.return_value = case

        repeater = BeneficiaryVaccinationRepeater()
        generator = BeneficiaryVaccinationPayloadGenerator(repeater)
        repeat_record = RepeatRecord()

        self.assertEqual(repeater.get_headers(repeat_record)['X-Api-Key'], "my-secure-api-key")

        # 1st dose
        case.case_json = {
            'beneficiary_reference_id': '1234567890123',
            'center_id': "1234",
            'vaccine': "COVISHIELD",
            'vaccine_batch': '123456',
            'dose': '1',
            'dose1_date': "2020-11-29",
            'vaccinator_name': 'Neelima',
        }

        payload = generator.get_payload(repeat_record=None, cowin_api_data_vaccination_case=case)
        self.assertDictEqual(
            json.loads(payload),
            {
                "beneficiary_reference_id": "1234567890123",
                "center_id": 1234,
                "vaccine": "COVISHIELD",
                "vaccine_batch": "123456",
                "dose": 1,
                "dose1_date": "29-11-2020",
                "vaccinator_name": "Neelima"
            }
        )

        # 2nd dose
        case.case_json = {
            'beneficiary_reference_id': '1234567890123',
            'center_id': "1234",
            'vaccine': "COVISHIELD",
            'vaccine_batch': '123456',
            'dose': '2',
            'dose2_date': "2020-12-29",
            'vaccinator_name': 'Sumanthra',
        }

        payload = generator.get_payload(repeat_record=None, cowin_api_data_vaccination_case=case)
        self.assertDictEqual(
            json.loads(payload),
            {
                "beneficiary_reference_id": "1234567890123",
                "center_id": 1234,
                "vaccine": "COVISHIELD",
                "vaccine_batch": "123456",
                "dose": 2,
                "dose2_date": "29-12-2020",
                "vaccinator_name": "Sumanthra"
            }
        )
Example #21
0
 def test_client_secret_setter(self):
     cs = ConnectionSettings()
     cs.plaintext_client_secret = 'secret'
     self.assertTrue(cs.client_secret.startswith(f'${ALGO_AES}$'))
Example #22
0
 def test_password_getter_returns(self):
     cs = ConnectionSettings()
     cs.password = '******'
     self.assertEqual(cs.plaintext_password, 'secret')
Example #23
0
 def test_client_secret_placeholder(self):
     cs = ConnectionSettings()
     cs.plaintext_client_secret = PASSWORD_PLACEHOLDER
     self.assertEqual(cs.client_secret, '')
Example #24
0
 def test_password_setter(self):
     cs = ConnectionSettings()
     cs.plaintext_password = '******'
     self.assertTrue(cs.password.startswith(f'${ALGO_AES}$'))
Example #25
0
 def test_password_placeholder(self):
     cs = ConnectionSettings()
     cs.plaintext_password = PASSWORD_PLACEHOLDER
     self.assertEqual(cs.password, '')
Example #26
0
 def test_default(self):
     cs = ConnectionSettings()
     self.assertEqual(cs.notify_addresses, [])
Example #27
0
 def test_empty(self):
     cs = ConnectionSettings()
     cs.notify_addresses_str = ""
     self.assertEqual(cs.notify_addresses, [])
Example #28
0
 def test_mess(self):
     cs = ConnectionSettings()
     cs.notify_addresses_str = "[email protected],,, ,  [email protected]"
     self.assertEqual(cs.notify_addresses,
                      ["*****@*****.**", "*****@*****.**"])
Example #29
0
    def test_get_programs_by_id(self):
        program_id = 'test program'

        form = {
            "domain": DOMAIN,
            "form": {
                "@xmlns": "test_xmlns",
                "event_date": "2017-05-25T21:06:27.012000",
                "completed_date": "2017-05-25T21:06:27.012000",
                "event_location": "-33.6543213 19.12344312 abcdefg",
                "name": "test event",
                "meta": {
                    "location": 'test location',
                    "timeEnd": "2017-05-25T21:06:27.012000",
                    "timeStart": "2017-05-25T21:06:17.739000",
                    "userID": self.user.user_id,
                    "username": self.user.username
                }
            },
            "received_on": "2017-05-26T09:17:23.692083Z",
        }
        config = {
            'form_configs': json.dumps([{
                'xmlns': 'test_xmlns',
                'program_id': program_id,
                'event_status': 'COMPLETED',
                'event_location': {
                    'form_question': '/data/event_location'
                },
                'completed_date': {
                    'doc_type': 'FormQuestion',
                    'form_question': '/data/completed_date',
                    'external_data_type': DHIS2_DATA_TYPE_DATE
                },
                'org_unit_id': {
                    'doc_type': 'FormUserAncestorLocationField',
                    'form_user_ancestor_location_field': LOCATION_DHIS_ID
                },
                'datavalue_maps': [
                    {
                        'data_element_id': 'dhis2_element_id',
                        'value': {
                            'doc_type': 'FormQuestion',
                            'form_question': '/data/name'
                        }
                    }
                ]
            }])
        }
        config_form = Dhis2ConfigForm(data=config)
        self.assertTrue(config_form.is_valid())
        data = config_form.cleaned_data
        repeater = Dhis2Repeater(domain=DOMAIN)
        conn = ConnectionSettings(domain=DOMAIN, url="http://dummy.com")
        conn.save()
        repeater.dhis2_config.form_configs = [Dhis2FormConfig.wrap(fc) for fc in data['form_configs']]
        repeater.connection_settings_id = conn.id
        repeater.save()

        info = CaseTriggerInfo(
            domain=DOMAIN,
            case_id=None,
            owner_id='test_location',
            form_question_values=get_form_question_values(form),
        )

        programs = get_programs_by_id(info, repeater.dhis2_config)

        self.assertDictEqual(
            programs[program_id]['geometry'],
            {'type': 'Point', 'coordinates': [-33.6543, 19.1234]}
        )