Add JWT auth with per-user data isolation and account settings.
Users can register, log in, and manage profile/password in a personal account page; server data is scoped by owner across contacts, maps, tags, and import. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
DEFAULT_SECTORS = [
|
||||
{'key': 'work', 'label': 'Работа'},
|
||||
{'key': 'study', 'label': 'Учёба'},
|
||||
{'key': 'hobby', 'label': 'Хобби'},
|
||||
{'key': 'family', 'label': 'Семья'},
|
||||
{'key': 'health', 'label': 'Здоровье'},
|
||||
{'key': 'other', 'label': 'Другое'},
|
||||
]
|
||||
|
||||
DEFAULT_CIRCLES = [
|
||||
{'key': 'support', 'label': 'Круг поддержки'},
|
||||
{'key': 'productivity', 'label': 'Круг продуктивности'},
|
||||
{'key': 'development', 'label': 'Круг развития'},
|
||||
]
|
||||
|
||||
|
||||
def assign_legacy_owner(apps, schema_editor):
|
||||
User = apps.get_model('auth', 'User')
|
||||
Contact = apps.get_model('contacts', 'Contact')
|
||||
Relation = apps.get_model('contacts', 'Relation')
|
||||
NetworkMap = apps.get_model('contacts', 'NetworkMap')
|
||||
NetworkMapType = apps.get_model('contacts', 'NetworkMapType')
|
||||
|
||||
user, created = User.objects.get_or_create(
|
||||
username='legacy',
|
||||
defaults={'email': 'legacy@local.invalid', 'password': '!'},
|
||||
)
|
||||
|
||||
Contact.objects.filter(owner__isnull=True).update(owner=user)
|
||||
Relation.objects.filter(owner__isnull=True).update(owner=user)
|
||||
NetworkMap.objects.filter(owner__isnull=True).update(owner=user)
|
||||
NetworkMapType.objects.filter(owner__isnull=True).update(owner=user)
|
||||
|
||||
if not NetworkMapType.objects.filter(owner=user, is_default=True).exists():
|
||||
default = NetworkMapType.objects.filter(is_default=True).first()
|
||||
if default:
|
||||
default.owner = user
|
||||
default.save(update_fields=['owner'])
|
||||
else:
|
||||
NetworkMapType.objects.create(
|
||||
owner=user,
|
||||
is_default=True,
|
||||
name='Стандартная',
|
||||
sectors=DEFAULT_SECTORS,
|
||||
circles=DEFAULT_CIRCLES,
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('contacts', '0010_conflictology_on_map_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contact',
|
||||
name='owner',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='contacts',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='Владелец',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='networkmap',
|
||||
name='owner',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='network_maps',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='Владелец',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='networkmaptype',
|
||||
name='owner',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='network_map_types',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='Владелец',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='relation',
|
||||
name='owner',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name='relations',
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='Владелец',
|
||||
),
|
||||
),
|
||||
migrations.RunPython(assign_legacy_owner, migrations.RunPython.noop),
|
||||
]
|
||||
Reference in New Issue
Block a user