#!/usr/bin/env python # # Import users from all different IETF authentication sources into # django. Map user names to people via the ietf.ietfauth.models.UserMap # model. Use the htpasswd file to get passwords, ignoring any password # stored in the database. # # If the user already exists, just update their group memberships # and/or privileges. This script can be run multiple times with no # adverse effect. # # Note that there are a couple of people who have multiple accounts. # This scheme will give them one single account, with all of the # privilges of the original account. # # Data sources: # - IESGLogin # - WgPassword # - Liaison tool ('Users') # - Then look for email address # # from ietf.idtracker.models import PersonOrOrgInfo, IESGLogin, EmailAddress from ietf.ietfauth.models import UserMap, WgPassword, LiaisonUser from django.core.validators import email_re from django.contrib.auth.models import User, Group from django.template import defaultfilters import sys # Group mappings for IESGLogin entries level2group = { 0: 'Secretariat', 1: 'IESG', 2: 'ex-IESG', } f = open(sys.argv[1], 'r') line = f.readline() while line != '': (user, pw) = line.rstrip("\n").split(":") person = None # Some login names are a different E-Mail # address than the one stored in email_addresses. # If the login name looks like an email address # then use it. if email_re.search(user): email = user else: email = None try: iesg = IESGLogin.objects.get(login_name=user) try: person = iesg.person except PersonOrOrgInfo.DoesNotExist: iesg = None except IESGLogin.DoesNotExist: pass if person is None: try: wg = WgPassword.objects.get(login_name=user) person = wg.person except WgPassword.DoesNotExist: pass except AssertionError: print "%s has multiple WGPassword rows, so couldn't pick" % user if person is None: try: liaison = LiaisonUser.objects.get(login_name=user) person = liaison.person except LiaisonUser.DoesNotExist: pass if person is None and email: try: person = PersonOrOrgInfo.objects.distinct().get(emailaddress__address=user) except PersonOrOrgInfo.DoesNotExist: pass except AssertionError: print "%s has multiple PersonOrOrgInfo entries, so couldn't pick" % email if person is not None: if '@' in user: # slugify to remove non-ASCII; slugify uses hyphens but # user schema says underscore. user = defaultfilters.slugify(str(person)).replace("-", "_") if email is None: email = person.email()[1] # Make sure the username is unique. # If it already exists, # 1. if the email is the same then skip, it's the same person # 2. otherwise, add a number to the end of the username # and loop. add = '' while True: try: t = user if add: t += "%d" % ( add ) u = User.objects.get(username = t) except User.DoesNotExist: u = None user = t break if u.email == email: break else: if add == '': add = 2 else: add = add + 1 if not u: try: map = UserMap.objects.get(person = person) u = map.user except UserMap.DoesNotExist: pass if u: print "Already in system as %s when adding %s (%s)" % ( u.username, user, email ) pass else: u = User(username = user, email = email, password = 'crypt$%s$%s' % ( pw[:2], pw[2:] ), first_name = person.first_name, last_name = person.last_name ) #print "Saving user: username='%s', email='%s'" % ( u.username, u.email ) u.save() umap, created = UserMap.objects.get_or_create(user = u, person = person) # get_or_create saves umap for us. if iesg: try: group, created = Group.objects.get_or_create(name = level2group[iesg.user_level]) except KeyError: group = None if group: u.groups.add(group) else: print "Could not map %s to person" % ( user ) line = f.readline()