use custom user and permission model
This commit is contained in:
parent
258065eec3
commit
0f911589ca
8 changed files with 252 additions and 0 deletions
0
core/authentication/__init__.py
Normal file
0
core/authentication/__init__.py
Normal file
67
core/authentication/migrations/0001_initial.py
Normal file
67
core/authentication/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Generated by Django 4.2.7 on 2023-12-11 21:10
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('inventory', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ExtendedUser',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Extended user',
|
||||
'verbose_name_plural': 'Extended users',
|
||||
},
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventPermission',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.event')),
|
||||
('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.permission')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('user', 'permission', 'event')},
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='extendeduser',
|
||||
name='permissions',
|
||||
field=models.ManyToManyField(through='authentication.EventPermission', to='auth.permission'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='extendeduser',
|
||||
name='user_permissions',
|
||||
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,45 @@
|
|||
# Generated by Django 4.2.7 on 2023-12-11 21:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0001_initial'),
|
||||
('knox', '0008_remove_authtoken_salt'),
|
||||
('authentication', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AuthTokenEventPermissions',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.event')),
|
||||
('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='authentication.eventpermission')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ExtendedAuthToken',
|
||||
fields=[
|
||||
('authtoken_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='knox.authtoken')),
|
||||
('permissions', models.ManyToManyField(through='authentication.AuthTokenEventPermissions', to='authentication.eventpermission')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Extended auth token',
|
||||
'verbose_name_plural': 'Extended auth tokens',
|
||||
},
|
||||
bases=('knox.authtoken',),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='authtokeneventpermissions',
|
||||
name='token',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='authentication.extendedauthtoken'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='authtokeneventpermissions',
|
||||
unique_together={('token', 'permission', 'event')},
|
||||
),
|
||||
]
|
33
core/authentication/migrations/0003_groups.py
Normal file
33
core/authentication/migrations/0003_groups.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.2.7 on 2023-11-26 00:16
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
from django.contrib.auth.models import Permission, Group
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('authentication', '0002_authtokeneventpermissions_extendedauthtoken_and_more'),
|
||||
('tickets', '0001_initial'),
|
||||
]
|
||||
|
||||
def create_groups(apps, schema_editor):
|
||||
admins = Group.objects.create(name='Admin')
|
||||
orga = Group.objects.create(name='Orga')
|
||||
team = Group.objects.create(name='Team')
|
||||
users = Group.objects.create(name='User')
|
||||
admins.permissions.add(*Permission.objects.all())
|
||||
users.permissions.add(*Permission.objects.filter(codename__in=
|
||||
['view_item', 'add_item', 'change_item', 'match_item']))
|
||||
team.permissions.add(*Permission.objects.filter(codename__in=
|
||||
['delete_item', 'view_issuethread', 'add_issuethread',
|
||||
'change_issuethread', 'delete_issuethread', 'send_mail']),
|
||||
*users.permissions.all())
|
||||
orga.permissions.add(*Permission.objects.filter(codename__in=['add_event']),
|
||||
*team.permissions.all())
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_groups),
|
||||
]
|
19
core/authentication/migrations/0004_legacy_user.py
Normal file
19
core/authentication/migrations/0004_legacy_user.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
from authentication.models import ExtendedUser
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('authentication', '0003_groups'),
|
||||
]
|
||||
|
||||
def create_legacy_user(apps, schema_editor):
|
||||
ExtendedUser.objects.create_user(settings.LEGACY_USER_NAME, 'mail@' + settings.MAIL_DOMAIN,
|
||||
settings.LEGACY_USER_PASSWORD)
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_legacy_user)
|
||||
]
|
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 4.2.7 on 2023-12-13 16:28
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0001_initial'),
|
||||
('authentication', '0004_legacy_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='eventpermission',
|
||||
name='event',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='inventory.event'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='eventpermission',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='event_permissions', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
0
core/authentication/migrations/__init__.py
Normal file
0
core/authentication/migrations/__init__.py
Normal file
62
core/authentication/models.py
Normal file
62
core/authentication/models.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import Permission, AbstractUser
|
||||
from knox.models import AuthToken
|
||||
|
||||
from inventory.models import Event
|
||||
|
||||
|
||||
class ExtendedUser(AbstractUser):
|
||||
permissions = models.ManyToManyField(Permission, through='EventPermission', through_fields=('user', 'permission'))
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Extended user'
|
||||
verbose_name_plural = 'Extended users'
|
||||
|
||||
def get_permissions(self):
|
||||
if self.is_superuser:
|
||||
for permission in Permission.objects.all():
|
||||
yield "*:" + permission.codename
|
||||
for permission in self.user_permissions.all():
|
||||
yield "*:" + permission.codename
|
||||
for group in self.groups.all():
|
||||
for permission in group.permissions.all():
|
||||
yield "*:" + permission.codename
|
||||
for permission in self.event_permissions.all():
|
||||
yield permission.event.slug + ":" + permission.permission.codename
|
||||
|
||||
def has_event_perm(self, event, permission):
|
||||
if self.is_superuser:
|
||||
return True
|
||||
permissions = set(self.get_permissions())
|
||||
if "*:" + permission in permissions:
|
||||
return True
|
||||
if event.slug + ":" + permission in permissions:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class ExtendedAuthToken(AuthToken):
|
||||
permissions = models.ManyToManyField('EventPermission', through='AuthTokenEventPermissions',
|
||||
through_fields=('token', 'permission'))
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Extended auth token'
|
||||
verbose_name_plural = 'Extended auth tokens'
|
||||
|
||||
|
||||
class EventPermission(models.Model):
|
||||
user = models.ForeignKey(ExtendedUser, on_delete=models.CASCADE, related_name='event_permissions')
|
||||
permission = models.ForeignKey(Permission, on_delete=models.CASCADE)
|
||||
event = models.ForeignKey(Event, on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('user', 'permission', 'event')
|
||||
|
||||
|
||||
class AuthTokenEventPermissions(models.Model):
|
||||
token = models.ForeignKey(ExtendedAuthToken, on_delete=models.CASCADE)
|
||||
permission = models.ForeignKey(EventPermission, on_delete=models.CASCADE)
|
||||
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('token', 'permission', 'event')
|
Loading…
Reference in a new issue