feat: scope project access to Django Admin

This commit is contained in:
mohamad
2026-10-29 04:39:49 +08:00
parent 9a8551ae23
commit 6fd236f518
6 changed files with 489 additions and 20 deletions
@@ -0,0 +1,49 @@
# Generated by Django 5.2.16 on 2026-10-28 20:20
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('products', '0026_alter_articleperson_options_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='mainproduct',
name='created_by',
field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_main_projects', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='subproduct',
name='created_by',
field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_sub_projects', to=settings.AUTH_USER_MODEL),
),
migrations.CreateModel(
name='ProjectAccessPolicy',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('mode', models.CharField(choices=[('own', 'Own projects only'), ('none', 'No projects by default'), ('all_view', 'View all projects'), ('all_edit', 'View and edit all projects')], default='own', max_length=12)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='project_access_policy', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='ProjectAccess',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('level', models.CharField(choices=[('none', 'No access'), ('view', 'View only'), ('edit', 'View and edit')], default='view', max_length=4)),
('main_product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='access_grants', to='products.mainproduct')),
('sub_product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='access_grants', to='products.subproduct')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_access_grants', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Project access override',
'verbose_name_plural': 'Project access overrides',
'constraints': [models.CheckConstraint(condition=models.Q(models.Q(('main_product__isnull', False), ('sub_product__isnull', True)), models.Q(('main_product__isnull', True), ('sub_product__isnull', False)), _connector='OR'), name='project_access_exactly_one_project'), models.UniqueConstraint(condition=models.Q(('main_product__isnull', False)), fields=('user', 'main_product'), name='unique_user_main_project_access'), models.UniqueConstraint(condition=models.Q(('sub_product__isnull', False)), fields=('user', 'sub_product'), name='unique_user_sub_project_access')],
},
),
]