From da18097faaa51a6eb210622b7f063edefac6a0ed Mon Sep 17 00:00:00 2001 From: Brian Moe <brian.moe@ligo.org> Date: Mon, 10 Jun 2013 16:41:01 -0500 Subject: [PATCH] Updated LIGO auth. Remove LigoUser model. --- gracedb/admin.py | 7 +- gracedb/api.py | 6 +- gracedb/feeds.py | 2 +- gracedb/forms.py | 8 +- gracedb/middleware/auth.py | 246 +++++++++--------- gracedb/migrations/0004_populate_tags.py | 106 ++++++++ ...tage1_rm_ligouser__add_new_foreign_keys.py | 199 ++++++++++++++ ..._rm_ligouser__populate_new_foreign_keys.py | 234 +++++++++++++++++ ...e3_rm_ligouser__remove_old_foreign_keys.py | 192 ++++++++++++++ gracedb/migrations/0008_auto__del_user.py | 158 +++++++++++ gracedb/models.py | 32 +-- gracedb/views.py | 45 ++-- ligoauth/__init__.py | 0 ligoauth/admin.py | 15 ++ ligoauth/fixtures/initial.json | 30 +++ ligoauth/management/__init__.py | 0 ligoauth/management/commands/__init__.py | 0 .../commands/refresh_users_from_ldap.py | 72 +++++ ligoauth/middleware/__init__.py | 0 ligoauth/middleware/auth.py | 128 +++++++++ ligoauth/migrations/0001_initial.py | 107 ++++++++ .../migrations/0002_remove_old_auth_users.py | 70 +++++ .../migrations/0003_utf8ify_user_tables.py | 80 ++++++ ligoauth/migrations/0004_add_localusers.py | 197 ++++++++++++++ ligoauth/migrations/0005_add_ldapusers.py | 148 +++++++++++ ligoauth/migrations/__init__.py | 0 ligoauth/models.py | 88 +++++++ ligoauth/tests.py | 16 ++ ligoauth/views.py | 1 + settings/default.py | 17 +- settings/development.py | 2 +- templates/admin/base_site.html | 3 +- templates/base.html | 6 +- templates/forbidden.html | 11 + templates/gracedb/create.html | 2 +- templates/gracedb/event_detail.html | 4 +- templates/rest_framework/api.html | 2 +- userprofile/migrations/0001_initial.py | 123 +++++++++ ...stage1_rm_ligouser__add_new_foreign_key.py | 109 ++++++++ ...2_rm_ligouser__populate_new_foreign_key.py | 152 +++++++++++ ...e3_rm_ligouser__remove_old_foreign_keys.py | 68 +++++ userprofile/migrations/__init__.py | 0 userprofile/models.py | 6 +- userprofile/views.py | 16 +- 44 files changed, 2514 insertions(+), 194 deletions(-) create mode 100644 gracedb/migrations/0005_stage1_rm_ligouser__add_new_foreign_keys.py create mode 100644 gracedb/migrations/0006_stage2_rm_ligouser__populate_new_foreign_keys.py create mode 100644 gracedb/migrations/0007_stage3_rm_ligouser__remove_old_foreign_keys.py create mode 100644 gracedb/migrations/0008_auto__del_user.py create mode 100644 ligoauth/__init__.py create mode 100644 ligoauth/admin.py create mode 100644 ligoauth/fixtures/initial.json create mode 100644 ligoauth/management/__init__.py create mode 100644 ligoauth/management/commands/__init__.py create mode 100644 ligoauth/management/commands/refresh_users_from_ldap.py create mode 100644 ligoauth/middleware/__init__.py create mode 100644 ligoauth/middleware/auth.py create mode 100644 ligoauth/migrations/0001_initial.py create mode 100644 ligoauth/migrations/0002_remove_old_auth_users.py create mode 100644 ligoauth/migrations/0003_utf8ify_user_tables.py create mode 100644 ligoauth/migrations/0004_add_localusers.py create mode 100644 ligoauth/migrations/0005_add_ldapusers.py create mode 100644 ligoauth/migrations/__init__.py create mode 100644 ligoauth/models.py create mode 100644 ligoauth/tests.py create mode 100644 ligoauth/views.py create mode 100644 templates/forbidden.html create mode 100644 userprofile/migrations/0001_initial.py create mode 100644 userprofile/migrations/0002_stage1_rm_ligouser__add_new_foreign_key.py create mode 100644 userprofile/migrations/0003_stage2_rm_ligouser__populate_new_foreign_key.py create mode 100644 userprofile/migrations/0004_stage3_rm_ligouser__remove_old_foreign_keys.py create mode 100644 userprofile/migrations/__init__.py diff --git a/gracedb/admin.py b/gracedb/admin.py index 99754ff51..bc37adcea 100644 --- a/gracedb/admin.py +++ b/gracedb/admin.py @@ -1,5 +1,5 @@ -from models import Event, EventLog, User, Group +from models import Event, EventLog, Group from models import Label, Labelling, Tag from django.contrib import admin @@ -15,10 +15,6 @@ class EventAdmin(admin.ModelAdmin): list_display = [ graceid, 'group', analysis_type, 'submitter' ] search_fields = [ 'group__name', 'submitter__name' ] -class UserAdmin(admin.ModelAdmin): - list_display = [ 'name', 'dn' ] - search_fields = [ 'name' ] - class LabelAdmin(admin.ModelAdmin): list_display = [ 'name', 'defaultColor' ] @@ -36,7 +32,6 @@ class TagAdmin(admin.ModelAdmin): admin.site.register(Event, EventAdmin) admin.site.register(EventLog, EventLogAdmin) -admin.site.register(User, UserAdmin) admin.site.register(Group) admin.site.register(Label, LabelAdmin) admin.site.register(Labelling, LabellingAdmin) diff --git a/gracedb/api.py b/gracedb/api.py index f2722cb60..10dc622cc 100644 --- a/gracedb/api.py +++ b/gracedb/api.py @@ -154,7 +154,7 @@ def eventToDict(event, columns=None, request=None): rv = {} graceid = event.graceid() - rv['submitter'] = event.submitter.name + rv['submitter'] = event.submitter.username rv['created'] = event.created rv['group'] = event.group.name rv['graceid'] = graceid @@ -478,7 +478,7 @@ class EventNeighbors(APIView): def labelToDict(label, request=None): return { "name" : label.label.name, - "creator" : label.creator.name, + "creator" : label.creator.username, "created" : label.created, "self" : reverse("labels", args=[label.event.graceid(), label.label.name], @@ -545,7 +545,7 @@ def eventLogToDict(log, n=None, request=None): return { "comment" : log.comment, "created" : log.created, - "issuer" : log.issuer.name, + "issuer" : log.issuer.username, "self" : uri, "tags" : taglist_uri, } diff --git a/gracedb/feeds.py b/gracedb/feeds.py index fd6ca5a5c..807b67960 100644 --- a/gracedb/feeds.py +++ b/gracedb/feeds.py @@ -62,7 +62,7 @@ class EventFeed(Feed): return reverse(view, args=[obj.graceid()]) def item_author_name(self, obj): - return obj.submitter.name + return u"{0} {1}".format(obj.submitter.first_name, obj.submitter.last_name) def item_pubdate(self, obj): return obj.created diff --git a/gracedb/forms.py b/gracedb/forms.py index b9c905b5e..93448eb71 100644 --- a/gracedb/forms.py +++ b/gracedb/forms.py @@ -2,7 +2,8 @@ from django import forms from django.utils.safestring import mark_safe from django.utils.html import escape -from models import Event, User, Group, Label +from models import Event, Group, Label +from django.contrib.auth.models import User from query import parseQuery, ParseException @@ -46,8 +47,9 @@ class EventSearchForm(forms.Form): typeChoices= [("","")]+list(Event.ANALYSIS_TYPE_CHOICES) submitterIds = Event.objects.values_list('submitter',flat=True).distinct() - submitterList = User.objects.filter(id__in=submitterIds).order_by('name') - submitterChoices = [("","")]+ [ (u.id, u.name) for u in submitterList] + submitterList = User.objects.filter(id__in=submitterIds).order_by('last_name', 'first_name') + submitterChoices = [("","")]+ \ + [ (u.id, u"{0} {1}".format(u.first_name, u.last_name)) for u in submitterList] labelChoices = [ ("hi%d"%n,"bye%d"%n) for n in [1,2,3]] labelChoices = [ (label.id, label.name) for label in Label.objects.all() ] diff --git a/gracedb/middleware/auth.py b/gracedb/middleware/auth.py index 58dcd8e6e..ed0ee3385 100644 --- a/gracedb/middleware/auth.py +++ b/gracedb/middleware/auth.py @@ -1,123 +1,125 @@ - -from django.contrib.auth import authenticate - -from gracedb.models import User -from django.contrib.auth.models import User as DjangoUser - -import re -proxyPattern = re.compile(r'^(.*?)(/CN=\d+)*$') - -def nameFromPrincipal(principal): - name = principal.split('@')[0] - first, last = name.split('.') - return first[0].upper() + first[1:] + " " + last[0].upper() + last[1:] - -class LigoAuthMiddleware: - - def process_request(self, request): - - ligouser = None - user = None - principal = None - - queryResult = [] - if not request.user.is_anonymous(): - # Scott's middleware has set the user aready using shib. - # Let's add some more attributes. - principal = request.user.username - request.user.name = nameFromPrincipal(principal) - queryResult = User.objects.filter(principal=principal) - else: - # authenticate with certs - certdn = request.META.get('SSL_CLIENT_S_DN') - issuer = request.META.get('SSL_CLIENT_I_DN') - - if not certdn: - try: - # mod_python is a little off... - # SSL info is in request._req - # Need to try/except because _req is - # not defined in WSGI request. - certdn = request._req.ssl_var_lookup ('SSL_CLIENT_S_DN') - issuer = request._req.ssl_var_lookup ('SSL_CLIENT_I_DN') - pass - except: - pass - - if certdn and certdn.startswith(issuer): - # proxy. - # Proxies can be signed by proxies. - # Each level of "proxification" causes the subject - # to have a '/CN=[0-9]+ appended to the signers subject. - # These must be removed to discover the original identity's - # subject DN. - issuer = proxyPattern.match(issuer).group(1) - queryResult = User.objects.filter(dn=issuer) - elif certdn: - # cert in browser. - queryResult = User.objects.filter(dn=certdn) - - if queryResult: - ligouser = queryResult[0] - try: - user = DjangoUser.objects.get(username=ligouser.unixid) - except DjangoUser.DoesNotExist: - user = DjangoUser(username=ligouser.unixid, password="") - user.is_staff = False - user.is_superuser = False - user.save() - elif principal: - # There is no user ... what do we do? - # If auth was via cert... nothing, DNs need to be registered. - # If auth was via kerberos, we make sure it was a LIGO.ORG - # principal and make a new user and ligouser with no DN. - #assert (principal.split('@')[1] == 'LIGO.ORG') - ligouser = User(name = nameFromPrincipal(principal), - email = principal.lower(), - principal = principal, - dn = "NONE", - unixid = principal.split('@')[0]) - ligouser.save() - try: - user = DjangoUser.objects.get(username=ligouser.unixid) - except DjangoUser.DoesNotExist: - user = DjangoUser(username=ligouser.unixid, password="") - user.is_staff = False - user.is_superuser = False - user.save() - - request.user = authenticate(ssluser=user) - request.ligouser = ligouser - - # Http404 doesn't check for user == None, just hasattr(x,'user') - # Why does this matter? I forget, but it does. - if not request.user: del request.user - - return None - -# def process_view(self, request, view_func, view_args, view_kwargs): -# return None - -# def process_response(self, request, response): -# return None - -# def process_exception(self, request, exception): -# return None - -class LigoAuthBackend: - - supports_object_permissions = False - supports_anonymous_user = False - supports_inactive_user = False - - def authenticate(self, ssluser): - return ssluser - - def get_user(self, user_id): - try: - return DjangoUser.get(id=user_id) - except DjangoUser.UserDoesNotExist: - return None - +# +#from django.contrib.auth import authenticate +# +#from gracedb.models import User +#from django.contrib.auth.models import User as DjangoUser +# +#import re +#proxyPattern = re.compile(r'^(.*?)(/CN=\d+)*$') +# +#def nameFromPrincipal(principal): +# name = principal.split('@')[0] +# first, last = name.split('.') +# return first[0].upper() + first[1:] + " " + last[0].upper() + last[1:] +# +#class LigoAuthMiddleware: +# +# def process_request(self, request): +# +# ligouser = None +# user = None +# principal = None +# +# queryResult = [] +# if not request.user.is_anonymous(): +# # Scott's middleware has set the user aready using shib. +# # Let's add some more attributes. +# principal = request.user.username +# request.user.name = nameFromPrincipal(principal) +# queryResult = User.objects.filter(principal=principal) +# else: +# # authenticate with certs +# certdn = request.META.get('SSL_CLIENT_S_DN') +# issuer = request.META.get('SSL_CLIENT_I_DN') +# +# if not certdn: +# try: +# # mod_python is a little off... +# # SSL info is in request._req +# # Need to try/except because _req is +# # not defined in WSGI request. +# certdn = request._req.ssl_var_lookup ('SSL_CLIENT_S_DN') +# issuer = request._req.ssl_var_lookup ('SSL_CLIENT_I_DN') +# pass +# except: +# pass +# +# if certdn and certdn.startswith(issuer): +# # proxy. +# # Proxies can be signed by proxies. +# # Each level of "proxification" causes the subject +# # to have a '/CN=[0-9]+ appended to the signers subject. +# # These must be removed to discover the original identity's +# # subject DN. +# issuer = proxyPattern.match(issuer).group(1) +# queryResult = User.objects.filter(dn=issuer) +# elif certdn: +# # cert in browser. +# queryResult = User.objects.filter(dn=certdn) +# +# if queryResult: +# ligouser = queryResult[0] +# try: +# user = DjangoUser.objects.get(username=ligouser.unixid) +# except DjangoUser.DoesNotExist: +# user = DjangoUser(username=ligouser.unixid, password="") +# user.is_staff = False +# user.is_superuser = False +# user.save() +# elif principal: +# # There is no user ... what do we do? +# # If auth was via cert... nothing, DNs need to be registered. +# # If auth was via kerberos, we make sure it was a LIGO.ORG +# # principal and make a new user and ligouser with no DN. +# #assert (principal.split('@')[1] == 'LIGO.ORG') +# ligouser = User(name = nameFromPrincipal(principal), +# email = principal.lower(), +# principal = principal, +# dn = "NONE", +# unixid = principal.split('@')[0]) +# ligouser.save() +# try: +# user = DjangoUser.objects.get(username=ligouser.unixid) +# except DjangoUser.DoesNotExist: +# user = DjangoUser(username=ligouser.unixid, password="") +# user.is_staff = False +# user.is_superuser = False +# user.save() +# +# request.user = authenticate(ssluser=user) +# request.ligouser = ligouser +# +# # Http404 doesn't check for user == None, just hasattr(x,'user') +# # Why does this matter? I forget, but it does. +# if not request.user: del request.user +# +# return None +# +## def process_view(self, request, view_func, view_args, view_kwargs): +## return None +# +## def process_response(self, request, response): +## return None +# +## def process_exception(self, request, exception): +## return None +# +#class LigoAuthBackend: +# +# supports_object_permissions = False +# supports_anonymous_user = False +# supports_inactive_user = False +# +# def authenticate(self, ssluser): +# return ssluser +# +# def get_user(self, user_id): +# try: +# return DjangoUser.get(id=user_id) +# except DjangoUser.UserDoesNotExist: +# return None +# def LigoAuthContext(request): - return { 'ligouser' : request.ligouser, 'user' : request.user } + #return { 'ligouser' : request.ligouser, 'user' : request.user } + return { 'user' : request.user } + return { 'ligouser' : request.user, 'user' : request.user } diff --git a/gracedb/migrations/0004_populate_tags.py b/gracedb/migrations/0004_populate_tags.py index 3a52a1691..5136a8725 100644 --- a/gracedb/migrations/0004_populate_tags.py +++ b/gracedb/migrations/0004_populate_tags.py @@ -12,3 +12,109 @@ class Migration(DataMigration): complete_apps = ['gracedb'] symmetrical = True + + models = { + 'gracedb.approval': { + 'Meta': {'object_name': 'Approval'}, + 'approvedEvent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'approvingCollaboration': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'gracedb.coincinspiralevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'CoincInspiralEvent', '_ormbases': ['gracedb.Event']}, + 'combined_far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'end_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'end_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'mass': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'mchirp': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'minimum_duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}) + }, + 'gracedb.event': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Event'}, + 'analysisType': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'gpstime': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instruments': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'through': "orm['gracedb.Labelling']", 'symmetrical': 'False'}), + 'likelihood': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'nevents': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'uid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}) + }, + 'gracedb.eventlog': { + 'Meta': {'ordering': "['-created']", 'object_name': 'EventLog'}, + 'comment': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'filename': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + }, + 'gracedb.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'managers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.User']", 'symmetrical': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.labelling': { + 'Meta': {'object_name': 'Labelling'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Label']"}) + }, + 'gracedb.multiburstevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'MultiBurstEvent', '_ormbases': ['gracedb.Event']}, + 'amplitude': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'bandwidth': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'central_freq': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'confidence': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'ligo_angle': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_angle_sig': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_dec': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_ra': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'peak_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'peak_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'start_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'start_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}) + }, + 'gracedb.tag': { + 'Meta': {'object_name': 'Tag'}, + 'displayName': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'eventlogs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.EventLog']", 'symmetrical': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + } + } + + complete_apps = ['gracedb'] diff --git a/gracedb/migrations/0005_stage1_rm_ligouser__add_new_foreign_keys.py b/gracedb/migrations/0005_stage1_rm_ligouser__add_new_foreign_keys.py new file mode 100644 index 000000000..d521509d9 --- /dev/null +++ b/gracedb/migrations/0005_stage1_rm_ligouser__add_new_foreign_keys.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Removing M2M table for field managers on 'Group' + db.delete_table('gracedb_group_managers') + + # Adding field 'Event.new_submitter' + db.add_column('gracedb_event', 'new_submitter', + self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['auth.User']), + keep_default=False) + + # Adding field 'Labelling.new_creator' + db.add_column('gracedb_labelling', 'new_creator', + self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['auth.User']), + keep_default=False) + + # Adding field 'Approval.new_approver' + db.add_column('gracedb_approval', 'new_approver', + self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['auth.User']), + keep_default=False) + + # Adding field 'EventLog.new_issuer' + db.add_column('gracedb_eventlog', 'new_issuer', + self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['auth.User']), + keep_default=False) + + + def backwards(self, orm): + # Adding M2M table for field managers on 'Group' + db.create_table('gracedb_group_managers', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('group', models.ForeignKey(orm['gracedb.group'], null=False)), + ('user', models.ForeignKey(orm['gracedb.user'], null=False)) + )) + db.create_unique('gracedb_group_managers', ['group_id', 'user_id']) + + # Deleting field 'Event.new_submitter' + db.delete_column('gracedb_event', 'new_submitter_id') + + # Deleting field 'Labelling.new_creator' + db.delete_column('gracedb_labelling', 'new_creator_id') + + # Deleting field 'Approval.new_approver' + db.delete_column('gracedb_approval', 'new_approver_id') + + # Deleting field 'EventLog.new_issuer' + db.delete_column('gracedb_eventlog', 'new_issuer_id') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.approval': { + 'Meta': {'object_name': 'Approval'}, + 'approvedEvent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'approvingCollaboration': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'new_approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.coincinspiralevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'CoincInspiralEvent', '_ormbases': ['gracedb.Event']}, + 'combined_far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'end_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'end_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'mass': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'mchirp': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'minimum_duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}) + }, + 'gracedb.event': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Event'}, + 'analysisType': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'gpstime': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instruments': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'through': "orm['gracedb.Labelling']", 'symmetrical': 'False'}), + 'likelihood': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'nevents': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'new_submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'uid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}) + }, + 'gracedb.eventlog': { + 'Meta': {'ordering': "['-created']", 'object_name': 'EventLog'}, + 'comment': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'filename': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'new_issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.labelling': { + 'Meta': {'object_name': 'Labelling'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Label']"}), + 'new_creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.multiburstevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'MultiBurstEvent', '_ormbases': ['gracedb.Event']}, + 'amplitude': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'bandwidth': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'central_freq': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'confidence': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'ligo_angle': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_angle_sig': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_dec': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_ra': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'peak_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'peak_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'start_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'start_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}) + }, + 'gracedb.tag': { + 'Meta': {'object_name': 'Tag'}, + 'displayName': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'eventlogs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.EventLog']", 'symmetrical': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + } + } + + complete_apps = ['gracedb'] diff --git a/gracedb/migrations/0006_stage2_rm_ligouser__populate_new_foreign_keys.py b/gracedb/migrations/0006_stage2_rm_ligouser__populate_new_foreign_keys.py new file mode 100644 index 000000000..73200fa19 --- /dev/null +++ b/gracedb/migrations/0006_stage2_rm_ligouser__populate_new_foreign_keys.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +from south.v2 import DataMigration +import sys +import re + + +def get_auth_user_for_ligo_user_id(orm, userid): + + LigoUser = orm['gracedb.User'] + DjangoUser = orm['auth.User'] + + service_cert_pattern = re.compile(r'.*CN=([^/]+)/[^/]+') + + try: + ligo_user = LigoUser.objects.get(id=userid) + except LigoUser.DoesNotExist: + print("Can't find Ligo User {0}. (this should not happen)".format(userid)) + sys.exit(1) + + try: + return DjangoUser.objects.get(username=ligo_user.unixid).id + except DjangoUser.DoesNotExist: + pass + try: + return DjangoUser.objects.get(username=ligo_user.principal) + return DjangoUser.objects.get(username="{0}@LIGO.ORG".format(ligo_user.unixid)) + except DjangoUser.DoesNotExist: + pass + + if ligo_user.unixid.lower() == 'none' or ligo_user.principal.lower() == 'none': + # Some service user, likely. + name = service_cert_pattern.match(ligo_user.dn).group(1) + return DjangoUser.objects.get(username=name) + + print("Can't find Django user named '{0}'\nUnixid: {1}\nPrincipal: ({2})\nDN:({3})". + format(ligo_user.name, ligo_user.unixid, ligo_user.principal, ligo_user.dn)) + sys.exit(1) + + +def get_ligo_user_for_django_user_id(orm, django_id): + django_user = orm['auth.User'].objects.get(id=django_id) + return orm['gracedb.User'].objects.get(unixid=django_user.username) + + +class Migration(DataMigration): + + def forwards(self, orm): + Labelling = orm['gracedb.Labelling'].objects + Event = orm['gracedb.Event'].objects + EventLog = orm['gracedb.EventLog'].objects + Approval = orm['gracedb.Approval'].objects + + # Collect pk's of ligouser entries references by foreignkeys + ids = set() + ids.update(Labelling.values_list('creator_id', flat=True).distinct()) + ids.update(Event.values_list('submitter_id', flat=True).distinct()) + ids.update(EventLog.values_list('issuer_id', flat=True).distinct()) + ids.update(Approval.values_list('approver_id', flat=True).distinct()) + + # Update all ligouser foreign key references (ligo_id) + # to refer to djano users (django_id) + for ligo_id in ids: + django_id = get_auth_user_for_ligo_user_id(orm, ligo_id) + Labelling.filter(creator=ligo_id).update(new_creator=django_id) + Event.filter(submitter=ligo_id).update(new_submitter=django_id) + EventLog.filter(issuer=ligo_id).update(new_issuer=django_id) + Approval.filter(approver=ligo_id).update(new_approver=django_id) + + def backwards(self, orm): + Labelling = orm['gracedb.Labelling'].objects + Event = orm['gracedb.Event'].objects + EventLog = orm['gracedb.EventLog'].objects + Approval = orm['gracedb.Approval'].objects + + ids = set() + ids.update(Labelling.values_list('new_creator_id', flat=True).distinct()) + ids.update(Event.values_list('new_submitter_id', flat=True).distinct()) + ids.update(EventLog.values_list('new_issuer_id', flat=True).distinct()) + ids.update(Approval.values_list('new_approver_id', flat=True).distinct()) + + for django_id in ids: + ligo_id = get_ligo_user_for_django_user_id(orm, django_id) + Labelling.filter(new_creator=django_id).update(creator=ligo_id) + Event.filter(new_submitter=django_id).update(submitter=ligo_id) + EventLog.filter(new_issuer=django_id).update(issuer=ligo_id) + Approval.filter(new_approver=django_id).update(approver=ligo_id) + + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.approval': { + 'Meta': {'object_name': 'Approval'}, + 'approvedEvent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'approvingCollaboration': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'new_approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.coincinspiralevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'CoincInspiralEvent', '_ormbases': ['gracedb.Event']}, + 'combined_far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'end_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'end_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'mass': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'mchirp': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'minimum_duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}) + }, + 'gracedb.event': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Event'}, + 'analysisType': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'gpstime': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instruments': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'through': "orm['gracedb.Labelling']", 'symmetrical': 'False'}), + 'likelihood': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'nevents': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'new_submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'uid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}) + }, + 'gracedb.eventlog': { + 'Meta': {'ordering': "['-created']", 'object_name': 'EventLog'}, + 'comment': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'filename': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'new_issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.labelling': { + 'Meta': {'object_name': 'Labelling'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Label']"}), + 'new_creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.multiburstevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'MultiBurstEvent', '_ormbases': ['gracedb.Event']}, + 'amplitude': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'bandwidth': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'central_freq': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'confidence': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'ligo_angle': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_angle_sig': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_dec': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_ra': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'peak_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'peak_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'start_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'start_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}) + }, + 'gracedb.tag': { + 'Meta': {'object_name': 'Tag'}, + 'displayName': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'eventlogs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.EventLog']", 'symmetrical': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + } + } + + complete_apps = ['gracedb'] + symmetrical = True diff --git a/gracedb/migrations/0007_stage3_rm_ligouser__remove_old_foreign_keys.py b/gracedb/migrations/0007_stage3_rm_ligouser__remove_old_foreign_keys.py new file mode 100644 index 000000000..4abe2f201 --- /dev/null +++ b/gracedb/migrations/0007_stage3_rm_ligouser__remove_old_foreign_keys.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Remove old fields + db.delete_column('gracedb_event', 'submitter_id') + db.delete_column('gracedb_labelling', 'creator_id') + db.delete_column('gracedb_approval', 'approver_id') + db.delete_column('gracedb_eventlog', 'issuer_id') + + # + # Move new_* to * (and make them non-nullable) + # + db.rename_column('gracedb_event', 'new_submitter_id', 'submitter_id') + db.rename_column('gracedb_labelling', 'new_creator_id', 'creator_id') + db.rename_column('gracedb_approval', 'new_approver_id', 'approver_id') + db.rename_column('gracedb_eventlog', 'new_issuer_id', 'issuer_id') + + db.alter_column('gracedb_event', 'submitter_id', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'],null=False)) + db.alter_column('gracedb_labelling', 'creator_id', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'],null=False)) + db.alter_column('gracedb_approval', 'approver_id', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'],null=False)) + db.alter_column('gracedb_eventlog', 'issuer_id', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'],null=False)) + + def backwards(self, orm): + # Move * to new_* + db.rename_column('gracedb_event', 'submitter_id', 'new_submitter_id') + db.rename_column('gracedb_labelling', 'creator_id', 'new_creator_id') + db.rename_column('gracedb_approval', 'approver_id', 'new_approver_id') + db.rename_column('gracedb_eventlog', 'issuer_id', 'new_issuer_id') + + # Replace old fields + db.add_column('gracedb_event', 'submitter', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'], null=False, default=1), + keep_default=False) + db.add_column('gracedb_labelling', 'creator', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'], null=False, default=1), + keep_default=False) + db.add_column('gracedb_approval', 'approver', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'], null=False, default=1), + keep_default=False) + db.add_column('gracedb_eventlog', 'issuer', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'], null=False, default=1), + keep_default=False) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.approval': { + 'Meta': {'object_name': 'Approval'}, + 'approvedEvent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'approvingCollaboration': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'gracedb.coincinspiralevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'CoincInspiralEvent', '_ormbases': ['gracedb.Event']}, + 'combined_far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'end_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'end_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'mass': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'mchirp': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'minimum_duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}) + }, + 'gracedb.event': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Event'}, + 'analysisType': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'gpstime': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instruments': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'through': "orm['gracedb.Labelling']", 'symmetrical': 'False'}), + 'likelihood': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'nevents': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'uid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}) + }, + 'gracedb.eventlog': { + 'Meta': {'ordering': "['-created']", 'object_name': 'EventLog'}, + 'comment': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'filename': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.labelling': { + 'Meta': {'object_name': 'Labelling'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Label']"}) + }, + 'gracedb.multiburstevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'MultiBurstEvent', '_ormbases': ['gracedb.Event']}, + 'amplitude': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'bandwidth': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'central_freq': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'confidence': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'ligo_angle': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_angle_sig': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_dec': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_ra': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'peak_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'peak_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'start_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'start_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}) + }, + 'gracedb.tag': { + 'Meta': {'object_name': 'Tag'}, + 'displayName': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'eventlogs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.EventLog']", 'symmetrical': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + } + } + + complete_apps = ['gracedb'] diff --git a/gracedb/migrations/0008_auto__del_user.py b/gracedb/migrations/0008_auto__del_user.py new file mode 100644 index 000000000..697f18291 --- /dev/null +++ b/gracedb/migrations/0008_auto__del_user.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Deleting model 'User' + db.delete_table('gracedb_user') + + + def backwards(self, orm): + # Adding model 'User' + db.create_table('gracedb_user', ( + ('dn', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('unixid', self.gf('django.db.models.fields.CharField')(max_length=25)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('email', self.gf('django.db.models.fields.EmailField')(max_length=75)), + ('principal', self.gf('django.db.models.fields.CharField')(max_length=100)), + )) + db.send_create_signal('gracedb', ['User']) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.approval': { + 'Meta': {'object_name': 'Approval'}, + 'approvedEvent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'approver': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'approvingCollaboration': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'gracedb.coincinspiralevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'CoincInspiralEvent', '_ormbases': ['gracedb.Event']}, + 'combined_far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'end_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'end_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'mass': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'mchirp': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'minimum_duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}) + }, + 'gracedb.event': { + 'Meta': {'ordering': "['-id']", 'object_name': 'Event'}, + 'analysisType': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'far': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'gpstime': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'instruments': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'through': "orm['gracedb.Labelling']", 'symmetrical': 'False'}), + 'likelihood': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'nevents': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'submitter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'uid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}) + }, + 'gracedb.eventlog': { + 'Meta': {'ordering': "['-created']", 'object_name': 'EventLog'}, + 'comment': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'filename': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issuer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'gracedb.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '20'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.labelling': { + 'Meta': {'object_name': 'Labelling'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Event']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.Label']"}) + }, + 'gracedb.multiburstevent': { + 'Meta': {'ordering': "['-id']", 'object_name': 'MultiBurstEvent', '_ormbases': ['gracedb.Event']}, + 'amplitude': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'bandwidth': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'central_freq': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'confidence': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['gracedb.Event']", 'unique': 'True', 'primary_key': 'True'}), + 'false_alarm_rate': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ifos': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20'}), + 'ligo_angle': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_angle_sig': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_dec': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'ligo_axis_ra': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'peak_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'peak_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'snr': ('django.db.models.fields.FloatField', [], {'null': 'True'}), + 'start_time': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}), + 'start_time_ns': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}) + }, + 'gracedb.tag': { + 'Meta': {'object_name': 'Tag'}, + 'displayName': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'eventlogs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.EventLog']", 'symmetrical': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['gracedb'] \ No newline at end of file diff --git a/gracedb/models.py b/gracedb/models.py index e7c3afea9..7cceece02 100644 --- a/gracedb/models.py +++ b/gracedb/models.py @@ -3,6 +3,9 @@ from django.core.urlresolvers import reverse from model_utils.managers import InheritanceManager +from django.contrib.auth.models import User as DjangoUser + + import datetime import thread import string @@ -23,23 +26,22 @@ SERVER_TZ = pytz.timezone(settings.TIME_ZONE) # schema_version = "1.1" -class User(models.Model): - name = models.CharField(max_length=100) - email = models.EmailField() - principal = models.CharField(max_length=100) - dn = models.CharField(max_length=100) - unixid = models.CharField(max_length=25) +#class User(models.Model): + #name = models.CharField(max_length=100) + #email = models.EmailField() + #principal = models.CharField(max_length=100) + #dn = models.CharField(max_length=100) + #unixid = models.CharField(max_length=25) - class Meta: - ordering = ["name"] + #class Meta: + #ordering = ["name"] - def __unicode__(self): - return self.name + #def __unicode__(self): + #return self.name class Group(models.Model): name = models.CharField(max_length=20) - managers = models.ManyToManyField(User) def __unicode__(self): return self.name @@ -68,7 +70,7 @@ class Event(models.Model): ) DEFAULT_EVENT_NEIGHBORHOOD = (5,5) - submitter = models.ForeignKey(User) + submitter = models.ForeignKey(DjangoUser) created = models.DateTimeField(auto_now_add=True) group = models.ForeignKey(Group) uid = models.CharField(max_length=20, default="") # XXX deprecated. should be removed. @@ -197,7 +199,7 @@ class EventLog(models.Model): ordering = ["-created"] event = models.ForeignKey(Event, null=False) created = models.DateTimeField(auto_now_add=True) - issuer = models.ForeignKey(User) + issuer = models.ForeignKey(DjangoUser) filename = models.CharField(max_length=100, default="") comment = models.TextField(null=False) @@ -225,14 +227,14 @@ class EventLog(models.Model): class Labelling(models.Model): event = models.ForeignKey(Event) label = models.ForeignKey(Label) - creator = models.ForeignKey(User) + creator = models.ForeignKey(DjangoUser) created = models.DateTimeField(auto_now_add=True) # XXX Deprecated? Is this used *anywhere*? # Appears to only be used in models.py. Here and Event class as approval_set class Approval(models.Model): COLLABORATION_CHOICES = ( ('L','LIGO'), ('V','Virgo'), ) - approver = models.ForeignKey(User) + approver = models.ForeignKey(DjangoUser) created = models.DateTimeField(auto_now_add=True) approvedEvent = models.ForeignKey(Event, null=False) approvingCollaboration = models.CharField(max_length=1, choices=COLLABORATION_CHOICES) diff --git a/gracedb/views.py b/gracedb/views.py index b78030ca3..9dfbcf7c3 100644 --- a/gracedb/views.py +++ b/gracedb/views.py @@ -1,6 +1,7 @@ from django.http import HttpResponse from django.http import HttpResponseRedirect, HttpResponseNotFound, HttpResponseBadRequest, Http404 +from django.http import HttpResponseForbidden from django.template import RequestContext from django.core.urlresolvers import reverse, get_script_prefix from django.shortcuts import render_to_response, get_object_or_404 @@ -9,14 +10,17 @@ from django.utils.html import strip_tags, escape, urlize from django.utils.safestring import mark_safe from django.views.generic.list_detail import object_detail, object_list +from django.contrib.auth.decorators import login_required -from models import Event, Group, EventLog, Labelling, Label, User, Tag +from models import Event, Group, EventLog, Labelling, Label, Tag from models import CoincInspiralEvent from models import MultiBurstEvent from forms import CreateEventForm, EventSearchForm, SimpleSearchForm from alert import issueAlert, issueAlertForLabel, issueAlertForUpdate from translator import handle_uploaded_data +from django.contrib.auth.models import User + import urllib from utils.vfile import VersionedFile @@ -38,7 +42,7 @@ GRACEDB_DATA_DIR = settings.GRACEDB_DATA_DIR import json def index(request): -# assert request.ligouser +# assert request.user return render_to_response( 'gracedb/index.html', {}, @@ -46,7 +50,7 @@ def index(request): def skyalert_authorized(request): try: - return request.ligouser.name in settings.SKYALERT_SUBMITTERS + return u"{0} {1}".format(request.user.first_name, request.user.last_name) in settings.SKYALERT_SUBMITTERS except: return False @@ -120,7 +124,7 @@ def skyalert(request, graceid): request.session['flash_msg'] = flashmessage or message if createLogEntry: - logentry = EventLog(event=event, issuer=request.ligouser, comment=message) + logentry = EventLog(event=event, issuer=request.user, comment=message) logentry.save() return HttpResponseRedirect(reverse(view, args=[graceid])) @@ -156,7 +160,7 @@ def create(request): context_instance=RequestContext(request)) def _create(request): - assert request.ligouser + assert request.user rv = {} @@ -211,7 +215,7 @@ def _createEventFromForm(request, form): event = MultiBurstEvent() else: event = Event() - event.submitter = request.ligouser + event.submitter = request.user event.group = group[0] event.analysisType = atype # ARGH. We don't get a graceid until we save, @@ -290,7 +294,7 @@ def _createLog(request, graceid, comment, uploadedFile=None): rdict['error'] = "Missing argument(s)" else: logEntry = EventLog(event=event, - issuer=request.ligouser, + issuer=request.user, comment=comment) if uploadedFile: try: @@ -335,7 +339,7 @@ def upload(request): #event issuer comment # XXX Note: filename or comment oughta have a version log = EventLog(event=event, - issuer=request.ligouser, + issuer=request.user, filename=uploadedfile.name, comment=comment) try: @@ -411,7 +415,7 @@ def cli_label(request): labelName = request.POST.get('label') doxmpp = request.POST.get('alert') == "True" - d = create_label(graceid, labelName, request.ligouser, doXMPP=doxmpp) + d = create_label(graceid, labelName, request.user, doXMPP=doxmpp) msg = str(d) response = HttpResponse(mimetype='application/json') @@ -449,7 +453,7 @@ def logentry(request, graceid, num=None): raise Http404 if request.method == "POST": # create a log entry - elog = EventLog(event=event, issuer=request.ligouser) + elog = EventLog(event=event, issuer=request.user) elog.comment = request.POST.get('comment') or request.GET.get('comment') elog.save() tagname = request.POST.get('tagname') @@ -467,7 +471,7 @@ def logentry(request, graceid, num=None): num = elog.getN() msg = "Tagged message %s: %s " % (num, tagname) tlog = EventLog(event=event, - issuer=request.ligouser, + issuer=request.user, comment=msg) tlog.save() else: @@ -481,7 +485,7 @@ def logentry(request, graceid, num=None): rv = {} rv['comment'] = elog.comment - rv['issuer'] = elog.issuer.name + rv['issuer'] = elog.issuer.username rv['created'] = elog.created.isoformat() rv['comment'] = elog.comment if tagname: @@ -509,7 +513,7 @@ def log(request): msg = "ERROR: Event '%s' does not exist" % graceid else: #event issuer comment - log = EventLog(event=event, issuer=request.ligouser, comment=message) + log = EventLog(event=event, issuer=request.user, comment=message) try: log.save() msg = "OK" @@ -565,7 +569,7 @@ def view(request, graceid): context_instance=RequestContext(request)) def cli_search(request): - assert request.ligouser + assert request.user form = SimpleSearchForm(request.POST) if form.is_valid(): query = form.cleaned_data['query'] @@ -635,7 +639,8 @@ def assembleLigoLw(objects): def search(request, format=""): - assert request.ligouser + if not request.user or not request.user.is_authenticated(): + return HttpResponseForbidden("Forbidden") # XXX DO NOT HARDCODE THIS # Also, user should be notified if their result hits this limit. limit = MAX_QUERY_RESULTS @@ -734,7 +739,7 @@ def search(request, format=""): context_instance=RequestContext(request)) def oldsearch(request): - assert request.ligouser + assert request.user if request.method == 'GET': form = EventSearchForm() else: @@ -909,7 +914,7 @@ def flexigridResponse(request, objects): 'cell': [ '<a href="%s">%s</a>' % (reverse(view, args=[object.graceid()]), object.graceid()), #Labels - " ".join(["""<span onmouseover="tooltip.show(tooltiptext('%s', '%s', '%s'));" onmouseout="tooltip.hide();" style="color: %s"> %s </span>""" % (label.label.name, label.creator.name, label.created, label.label.defaultColor, label.label.name) + " ".join(["""<span onmouseover="tooltip.show(tooltiptext('%s', '%s', '%s'));" onmouseout="tooltip.hide();" style="color: %s"> %s </span>""" % (label.label.name, label.creator.username, label.created, label.label.defaultColor, label.label.name) for label in object.labelling_set.all()]), # Links to neighbors ', '.join([ @@ -932,7 +937,7 @@ def flexigridResponse(request, objects): #created_times['gps'], created_times.get('utc',""), - object.submitter.name, + "{0} {1}".format(object.submitter.first_name, object.submitter.last_name) ] } @@ -992,7 +997,7 @@ def latest(request): form = SimpleSearchForm(request.POST) template = 'gracedb/latest.html' - if not request.ligouser: + if not request.user or not request.user.is_authenticated(): limit = LimitedEvent template = 'gracedb/latest_public.html' else: @@ -1048,7 +1053,7 @@ def taglogentry(request, graceid, num, tagname): # Create a log entry to document the tag creation. msg = "Tagged message %s: %s " % (num, tagname) logentry = EventLog(event=event, - issuer=request.ligouser, + issuer=request.user, comment=msg) logentry.save() else: diff --git a/ligoauth/__init__.py b/ligoauth/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ligoauth/admin.py b/ligoauth/admin.py new file mode 100644 index 000000000..a1b1a5bf3 --- /dev/null +++ b/ligoauth/admin.py @@ -0,0 +1,15 @@ + +from django.contrib import admin +from models import LocalUser, LigoLdapUser, X509Cert + +class LigoLdapUserAdmin(admin.ModelAdmin): + list_display = ['username', 'first_name', 'last_name'] + search_fields = ['username'] + +class X509CertAdmin(admin.ModelAdmin): + list_display = ['subject'] + search_fields = ['subject'] + +admin.site.register(LocalUser) +admin.site.register(LigoLdapUser, LigoLdapUserAdmin) +admin.site.register(X509Cert, X509CertAdmin) diff --git a/ligoauth/fixtures/initial.json b/ligoauth/fixtures/initial.json new file mode 100644 index 000000000..050de1d29 --- /dev/null +++ b/ligoauth/fixtures/initial.json @@ -0,0 +1,30 @@ + +/C=IT/O=INFN/OU=Service/L=EGO/CN=MbtaAlert/lscgw.virgo.infn.it +/C=IT/O=INFN/OU=Service/L=EGO/CN=MbtaAlert/olnode04.virgo.infn.it +/C=IT/O=INFN/OU=Service/L=EGO/CN=MbtaAlert/olnode33.virgo.infn.it + +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-grid.ligo-la.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-grid.ligo-wa.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-grid.ligo.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev1.ligo-la.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev1.ligo-wa.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev1.ligo.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev2.ligo-la.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev2.ligo-wa.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev2.ligo.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev3.ligo.caltech.edu +/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev4.ligo.caltech.edu + +/DC=org/DC=doegrids/OU=Services/CN=excesspower-processor/marlin.phys.uwm.edu + +/DC=org/DC=doegrids/OU=Services/CN=gdb-processor/marlin.phys.uwm.edu + +/DC=org/DC=doegrids/OU=Services/CN=gis/lscgis.phys.uwm.edu + +/DC=org/DC=doegrids/OU=Services/CN=luminrobot/ldas-pcdev1.ligo.caltech.edu + +/DC=org/DC=doegrids/OU=Services/CN=omegarobot/node499.ldas-cit.ligo.caltech.edu + +/DC=org/DC=doegrids/OU=Services/CN=waveburst/ldas-pcdev1.ligo.caltech.edu + +/DC=org/DC=ligo/O=LIGO/OU=Services/CN=gstlalcbc/ldas-pcdev1.ligo.caltech.edu diff --git a/ligoauth/management/__init__.py b/ligoauth/management/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ligoauth/management/commands/__init__.py b/ligoauth/management/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ligoauth/management/commands/refresh_users_from_ldap.py b/ligoauth/management/commands/refresh_users_from_ldap.py new file mode 100644 index 000000000..4799e23ad --- /dev/null +++ b/ligoauth/management/commands/refresh_users_from_ldap.py @@ -0,0 +1,72 @@ + +from django.core.management.base import NoArgsCommand + +from ligoauth.models import LigoLdapUser, X509Cert + +import ldap + +baseDN = "ou=people,dc=ligo,dc=org" +searchScope = ldap.SCOPE_SUBTREE +searchFilter = "(employeeNumber=*)" +retrieveAttributes = ["krbPrincipalName", + "gridX509subject", + "givenName", + "sn", + "mail", + "isMemberOf"] + +class Command(NoArgsCommand): + help = "Update ligoauth.models.LigoUser and django.contrib.auth.models.User from LIGO LDAP" + + def handle_noargs(self, **options): + l = ldap.open("ldap.ligo.org") + l.protocol_version = ldap.VERSION3 + ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes) + while 1: + result_type, result_data = l.result(ldap_result_id, 0) + if (result_data == []): + break + else: + if result_type == ldap.RES_SEARCH_ENTRY: + for (ldap_dn, ldap_result) in result_data: + + first_name = unicode(ldap_result['givenName'][0], 'utf-8') + last_name = unicode(ldap_result['sn'][0], 'utf-8') + email = ldap_result['mail'][0] + new_dns = set(ldap_result.get('gridX509subject',[])) + is_active = "Communities:LVC:LVCGroupMembers" \ + in ldap_result.get('isMemberOf',[]) + principal = ldap_result['krbPrincipalName'][0] + + # Update/Create LigoLdapUser entry + user, created = LigoLdapUser.objects.get_or_create(ldap_dn=ldap_dn) + + changed = created \ + or (user.first_name != first_name) \ + or (user.last_name != last_name) \ + or (user.email != email) \ + or (user.username != principal) \ + or (user.is_active != is_active) + + if changed: + user.first_name = first_name + user.last_name = last_name + user.email = email + user.username = principal + user.is_active = is_active + # revoke staff/superuser if not active. + user.is_staff = user.is_staff and is_active + user.is_superuser = user.is_superuser and is_active + user.save() + + # update X509 certs for user + current_dns = set([ cert.subject for cert in user.x509cert_set.all() ]) + + if current_dns != new_dns: + for dn in current_dns - new_dns: + X509Cert.objects.get(subject=dn).delete() + for dn in new_dns - current_dns: + cert, created = X509Cert.objects.get_or_create(subject=dn) + if created: + cert.save() + cert.users.add(user) diff --git a/ligoauth/middleware/__init__.py b/ligoauth/middleware/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ligoauth/middleware/auth.py b/ligoauth/middleware/auth.py new file mode 100644 index 000000000..cf5ac5248 --- /dev/null +++ b/ligoauth/middleware/auth.py @@ -0,0 +1,128 @@ + +import re +from django.contrib.auth import authenticate +from django.contrib.auth.models import User, AnonymousUser +from django.contrib.auth.backends import RemoteUserBackend as DefaultRemoteUserBackend +from ligoauth.models import certdn_to_user + +from django.shortcuts import render_to_response +from django.template import RequestContext + +from django.http import HttpResponseForbidden + +proxyPattern = re.compile(r'^(.*?)(/CN=\d+)*$') + +def cert_dn_from_request(request): + """Take a request, rummage through SSL_* headers, return the DN for the user.""" + certdn = request.META.get('SSL_CLIENT_S_DN') + issuer = request.META.get('SSL_CLIENT_I_DN') + + if not certdn: + try: + # mod_python is a little off... + # SSL info is in request._req + # Need to try/except because _req is + # not defined in WSGI request. + certdn = request._req.ssl_var_lookup ('SSL_CLIENT_S_DN') + issuer = request._req.ssl_var_lookup ('SSL_CLIENT_I_DN') + pass + except: + pass + + if certdn and certdn.startswith(issuer): + # proxy. + # Proxies can be signed by proxies. + # Each level of "proxification" causes the subject + # to have a '/CN=[0-9]+ appended to the signers subject. + # These must be removed to discover the original identity's cert DN. + certdn = proxyPattern.match(issuer).group(1) + + return certdn + +class LigoAuthMiddleware: + """This is the ultimate gatekeeper for GraceDb auth/authz. + Ideally, Apache will do all authentication and the GraceDb + Django code will do authorization. That is for the future. + Today -- it all happens here.""" + + def process_request(self, request): + user = None + + # An authenticated LIGO user will have one of these set. + + remote_user = request.META.get('REMOTE_USER') + dn = cert_dn_from_request(request) + + if remote_user: + user = authenticate(principal=remote_user) + if not (user and user.is_authenticated()): + # XXX THIS SHOULD NEVER HAPPEN + pass + + if not user and dn: + user = authenticate(dn=dn) + + if user and user.is_active: + # Ideal, normal case. Yay! + pass + elif request.path.find('latest') > 0: + # We are on a "public" page. + # XXX Needs to be better refined. (dealt with elsewhere, in fact) + user = AnonymousUser() + elif user: + # Grotesque case. User authenticates, but is not active. + # How is this? Good credentials, but LDAP says you shouldn't + # have credentials? + user = None + else: + user = None + + request.user = user + + if user is None: + # Forbidden! + is_cli = request.POST.get('cli_version') or \ + request.GET.get('cli_version') + if is_cli: + message = "Your credentials are not valid." + return HttpResponseForbidden("{ 'error': '%s' }" % message) + return render_to_response( + 'forbidden.html', + {}, + context_instance=RequestContext(request)) + +class RemoteUserBackend(DefaultRemoteUserBackend): + create_unknown_user = False + +class LigoX509Backend: + + supports_object_permissions = False + supports_anonymous_user = False + supports_inactive_user = False + + def authenticate(self, dn, username=None): + return certdn_to_user(dn) + + def get_user(self, user_id): + try: + return User.objects.get(id=user_id) + except User.DoesNotExist: + return None + +class LigoShibBackend: + + supports_object_permissions = False + supports_anonymous_user = False + supports_inactive_user = False + + def authenticate(self, principal): + try: + return User.objects.get(username=principal) + except User.DoesNotExist: + return None + + def get_user(self, user_id): + try: + return User.objects.get(id=user_id) + except User.DoesNotExist: + return None diff --git a/ligoauth/migrations/0001_initial.py b/ligoauth/migrations/0001_initial.py new file mode 100644 index 000000000..6b86b5cc7 --- /dev/null +++ b/ligoauth/migrations/0001_initial.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'LigoLdapUser' + db.create_table('ligoauth_ligoldapuser', ( + ('user_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True, primary_key=True)), + ('ldap_dn', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)), + )) + db.send_create_signal('ligoauth', ['LigoLdapUser']) + + # Adding model 'LocalUser' + db.create_table('ligoauth_localuser', ( + ('user_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True, primary_key=True)), + )) + db.send_create_signal('ligoauth', ['LocalUser']) + + # Adding model 'X509Cert' + db.create_table('ligoauth_x509cert', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('subject', self.gf('django.db.models.fields.CharField')(max_length=200)), + )) + db.send_create_signal('ligoauth', ['X509Cert']) + + # Adding M2M table for field users on 'X509Cert' + db.create_table('ligoauth_x509cert_users', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('x509cert', models.ForeignKey(orm['ligoauth.x509cert'], null=False)), + ('user', models.ForeignKey(orm['auth.user'], null=False)) + )) + db.create_unique('ligoauth_x509cert_users', ['x509cert_id', 'user_id']) + + + def backwards(self, orm): + # Deleting model 'LigoLdapUser' + db.delete_table('ligoauth_ligoldapuser') + + # Deleting model 'LocalUser' + db.delete_table('ligoauth_localuser') + + # Deleting model 'X509Cert' + db.delete_table('ligoauth_x509cert') + + # Removing M2M table for field users on 'X509Cert' + db.delete_table('ligoauth_x509cert_users') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ligoauth.ligoldapuser': { + 'Meta': {'object_name': 'LigoLdapUser', '_ormbases': ['auth.User']}, + 'ldap_dn': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.localuser': { + 'Meta': {'object_name': 'LocalUser', '_ormbases': ['auth.User']}, + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.x509cert': { + 'Meta': {'object_name': 'X509Cert'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ligoauth'] diff --git a/ligoauth/migrations/0002_remove_old_auth_users.py b/ligoauth/migrations/0002_remove_old_auth_users.py new file mode 100644 index 000000000..aad2071b2 --- /dev/null +++ b/ligoauth/migrations/0002_remove_old_auth_users.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + db.clear_table("auth_user") + + def backwards(self, orm): + "Nothing to do" + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ligoauth.ligoldapuser': { + 'Meta': {'object_name': 'LigoLdapUser', '_ormbases': ['auth.User']}, + 'ldap_dn': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.localuser': { + 'Meta': {'object_name': 'LocalUser', '_ormbases': ['auth.User']}, + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.x509cert': { + 'Meta': {'object_name': 'X509Cert'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ligoauth'] + symmetrical = True diff --git a/ligoauth/migrations/0003_utf8ify_user_tables.py b/ligoauth/migrations/0003_utf8ify_user_tables.py new file mode 100644 index 000000000..de37a6458 --- /dev/null +++ b/ligoauth/migrations/0003_utf8ify_user_tables.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import DataMigration + + +class Migration(DataMigration): + + def forwards(self, orm): + # XXX MySQL specific. + db.execute("ALTER TABLE ligoauth_ligoldapuser DEFAULT CHARACTER SET UTF8") + db.execute("ALTER TABLE ligoauth_ligoldapuser CONVERT TO CHARACTER SET UTF8") + db.execute("ALTER TABLE auth_user DEFAULT CHARACTER SET UTF8") + db.execute("ALTER TABLE auth_user CONVERT TO CHARACTER SET UTF8") + + def backwards(self, orm): + # We can't go back! + pass + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.message': { + 'Meta': {'object_name': 'Message'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'_message_set'", 'to': "orm['auth.User']"}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ligoauth.ligoldapuser': { + 'Meta': {'object_name': 'LigoLdapUser'}, + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'ldap_dn': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ligoauth.x509cert': { + 'Meta': {'object_name': 'X509Cert'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ligouser': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ligoauth.LigoLdapUser']"}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + } + } + + complete_apps = ['auth', 'ligoauth'] + symmetrical = True diff --git a/ligoauth/migrations/0004_add_localusers.py b/ligoauth/migrations/0004_add_localusers.py new file mode 100644 index 000000000..83fa02d0a --- /dev/null +++ b/ligoauth/migrations/0004_add_localusers.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +users = [ + { + 'username' : 'MbtaAlert', + 'first_name' : '', + 'last_name' : 'MBTA Alert', + 'email' : 'mours@lapp.in2p3.fr', + 'dns' : [ + "/C=IT/O=INFN/OU=Service/L=EGO/CN=MbtaAlert/lscgw.virgo.infn.it", + "/C=IT/O=INFN/OU=Service/L=EGO/CN=MbtaAlert/olnode04.virgo.infn.it", + "/C=IT/O=INFN/OU=Service/L=EGO/CN=MbtaAlert/olnode33.virgo.infn.it", + ] + }, + { + 'username' : 'detchar', + 'first_name' : '', + 'last_name' : 'Detchar', + 'email' : 'pankow@gravity.phys.uwm.edu', + 'dns' : [ + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-grid.ligo-la.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-grid.ligo-wa.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-grid.ligo.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev1.ligo-la.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev1.ligo-wa.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev1.ligo.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev2.ligo-la.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev2.ligo-wa.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev2.ligo.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev3.ligo.caltech.edu", + "/DC=org/DC=doegrids/OU=Services/CN=detchar/ldas-pcdev4.ligo.caltech.edu", + ] + }, + { + 'username' : 'excesspower-processor', + 'first_name' : '', + 'last_name' : 'Excess Power Processor', + 'email' : 'pankow@gravity.phys.uwm.edu', + 'dns' : [ + '/DC=org/DC=doegrids/OU=Services/CN=excesspower-processor/marlin.phys.uwm.edu', + ] + }, + { + 'username' : 'gdb-processor', + 'first_name' : '', + 'last_name' : 'GDB Processor', + 'email' : 'gdb_processor@gravity.phys.uwm.edu', + 'dns' : [ + "/DC=org/DC=doegrids/OU=Services/CN=gdb-processor/marlin.phys.uwm.edu", + ] + }, + { + 'username' : 'gis', + 'first_name' : '', + 'last_name' : 'GIS', + 'email' : 'xavier.amador@ligo.org', + 'dns' : [ + "/DC=org/DC=doegrids/OU=Services/CN=gis/lscgis.phys.uwm.edu", + ] + }, + { + 'username' : 'lumin', + 'first_name' : '', + 'last_name' : 'LUMIN', + 'email' : 'bmoe@gravity.phys.uwm.edu', + 'dns' : [ + "/DC=org/DC=doegrids/OU=Services/CN=luminrobot/ldas-pcdev1.ligo.caltech.edu", + ] + }, + { + 'username' : 'omega', + 'first_name' : '', + 'last_name' : 'Omega Analysis', + 'email' : '', + 'dns' : [ + "/DC=org/DC=doegrids/OU=Services/CN=omegarobot/node499.ldas-cit.ligo.caltech.edu", + ] + }, + { + 'username' : 'waveburst', + 'first_name' : '', + 'last_name' : 'Cwb Analysis', + 'email' : 'bmoe@gravity.phys.uwm.edu', + 'dns' : [ + "/DC=org/DC=doegrids/OU=Services/CN=waveburst/ldas-pcdev1.ligo.caltech.edu", + ] + }, + { + 'username' : 'gstlalcbc', + 'first_name' : '', + 'last_name' : 'GstLal CBC', + 'email' : 'chad.r.hanna@gmail.com', + 'dns' : [ + "/DC=org/DC=ligo/O=LIGO/OU=Services/CN=gstlalcbc/ldas-pcdev1.ligo.caltech.edu", + ] + }, +] + + +class Migration(DataMigration): + + def forwards(self, orm): + LocalUser = orm['ligoauth.LocalUser'] + X509Cert = orm['ligoauth.X509Cert'] + + # Local Users + for entry in users: + user, created = LocalUser.objects.get_or_create(username=entry['username']) + if created: + user.first_name = entry['first_name'] + user.last_name = entry['last_name'] + user.email = entry['email'] + user.is_active = True + user.is_staff = False + user.is_superuser = False + user.save() + current_dns = set([cert.subject for cert in user.x509cert_set.all()]) + new_dns = set(entry['dns']) + + missing_dns = new_dns - current_dns + redundant_dns = current_dns - new_dns + + for dn in missing_dns: + cert, created = X509Cert.objects.get_or_create(subject=dn) + if created: + cert.save() + cert.users.add(user) + + for dn in redundant_dns: + cert = X509Cert.objects.get(subject=dn) + cert.users.remove(user) + + def backwards(self, orm): + LocalUser = orm['ligoauth.LocalUser'] + for user in LocalUser.objects.all(): + user.delete() + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ligoauth.ligoldapuser': { + 'Meta': {'object_name': 'LigoLdapUser', '_ormbases': ['auth.User']}, + 'ldap_dn': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.localuser': { + 'Meta': {'object_name': 'LocalUser', '_ormbases': ['auth.User']}, + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.x509cert': { + 'Meta': {'object_name': 'X509Cert'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ligoauth'] + symmetrical = True diff --git a/ligoauth/migrations/0005_add_ldapusers.py b/ligoauth/migrations/0005_add_ldapusers.py new file mode 100644 index 000000000..91b89ef95 --- /dev/null +++ b/ligoauth/migrations/0005_add_ldapusers.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +import ldap + + +def update_from_ldap(LigoLdapUser, X509Cert): + # Copied here from ligoauth/management/commands/refresh_from_ldap + # because it might not be there or be crazy different in the future. + # Of course, it might still be broken in the future anyway, but hey. + baseDN = "ou=people,dc=ligo,dc=org" + searchScope = ldap.SCOPE_SUBTREE + searchFilter = "(employeeNumber=*)" + retrieveAttributes = ["krbPrincipalName", + "gridX509subject", + "givenName", + "sn", + "mail", + "isMemberOf"] + + l = ldap.open("ldap.ligo.org") + l.protocol_version = ldap.VERSION3 + ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes) + while 1: + result_type, result_data = l.result(ldap_result_id, 0) + if (result_data == []): + break + else: + if result_type == ldap.RES_SEARCH_ENTRY: + for (ldap_dn, ldap_result) in result_data: + + first_name = unicode(ldap_result['givenName'][0], 'utf-8') + last_name = unicode(ldap_result['sn'][0], 'utf-8') + email = ldap_result['mail'][0] + new_dns = set(ldap_result.get('gridX509subject',[])) + is_active = "Communities:LVC:LVCGroupMembers" \ + in ldap_result.get('isMemberOf',[]) + principal = ldap_result['krbPrincipalName'][0] + + # Update/Create LigoLdapUser entry + user, created = LigoLdapUser.objects.get_or_create(ldap_dn=ldap_dn) + + changed = created \ + or (user.first_name != first_name) \ + or (user.last_name != last_name) \ + or (user.email != email) \ + or (user.username != principal) \ + or (user.is_active != is_active) + + if changed: + user.first_name = first_name + user.last_name = last_name + user.email = email + user.username = principal + user.is_active = is_active + # revoke staff/superuser if not active. + user.is_staff = user.is_staff and is_active + user.is_superuser = user.is_superuser and is_active + user.save() + + # update X509 certs for user + current_dns = set([ cert.subject for cert in user.x509cert_set.all() ]) + + if current_dns != new_dns: + for dn in current_dns - new_dns: + X509Cert.objects.get(subject=dn).delete() + for dn in new_dns - current_dns: + cert, created = X509Cert.objects.get_or_create(subject=dn) + if created: + cert.save() + cert.users.add(user) + +class Migration(DataMigration): + + needed_by = ( + ("gracedb", "0005_stage1_rm_ligouser__add_new_foreign_keys"), + ("userprofile", "0002_stage1_rm_ligouser__add_new_foreign_key"), + ) + + def forwards(self, orm): + LigoLdapUser = orm['ligoauth.LigoLdapUser'] + X509Cert = orm['ligoauth.X509Cert'] + update_from_ldap(LigoLdapUser, X509Cert) + + def backwards(self, orm): + LigoLdapUser = orm['ligoauth.LigoLdapUser'] + for user in LigoLdapUser.objects.all(): + user.delete() + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ligoauth.ligoldapuser': { + 'Meta': {'object_name': 'LigoLdapUser', '_ormbases': ['auth.User']}, + 'ldap_dn': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.localuser': { + 'Meta': {'object_name': 'LocalUser', '_ormbases': ['auth.User']}, + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ligoauth.x509cert': { + 'Meta': {'object_name': 'X509Cert'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['ligoauth'] + symmetrical = True diff --git a/ligoauth/migrations/__init__.py b/ligoauth/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ligoauth/models.py b/ligoauth/models.py new file mode 100644 index 000000000..eb8efc716 --- /dev/null +++ b/ligoauth/models.py @@ -0,0 +1,88 @@ + +from __future__ import unicode_literals + +from django.db import models +from django.contrib.auth.models import User + +# There seems to be a LOT of duplication here and I don't know +# if that is good or bad. Normally, that seems bad... +# +# The thing is, LigoLdapUser and LocalUser (and whatever we might add later) +# are actual entities that we want synched with the Django User, so they *are* +# separate could conceivably have different first_name's, say, yet still refer +# to the same (abstract) user entity. Not likely, and not initially, but +# conceivably. +# +# Whatever. Just am not fully pleased with this. + +#from exceptions import NotImplementedError + +#class MetaUser(models.Model): + #class Meta: + #abstract = True + + #first_name = models.CharField(max_length=50, blank=False, null=False, unique=True) + #last_name = models.CharField(max_length=50, blank=False, null=False, unique=True) + #email = models.EmailField() + #username = models.CharField(max_length=100, unique=True) + #is_active = models.BooleanField(default=True) + #auth_user = models.ForeignKey(User, null=False) + + #def _get_or_create_auth_user(self): + #raise NotImplementedError(str(self.__class__) + " _get_auth_user") + + #def save(self): + #user, created = self._get_auth_user() + #changed = created \ + #or (user.first_name != self.first_name) \ + #or (user.last_name != self.last_name) \ + #or (user.email != self.email) \ + #or (user.is_active == self.is_active) + #if changed: + #user.first_name = self.first_name + #user.last_name = self.last_name + #user.email = self.email + #user.is_active = self.is_active + #user.save() + #models.Model.save(self) + +class LigoLdapUser(User): + ldap_dn = models.CharField(max_length=100, null=False, unique=True) + +# def _get_or_create_auth_user(self): +# return User.get_or_create(username=self.principal) + + def name(self): + # XXX I really don't freaking understand WHY THIS SEEMS NECESSARY. + # print user.name() gives an idiotic ascii coding error otherwise. WHY!? + return u"{0} {1}".format(self.first_name, self.last_name).encode('utf-8') + + +class LocalUser(User): + pass + +class X509Cert(models.Model): + subject = models.CharField(max_length=200) + users = models.ManyToManyField(User) + + +def shibid_to_user(shibid): + try: + return User.objects.get(username=shibid) + except User.DoesNotExist: + return None + +def certdn_to_user(dn, username=None): + try: + possible_users = X509Cert.objects.get(subject=dn).users + except: + return None + + if username: + possible_users.filter(username=username) + + try: + return possible_users.all()[0] + except IndexError: + return None + diff --git a/ligoauth/tests.py b/ligoauth/tests.py new file mode 100644 index 000000000..501deb776 --- /dev/null +++ b/ligoauth/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/ligoauth/views.py b/ligoauth/views.py new file mode 100644 index 000000000..60f00ef0e --- /dev/null +++ b/ligoauth/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/settings/default.py b/settings/default.py index d3d09bbb4..d6620570b 100644 --- a/settings/default.py +++ b/settings/default.py @@ -169,9 +169,12 @@ TEMPLATE_CONTEXT_PROCESSORS = ( ) AUTHENTICATION_BACKENDS = ( - 'gracedb.middleware.auth.LigoAuthBackend', - 'ligodjangoauth.LigoShibbolethAuthBackend', - 'django.contrib.auth.backends.ModelBackend', +# 'gracedb.middleware.auth.LigoAuthBackend', + 'ligoauth.middleware.auth.LigoX509Backend', + 'ligoauth.middleware.auth.LigoShibBackend', +# 'ligoauth.middleware.auth.RemoteUserBackend', +# 'ligodjangoauth.LigoShibbolethAuthBackend', +# 'django.contrib.auth.backends.ModelBackend', ) SHIB_AUTHENTICATION_SESSION_INITIATOR = 'https://moe.phys.uwm.edu/Shibboleth.sso/Login' @@ -187,9 +190,10 @@ MIDDLEWARE_CLASSES = [ 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'ligodjangoauth.LigoShibbolethMiddleware', - 'gracedb.middleware.auth.LigoAuthMiddleware', +# 'django.contrib.auth.middleware.AuthenticationMiddleware', +# 'ligodjangoauth.LigoShibbolethMiddleware', + 'ligoauth.middleware.auth.LigoAuthMiddleware', +# 'django.contrib.auth.middleware.RemoteUserMiddleware', ] ROOT_URLCONF = 'urls' @@ -210,6 +214,7 @@ INSTALLED_APPS = ( 'django.contrib.staticfiles', 'gracedb', 'userprofile', + 'ligoauth', 'rest_framework', 'south', ) diff --git a/settings/development.py b/settings/development.py index 8569d0169..dbd0163ce 100644 --- a/settings/development.py +++ b/settings/development.py @@ -35,7 +35,7 @@ LATENCY_REPORT_WEB_PAGE_FILE_PATH = LATENCY_REPORT_DEST_DIR + "/latency.inc" UPTIME_REPORT_DIR = "/home/bmoe/data/uptime" -SITE_ID = 4 +SITE_ID = 1 TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html index d2d77abe3..76e911a67 100644 --- a/templates/admin/base_site.html +++ b/templates/admin/base_site.html @@ -20,6 +20,7 @@ <li id="nav-reports"><a href="{% url reports %}">Reports</a></li> <li id="nav-feeds"><a href="{% url feeds %}">RSS</a></li> <li id="nav-userprofile"><a href="{% url userprofile-home %}">Options</a></li> - {% if ligouser %}<li id="nav-user">Authenticated as: {{ ligouser.name }}</li>{% endif %} + {% if user %}<li id="nav-user">Authenticated as: + {{ user.first_name }} {{ user.last_name }}</li>{% endif %} <ul> {% endblock %} diff --git a/templates/base.html b/templates/base.html index dc32d8af6..82a670103 100644 --- a/templates/base.html +++ b/templates/base.html @@ -37,7 +37,7 @@ function changeTime(obj, label) { <li id="nav-feeds"><a href="{% url feeds %}">RSS</a></li> <li id="nav-latest"><a href="{% url latest %}">Latest</a></li> <li id="nav-userprofile"><a href="{% url userprofile-home %}">Options</a></li> - {% if ligouser %}<li id="nav-user">Authenticated as: {{ ligouser.name }}</li>{% endif %} + {% if user %}<li id="nav-user">Authenticated as: {{ user.first_name }} {{user.last_name }}</li>{% endif %} </ul> <center> {% if config_name %} @@ -78,9 +78,9 @@ function changeTime(obj, label) { </td> <td align="center"> - {% if ligouser and ligouser.name == "Chad Hanna" %} + {% if user and user.username == "chad.hanna@LIGO.ORG" %} <img width="194" height="37" src="{{MEDIA_URL}}images/PI_Logo-anim.gif"> - {% else %}{% if ligouser and ligouser.name == "Kipp Cannon" %} + {% else %}{% if user and user.username == "kipp.cannon@LIGO.ORG" %} <img width="194" height="37" src="{{MEDIA_URL}}images/CITA_logo-anim.gif"> {% else %} <img width="107" height="37" src="{{MEDIA_URL}}images/anim2.gif"> diff --git a/templates/forbidden.html b/templates/forbidden.html new file mode 100644 index 000000000..e383758b9 --- /dev/null +++ b/templates/forbidden.html @@ -0,0 +1,11 @@ + + +{% extends "base.html" %} + +{% block title %}403 – Forbidden{{ object.graceid }}{% endblock %} +{% block heading %}Forbidden{{ object.graceid }}{% endblock %} + +{% block content %} + <p>The item you requested is not for you.</p> {{ message|safe }} +{% endblock %} + diff --git a/templates/gracedb/create.html b/templates/gracedb/create.html index 604421bf3..90573335e 100644 --- a/templates/gracedb/create.html +++ b/templates/gracedb/create.html @@ -10,7 +10,7 @@ <form enctype="multipart/form-data" action="" method="POST"> <table> {{ form }} - <tr><td>Submitter:</td><td>{{ ligouser }}</td></tr> + <tr><td>Submitter:</td><td>{{ user }}</td></tr> <tr><td><input type="submit" value="Submit"></td></tr> </table> </form> diff --git a/templates/gracedb/event_detail.html b/templates/gracedb/event_detail.html index b224a02ed..a8645d92e 100644 --- a/templates/gracedb/event_detail.html +++ b/templates/gracedb/event_detail.html @@ -491,7 +491,7 @@ <tr class="{% cycle 'odd' 'even'%}"> <td>{{log.getN}}</td> <td>{{log.created|multiTime:"logtime"}}</td> - <td>{{log.issuer}}</td> + <td>{{log.issuer.first_name}} {{log.issuer.last_name}}</td> <td>{{log.comment|sanitize}} {% if log.fileurl %} <a href="{{log.fileurl}}">{{log.filename}}</a> @@ -567,7 +567,7 @@ <tr class="{% cycle 'odd' 'even'%}"> <td>{{log.getN}} <td>{{log.created|multiTime:"logtime"}}</td> - <td>{{log.issuer}}</td> + <td>{{log.issuer.first_name}} {{ log.issuer.last_name}}</td> {% if object.getAvailableTags %} <td> <table> diff --git a/templates/rest_framework/api.html b/templates/rest_framework/api.html index 608e7f005..e89675dea 100644 --- a/templates/rest_framework/api.html +++ b/templates/rest_framework/api.html @@ -12,7 +12,7 @@ GraceDB — REST API {% endblock %} {% block userlinks %} - {% if ligouser %}<li>Authenticated as: {{ ligouser.name }}</li>{% endif %} + {% if user %}<li>Authenticated as: {{ user.first_name }} {{ user.last_name }}</li>{% endif %} {% endblock %} {% block breadcrumbs %} diff --git a/userprofile/migrations/0001_initial.py b/userprofile/migrations/0001_initial.py new file mode 100644 index 000000000..def4e474c --- /dev/null +++ b/userprofile/migrations/0001_initial.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'AnalysisType' + db.create_table('userprofile_analysistype', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('code', self.gf('django.db.models.fields.CharField')(unique=True, max_length=20)), + ('display', self.gf('django.db.models.fields.CharField')(unique=True, max_length=20)), + )) + db.send_create_signal('userprofile', ['AnalysisType']) + + # Adding model 'Contact' + db.create_table('userprofile_contact', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'])), + ('desc', self.gf('django.db.models.fields.CharField')(max_length=20)), + ('email', self.gf('django.db.models.fields.EmailField')(max_length=75)), + )) + db.send_create_signal('userprofile', ['Contact']) + + # Adding model 'Trigger' + db.create_table('userprofile_trigger', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'])), + ('triggerType', self.gf('django.db.models.fields.CharField')(max_length=20, blank=True)), + ('farThresh', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)), + )) + db.send_create_signal('userprofile', ['Trigger']) + + # Adding M2M table for field labels on 'Trigger' + db.create_table('userprofile_trigger_labels', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('trigger', models.ForeignKey(orm['userprofile.trigger'], null=False)), + ('label', models.ForeignKey(orm['gracedb.label'], null=False)) + )) + db.create_unique('userprofile_trigger_labels', ['trigger_id', 'label_id']) + + # Adding M2M table for field atypes on 'Trigger' + db.create_table('userprofile_trigger_atypes', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('trigger', models.ForeignKey(orm['userprofile.trigger'], null=False)), + ('analysistype', models.ForeignKey(orm['userprofile.analysistype'], null=False)) + )) + db.create_unique('userprofile_trigger_atypes', ['trigger_id', 'analysistype_id']) + + # Adding M2M table for field contacts on 'Trigger' + db.create_table('userprofile_trigger_contacts', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('trigger', models.ForeignKey(orm['userprofile.trigger'], null=False)), + ('contact', models.ForeignKey(orm['userprofile.contact'], null=False)) + )) + db.create_unique('userprofile_trigger_contacts', ['trigger_id', 'contact_id']) + + + def backwards(self, orm): + # Deleting model 'AnalysisType' + db.delete_table('userprofile_analysistype') + + # Deleting model 'Contact' + db.delete_table('userprofile_contact') + + # Deleting model 'Trigger' + db.delete_table('userprofile_trigger') + + # Removing M2M table for field labels on 'Trigger' + db.delete_table('userprofile_trigger_labels') + + # Removing M2M table for field atypes on 'Trigger' + db.delete_table('userprofile_trigger_atypes') + + # Removing M2M table for field contacts on 'Trigger' + db.delete_table('userprofile_trigger_contacts') + + + models = { + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + }, + 'userprofile.analysistype': { + 'Meta': {'object_name': 'AnalysisType'}, + 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'display': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'userprofile.contact': { + 'Meta': {'object_name': 'Contact'}, + 'desc': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + }, + 'userprofile.trigger': { + 'Meta': {'object_name': 'Trigger'}, + 'atypes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.AnalysisType']", 'symmetrical': 'False', 'blank': 'True'}), + 'contacts': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.Contact']", 'symmetrical': 'False', 'blank': 'True'}), + 'farThresh': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'symmetrical': 'False', 'blank': 'True'}), + 'triggerType': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + } + } + + complete_apps = ['userprofile'] \ No newline at end of file diff --git a/userprofile/migrations/0002_stage1_rm_ligouser__add_new_foreign_key.py b/userprofile/migrations/0002_stage1_rm_ligouser__add_new_foreign_key.py new file mode 100644 index 000000000..8143bf92b --- /dev/null +++ b/userprofile/migrations/0002_stage1_rm_ligouser__add_new_foreign_key.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Trigger.new_user' + db.add_column('userprofile_trigger', 'new_user', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True), + keep_default=False) + + # Adding field 'Contact.new_user' + db.add_column('userprofile_contact', 'new_user', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Trigger.new_user' + db.delete_column('userprofile_trigger', 'new_user_id') + + # Deleting field 'Contact.new_user' + db.delete_column('userprofile_contact', 'new_user_id') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + }, + 'userprofile.analysistype': { + 'Meta': {'object_name': 'AnalysisType'}, + 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'display': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'userprofile.contact': { + 'Meta': {'object_name': 'Contact'}, + 'desc': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'new_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + }, + 'userprofile.trigger': { + 'Meta': {'object_name': 'Trigger'}, + 'atypes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.AnalysisType']", 'symmetrical': 'False', 'blank': 'True'}), + 'contacts': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.Contact']", 'symmetrical': 'False', 'blank': 'True'}), + 'farThresh': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'symmetrical': 'False', 'blank': 'True'}), + 'new_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'triggerType': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + } + } + + complete_apps = ['userprofile'] \ No newline at end of file diff --git a/userprofile/migrations/0003_stage2_rm_ligouser__populate_new_foreign_key.py b/userprofile/migrations/0003_stage2_rm_ligouser__populate_new_foreign_key.py new file mode 100644 index 000000000..5a8cc65dd --- /dev/null +++ b/userprofile/migrations/0003_stage2_rm_ligouser__populate_new_foreign_key.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +#import datetime +#from south.db import db +from south.v2 import DataMigration +#from django.db import models +import sys +import re + +def get_auth_user_for_ligo_user_id(orm, userid): + + LigoUser = orm['gracedb.User'] + DjangoUser = orm['auth.User'] + + service_cert_pattern = re.compile(r'.*CN=([^/]+)/[^/]+') + + try: + ligo_user = LigoUser.objects.get(id=userid) + except LigoUser.DoesNotExist: + print("Can't find Ligo User {0}. (this should not happen)".format(userid)) + sys.exit(1) + + try: + return DjangoUser.objects.get(username=ligo_user.unixid).id + except DjangoUser.DoesNotExist: + pass + try: + return DjangoUser.objects.get(username=ligo_user.principal) + return DjangoUser.objects.get(username="{0}@LIGO.ORG".format(ligo_user.unixid)) + except DjangoUser.DoesNotExist: + pass + + if ligo_user.unixid.lower() == 'none' or ligo_user.principal.lower() == 'none': + # Some service user, likely. + name = service_cert_pattern.match(ligo_user.dn).group(1) + return DjangoUser.objects.get(username=name) + + print("Can't find Django user named '{0}'\nUnixid: {1}\nPrincipal: ({2})\nDN:({3})". + format(ligo_user.name, ligo_user.unixid, ligo_user.principal, ligo_user.dn)) + sys.exit(1) + +#def get_auth_user_for_ligo_user_id(orm, userid): + #ligo_user = orm['gracedb.User'].objects.get(id=userid) + #return orm['auth.User'].objects.get(username=ligo_user.unixid).id + +def get_ligo_user_for_django_user_id(orm, django_id): + django_user = orm['auth.User'].objects.get(id=django_id) + return orm['gracedb.User'].objects.get(unixid=django_user.username) + return 1 + +class Migration(DataMigration): + + def forwards(self, orm): + ids = set() + ids.update(orm['userprofile.Contact'].objects.values_list('user_id', flat=True).distinct()) + ids.update(orm['userprofile.Trigger'].objects.values_list('user_id', flat=True).distinct()) + + for ligo_id in ids: + django_id = get_auth_user_for_ligo_user_id(orm, ligo_id) + orm['userprofile.Contact'].objects.filter(user=ligo_id).update(new_user=django_id) + orm['userprofile.Trigger'].objects.filter(user=ligo_id).update(new_user=django_id) + + def backwards(self, orm): + ids = set() + + ids.update(orm['userprofile.Contact'].objects.values_list('new_user_id', flat=True).distinct()) + ids.update(orm['userprofile.Trigger'].objects.values_list('new_user_id', flat=True).distinct()) + for django_id in ids: + ligo_id = get_ligo_user_for_django_user_id(orm, django_id) + orm['userprofile.Contact'].objects.filter(new_user=django_id).update(user=ligo_id) + orm['userprofile.Trigger'].objects.filter(new_user=django_id).update(user=ligo_id) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + }, + 'userprofile.analysistype': { + 'Meta': {'object_name': 'AnalysisType'}, + 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'display': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'userprofile.contact': { + 'Meta': {'object_name': 'Contact'}, + 'desc': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'new_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + }, + 'userprofile.trigger': { + 'Meta': {'object_name': 'Trigger'}, + 'atypes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.AnalysisType']", 'symmetrical': 'False', 'blank': 'True'}), + 'contacts': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.Contact']", 'symmetrical': 'False', 'blank': 'True'}), + 'farThresh': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'symmetrical': 'False', 'blank': 'True'}), + 'new_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'triggerType': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + } + } + + complete_apps = ['userprofile'] + symmetrical = True diff --git a/userprofile/migrations/0004_stage3_rm_ligouser__remove_old_foreign_keys.py b/userprofile/migrations/0004_stage3_rm_ligouser__remove_old_foreign_keys.py new file mode 100644 index 000000000..8bfc19126 --- /dev/null +++ b/userprofile/migrations/0004_stage3_rm_ligouser__remove_old_foreign_keys.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration + + +class Migration(SchemaMigration): + needed_by = (("gracedb","0008_auto__del_user"),) + + def forwards(self, orm): + db.delete_column('userprofile_contact', 'user_id') + db.delete_column('userprofile_trigger', 'user_id') + + db.rename_column('userprofile_contact', 'new_user_id', 'user_id') + db.rename_column('userprofile_trigger', 'new_user_id', 'user_id') + + def backwards(self, orm): + db.rename_column('userprofile_contact', 'user_id', 'new_user_id') + db.rename_column('userprofile_trigger', 'user_id', 'new_user_id') + + db.add_column('userprofile_contact', 'trigger', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'], null=False, default=1), + keep_default=False) + db.add_column('userprofile_trigger', 'trigger', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['gracedb.User'], null=False, default=1), + keep_default=False) + + models = { + 'gracedb.label': { + 'Meta': {'object_name': 'Label'}, + 'defaultColor': ('django.db.models.fields.CharField', [], {'default': "'black'", 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}) + }, + 'gracedb.user': { + 'Meta': {'ordering': "['name']", 'object_name': 'User'}, + 'dn': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'principal': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'unixid': ('django.db.models.fields.CharField', [], {'max_length': '25'}) + }, + 'userprofile.analysistype': { + 'Meta': {'object_name': 'AnalysisType'}, + 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'display': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'userprofile.contact': { + 'Meta': {'object_name': 'Contact'}, + 'desc': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + }, + 'userprofile.trigger': { + 'Meta': {'object_name': 'Trigger'}, + 'atypes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.AnalysisType']", 'symmetrical': 'False', 'blank': 'True'}), + 'contacts': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['userprofile.Contact']", 'symmetrical': 'False', 'blank': 'True'}), + 'farThresh': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'labels': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['gracedb.Label']", 'symmetrical': 'False', 'blank': 'True'}), + 'triggerType': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['gracedb.User']"}) + } + } + + complete_apps = ['userprofile'] diff --git a/userprofile/migrations/__init__.py b/userprofile/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/userprofile/models.py b/userprofile/models.py index 50eeecc12..95e9f66d0 100644 --- a/userprofile/models.py +++ b/userprofile/models.py @@ -1,7 +1,9 @@ from django.db import models -from gracedb.models import User, Label, Event +from gracedb.models import Label, Event + +from django.contrib.auth.models import User #class Notification(models.Model): @@ -33,6 +35,7 @@ def populateAnalysisType(): class Contact(models.Model): user = models.ForeignKey(User, null=False) + #new_user = models.ForeignKey(DjangoUser, null=True) desc = models.CharField(max_length=20) email = models.EmailField() @@ -42,6 +45,7 @@ class Contact(models.Model): class Trigger(models.Model): TYPES = ( ("create", "create"), ("change","change"), ("label","label") ) user = models.ForeignKey(User, null=False) + #new_user = models.ForeignKey(DjangoUser, null=True) triggerType = models.CharField(max_length=20, choices=TYPES, blank=True) labels = models.ManyToManyField(Label, blank=True) atypes = models.ManyToManyField(AnalysisType, blank=True, verbose_name="Analysis Types") diff --git a/userprofile/views.py b/userprofile/views.py index 7256f500d..615793be4 100644 --- a/userprofile/views.py +++ b/userprofile/views.py @@ -13,8 +13,8 @@ from models import Trigger, Contact from forms import ContactForm, triggerFormFactory def index(request): - triggers = Trigger.objects.filter(user=request.ligouser) - contacts = Contact.objects.filter(user=request.ligouser) + triggers = Trigger.objects.filter(user=request.user) + contacts = Contact.objects.filter(user=request.user) d = { 'triggers' : triggers, 'contacts': contacts } return render_to_response('profile/notifications.html', d, @@ -24,10 +24,10 @@ def create(request): explanation = "" message = "" if request.method == "POST": - form = triggerFormFactory(request.POST, user=request.ligouser) + form = triggerFormFactory(request.POST, user=request.user) if form.is_valid(): # Create the Trigger - t = Trigger(user=request.ligouser) + t = Trigger(user=request.user) labels = form.cleaned_data['labels'] atypes = form.cleaned_data['atypes'] contacts = form.cleaned_data['contacts'] @@ -56,7 +56,7 @@ def create(request): # hopefully, there are error messages in the form. pass else: - form = triggerFormFactory(user=request.ligouser) + form = triggerFormFactory(user=request.user) if message: request.session['flash_msg'] = message return render_to_response('profile/createNotification.html', @@ -74,7 +74,7 @@ def delete(request, id): t = Trigger.objects.get(id=id) except Trigger.DoesNotExist: raise Http404 - if request.ligouser != t.user: + if request.user != t.user: return HttpResponseForbidden("NO!") request.session['flash_msg'] = "Notification Deleted: %s" % t.userlessDisplay() t.delete() @@ -90,7 +90,7 @@ def createContact(request): if form.is_valid(): # Create the Contact c = Contact( - user=request.ligouser, + user=request.user, desc = form.cleaned_data['desc'], email = form.cleaned_data['email'] ) @@ -114,7 +114,7 @@ def deleteContact(request, id): c = Contact.objects.get(id=id) except Contact.DoesNotExist: raise Http404 - if request.ligouser != c.user: + if request.user != c.user: return HttpResponseForbidden("NO!") request.session['flash_msg'] = "Notification Deleted: %s" % c c.delete() -- GitLab