2016-02-08 03:59:38 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
2016-06-29 01:32:57 +02:00
|
|
|
from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
|
|
|
|
from django.db.migrations.state import StateApps
|
2016-02-08 03:59:38 +01:00
|
|
|
from django.db import models, migrations, connection
|
|
|
|
from django.conf import settings
|
|
|
|
|
|
|
|
# Translate the UserProfile fields back to the old Guardian model
|
|
|
|
def unmigrate_guardian_data(apps, schema_editor):
|
2016-06-29 01:32:57 +02:00
|
|
|
# type: (StateApps, DatabaseSchemaEditor) -> None
|
2016-02-08 03:59:38 +01:00
|
|
|
Permission = apps.get_model('auth', 'Permission')
|
|
|
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
|
|
|
UserProfile = apps.get_model('zerver', 'UserProfile')
|
|
|
|
|
|
|
|
try:
|
|
|
|
administer = Permission.objects.get(codename="administer")
|
|
|
|
except Permission.DoesNotExist:
|
|
|
|
administer = Permission.objects.create(codename="administer")
|
|
|
|
try:
|
|
|
|
api_super_user = Permission.objects.get(codename="api_super_user")
|
|
|
|
except Permission.DoesNotExist:
|
|
|
|
api_super_user = Permission.objects.create(codename="api_super_user")
|
|
|
|
realm_content_type = ContentType.objects.get(app_label="zerver",
|
|
|
|
model="realm")
|
|
|
|
|
|
|
|
# assign_perm isn't usable inside a migration, so we just directly
|
|
|
|
# create the UserObjectPermission objects
|
|
|
|
UserObjectPermission = apps.get_model('guardian', 'UserObjectPermission')
|
|
|
|
for user_profile in UserProfile.objects.filter(is_realm_admin=True):
|
|
|
|
UserObjectPermission(permission=administer,
|
|
|
|
user_id=user_profile.id,
|
|
|
|
object_pk=user_profile.realm_id,
|
|
|
|
content_type=realm_content_type).save()
|
|
|
|
for user_profile in UserProfile.objects.filter(is_api_super_user=True):
|
|
|
|
UserObjectPermission(permission=api_super_user,
|
|
|
|
user_id=user_profile.id,
|
|
|
|
object_pk=user_profile.realm_id,
|
|
|
|
content_type=realm_content_type).save()
|
|
|
|
|
|
|
|
# Migrate all the guardian data for which users are realm admins or
|
|
|
|
# API super users to the new fields on the UserProfile model
|
|
|
|
def migrate_guardian_data(apps, schema_editor):
|
2016-06-29 01:32:57 +02:00
|
|
|
# type: (StateApps, DatabaseSchemaEditor) -> None
|
2016-02-08 03:59:38 +01:00
|
|
|
Permission = apps.get_model('auth', 'Permission')
|
|
|
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
|
|
|
UserProfile = apps.get_model('zerver', 'UserProfile')
|
|
|
|
|
|
|
|
try:
|
|
|
|
administer_id = Permission.objects.get(codename="administer").id
|
|
|
|
except Permission.DoesNotExist:
|
|
|
|
administer_id = None
|
|
|
|
try:
|
|
|
|
api_super_user_id = Permission.objects.get(codename="api_super_user").id
|
|
|
|
except Permission.DoesNotExist:
|
|
|
|
api_super_user_id = None
|
|
|
|
|
|
|
|
# If ContentType hasn't been initialized yet, we have a new, clean
|
|
|
|
# database and the below is not needed
|
|
|
|
if ContentType.objects.count() == 0:
|
|
|
|
return
|
|
|
|
|
|
|
|
realm_content_type = ContentType.objects.get(app_label="zerver",
|
|
|
|
model="realm")
|
|
|
|
|
|
|
|
cursor = connection.cursor()
|
|
|
|
cursor.execute("SELECT id, object_pk, content_type_id, permission_id, user_id FROM guardian_userobjectpermission")
|
|
|
|
for row in cursor.fetchall():
|
|
|
|
(row_id, object_pk, content_type_id, permission_id, user_id) = row
|
|
|
|
if content_type_id != realm_content_type.id:
|
|
|
|
raise Exception("Unexected non-realm content type")
|
|
|
|
user_profile = UserProfile.objects.get(id=user_id)
|
|
|
|
if permission_id == administer_id:
|
|
|
|
user_profile.is_realm_admin = True
|
|
|
|
elif permission_id == api_super_user_id:
|
|
|
|
user_profile.is_api_super_user = True
|
|
|
|
else:
|
|
|
|
raise Exception("Unexpected Django permission")
|
|
|
|
user_profile.save()
|
|
|
|
# Set the email gateway bot as an API super user so we can clean
|
|
|
|
# up the old API_SUPER_USERS hack.
|
|
|
|
if settings.EMAIL_GATEWAY_BOT is not None:
|
|
|
|
try:
|
|
|
|
email_gateway_bot = UserProfile.objects.get(email__iexact=settings.EMAIL_GATEWAY_BOT)
|
|
|
|
email_gateway_bot.is_api_super_user = True
|
|
|
|
email_gateway_bot.save()
|
|
|
|
except UserProfile.DoesNotExist:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# Delete the old permissions data in the Guardian tables; this
|
|
|
|
# makes the reverse-migration work safely (otherwise we'd have to
|
|
|
|
# worry about the migrate/unmigrate process racing with a user's
|
|
|
|
# admin permissions being revoked).
|
|
|
|
cursor.execute("DELETE FROM guardian_userobjectpermission")
|
|
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
|
|
|
|
dependencies = [
|
|
|
|
('zerver', '0010_delete_streamcolor'),
|
|
|
|
]
|
|
|
|
|
|
|
|
operations = [
|
|
|
|
migrations.AddField(
|
|
|
|
model_name='userprofile',
|
|
|
|
name='is_api_super_user',
|
|
|
|
field=models.BooleanField(default=False, db_index=True),
|
|
|
|
),
|
|
|
|
migrations.AddField(
|
|
|
|
model_name='userprofile',
|
|
|
|
name='is_realm_admin',
|
|
|
|
field=models.BooleanField(default=False, db_index=True),
|
|
|
|
),
|
|
|
|
migrations.RunPython(migrate_guardian_data, unmigrate_guardian_data),
|
|
|
|
]
|