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)
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.')
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)
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
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' )
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')
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
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
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
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
def get_api_token(self): return b64_aes_decrypt(self.api_token)
def __init__(self, *args, **kwargs): super(TransifexOrganizationForm, self).__init__(*args, **kwargs) self.initial['api_token'] = b64_aes_decrypt(self.instance.api_token)
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.')
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
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
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