Django-allauth How to Ban Certain Users? - django

I'm using django-allauth for my Django web app. How can I ban certain users from logging in or restrict certain actions after they log in for a period of time?
Should I just deactivate their accounts outright? What are some good solutions?

Normally for django authentication you would set the user object's is_active attribute to False and the user wouldn't be able to log in (into django admin for example). But you're using allauth, so by simply setting the is_staff attribute would be enough to block them from entering django admin for example.
Now, if you're implementing another type of frontend dashboard or need to set rules to how a user logs in, I'd say for you to use AccessMixins if you're using CBVs or decorators if you're using FBV. Specially the UserPassesTest mixin and user_passes_test decorator. With them you can check if a user comply to a certain rule and then allow them to log in or not. Check the docs here.

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 Admin: deactivate authentication

I am using Django for a small one-person tool. I would like to add/adapt my models via the admin interface, but I don't want to login everytime.
How can I switch off the required authentication at /admin/?
I highly recommend against you doing down that road:
Is it possible? No; the admin relies on the django auth app being with your settings' INSTALLED_APPS; of course this is because the admin relies on permissions and permissions rely on the admin user being authenticated.
The admin is built to edit not simply "your" models but also the models enabling the admin itself, mainly the models exposed by the auth app itself.
What to do ... 2 options:
Quickly develop a simple solution requiring no authentication using Django's ModelForms - docs and another good link here.
If it's a "one-person tool" then simply keep your authentication details saved in the browser you use; i.e. let the browser remember your username and password, so you just have to hit the "login" button rather than re-enter your data.

Multiple User Types For Auth in Django

My web features two user types, Client and Professional. There are also two 'main modules', one for clients to buy stuff and so on (the main site), and the other for professionals to manage operations. For auth, I would like to have:
A single 'sign in' form, which detects whether the user is a client or a professional and forwards her to the right module (main site or management site).
Two 'sign up' forms, one for clients and other for professionals. Probably, the site will ask the user whether she wants to register as a professional or as a client, to trigger the right registration flow for each case.
Clients will use the 'main site' and should not be authorized to use the 'management site'.
Professionals will use the 'management site' but should not be authorized to sign in to the main site.
Both professionals and clients are registered as Users, and share common fields, such as username, phone, email, etc...
Since Django won't let me use two models for authentication. I've created custom model subclassing AbstractBaseUser and which serves me as a base auth class for Client and Professional.
class BaseUser(AbstractBaseUser):
...
class Client(BaseUser):
...
class Professional(BaseUser):
...
I've also changed the AUTH_USER_MODEL setting to:
AUTH_USER_MODEL = 'myapp.BaseUser'
I've also included django-allauth to manage user registration and authentication. But now I'm stuck. I just began playing with Django/Python and I'm not sure how to solve this.
It seems there is no official recommended way for doing this (Implementing multiple user types with Django 1.5). Should I stick to the subclassing approach, or should I do the OnetoOne relationship pointed out in the docs ?
Once I have the models properly setup, how should I proceed with the two registration forms? Is it possible to accomplish this with django-allauth, or do I need to do it manually?
As far as I know, when a new user is registered, a new base user is created in the User table. But since I will be creating user specializations (Client or Professional), how should I specify that I also want to create the client-related data or professional-related data in the corresponding table?
I'm pretty new to Django, so any advise will help
I think the easiest way for you to do what you are talking about is going to be to have 3 apps in your project: your top level app, a "professional" app and a "client" app. At the top level app, all you really need to do is give the users a login form, and 2 links, one for registering as a Professional and one for registering as a Client.
In this case, I believe it will be easiest for you to use Django's built in Permissions system, and assign each type of user to a corresponding group (eg. professionals and clients). You can use a decorator on your views to ensure that only members of a particular group can access that view (since you have 2 separate apps for each group, you can add a decorator to all views in each of them, or you can import Django's authorization functions into your urls.py and check it there, although that is beyond the scope of this answer).
Registration is easy enough, use your urls.py file to forward the user that wants to register to the correct app. Once you do that, you should be able to use django-allauth registration on each app, allowing you to create 2 different kinds of users. Make sure when the register, you assign them to the correct group membership.
As for the login redirection, once you receive the POST data, I would check for which type of user logged in, and use that to forward the user to the correct URL that goes with the Professional or Client app. You can see the below link for an idea of redirecting a user after login.
Django - after login, redirect user to his custom page --> mysite.com/username

django staff users manage their own users only

In my Django app a user can register to the site and receive staff_user privileges from the admin.
After that the staff user can create and manage some other users (normal users) using default django admin site.
Now, I would like to let the staff user see and manage only the users he created from the admin site, I don't want him to see other users created by another staff user.
how can I do that? I imagine I need to modify admin.py right?
Don't modify the admin site.
In general, you have the following tools available:
Create groups
Add users to groups
Create custom permissions on your models, to indicate certain actions
https://docs.djangoproject.com/en/1.4/topics/auth/#custom-permissions
However, what you are asking: Now, I would like to let the staff user see and manage only the users he created from the admin site is not possible in django-admin.
The Django-admin site is only intended as a glorified development tool for fully trusted users, not as a customizable app for end users.
If your project requires an admin site with any of the following ...
Customized administraion functionality.
Exposure to any user that is not completely trusted.
... then I'm afraid you have to create your own custom app.
You can replace the stock UserAdmin with your own which overrides queryset() and does the filtering. The bigger issue is what to filter by. The default User model does not store a "created_by" in the model instance. So you would need to add this information whenever a User is added.
How best to do this depends on your Django version.
Django 1.5 introduced a "Configurable User model" which makes this very easy.
https://docs.djangoproject.com/en/dev/releases/1.5/#configurable-user-model
In earlier versions you would either have to monkeypatch the User model, or store that information in a separate "user profile" attached 1:1 to the User.
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
Regarding the trusting of users (which wasn't a topic but I feel the need to comment on thnee's answer) in the Django admin, check out the links in my answer here: Should I use Django's Admin feature?

object-level permissions django

How do you ensure that a User can only edit objects they've created? What's the best way to set this up?
I'm using django-rest-framework and wondering if there's a way I can restrict users from viewing/ editing objects they don't 'own'.
class Video(models.Model):
owner = models.ForeignKey(User)
...
So User 'x' should only be able to edit videos in their owner_set.
Presumably you have sessions and the auth model turned on.
You must be sure that all views (REST and non-REST) require authentication.
For non-REST, it's easy. You simply use a basic #login-required decorator everywhere.
For the Django-REST Framework, read this: http://django-rest-framework.org/library/authentication.html#module-authentication.
You have to use the authentication mixin to be sure that authentication actually happened.
The framework supports BASIC Authentication, which requires an SSL connection to be secure. It's not too difficult to implement DIGEST authentication, which doesn't require SSL.
Avoid sessions. It violates a principle of REST to login and logout. The framework supports sessions, but it's less than ideal.
Once you have all requests authenticated, you'll know the user.
If you know the user, then user.video_set works perfectly. You can also use Video.objects.filter(...) to be sure that you're querying the user, but it's easier to confirm the code is correct if you work with user.video_set.get(...) or user.video_set.filter() or whatever.
All the relevant authorization checking is done in Views. You're providing Views for your ModelResources.
These are "class-based views". Documentation is here: https://docs.djangoproject.com/en/dev/topics/class-based-views/#viewing-subsets-of-objects
The trick is to pick all the right mixing and serializers.
For example, you can mixing get processing this way:
http://django-rest-framework.org/howto/mixin.html
You'll implement the filter in the get method