From fcad034b738915269acfceca0203fc48517b2230 Mon Sep 17 00:00:00 2001 From: Tanner Prestegard <tanner.prestegard@ligo.org> Date: Tue, 24 Apr 2018 14:27:58 -0500 Subject: [PATCH] migration to deactivate old gracedb processor accounts and add a new EM follow-up account --- .../0005_update_emfollow_accounts.py | 96 +++++++++++++++++++ .../auth/0015_update_emfollow_accounts.py | 58 +++++++++++ .../guardian/0003_update_emfollow_accounts.py | 81 ++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 gracedb/ligoauth/migrations/0005_update_emfollow_accounts.py create mode 100644 gracedb/migrations/auth/0015_update_emfollow_accounts.py create mode 100644 gracedb/migrations/guardian/0003_update_emfollow_accounts.py diff --git a/gracedb/ligoauth/migrations/0005_update_emfollow_accounts.py b/gracedb/ligoauth/migrations/0005_update_emfollow_accounts.py new file mode 100644 index 000000000..8382f725e --- /dev/null +++ b/gracedb/ligoauth/migrations/0005_update_emfollow_accounts.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2018-04-24 16:12 +# +# This migration adds a new "emfollow" user which will be used for +# EM follow-up activities. The old EM follow-up accounts will be deactivated +# and their X509Certs will be deleted. + +from __future__ import unicode_literals + +from django.db import migrations +from django.conf import settings + +OLD_ACCOUNTS = { + 'gdb-processor': { + 'email': 'gdb_processor@gravity.phys.uwm.edu', + 'last_name': 'GDB Processor', + 'certs': [ + '/DC=org/DC=ligo/O=LIGO/OU=Services/CN=gdb_processor/pcdev2.phys.uwm.edu', + '/DC=org/DC=ligo/O=LIGO/OU=Services/CN=gdb-processor/marlin.phys.uwm.edu', + ], + }, + 'gracedb.processor': { + 'email': 'alexander.urban@ligo.org', + 'last_name': 'GraceDB Processor', + 'certs': [ + '/DC=org/DC=ligo/O=LIGO/OU=Services/CN=gracedb.processor/ldas-grid.ligo.caltech.edu', + '/DC=org/DC=ligo/O=LIGO/OU=Services/CN=gracedb.processor/emfollow.ligo.caltech.edu', + ], + }, +} + +NEW_ACCOUNT = { + 'username': 'emfollow', + 'last_name': 'LIGO/Virgo EM Follow-Up', + 'email': 'leo.singer@ligo.org', +} + +NEW_CERTS = [ + '/DC=org/DC=ligo/O=LIGO/OU=Services/CN=emfollow/emfollow.ligo.caltech.edu' +] + +def deactivate_old_and_add_new_accounts(apps, schema_editor): + LocalUser = apps.get_model('ligoauth', 'LocalUser') + X509Cert = apps.get_model('ligoauth', 'X509Cert') + Group = apps.get_model('auth', 'Group') + + # Mark old users as inactive and delete their certificates + for username in OLD_ACCOUNTS.keys(): + user = LocalUser.objects.get(username=username) + for subject in OLD_ACCOUNTS[username]['certs']: + cert = user.x509cert_set.get(subject=subject) + cert.delete() + user.is_active = False + user.save() + + # Create new EM follow-up user + new_user = LocalUser.objects.create(**NEW_ACCOUNT) + + # Create and add certificate for new account + for subject in NEW_CERTS: + new_user.x509cert_set.create(subject=subject) + + # Add user to LVC group + group = Group.objects.get(name=settings.LVC_GROUP) + group.user_set.add(new_user) + +def activate_old_and_remove_new_accounts(apps, schema_editor): + LocalUser = apps.get_model('ligoauth', 'LocalUser') + X509Cert = apps.get_model('ligoauth', 'X509Cert') + + # Activate old accounts and add their X509 certificates + for username in OLD_ACCOUNTS.keys(): + user = LocalUser.objects.get(username=username) + for subject in OLD_ACCOUNTS[username]['certs']: + cert = user.x509cert_set.create(subject=subject) + user.is_active = True + user.save() + + # Delete new EM follow-up user and certs + new_user = LocalUser.objects.get(username=NEW_ACCOUNT['username']) + for subject in NEW_CERTS: + cert = new_user.x509cert_set.get(subject=subject) + cert.delete() + new_user.delete() + + # Create and add certificate for new account +class Migration(migrations.Migration): + + dependencies = [ + ('ligoauth', '0004_update_gstlal_spiir_account'), + ] + + operations = [ + migrations.RunPython(deactivate_old_and_add_new_accounts, + activate_old_and_remove_new_accounts), + ] diff --git a/gracedb/migrations/auth/0015_update_emfollow_accounts.py b/gracedb/migrations/auth/0015_update_emfollow_accounts.py new file mode 100644 index 000000000..6da3934da --- /dev/null +++ b/gracedb/migrations/auth/0015_update_emfollow_accounts.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-11-02 19:26 +from __future__ import unicode_literals + +from django.db import migrations + +# Gives users table-level permissions which allows the addition and deletion +# of row-level permissions (again, used for exposing/hiding events). + +# List of usernames +OLD_USER = 'gracedb.processor' +NEW_USER = 'emfollow' + +# List of permission codenames +PERMS = [ + 'add_groupobjectpermission', + 'delete_groupobjectpermission', +] + +def add_perms(apps, schema_editor): + User = apps.get_model('auth', 'User') + Permission = apps.get_model('auth', 'Permission') + + # Get users + old_user = User.objects.get(username=OLD_USER) + new_user = User.objects.get(username=NEW_USER) + + # Add/remove perms + for perm in PERMS: + perm = Permission.objects.get(codename=perm) + old_user.user_permissions.remove(perm) + new_user.user_permissions.add(perm) + + +def remove_perms(apps, schema_editor): + User = apps.get_model('auth', 'User') + Permission = apps.get_model('auth', 'Permission') + + # Get users + old_user = User.objects.get(username=OLD_USER) + new_user = User.objects.get(username=NEW_USER) + + # Add/remove perms + for perm in PERMS: + perm = Permission.objects.get(codename=perm) + old_user.user_permissions.add(perm) + new_user.user_permissions.remove(perm) + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0014_add_user_permissions_on_groupobjectpermissions'), + ('ligoauth', '0005_update_emfollow_accounts'), + ] + + operations = [ + migrations.RunPython(add_perms, remove_perms) + ] diff --git a/gracedb/migrations/guardian/0003_update_emfollow_accounts.py b/gracedb/migrations/guardian/0003_update_emfollow_accounts.py new file mode 100644 index 000000000..3f799dbfb --- /dev/null +++ b/gracedb/migrations/guardian/0003_update_emfollow_accounts.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2018-04-25 01:51 +from __future__ import unicode_literals + +from django.db import migrations + +OLD_ACCOUNTS = { + 'gdb-processor': ['CWB', 'Fermi', 'gstlal', 'HardwareInjection', 'SNEWS', + 'Swift'], + 'gracedb.processor': ['CWB2G', 'Fermi', 'gstlal', 'SNEWS', 'Swift'], +} + +NEW_ACCOUNT_USERNAME = 'emfollow' +NEW_ACCOUNT_PIPELINES = list(set([item for items in OLD_ACCOUNTS.values() for + item in items])) + + +def update_perms(apps, schema_editor): + LocalUser = apps.get_model('ligoauth', 'LocalUser') + UserObjectPermission = apps.get_model('guardian', 'UserObjectPermission') + Pipeline = apps.get_model('events', 'Pipeline') + Permission = apps.get_model('auth', 'Permission') + ContentType = apps.get_model('contenttypes', 'ContentType') + + perm = Permission.objects.get(codename='populate_pipeline') + ctype = ContentType.objects.get_for_model(Pipeline) + + # Remove UOPs from old accounts which allow pipeline population + for username, pipelines in OLD_ACCOUNTS.iteritems(): + user = LocalUser.objects.get(username=username) + for pipeline_name in pipelines: + pipeline = Pipeline.objects.get(name=pipeline_name) + uop = UserObjectPermission.objects.get(user=user, + permission=perm, content_type=ctype, object_pk=pipeline.id) + uop.delete() + + # Add these UOPs to new acccount + user = LocalUser.objects.get(username=NEW_ACCOUNT_USERNAME) + for pipeline_name in NEW_ACCOUNT_PIPELINES: + pipeline = Pipeline.objects.get(name=pipeline_name) + uop = UserObjectPermission.objects.create(user=user, permission=perm, + content_type=ctype, object_pk = pipeline.id) + + +def revert_perms(apps, schema_editor): + LocalUser = apps.get_model('ligoauth', 'LocalUser') + UserObjectPermission = apps.get_model('guardian', 'UserObjectPermission') + Pipeline = apps.get_model('events', 'Pipeline') + Permission = apps.get_model('auth', 'Permission') + ContentType = apps.get_model('contenttypes', 'ContentType') + + perm = Permission.objects.get(codename='populate_pipeline') + ctype = ContentType.objects.get_for_model(Pipeline) + + # Re-add UOPs to old accounts which allow pipeline population + for username, pipelines in OLD_ACCOUNTS.iteritems(): + user = LocalUser.objects.get(username=username) + for pipeline_name in pipelines: + pipeline = Pipeline.objects.get(name=pipeline_name) + uop = UserObjectPermission.objects.create(user=user, + permission=perm, content_type=ctype, object_pk = pipeline.id) + + # Remove these UOPs from new acccount + user = LocalUser.objects.get(username=NEW_ACCOUNT_USERNAME) + for pipeline_name in NEW_ACCOUNT_PIPELINES: + pipeline = Pipeline.objects.get(name=pipeline_name) + uop = UserObjectPermission.objects.get(user=user, permission=perm, + content_type=ctype, object_pk = pipeline.id) + uop.delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('guardian', '0002_authorize_users_to_populate_pipelines'), + ('ligoauth', '0005_update_emfollow_accounts'), + ] + + operations = [ + migrations.RunPython(update_perms, revert_perms), + ] -- GitLab