Django user account creation confirmation email - django

I have a django project where I want to create users, and some time later be able to send a welcome email with a link inviting them to log in and set a password.
I'm using django-allauth. I found this SO question which shows how to call allauth's password reset form, which is close to what I need, except that:
I want to send a "welcome" email, which would be worded differently.
I want it to send them to a "welcome" page, which would be different to a password reset (although perhaps operate the same way in that it use a token etc...)
I'm thinking I could somehow hijack that, but am not sure how or where that email gets sent.
django-allauth docs mention the routes /accounts/password/set/ and /accounts/password/set/ but I can't access either without logging in first.
This is an existing project I inherited, and I do have a template for "/account/password_reset_from_key.html". Just not sure how it all gets wired together.
Has anyone done anything similar?

You mention:
...and some time later be able to send a welcome email with a link inviting them to log in and set a password.
If sometime later, then you might be interested in queues like Celery to do that for you.
Here's an approach you might take:
Listen to the save django model signal on the User model. Send an email to a user whenever that is triggered (this will happen immediately. However with your "some time later" thing, then you add that sending to the user to a celery job queue for later
Send a dynamic email with html. With this, you can customize the design etc to your taste.

Related

Should I Leave Django Allauth As-Is Or Make The Changes I've Suggested

Im using Django Allauth and have a number of questions.
(a) When a user registers they are instantly logged in and a confirmation email is sent to their inbox. I am wondering if this is best practice? Should the user instead be signed out after registration and only allowed to sign in using the link in their email?
I am also wondering about password change. The password change functionality that comes with Allauth simply asks the user to enter their old password then enter a new one twice. My two questions for this are (b) is this good practice or should I make my users request a new password via email, and (c) should I force logout my users after a password change and make them login using their new credentials?
(d) And lastly, if a user has forgotten their password they can request a new one sent to them via email. I could imagine this could easily be abused as you do not need to be signed in to do this (a person or bot continually enter a users email address sending them thousands of password reset links). Is there a way to add a limit on a persons email address so the one user can only be sent maybe 2 password reset links per day?
I would appreciate answers to any of these questions and greatly appreciate any elaboration on how to do any of this as I am new to Django and really dont know where to begin if I am to make these changes.
Thank you very much.
It all depends on what you want to do, if your site is gonna manage a lot privacy data, then the story would be completely different. Assuming that it is true.
A) Best practice would be to be able to log in right away but they have restriction until they confirm the email.
B)Always request password change via Email using generated url.
C)You should not keep the user logged in with the old password, either log it out or automatic re login.
D)This is probably the most important here. There is a lot of way to prevent such abuse, tho they are not 100% effective but it is very effective, here is the thing: 1) if your way to recover password is by email, you can KEEP THE EMAIL PRIVATE, no one can see it, and what do you think the odds are to type a random email and matches the one on your database ? 2) Use popular antibots like Google's Recaptcha. 3) Set a limit of attempts on a limited range of time.

Django allauth activation code during registration

I am using Django allauth for authentication to my rest api. I have the whole process working as expected (login, registration, password reset) with email confirmation ..etc.
My question is when a user register the user receives an email with the link that user need to click and confirm to get access to the website. However, i want to use allauth but instead of a link I want a randomly generated activation code (example: 123456). That user can input in a form to confirm.
Allauth currently doesn't support this. You could open up an issue asking for the feature to be implemented, but considering that there's really no obvious advantage of using both systems, I doubt this would be accepted.
Is there a reason why the link method doesn't work for you, but this does? If so, maybe there's some workaround that could work?
Here's a possible workaround (albeit a very complicated one):
Write a template tag that would trim out the website part (ex example.com/confirm/ out of example.com/confirm/sdafsdagfsagfsdafasdfsafgfdsg), so that only the actual code is sent to the user in the email
Make a form that would accept this code, and, on submission, reconstruct the url back to its original state, and go to that url, effectively activating the account. You would almost definitely need to write custom javascript for this.

Is there a way to use Django's default password reset without sending reset link via email?

Is there a way to use django's inbuilt password reset function without sending reset links via email or without the email option. I am currently developing a simple system with a few number of users on which sending emails are not needed.Thanks in advance
There are some options in django.contrib.auth that allows you to change the password without needing to send an email:
PasswordChangeForm: A form that lets a user change their password by entering their old password.
SetPasswordForm: A form that lets a user change set their password without entering the old password
You can implement one of them in your view to change the users password.
You can change password with forms and in the views.py use the function
make_password()
if passwordForm.is_valid():
password = passwordForm.cleaned_data['password']
request.user.password = make_password(password)
request.user.save()
[make_password][1]https://docs.djangoproject.com/en/1.11/topics/auth/passwords/
I'm not familiar with django but I've worked on other apps before where access was gained for any user, even the initial admin, via password reset. In all those cases the method of working has been similar - the reset link is formed from some URL stub plus a unique key that is found in some database table somewhere. Manually assembling the link and using it worked out just fine, though one system used an emailsentdate column and refused to do anything unless it was populated , so check for anything similar if you don't get success with a simple approach
If you absolutely have to have an email server, there do exist simple ones intended for dev use like smtpdev, they behave like an smtp server to fool an app that demands one, but they don't send the emails onto anywhere, they just display them. Intended for debugging but might help you if django insists on one being configured that looks like a real mail server

How to prevent my rails app to give away available emails once a user has requested to reset his password

I want my rails app, which i use devise gem, not to give away the availability of an email in my database when a user requests to reset his/her password, after he/she has forgotten it while trying to login.
Please if possible you can also provide the link of the reference material for me to understand it better.
I assume you mean that you don't want the app to say that an account with that email address was found in your database in case this is used as a way to find account names to try and break into. If so, then devise has a paranoid setting which will mean that the messages for password reset, resend confirmation etc. are vague and say that an email will have been sent if that email address exists in the database, without actually saying if it does or not. (It doesn't do this for registerable because if someone tried to create an account with a duplicate email address, devise thinks they should be told the creation failed.) The line you need in your devise.rb initialiser is:
config.paranoid = true
It's probably already there, just commented out with a comment above explaining it.
Here's a link to the blog post announcing this feature:
http://blog.plataformatec.com.br/2013/11/e-mail-enumeration-in-devise-in-paranoid-mode/

Django user registration - email invitations?

I am trying to hack my way through the wonderful django-registration app, and add the ability to send email invitations for the site.
The sending of invitations is trivial: the user enters an email, and the view sends an email to the recipient with a random alphanumeric sequence in the activation link.
I largely took the code from Ayman Hourieh's book on Django. The problem is that in the book Ayman develops a custom made registration system, and then adds the variable invitation to the session. I don't know how to do it with Bennett's django-registration, so that when somebody follows the link, and performs the activation, he can become friend with the user than sent the invitation. This is crucial for me because I need the ability to track the number of users that each user drove to the site. Anyone had experience with this problem?
Have you had a look at django-invitation? It's build on django-registration
http://code.welldev.org/django-invitation/wiki/Home
EDIT
I haven't used it before so I don't know its exact functionality, but looking at the code, when an invitation is sent, an InvitationKey object is created which has a from_user and registrant so the functionality is there whether it's documented or not.