Esempio n. 1
0
 def test_known_bad_0x80_0x00(self):
     # This test documents behavior of the current implementation, and can
     # be removed when there are no encrypted passwords padded with spaces.
     password = '******' + 13 * '\x00'
     assert len(password.encode('utf-8')) == AES_BLOCK_SIZE
     ciphertext = self._encrypt_with_simple_padding(password)
     with self.assertRaises(UnicodeDecodeError):
         b64_aes_decrypt(ciphertext)
Esempio n. 2
0
 def test_simple_padded(self):
     """
     Make sure we can decrypt old passwords
     """
     ciphertext_using_simple_padding = 'Vh2Tmlnr5+out2PQDefkuS9+9GtIsiEX8YBA0T/V87I='
     plaintext = b64_aes_decrypt(ciphertext_using_simple_padding)
     self.assertEqual(plaintext, 'Around you is a forest.')
Esempio n. 3
0
 def assert_message_equals_plaintext(self, message):
     assert isinstance(message, str)
     ciphertext = b64_aes_encrypt(message)
     plaintext = b64_aes_decrypt(ciphertext)
     self.assertEqual(plaintext, message)
     self.assertIsInstance(ciphertext, str)
     self.assertIsInstance(plaintext, str)
Esempio n. 4
0
 def plaintext_password(self):
     if self.password is None:
         return ''
     if self.password.startswith('${algo}$'.format(algo=ALGO_AES)):
         ciphertext = self.password.split('$', 2)[2]
         return b64_aes_decrypt(ciphertext)
     return self.password
Esempio n. 5
0
def import_patients_with_importer(importer_json):
    importer = OpenmrsImporter.wrap(importer_json)
    password = b64_aes_decrypt(importer.password)
    requests = get_basic_requests(
        importer.domain, importer.server_url, importer.username, password,
        notify_addresses=importer.notify_addresses,
    )
    if importer.location_type_name:
        try:
            location_type = LocationType.objects.get(domain=importer.domain, name=importer.location_type_name)
        except LocationType.DoesNotExist:
            requests.notify_error(
                f'No organization level named "{importer.location_type_name}" '
                f'found in project space "{importer.domain}".'
            )
            return
        if importer.location_id:
            location = SQLLocation.objects.filter(domain=importer.domain).get(importer.location_id)
            locations = location.get_descendants.filter(location_type=location_type)
        else:
            locations = SQLLocation.objects.filter(domain=importer.domain, location_type=location_type)
        for location in locations:
            # Assign cases to the first user in the location, not to the location itself
            owner = get_one_commcare_user_at_location(importer.domain, location.location_id)
            if not owner:
                requests.notify_error(
                    f'Project space "{importer.domain}" at location '
                    f'"{location.name}" has no user to own cases imported '
                    f'from OpenMRS Importer "{importer}"'
                )
                continue
            # The same report is fetched for each location. WE DO THIS
            # ASSUMING THAT THE LOCATION IS USED IN THE REPORT
            # PARAMETERS. If not, OpenMRS will return THE SAME PATIENTS
            # multiple times and they will be assigned to a different
            # user each time.
            try:
                import_patients_of_owner(requests, importer, importer.domain, owner.user_id, location)
            except ConfigurationError as err:
                requests.notify_error(str(err))
    elif importer.owner_id:
        if not is_valid_owner(importer.owner_id):
            requests.notify_error(
                f'Error importing patients for project space "{importer.domain}" '
                f'from OpenMRS Importer "{importer}": owner_id "{importer.owner_id}" '
                'is invalid.'
            )
            return
        try:
            import_patients_of_owner(requests, importer, importer.domain, importer.owner_id)
        except ConfigurationError as err:
            requests.notify_error(str(err))
    else:
        requests.notify_error(
            f'Error importing patients for project space "{importer.domain}" from '
            f'OpenMRS Importer "{importer}": Unable to determine the owner of '
            'imported cases without either owner_id or location_type_name'
        )
Esempio n. 6
0
def import_patients_with_importer(importer_json):
    importer = OpenmrsImporter.wrap(importer_json)
    password = b64_aes_decrypt(importer.password)
    requests = Requests(importer.domain, importer.server_url,
                        importer.username, password)
    if importer.location_type_name:
        try:
            location_type = LocationType.objects.get(
                domain=importer.domain, name=importer.location_type_name)
        except LocationType.DoesNotExist:
            logger.error(
                f'No organization level named "{importer.location_type_name}" '
                f'found in project space "{importer.domain}".')
            return
        if importer.location_id:
            location = SQLLocation.objects.filter(domain=importer.domain).get(
                importer.location_id)
            locations = location.get_descendants.filter(
                location_type=location_type)
        else:
            locations = SQLLocation.objects.filter(domain=importer.domain,
                                                   location_type=location_type)
        for location in locations:
            # Assign cases to the first user in the location, not to the location itself
            owner = get_one_commcare_user_at_location(importer.domain,
                                                      location.location_id)
            if not owner:
                logger.error(
                    f'Project space "{importer.domain}" at location '
                    f'"{location.name}" has no user to own cases imported '
                    f'from OpenMRS Importer "{importer}"')
                continue
            import_patients_of_owner(requests, importer, importer.domain,
                                     owner, location)
    elif importer.owner_id:
        try:
            owner = CommCareUser.get(importer.owner_id)
        except ResourceNotFound:
            logger.error(
                f'Project space "{importer.domain}" has no user to own cases '
                f'imported from OpenMRS Importer "{importer}"')
            return
        import_patients_of_owner(requests, importer, importer.domain, owner)
    else:
        logger.error(
            f'Error importing patients for project space "{importer.domain}" from '
            f'OpenMRS Importer "{importer}": Unable to determine the owner of '
            'imported cases without either owner_id or location_type_name')
Esempio n. 7
0
    def plaintext_password(self):
        def clean_repr(bytes_repr):
            """
            Drops the bytestring representation from ``bytes_repr``

            >>> clean_repr("b'spam'")
            'spam'
            """
            if bytes_repr.startswith("b'") and bytes_repr.endswith("'"):
                return bytes_repr[2:-1]
            return bytes_repr

        if self.password is None:
            return ''
        if self.password.startswith('${algo}$'.format(algo=ALGO_AES)):
            ciphertext = self.password.split('$', 2)[2]
            # Work around Py2to3 string-handling bug in encryption code
            # (fixed on 2018-03-12 by commit 3a900068)
            ciphertext = clean_repr(ciphertext)
            return b64_aes_decrypt(ciphertext)
        return self.password
Esempio n. 8
0
 def last_token(self) -> Optional[dict]:
     if self.last_token_aes:
         plaintext = b64_aes_decrypt(self.last_token_aes)
         return json.loads(plaintext)
     return None
Esempio n. 9
0
 def plaintext_client_secret(self):
     if self.client_secret.startswith(f'${ALGO_AES}$'):
         ciphertext = self.client_secret.split('$', 2)[2]
         return b64_aes_decrypt(ciphertext)
     return self.client_secret
Esempio n. 10
0
 def plaintext_password(self):
     if self.password.startswith(f'${ALGO_AES}$'):
         ciphertext = self.password.split('$', 2)[2]
         return b64_aes_decrypt(ciphertext)
     return self.password
Esempio n. 11
0
 def get_api_token(self):
     return b64_aes_decrypt(self.api_token)
Esempio n. 12
0
 def __init__(self, *args, **kwargs):
     super(TransifexOrganizationForm, self).__init__(*args, **kwargs)
     self.initial['api_token'] = b64_aes_decrypt(self.instance.api_token)
Esempio n. 13
0
 def test_crypto_padded(self):
     ciphertext_using_crypto_padding = 'Vh2Tmlnr5+out2PQDefkudZ2frfze5onsAlUGTLv3Oc='
     plaintext = b64_aes_decrypt(ciphertext_using_crypto_padding)
     self.assertEqual(plaintext, 'Around you is a forest.')
Esempio n. 14
0
 def get_api_token(self):
     return b64_aes_decrypt(self.api_token)
Esempio n. 15
0
 def __init__(self, *args, **kwargs):
     super(TransifexOrganizationForm, self).__init__(*args, **kwargs)
     self.initial['api_token'] = b64_aes_decrypt(self.instance.api_token)
Esempio n. 16
0
def import_patients_to_domain(domain_name, force=False):
    """
    Iterates OpenmrsImporters of a domain, and imports patients

    Who owns the imported cases?

    If `importer.owner_id` is set, then the server will be queried
    once. All patients, regardless of their location, will be assigned
    to the mobile worker whose ID is `importer.owner_id`.

    If `importer.location_type_name` is set, then check whether the
    OpenmrsImporter's location is set with `importer.location_id`.

    If `importer.location_id` is given, then the server will be queried
    for each location among its descendants whose type is
    `importer.location_type_name`. The request's query parameters will
    include that descendant location's OpenMRS UUID. Imported cases
    will be owned by the first mobile worker in that location.

    If `importer.location_id` is given, then the server will be queried
    for each location in the project space whose type is
    `importer.location_type_name`. As when `importer.location_id` is
    specified, the request's query parameters will include that
    location's OpenMRS UUID, and imported cases will be owned by the
    first mobile worker in that location.

    ..NOTE:: As you can see from the description above, if
             `importer.owner_id` is set then `importer.location_id` is
             not used.

    :param domain_name: The name of the domain
    :param force: Import regardless of the configured import frequency / today's date
    """
    today = datetime.today()
    for importer in get_openmrs_importers_by_domain(domain_name):
        if not force and importer.import_frequency == IMPORT_FREQUENCY_WEEKLY and today.weekday(
        ) != 1:
            continue  # Import on Tuesdays
        if not force and importer.import_frequency == IMPORT_FREQUENCY_MONTHLY and today.day != 1:
            continue  # Import on the first of the month
        # TODO: ^^^ Make those configurable

        password = b64_aes_decrypt(importer.password)
        requests = Requests(domain_name, importer.server_url,
                            importer.username, password)
        if importer.location_type_name:
            try:
                location_type = LocationType.objects.get(
                    domain=domain_name, name=importer.location_type_name)
            except LocationType.DoesNotExist:
                logger.error(
                    'No organization level named "{location_type}" found in project space "{domain}".'
                    .format(location_type=importer.location_type_name,
                            domain=domain_name))
                continue
            if importer.location_id:
                location = SQLLocation.objects.filter(domain=domain_name).get(
                    importer.location_id)
                locations = location.get_descendants.filter(
                    location_type=location_type)
            else:
                locations = SQLLocation.objects.filter(
                    domain=domain_name, location_type=location_type)
            for location in locations:
                # Assign cases to the first user in the location, not to the location itself
                owner = get_one_commcare_user_at_location(
                    domain_name, location.location_id)
                if not owner:
                    logger.error(
                        'Project space "{domain}" at location "{location}" has no user to own cases imported from '
                        'OpenMRS Importer "{importer}"'.format(
                            domain=domain_name,
                            location=location.name,
                            importer=importer))
                    continue
                import_patients_of_owner(requests, importer, domain_name,
                                         owner, location)
        elif importer.owner_id:
            try:
                owner = CommCareUser.get(importer.owner_id)
            except ResourceNotFound:
                logger.error(
                    'Project space "{domain}" has no user to own cases imported from OpenMRS Importer '
                    '"{importer}"'.format(domain=domain_name,
                                          importer=importer))
                continue
            import_patients_of_owner(requests, importer, domain_name, owner)
        else:
            logger.error(
                'Error importing patients for project space "{domain}" from OpenMRS Importer "{importer}": Unable '
                'to determine the owner of imported cases without either owner_id or location_type_name'
                .format(domain=domain_name, importer=importer))
            continue
Esempio n. 17
0
 def plaintext_password(self):
     if self.password.startswith('${algo}$'.format(algo=ALGO_AES)):
         ciphertext = self.password.split('$', 2)[2]
         return b64_aes_decrypt(ciphertext)
     return self.password
Esempio n. 18
0
def import_patients_to_domain(domain_name, force=False):
    """
    Iterates OpenmrsImporters of a domain, and imports patients

    Who owns the imported cases?

    If `importer.owner_id` is set, then the server will be queried
    once. All patients, regardless of their location, will be assigned
    to the mobile worker whose ID is `importer.owner_id`.

    If `importer.location_type_name` is set, then check whether the
    OpenmrsImporter's location is set with `importer.location_id`.

    If `importer.location_id` is given, then the server will be queried
    for each location among its descendants whose type is
    `importer.location_type_name`. The request's query parameters will
    include that descendant location's OpenMRS UUID. Imported cases
    will be owned by the first mobile worker in that location.

    If `importer.location_id` is given, then the server will be queried
    for each location in the project space whose type is
    `importer.location_type_name`. As when `importer.location_id` is
    specified, the request's query parameters will include that
    location's OpenMRS UUID, and imported cases will be owned by the
    first mobile worker in that location.

    ..NOTE:: As you can see from the description above, if
             `importer.owner_id` is set then `importer.location_id` is
             not used.

    :param domain_name: The name of the domain
    :param force: Import regardless of the configured import frequency / today's date
    """
    today = datetime.today()
    for importer in get_openmrs_importers_by_domain(domain_name):
        if not force and importer.import_frequency == IMPORT_FREQUENCY_WEEKLY and today.weekday() != 1:
            continue  # Import on Tuesdays
        if not force and importer.import_frequency == IMPORT_FREQUENCY_MONTHLY and today.day != 1:
            continue  # Import on the first of the month
        # TODO: ^^^ Make those configurable

        password = b64_aes_decrypt(importer.password)
        requests = Requests(domain_name, importer.server_url, importer.username, password)
        if importer.location_type_name:
            try:
                location_type = LocationType.objects.get(domain=domain_name, name=importer.location_type_name)
            except LocationType.DoesNotExist:
                logger.error(
                    'No organization level named "{location_type}" found in project space "{domain}".'.format(
                        location_type=importer.location_type_name, domain=domain_name)
                )
                continue
            if importer.location_id:
                location = SQLLocation.objects.filter(domain=domain_name).get(importer.location_id)
                locations = location.get_descendants.filter(location_type=location_type)
            else:
                locations = SQLLocation.objects.filter(domain=domain_name, location_type=location_type)
            for location in locations:
                # Assign cases to the first user in the location, not to the location itself
                owner = get_one_commcare_user_at_location(domain_name, location.location_id)
                if not owner:
                    logger.error(
                        'Project space "{domain}" at location "{location}" has no user to own cases imported from '
                        'OpenMRS Importer "{importer}"'.format(
                            domain=domain_name, location=location.name, importer=importer)
                    )
                    continue
                import_patients_of_owner(requests, importer, domain_name, owner, location)
        elif importer.owner_id:
            try:
                owner = CommCareUser.get(importer.owner_id)
            except ResourceNotFound:
                logger.error(
                    'Project space "{domain}" has no user to own cases imported from OpenMRS Importer '
                    '"{importer}"'.format(
                        domain=domain_name, importer=importer)
                )
                continue
            import_patients_of_owner(requests, importer, domain_name, owner)
        else:
            logger.error(
                'Error importing patients for project space "{domain}" from OpenMRS Importer "{importer}": Unable '
                'to determine the owner of imported cases without either owner_id or location_type_name'.format(
                    domain=domain_name, importer=importer)
            )
            continue