def migrate_usernames(stream=None, quiet=False): """ Migrate all existing users to django-email-as-username hashed usernames. If any users cannot be migrated an exception will be raised and the migration will not run. """ stream = stream or (quiet and open(os.devnull, 'w') or sys.stdout) # Check all users can be migrated before applying migration emails = set() errors = [] for user in get_user_model().objects.all(): if not user.email: errors.append("Cannot convert user '%s' because email is not " "set." % (user._username, )) elif user.email.lower() in emails: errors.append("Cannot convert user '%s' because email '%s' " "already exists." % (user._username, user.email)) else: emails.add(user.email.lower()) # Cannot migrate. if errors: [stream.write(error + '\n') for error in errors] raise Exception('django-email-as-username migration failed.') # Can migrate just fine. total = get_user_model().objects.count() for user in get_user_model().objects.all(): user.username = _email_to_username(user.email) user.save() stream.write("Successfully migrated usernames for all %d users\n" % (total, ))
def get_user(email, queryset=None): """ Return the user with given email address. Note that email address matches are case-insensitive. """ if queryset is None: queryset = get_user_model().objects return queryset.get(username=_email_to_username(email))
def user_exists(email, queryset=None): """ Return True if a user with given email address exists. Note that email address matches are case-insensitive. """ try: get_user(email, queryset) except get_user_model().DoesNotExist: return False return True
def create_user(email, password=None, is_staff=None, is_active=None): """ Create a new user with the given email. Use this instead of `User.objects.create_user`. """ try: user = get_user_model().objects.create_user(email, email, password) except IntegrityError, err: regexp = '|'.join(re.escape(e) for e in _DUPLICATE_USERNAME_ERRORS) if re.match(regexp, err.message): raise IntegrityError('user email is not unique') raise
def user_save_patch(self, *args, **kwargs): email_as_username = (self.username.lower() == self.email.lower()) if self.pk is not None: try: old_user = self.__class__.objects.get(pk=self.pk) email_as_username = ( email_as_username or ('@' in self.username and old_user.username == old_user.email) ) except self.__class__.DoesNotExist: pass if email_as_username: #self.username = _email_to_username(self.email) self.username = id_generator(12) try: super(get_user_model(), self).save_base(*args, **kwargs) finally: if email_as_username: self.username = self.email #self.username = id_generator(12) if email_as_username: self.username = self.email
def handle(self, *args, **options): email = options.get('email', None) interactive = options.get('interactive') verbosity = int(options.get('verbosity', 1)) # Do quick and dirty validation if --noinput if not interactive: if not email: raise CommandError("You must use --email with --noinput.") try: is_valid_email(email) except exceptions.ValidationError: raise CommandError("Invalid email address.") # If not provided, create the user with an unusable password password = None # Prompt for username/email/password. Enclose this whole thing in a # try/except to trap for a keyboard interrupt and exit gracefully. if interactive: try: # Get an email while 1: if not email: email = raw_input('E-mail address: ') try: is_valid_email(email) except exceptions.ValidationError: sys.stderr.write("Error: That e-mail address is invalid.\n") email = None continue try: get_user(email) except get_user_model().DoesNotExist: break else: sys.stderr.write("Error: That email is already taken.\n") email = None # Get a password while 1: if not password: password = getpass.getpass() password2 = getpass.getpass('Password (again): ') if password != password2: sys.stderr.write("Error: Your passwords didn't match.\n") password = None continue if password.strip() == '': sys.stderr.write("Error: Blank passwords aren't allowed.\n") password = None continue break except KeyboardInterrupt: sys.stderr.write("\nOperation cancelled.\n") sys.exit(1) # Make Django's tests work by accepting a username through # call_command() but not through manage.py username = options.get('username', None) if username is None: create_superuser(email, password) else: get_user_model().objects.create_superuser(username, email, password) if verbosity >= 1: self.stdout.write("Superuser created successfully.\n")
def unmonkeypatch_user(): get_user_model().__init__ = original_init get_user_model().save_base = original_save_base
def monkeypatch_user(): get_user_model().__init__ = user_init_patch get_user_model().save_base = user_save_patch
def user_init_patch(self, *args, **kwargs): super(get_user_model(), self).__init__(*args, **kwargs) self._username = self.username if self.username == _email_to_username(self.email): # Username should be replaced by email, since the hashes match self.username = self.email
if email_as_username: #self.username = _email_to_username(self.email) self.username = id_generator(12) try: super(get_user_model(), self).save_base(*args, **kwargs) finally: if email_as_username: self.username = self.email #self.username = id_generator(12) if email_as_username: self.username = self.email #self.username = id_generator(12) original_init = get_user_model().__init__ original_save_base = get_user_model().save_base def monkeypatch_user(): get_user_model().__init__ = user_init_patch get_user_model().save_base = user_save_patch def unmonkeypatch_user(): get_user_model().__init__ = original_init get_user_model().save_base = original_save_base monkeypatch_user()
def create_superuser(email, password): """ Create a new superuser with the given email. Use this instead of `User.objects.create_superuser`. """ return get_user_model().objects.create_superuser(email, email, password)
def test_can_create_user_with_explicit_id(self): """Regression test for https://github.com/dabapps/django-email-as-username/issues/52 """ get_user_model().objects.create(email=self.email, id=1)
def test_can_create_user(self): user = create_user(self.email, self.password) self.assertEquals(list(get_user_model().objects.all()), [user])