django-allauth - It is possible to implement a two steps registration? - django

I've installed django-allauth but I need to costumize the signup process with a two steps sign up where the first page will collect the username, email, password and a custom user profile and the second page will handle a payment(paypal) subscription.
This is possible to implement using django-allauth?
Best Regards,
André

So far the easiest solution for me was using #user_passes_test on all view functions, that in principle expect logged in user. Your decorator should invoke the function, which checks if the second step of the setup has been completed. If yes, it returns true, if not, redirects to the relevant form:
#user_passes_test(checkUser, "/signup/second-step")
def showSomeStuff(request):
pass
Note, that this is actually not allauth specific in any way, this will work with any other form of user creation/registration.

Related

Possible to change password in DRF without the previous password?

Say I had a setup that was similar to an office with a system admin. But instead of using email to reset passwords, the system admin did it himself, and then got the password to the user through some other fashion. Is this possible to do in Django? Can I use the hash of the previous password somehow? Is there possibly a way to overwrite the rest-auth in the serializer and view? Please let me know if you guys have any methods for this. I haven't really come across anything that isn't email or Django frontend stuff.
Yes it is possible indeed. The admin could use the admin interface.
Just implement a custom Django admin action for that.
https://docs.djangoproject.com/en/2.1/ref/contrib/admin/actions/
And use user.set_password so you won't have to deal the hash for the previuos password.
If you don't want to use the admin interface you still can use user.set_password from any view.

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.

How to let the user set a username during registration with Django social-auth?

I use Django social-auth (omab version just to avoid any confusion with the other similarly named project) and right now I am trying it with Facebook. It is possible to register a new user and to login/logout without any issue. The only thing that I would like to add is a form during registration to let the user enter the desired username to be used on site because at the moment the username is either a facebook username (I do not want to force the user to use the same username) or a uuid if there is no facebook username (and that is ugly).
I am reading the docs, the pipelines and all that stuff but I'm not sure to understand, any hint or explanation would be welcome.
I found it in the example app that comes with social-auth https://github.com/omab/django-social-auth/tree/master/example/app. There is an example of the pipeline to use and even the form and views you need to implement. Very few to no changes are necessary to have a working implementation. At least some work needs to be done on the form at the time I write this because you can enter a username already taken.
The accepted answer links to an entire GitHub project without explaining anything about what parts of it are relevant, and some of it is outdated, so I'll try to share what I've learned.
django-social-auth is deprecated and the replacement is social-app-django, which integrates Django with the python-social-auth project.
The documentation on python-social-auth Pipelines is relevant. In the default pipeline, this is the stage that generates the username:
# Make up a username for this person, appends a random string at the end if
# there's any collision.
'social_core.pipeline.user.get_username',
The implementation of get_username shows the default behavior. We will have to copy these aspects:
It ensures that the username it comes up with is unique, by checking storage.user.user_exists(username=...) and modifying the username until it is unique.
It returns the dictionary {'username': '...'}, which is passed to the next stages in the pipeline.
To prompt the user, we need a custom "partial" pipeline stage. This lets us pause the pipeline to wait for the user to submit the username form and then resume it once we have the username.

Using Django-Registration, what's the easiest way to remove and use email address

For my app, I'd just like people to register with an email address and password and use that to log in. Essentially I dont want the username to ever be seen by the end user.
I'm using django-registration. Is there a super simple way to set it this way? Seems like a fairly common need.
Thanks!
http://djangosnippets.org/snippets/1001/
In your registration form, you'll need to remove the username and have it be autogenerated. The username field isn't very long in Django so just using an email isn't a viable option without (monkey)patching Django.
Once you are registering users with a autogenerated username, you'll need to enable authenication. To do this you need to use a custom Authentication backend that enables signing in by email. Pinax has one that you can use as a reference:
Link

Implementing a secure two-factor authentication for a login page with Django form wizard

So basically i want to achieve something similar to Google Two-factor authentication implementation. My login form consists of a 2-step form wizard:
Step 1 (verifying username and password)
Step 2 (authenticate security token)
The usage scenarios would be:
User has a security token associated with his account: logs user in if user passes Step 1 and Step 2
User doesn't have a security token: logs user in right after he passes Step 1 only
I'm subclassing django's Form Wizard now to be used as my login view. In Step 2, by default Django FormWizard will include field values from previously submitted forms as hidden fields. But as you know, password is entered in Step 1, so I don't want to include it in Step 2 for security reasons.
My first thought would be to use session to indicate if a user has passed Step 1, so I don't need to include field values from Step 1.. but I may be overlooking something here. What are the more secure solutions to this?
Also I don't quite understand the use of security-hash in FormWizard. Can someone explain?
Thanks a lot.
More than a year after the last answer:
Django-two-factor-auth builds on django-otp and adds out of the box support for Google Authenticator, Twilio SMS, backup codes. Very impressive.
Duo Security's duo_web project has an open source Django demo which will show you one way to do this (I am a Duo developer).
The demo setup has a #duo_auth_requried decorator similar to the builtin #login_required which checks for a session cookie indicating that the user has passed the 2nd factor authentication. The #login_required decorator verifies local authentication, the #duo_auth_required decorator verifies 2nd factor authentication, and the lack of either redirects the user to the relevant form.
The difference with your description is that we don't authenticate both in a single form or pass credentials between forms, we do them separately. Just protect a view with both decorators and you can rely on Django to assert local authentication before the 2nd factor auth is attempted.
I'm not exactly getting the point of the security token, but it would seem simpler and faster if you forgo extending the FormWizard and just implement it as two separate views. The whole point of the FormWizard is to break and aggregate several forms into one and your particular use case goes against it—you'd just be hacking it to functionally do something otherwise.
As for the security hash, it calculates a hash for all of the form data from successfully completed steps. This is just a security measure to ensure that the form data has not changed/been tampered with inbetween steps and that none of the steps were otherwise bypassed somehow.
The django-otp project adds pluggable two-factor authentication to Django. It can be integrated at various levels, from view to form to low-level API.
You could use an existing multifactor authentication backend like LinOTP or privacyidea.
I created a django-plugin writeup.