def test_email_to_hash_is_normalized(salt_list): """ Make sure identical emails with different cases map to the same retired email. """ email_mixed = '*****@*****.**' email_lower = email_mixed.lower() retired_email_mixed = user_util.get_retired_email(email_mixed, salt_list) retired_email_lower = user_util.get_retired_email(email_lower, salt_list) # No matter the case of the input email, the retired email hash should be identical. assert retired_email_mixed == retired_email_lower
def test_unicode_email_to_hash(): email = u'🅐.🅛🅔🅐🅡🅝🅔🅡[email protected]' retired_email = user_util.get_retired_email(email, VALID_SALT_LIST_ONE_SALT) assert retired_email != email # Since SHA1 is used, the hexadecimal digest length should be 40. assert len(retired_email.split('@')[0]) == len('retired_email_') + 40
def test_email_to_hash_with_different_format(salt_list): email = '*****@*****.**' retired_email_fmt = "{}[email protected]" retired_username = user_util.get_retired_email(email, salt_list, retired_email_fmt=retired_email_fmt) assert retired_username.endswith('_'.join(retired_email_fmt.split('_')[1:])) # Since SHA1 is used, the hexadecimal digest length should be 40. assert len(retired_username.split('_')[0]) == 40
def test_email_to_hash(salt_list): email = '*****@*****.**' retired_email = user_util.get_retired_email(email, salt_list) assert retired_email != email assert retired_email.startswith('_'.join(user_util.RETIRED_EMAIL_DEFAULT_FMT.split('_')[0:2])) assert retired_email.endswith(user_util.RETIRED_EMAIL_DEFAULT_FMT.split('@')[-1]) # Since SHA1 is used, the hexadecimal digest length should be 40. assert len(retired_email.split('@')[0]) == len('retired_email_') + 40
def test_correct_email_hash(salt_list): """ Verify that get_retired_username uses the current salt and returns the expected hash. """ email = '*****@*****.**' # Valid retired emails for the above email address when using VALID_SALT_LIST_THREE_SALTS. valid_retired_emails = [ user_util.RETIRED_EMAIL_DEFAULT_FMT.format(user_util._compute_retired_hash(email.lower(), salt)) for salt in salt_list ] retired_email = user_util.get_retired_email(email, salt_list) assert retired_email == valid_retired_emails[-1]
def handle(self, *args, **options): """ Execute the command. """ dry_run = options['dry_run'] retirements = UserRetirementStatus.objects.all().select_related('user') for retirement in retirements: original_email = retirement.original_email old_retired_email = retirement.retired_email new_retired_email = user_util.get_retired_email( original_email, settings.RETIRED_USER_SALTS, settings.RETIRED_EMAIL_FMT ) # Sanity check: if retirement.user.email != old_retired_email: print( u'WARNING: Skipping UserRetirementStatus ID {} / User ID {} because the user does not appear to ' 'have a retired email address: {}.'.format( retirement.id, retirement.user.id, retirement.user.email, ) ) # If the original email address was already normalized (or all lowercase), the old and new hashes would # match: elif old_retired_email == new_retired_email: print( u'Skipping UserRetirementStatus ID {} / User ID {} because the email hash would not change.'.format( retirement.id, retirement.user.id, ) ) # Found an email to update: else: print(u'Updating UserRetirementStatus ID {} / User ID {} to rehash their retired email: {} -> {}'.format( retirement.id, retirement.user.id, old_retired_email, new_retired_email, )) if not dry_run: # Update and save both the user table and retirement queue table: with transaction.atomic(): retirement.user.email = new_retired_email retirement.user.save() retirement.retired_email = new_retired_email retirement.save()
def handle(self, *args, **options): """ Execute the command. """ dry_run = options['dry_run'] retirements = UserRetirementStatus.objects.all().select_related('user') for retirement in retirements: original_email = retirement.original_email old_retired_email = retirement.retired_email new_retired_email = user_util.get_retired_email( original_email, settings.RETIRED_USER_SALTS, settings.RETIRED_EMAIL_FMT ) # Sanity check: if retirement.user.email != old_retired_email: print( 'WARNING: Skipping UserRetirementStatus ID {} / User ID {} because the user does not appear to ' 'have a retired email address: {}.'.format( retirement.id, retirement.user.id, retirement.user.email, ) ) # If the original email address was already normalized (or all lowercase), the old and new hashes would # match: elif old_retired_email == new_retired_email: print( 'Skipping UserRetirementStatus ID {} / User ID {} because the email hash would not change.'.format( retirement.id, retirement.user.id, ) ) # Found an email to update: else: print('Updating UserRetirementStatus ID {} / User ID {} to rehash their retired email: {} -> {}'.format( retirement.id, retirement.user.id, old_retired_email, new_retired_email, )) if not dry_run: # Update and save both the user table and retirement queue table: with transaction.atomic(): retirement.user.email = new_retired_email retirement.user.save() retirement.retired_email = new_retired_email retirement.save()
def get_retired_email(self, email): """ Convert user email to retired email format. """ return user_util.get_retired_email(email, RETIRED_USER_SALTS, RETIRED_EMAIL_FMT)