2

I apologize if there has been a substantial answer on this already, I have searched for quite a while and can't find any helpful answers.

I have a django project that has varying levels of account access. I have a group of 'Managers' and I want to allow them to manage user accounts.

I want the Managers to be able to create the user account objects for the users. However, I don't want them to have to deal with creating their passwords and sending them to the users (for obvious reasons). This way, managers can impersonate users to get work done on their behalf, and users maintain password control and ownership of their data.

The idea is that managers create the account, and when the account is created Users will be sent a password reset form (same as django's out-of-box auth) which will allow them to set their passwords.

My code looks similar to below (omitted non-imperative stuff)

from django.contrib.auth.models import User
from django.contrib.auth.forms import PasswordResetForm

@manager_required
def manager_add_users(request):
    add_user_form = manager_add_user_form(request.POST)
    new_user_name = add_user_form.cleaned_data['user_name']
    new_user_email = add_user_form.cleaned_data['user_email']

    new_user = User.objects.create_user(
        username = new_user_name, 
        email = new_user_email, 
        )
    new_user.save()

    set_password_form = PasswordResetForm({'email': new_user.email })
            if set_password_form.is_valid():
                print 'Reset Form Is Valid'
                set_password_form.save(
                    request= request,
                    use_https=True,
                    from_email="[email protected]",
                    email_template_name='registration/password_reset_email.html')

The account creates properly and everything runs without error. The issue is that although the form is valid (reset form is valid statement prints) it is not actually sending the reset form. There are no form errors.

However, in testing when I initialize the form with an address that already exists in the system like this:

set_password_form = PasswordResetForm({'email':'[email protected]'})

The password reset form sends without error. So it only works with existing user email addresses in the system, but although the user has been created and the .save() method called, it's still not catching it (The users are marked as 'Active' upon creation, so they should be able to be found)

I'm a bit at a loss. I can think of a few ways that I could get around this issue, but this seems the most direct way of doing it and I'm really not entirely sure why it doesn't work.

Yes, I am able to send messages. I am using django's backend mail for testing:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
3
  • You haven't mentioned anything about your email backend. Django itself doesn't send any emails, you have to configure an email server. When running tests it substitutes a dummy backend. Have you set up an email server and confirmed that you can actually send emails with it? Commented Jul 5, 2016 at 23:32
  • Sorry. I'm using django's backend. I figured it would be clear that I had a mail server configured when I mentioned that I successfully have mails delivered in some test cases. I have updated the question to include my settings. Commented Jul 6, 2016 at 0:56
  • Thanks for clarifying. I mentioned it because it's possible for tests to work just fine without having a mail server set up since Django's test runner substitutes a test backend. Commented Jul 6, 2016 at 3:35

1 Answer 1

1

Glancing at the source code, it looks like Django is ignoring the request because the password is blank.

Try setting a temporary password (using, say, django.utils.crypto.get_random_string()) before saving the user.

Sign up to request clarification or add additional context in comments.

3 Comments

Sending passwords with an email is a bad Idea. Use dango-registration to generate tokens and send the token instead. Once the token is clicked from the email read it and offer the user to set the password.
@dmitryro: What you're describing is exactly how Django's password reset flow works. My answer is about setting a temporary password in the database, not sending it in an email.
Thank you. This is the absolute correct answer. Although user accounts created without passwords were active and could be impersonated by admins, the lack of password prevented auth from sending a reset. It seems so obvious now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.