mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 20:40:17 +02:00
* Added a check to prevent dataloss from missing service modules Migration will raise an exception and refuse to run if a model has data for a field which is missing its target service. * Add setting to allow services to be installed after service migration Previously django would complain about migrations being out of order. By setting `SERVICES_MIGRATED=True` the `authentication.0013_service_modules` migration drops all of its 'optional' dependencies which allows the initial migrations of service modules to run normally. If the setting is missing or set to False, the migration will require all installed and required services migrations to have run before the `authentication.0013_service_modules` migration. * Move setting to somewhere it makes more sense * Modify celerybeat registration to automatically register services
324 lines
14 KiB
Python
324 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Generated by Django 1.10.2 on 2016-12-11 23:14
|
|
from __future__ import unicode_literals
|
|
|
|
from django.db import migrations
|
|
from django.conf import settings
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def optional_dependencies():
|
|
"""
|
|
Only require these migrations if the given app
|
|
is installed. If the app isn't installed then
|
|
the relevant AuthServicesInfo field will be LOST
|
|
when the data migration is run.
|
|
"""
|
|
installed_apps = settings.INSTALLED_APPS
|
|
|
|
dependencies = []
|
|
|
|
# Skip adding module dependencies if the settings specifies that services have been migrated
|
|
if hasattr(settings, 'SERVICES_MIGRATED') and settings.SERVICES_MIGRATED:
|
|
return dependencies
|
|
|
|
if 'services.modules.xenforo' in installed_apps:
|
|
dependencies.append(('xenforo', '0001_initial'))
|
|
if 'services.modules.discord' in installed_apps:
|
|
dependencies.append(('discord', '0001_initial'))
|
|
if 'services.modules.discourse' in installed_apps:
|
|
dependencies.append(('discourse', '0001_initial'))
|
|
if 'services.modules.ipboard' in installed_apps:
|
|
dependencies.append(('ipboard', '0001_initial'))
|
|
if 'services.modules.ips4' in installed_apps:
|
|
dependencies.append(('ips4', '0001_initial'))
|
|
if 'services.modules.market' in installed_apps:
|
|
dependencies.append(('market', '0001_initial'))
|
|
if 'services.modules.openfire' in installed_apps:
|
|
dependencies.append(('openfire', '0001_initial'))
|
|
if 'services.modules.smf' in installed_apps:
|
|
dependencies.append(('smf', '0001_initial'))
|
|
if 'services.modules.teamspeak3' in installed_apps:
|
|
dependencies.append(('teamspeak3', '0003_teamspeak3user'))
|
|
if 'services.modules.mumble' in installed_apps:
|
|
dependencies.append(('mumble', '0003_mumbleuser_user'))
|
|
if 'services.modules.phpbb3' in installed_apps:
|
|
dependencies.append(('phpbb3', '0001_initial'))
|
|
|
|
return dependencies
|
|
|
|
|
|
class DatalossException(Exception):
|
|
def __init__(self, field, app):
|
|
message = "This migration would cause a loss of data for the %s field, ensure the %s app is installed and" \
|
|
" run the migration again" % (field, app)
|
|
super(Exception, self).__init__(message)
|
|
|
|
|
|
def check_for_dataloss(authservicesinfo):
|
|
"""
|
|
Check if any of the authservicesinfo contain a field which contains data
|
|
that would be lost because the target module for migration is not installed.
|
|
If a record is found with no matching target installed an exception is raised.
|
|
:param authservicesinfo: AuthServicesInfo records to check
|
|
"""
|
|
installed_apps = settings.INSTALLED_APPS
|
|
|
|
for authinfo in authservicesinfo:
|
|
if authinfo.xenforo_username and 'services.modules.xenforo' not in installed_apps:
|
|
raise DatalossException('xenforo_username', 'services.modules.xenforo')
|
|
if authinfo.discord_uid and 'services.modules.discord' not in installed_apps:
|
|
raise DatalossException('discord_uid', 'services.modules.discord')
|
|
if authinfo.discourse_enabled and 'services.modules.discourse' not in installed_apps:
|
|
raise DatalossException('discourse_enabled', 'services.modules.discourse')
|
|
if authinfo.ipboard_username and 'services.modules.ipboard' not in installed_apps:
|
|
raise DatalossException('ipboard_username', 'services.modules.ipboard')
|
|
if authinfo.ips4_id and 'services.modules.ips4' not in installed_apps:
|
|
raise DatalossException('ips4_id', 'services.modules.ips4')
|
|
if authinfo.market_username and 'services.modules.market' not in installed_apps:
|
|
raise DatalossException('market_username', 'services.modules.market')
|
|
if authinfo.jabber_username and 'services.modules.openfire' not in installed_apps:
|
|
raise DatalossException('jabber_username', 'services.modules.openfire')
|
|
if authinfo.smf_username and 'services.modules.smf' not in installed_apps:
|
|
raise DatalossException('smf_username', 'services.modules.smf')
|
|
if authinfo.teamspeak3_uid and 'services.modules.teamspeak3' not in installed_apps:
|
|
raise DatalossException('teamspeak3_uid', 'services.modules.teamspeak3')
|
|
if authinfo.mumble_username and 'services.modules.mumble' not in installed_apps:
|
|
raise DatalossException('mumble_username', 'services.modules.mumble')
|
|
if authinfo.forum_username and 'services.modules.phpbb3' not in installed_apps:
|
|
raise DatalossException('forum_username', 'services.modules.phpbb3')
|
|
|
|
|
|
def forward(apps, schema_editor):
|
|
installed_apps = settings.INSTALLED_APPS
|
|
AuthServicesInfo = apps.get_model("authentication", "AuthServicesInfo")
|
|
|
|
# Check if any records would result in dataloss
|
|
check_for_dataloss(AuthServicesInfo.objects.all())
|
|
|
|
XenforoUser = apps.get_model('xenforo', 'XenforoUser') if 'services.modules.xenforo' in installed_apps else None
|
|
DiscordUser = apps.get_model('discord', 'DiscordUser') if 'services.modules.discord' in installed_apps else None
|
|
DiscourseUser = apps.get_model('discourse', 'DiscourseUser') if 'services.modules.discourse' in installed_apps else None
|
|
IpboardUser = apps.get_model('ipboard', 'IpboardUser') if 'services.modules.ipboard' in installed_apps else None
|
|
Ips4User = apps.get_model('ips4', 'Ips4User') if 'services.modules.ips4' in installed_apps else None
|
|
MarketUser = apps.get_model('market', 'MarketUser') if 'services.modules.market' in installed_apps else None
|
|
OpenfireUser = apps.get_model('openfire', 'OpenfireUser') if 'services.modules.openfire' in installed_apps else None
|
|
SmfUser = apps.get_model('smf', 'SmfUser') if 'services.modules.smf' in installed_apps else None
|
|
Teamspeak3User = apps.get_model('teamspeak3', 'Teamspeak3User') if 'services.modules.teamspeak3' in installed_apps else None
|
|
MumbleUser = apps.get_model('mumble', 'MumbleUser') if 'services.modules.mumble' in installed_apps else None
|
|
Phpbb3User = apps.get_model('phpbb3', 'Phpbb3User') if 'services.modules.phpbb3' in installed_apps else None
|
|
|
|
for authinfo in AuthServicesInfo.objects.all():
|
|
user = authinfo.user
|
|
|
|
if XenforoUser is not None and authinfo.xenforo_username:
|
|
logging.debug('Updating Xenforo info for %s' % user.username)
|
|
xfu = XenforoUser()
|
|
xfu.user = user
|
|
xfu.username = authinfo.xenforo_username
|
|
xfu.save()
|
|
|
|
if DiscordUser is not None and authinfo.discord_uid:
|
|
logging.debug('Updating Discord info for %s' % user.username)
|
|
du = DiscordUser()
|
|
du.user = user
|
|
du.uid = authinfo.discord_uid
|
|
du.save()
|
|
|
|
if DiscourseUser is not None and authinfo.discourse_enabled:
|
|
logging.debug('Updating Discourse info for %s' % user.username)
|
|
du = DiscourseUser()
|
|
du.user = user
|
|
du.enabled = authinfo.discourse_enabled
|
|
du.save()
|
|
|
|
if IpboardUser is not None and authinfo.ipboard_username:
|
|
logging.debug('Updating IPBoard info for %s' % user.username)
|
|
ipb = IpboardUser()
|
|
ipb.user = user
|
|
ipb.username = authinfo.ipboard_username
|
|
ipb.save()
|
|
|
|
if Ips4User is not None and authinfo.ips4_id:
|
|
logging.debug('Updating Ips4 info for %s' % user.username)
|
|
ips = Ips4User()
|
|
ips.user = user
|
|
ips.id = authinfo.ips4_id
|
|
ips.username = authinfo.ips4_username
|
|
ips.save()
|
|
|
|
if MarketUser is not None and authinfo.market_username:
|
|
logging.debug('Updating Market info for %s' % user.username)
|
|
mkt = MarketUser()
|
|
mkt.user = user
|
|
mkt.username = authinfo.market_username
|
|
mkt.save()
|
|
|
|
if OpenfireUser is not None and authinfo.jabber_username:
|
|
logging.debug('Updating Openfire (jabber) info for %s' % user.username)
|
|
ofu = OpenfireUser()
|
|
ofu.user = user
|
|
ofu.username = authinfo.jabber_username
|
|
ofu.save()
|
|
|
|
if SmfUser is not None and authinfo.smf_username:
|
|
logging.debug('Updating SMF info for %s' % user.username)
|
|
smf = SmfUser()
|
|
smf.user = user
|
|
smf.username = authinfo.smf_username
|
|
smf.save()
|
|
|
|
if Teamspeak3User is not None and authinfo.teamspeak3_uid:
|
|
logging.debug('Updating Teamspeak3 info for %s' % user.username)
|
|
ts3 = Teamspeak3User()
|
|
ts3.user = user
|
|
ts3.uid = authinfo.teamspeak3_uid
|
|
ts3.perm_key = authinfo.teamspeak3_perm_key
|
|
ts3.save()
|
|
|
|
if MumbleUser is not None and authinfo.mumble_username:
|
|
logging.debug('Updating mumble info for %s' % user.username)
|
|
try:
|
|
mbl = MumbleUser.objects.get(username=authinfo.mumble_username)
|
|
mbl.user = user
|
|
mbl.save()
|
|
except ObjectDoesNotExist:
|
|
logger.warn('AuthServiceInfo mumble_username for {} but no '
|
|
'corresponding record in MumbleUser, dropping'.format(user.username))
|
|
|
|
if Phpbb3User is not None and authinfo.forum_username:
|
|
logging.debug('Updating phpbb3 info for %s' % user.username)
|
|
phb = Phpbb3User()
|
|
phb.user = user
|
|
phb.username = authinfo.forum_username
|
|
phb.save()
|
|
|
|
|
|
def reverse(apps, schema_editor):
|
|
User = apps.get_model('auth', 'User')
|
|
AuthServicesInfo = apps.get_model("authentication", "AuthServicesInfo")
|
|
|
|
for user in User.objects.all():
|
|
authinfo, c = AuthServicesInfo.objects.get_or_create(user=user)
|
|
|
|
if hasattr(user, 'xenforo'):
|
|
logging.debug('Reversing xenforo for %s' % user.username)
|
|
authinfo.xenforo_username = user.xenforo.username
|
|
|
|
if hasattr(user, 'discord'):
|
|
logging.debug('Reversing discord for %s' % user.username)
|
|
authinfo.discord_uid = user.discord.uid
|
|
|
|
if hasattr(user, 'discourse'):
|
|
logging.debug('Reversing discourse for %s' % user.username)
|
|
authinfo.discourse_enabled = user.discourse.enabled
|
|
|
|
if hasattr(user, 'ipboard'):
|
|
logging.debug('Reversing ipboard for %s' % user.username)
|
|
authinfo.ipboard_username = user.ipboard.username
|
|
|
|
if hasattr(user, 'ips4'):
|
|
logging.debug('Reversing ips4 for %s' % user.username)
|
|
authinfo.ips4_id = user.ips4.id
|
|
authinfo.ips4_username = user.ips4.username
|
|
|
|
if hasattr(user, 'market'):
|
|
logging.debug('Reversing market for %s' % user.username)
|
|
authinfo.market_username = user.market.username
|
|
|
|
if hasattr(user, 'openfire'):
|
|
logging.debug('Reversing openfire (jabber) for %s' % user.username)
|
|
authinfo.jabber_username = user.openfire.username
|
|
|
|
if hasattr(user, 'smf'):
|
|
logging.debug('Reversing smf for %s' % user.username)
|
|
authinfo.smf_username = user.smf.username
|
|
|
|
if hasattr(user, 'teamspeak3'):
|
|
logging.debug('Reversing teamspeak3 for %s' % user.username)
|
|
authinfo.teamspeak3_uid = user.teamspeak3.uid
|
|
authinfo.teamspeak3_perm_key = user.teamspeak3.perm_key
|
|
|
|
if hasattr(user, 'mumble'):
|
|
logging.debug('Reversing mumble for %s' % user.username)
|
|
try:
|
|
authinfo.mumble_username = user.mumble.all()[:1].get().username
|
|
except ObjectDoesNotExist:
|
|
logging.debug('Failed to reverse mumble for %s' % user.username)
|
|
|
|
if hasattr(user, 'phpbb3'):
|
|
logging.debug('Reversing phpbb3 for %s' % user.username)
|
|
authinfo.forum_username = user.phpbb3.username
|
|
|
|
logging.debug('Saving AuthServicesInfo for %s ' % user.username)
|
|
authinfo.save()
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = optional_dependencies() + [
|
|
('authentication', '0012_remove_add_delete_authservicesinfo_permissions'),
|
|
]
|
|
|
|
operations = [
|
|
# Migrate data
|
|
migrations.RunPython(forward, reverse),
|
|
# Remove fields
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='discord_uid',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='discourse_enabled',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='forum_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='ipboard_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='ips4_id',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='ips4_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='jabber_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='market_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='mumble_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='smf_username',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='teamspeak3_perm_key',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='teamspeak3_uid',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='authservicesinfo',
|
|
name='xenforo_username',
|
|
),
|
|
]
|