django-social-auth registration extra step - django

I'm using django-social-auth & custom User model (django 1.5) with extra fields which are required. I need the user to fill these fields before the models is saved. Is there any way to "interrupt" the django-social-auth right after the backend authorization succeeded, but before the new User model is created, in order to show the form asking for account details?
Thanks in advance

You add a pipeline entry which returns a HttpResponseRedirect to any place you need. Check the example app with django-social-auth, it cuts the pipeline in two places (here and here) to ask the user some extra information. The first one takes place before the user instance is created.
Check the save_status_to_session call before each break, that is required to ensure the pipeline status when it's continued.

Related

Increasing Django login security and password strengths

When I create the Django superuser , if I try to add a weak password Django doesn't let me, but for normal users, in admin, or using register form I can add very simple password.
How can I ad the password validation from the superuser creation to all users ?
Can the number of login bad tries be limited (I prefer without third-party)
When creating users or super users alike both use the same Django configuration settings AUTH_PASSWORD_VALIDATORS and if left unmodified it'll contain a list of validators that all passwords will validate against when creating users via Django admin.
This is also the place where you strengthen your validators by adding more if you want harder or remove if you want to be more lax.
However, if you're creating users via the management commands create_user and create_superuser this list of validators will not apply. This is because Django assumes that only developers are interacting with Django at this level.
For your second ask, there is nothing built-in to Django that supports login tries and following blocking of further logins. This is something that either comes from 3rd party apps such as django-defender or from own implementation.
The broad strokes of that implementation is
Add a new tablemechanism that stores number of tries
Add a new settings in settings.py LOGIN_ATTEMPTS = 3
Override the login flow for a user in which you check this table for attempts
If failed attempt increment counter, if successful reset counter.
If user hits the limit of attempts, set users is_active to False and always return False from your login override.

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

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.

Sending emails after updating the model from the admin page (Django)

Hello I want to know if there is a way to send an email to a user upon someone updating certain fields in the Django admin page being updated. Is there a way to do this? I already have an email being sent upon the forms completion, but I need to send more emails once one of the users updates through the admin page.
I have taken a look at the post_save, model_save and save_formset methods, but I did not feel that they were what I was looking for.
Try overriding the ModelAdmin.save_model method. I think it has hooks for all the information you require.
The change variable lets you distinguish between a user adding or changing the model instance.
form.changed_data gives you a list of the names of the fields which have changed, which lets you determine whether or not to send the email.
Finally request.user identifies the user which made the changes.
You need django.db.models.signals.post_save signal. It is sanding after the model has been saved.
def my_callback(sender, **kwargs):
# Your specific logic here
pass
post_syncdb.connect(my_callback, sender=yourapp.models.TheModel)
Arguments sent with this signal:
sender:
The model class.
instance:
The actual instance being saved.
created
A boolean; True if a new record was created.
raw:
A boolean; True if the model is saved exactly as presented (i.e. when loading a fixture). One should not query/modify other records in the database as the database might not be in a consistent state yet.
So you need only callback and sender.

How to store additional information about the Users in Django ?

I have several notifications that can be sent out from my Django application for users. These users are managed with the django.contrib.auth app.
I need to keep track for each whether the user has specified he/she wants to get that notification.
Where should I save this information?
I was going to create my own custom table but I've seen perhaps I can save that information somewhere in the auth module?
User Profiles are a good way to go.
https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
Set up a model with a OneToOneField to your User object as described and you have easy access to an arbitrary table of extra information.
PS: Heed the note about the fact that profiles are not automatically created. There is an example about how to use a Signal to automatically create one whenever a User is created.

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.