# Generated by Django 3.2.4 on 2022-02-14 02:42
from django.contrib.auth.management import create_permissions
from django.db import migrations
from django.db.models import Q
# Fetch a list of known permissions with:
# ./manage.py dbshell # sqlite
# .mode quote
# SELECT app_label, model, codename FROM auth_permission ap
# LEFT OUTER JOIN django_content_type dct ON ap.content_type_id=dct.id;
NEW_PERMISSIONS = {
'basic-readonly': [ # Non-sensitive read access (eg, fee categories, sub periods)
('membership','feecategory','view_feecategory'),
('membership','mitaffil','view_mitaffil'),
('membership','personstatus','view_personstatus'),
('membership','squarelevel','view_squarelevel'),
('membership','personfrequency','view_personfrequency'),
# Waffled about TSClass, decided not to because it has class coordinator
# Waffled about Dance, decided not to in case of private dances
# SubPeriods, OTOH, are more likely to always be on the website
('gate','paymentmethod','view_paymentmethod'),
('gate','subscriptionperiod','view_subscriptionperiod'),
('gate','subscriptionperiodprice','view_subscriptionperiodprice'),
('gate','dancepricescheme','view_dancepricescheme'),
('gate','danceprice','view_danceprice'),
],
'member-readonly': [ # Mildly sensitive membership (eg, contact info)
('membership','feecategory','view_feecategory'),
('membership','mitaffil','view_mitaffil'),
('membership','person','view_person'),
('membership','personcomment','view_personcomment'),
('membership','personstatus','view_personstatus'),
('membership','squarelevel','view_squarelevel'),
('membership','tsclass','view_tsclass'),
('membership','tsclassassist','view_tsclassassist'),
('membership','tsclassmember','view_tsclassmember'),
('membership','personfrequency','view_personfrequency'),
],
'gate-readonly': [ # Mildly sensitive gate (eg, attendance)
('gate','dance','view_dance'),
('gate','paymentmethod','view_paymentmethod'),
('gate','subscriptionperiod','view_subscriptionperiod'),
('gate','subscriptionperiodprice','view_subscriptionperiodprice'),
('gate','payment','view_payment'),
('gate','attendee','view_attendee'),
('gate','subscriptionpayment','view_subscriptionpayment'),
('gate','dancepayment','view_dancepayment'),
('gate','dancepricescheme','view_dancepricescheme'),
('gate','danceprice','view_danceprice'),
],
'member-edit': [ # Edit membership that's not migration-managed
('membership','feecategory','view_feecategory'),
('membership','mitaffil','view_mitaffil'),
('membership','person','add_person'),
('membership','person','change_person'),
('membership','person','delete_person'),
('membership','person','view_person'),
('membership','personcomment','add_personcomment'),
('membership','personcomment','change_personcomment'),
('membership','personcomment','delete_personcomment'),
('membership','personcomment','view_personcomment'),
('membership','personstatus','view_personstatus'),
('membership','squarelevel','view_squarelevel'),
('membership','tsclass','add_tsclass'),
('membership','tsclass','change_tsclass'),
('membership','tsclass','delete_tsclass'),
('membership','tsclass','view_tsclass'),
('membership','tsclassassist','add_tsclassassist'),
('membership','tsclassassist','change_tsclassassist'),
('membership','tsclassassist','delete_tsclassassist'),
('membership','tsclassassist','view_tsclassassist'),
('membership','tsclassmember','add_tsclassmember'),
('membership','tsclassmember','change_tsclassmember'),
('membership','tsclassmember','delete_tsclassmember'),
('membership','tsclassmember','view_tsclassmember'),
('membership','personauthlink','bulk_create_personauthlink'),
('membership','personauthlink','delete_personauthlink'),
('membership','personauthlink','view_personauthlink'),
('membership','personfrequency','view_personfrequency'),
],
'gate-edit': [ # Edit gate that's not migration-managed
('gate','dance','add_dance'),
('gate','dance','change_dance'),
('gate','dance','delete_dance'),
('gate','dance','view_dance'),
('gate','paymentmethod','view_paymentmethod'),
('gate','subscriptionperiod','add_subscriptionperiod'),
('gate','subscriptionperiod','change_subscriptionperiod'),
('gate','subscriptionperiod','delete_subscriptionperiod'),
('gate','subscriptionperiod','view_subscriptionperiod'),
('gate','subscriptionperiodprice','add_subscriptionperiodprice'),
('gate','subscriptionperiodprice','change_subscriptionperiodprice'),
('gate','subscriptionperiodprice','delete_subscriptionperiodprice'),
('gate','subscriptionperiodprice','view_subscriptionperiodprice'),
('gate','payment','add_payment'),
('gate','payment','change_payment'),
('gate','payment','delete_payment'),
('gate','payment','view_payment'),
('gate','attendee','add_attendee'),
('gate','attendee','books_app'),
('gate','attendee','change_attendee'),
('gate','attendee','delete_attendee'),
('gate','attendee','signin_app'),
('gate','attendee','view_attendee'),
('gate','subscriptionpayment','add_subscriptionpayment'),
('gate','subscriptionpayment','change_subscriptionpayment'),
('gate','subscriptionpayment','delete_subscriptionpayment'),
('gate','subscriptionpayment','view_subscriptionpayment'),
('gate','dancepayment','add_dancepayment'),
('gate','dancepayment','change_dancepayment'),
('gate','dancepayment','delete_dancepayment'),
('gate','dancepayment','view_dancepayment'),
('gate','dancepricescheme','add_dancepricescheme'),
('gate','dancepricescheme','change_dancepricescheme'),
('gate','dancepricescheme','delete_dancepricescheme'),
('gate','dancepricescheme','view_dancepricescheme'),
('gate','danceprice','add_danceprice'),
('gate','danceprice','change_danceprice'),
('gate','danceprice','delete_danceprice'),
('gate','danceprice','view_danceprice'),
],
'signin': [ # gate/books user
('gate','attendee','books_app'),
('gate','attendee','change_attendee'),
('gate','attendee','delete_attendee'),
('gate','attendee','signin_app'),
],
}
NEW_USERS = dict(
signin=dict(
args=dict(first_name='Signin', last_name='User',
email='squares-webapps@mit.edu',
is_staff=False),
groups=['signin', 'basic-readonly'],
),
demo=dict(
args=dict(first_name='Demo', last_name='User',
email='squares-webapps@mit.edu',
is_staff=True),
groups=['member-edit', 'gate-edit'],
),
)
# From https://stackoverflow.com/a/40092780/1797496
[docs]
def migrate_permissions(apps, schema_editor):
for app_config in apps.get_app_configs():
app_config.models_module = True
create_permissions(app_config, apps=apps, verbosity=0)
app_config.models_module = None
[docs]
def apply_migration(apps, schema_editor):
# Otherwise, perms don't exist yet if this migration is run on a pristine DB
migrate_permissions(apps, schema_editor)
# Create the groups
Group = apps.get_model("auth", "Group")
Permission = apps.get_model("auth", "Permission")
for name, perms in NEW_PERMISSIONS.items():
group, created = Group.objects.get_or_create(name=name)
perm_q = Q()
for app_label, model, codename in perms:
perm_q |= Q(content_type__app_label=app_label,
content_type__model=model,
codename=codename)
perm_objs = list(Permission.objects.filter(perm_q))
assert len(perm_objs) == len(perms)
group.permissions.add(*perm_objs)
# Create the users
User = apps.get_model("auth", "User")
for name, attrs in NEW_USERS.items():
user, created = User.objects.get_or_create(username=name, defaults=attrs['args'])
group_q = Q()
for group in attrs['groups']:
group_q |= Q(name=group)
group_objs = list(Group.objects.filter(group_q))
assert len(group_objs) == len(attrs['groups'])
user.groups.add(*group_objs)
[docs]
def revert_migration(apps, schema_editor):
Group = apps.get_model("auth", "Group")
Group.objects.filter(name__in=NEW_PERMISSIONS.keys()).delete()
User = apps.get_model("auth", "User")
User.objects.filter(username__in=NEW_USERS.keys()).delete()
[docs]
class Migration(migrations.Migration):
dependencies = [
('gate', '0005_books_perm_and_notes'),
('membership', '0008_personfreq'),
# https://stackoverflow.com/q/31735042/1797496#comment121056380_40092780
("contenttypes", "0002_remove_content_type_name"),
("auth", "0012_alter_user_first_name_max_length"),
]
operations = [
migrations.RunPython(apply_migration, revert_migration)
]