Python 3.5.1 and Django 1.9
I have created a custom user model in my project:
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class UserManager(BaseUserManager):
def create_user(self, username, password=None):
user = self.model(
username=username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, password):
user = self.create_user(
username,
password=password,
)
user.is_admin = True
user.is_superuser = True
user.save(using=self._db)
return user
# Users
class User(AbstractBaseUser):
username = models.CharField(
unique=True,
max_length=50,
)
bio = models.TextField()
is_active = models.BooleanField(default=True,
verbose_name="Active",
help_text="lorem")
is_admin = models.BooleanField(default=False,
verbose_name="Staff status",
help_text="lorem")
is_superuser = models.BooleanField(default=False,
verbose_name="Superuser status",
help_text="lorem")
objects = UserManager()
USERNAME_FIELD = 'username'
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
def is_staff(self):
return self.is_admin
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, db):
return True
I followed the guide in the official documentation here
I have defined AUTH_USER_MODEL in settings.py
Everything seems to work correctly with the custom user model, execpt...
Any user can login to the admin interface. This of course is not a good thing
Here is a screenshot of the admin interface when logged in as a non-admin user:
And here when logged as an actual admin user
Note the top right corners. When logged in with a non-admin user, the menu dose not appear. Strange.
Both admin and non-admin users have full access to the admin interface, they can both add, change and delete entries.
Clearly this is a terrible security issue, I don't even know where to start dubugging
Django admin allows access to users marked as is_staff=True . To disable a user from being able to access the admin, you should set is_staff=False . This holds true even if the user is a superuser. is_superuser=True .
Test the 'view' permission is added to all models Using #3 for Django 1.7 only creates the permission objects if the model doesn't already exist. Is there a way to create a migration (or something else) to create the permission objects for existing models?
Django's Admin is amazing. A built-in and fully functional interface that quickly gets in and allows data entry is priceless. Developers can focus on building additional functionality instead of creating dummy interfaces to interact with the database.
You'll need to turn is_staff
into a property. If you use the built-in User model, Django expects it to be a model field, which means all checks for staff status happen as if user.is_staff:
, not as if user.is_staff():
. All you need to do is to include a single line before your is_staff
method definition:
@property
def is_staff(self):
return self.is_admin
Since Python considers every function object to be True when used in a boolean context, all your users pass the check for is_staff
.
If you want to know why the admin displays the correct value in the “STAFF STATUS” column, it's because is_staff
is listed in list_display
of the default ModelAdmin
for the user model, and ModelAdmin
does check items in list_display
if they're callable or not, and in case they are, it calls them. However, this is only done for the purpose of displaying the value (since list_display
is a more general mechanism), but not for any actual access control checks.
You musst inheritat from AbstractBaseUser
and PermissionsMixin
.
You just included a "bio" field in your User class.
Maybe just extend from AbstractUser
and not AbstractBaseUser
. The AbstractUser has most of the important stuff and you can include you bio field there
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With