Skip to content

Commit 306bece

Browse files
committed
Import users from htpasswd file, searching IESGLogin, WgPassword,
LiaisonUser, and EmailAddresses for a mapping to a PersonOrOrgInfo. It doesn't yet import all groups or permissions; that'll be a separate (repeatable) process. The goal is to eventually eliminate completely the WgPassword and LiaisonUser tables. IESGLogin could go too eventually, but that requires schema changes, not just changes in the authentication mechanisms. - Legacy-Id: 616
1 parent 472669b commit 306bece

1 file changed

Lines changed: 133 additions & 0 deletions

File tree

ietf/bin/import-users

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/usr/bin/env python
2+
#
3+
# Import users from all different IETF authentication sources into
4+
# django. Map user names to people via the ietf.ietfauth.models.UserMap
5+
# model. Use the htpasswd file to get passwords, ignoring any password
6+
# stored in the database.
7+
#
8+
# If the user already exists, just update their group memberships
9+
# and/or privileges. This script can be run multiple times with no
10+
# adverse effect.
11+
#
12+
# Note that there are a couple of people who have multiple accounts.
13+
# This scheme will give them one single account, with all of the
14+
# privilges of the original account.
15+
#
16+
# Data sources:
17+
# - IESGLogin
18+
# - WgPassword
19+
# - Liaison tool ('Users')
20+
# - Then look for email address
21+
#
22+
#
23+
from ietf.idtracker.models import PersonOrOrgInfo, IESGLogin, EmailAddress
24+
from ietf.ietfauth.models import UserMap, WgPassword, LiaisonUser
25+
from django.core.validators import email_re
26+
from django.contrib.auth.models import User, Group
27+
from django.template import defaultfilters
28+
import sys
29+
30+
# Group mappings for IESGLogin entries
31+
level2group = {
32+
0: 'Secretariat',
33+
1: 'IESG',
34+
2: 'ex-IESG',
35+
}
36+
37+
f = open(sys.argv[1], 'r')
38+
line = f.readline()
39+
while line != '':
40+
(user, pw) = line.rstrip("\n").split(":")
41+
person = None
42+
# Some login names are a different E-Mail
43+
# address than the one stored in email_addresses.
44+
# If the login name looks like an email address
45+
# then use it.
46+
if email_re.search(user):
47+
email = user
48+
else:
49+
email = None
50+
try:
51+
iesg = IESGLogin.objects.get(login_name=user)
52+
try:
53+
person = iesg.person
54+
except PersonOrOrgInfo.DoesNotExist:
55+
iesg = None
56+
except IESGLogin.DoesNotExist:
57+
pass
58+
if person is None:
59+
try:
60+
wg = WgPassword.objects.get(login_name=user)
61+
person = wg.person
62+
except WgPassword.DoesNotExist:
63+
pass
64+
except AssertionError:
65+
print "%s has multiple WGPassword rows, so couldn't pick" % user
66+
if person is None:
67+
try:
68+
liaison = LiaisonUser.objects.get(login_name=user)
69+
person = liaison.person
70+
except LiaisonUser.DoesNotExist:
71+
pass
72+
if person is None and email:
73+
try:
74+
person = PersonOrOrgInfo.objects.distinct().get(emailaddress__address=user)
75+
except PersonOrOrgInfo.DoesNotExist:
76+
pass
77+
except AssertionError:
78+
print "%s has multiple PersonOrOrgInfo entries, so couldn't pick" % email
79+
if person is not None:
80+
if '@' in user:
81+
# slugify to remove non-ASCII; slugify uses hyphens but
82+
# user schema says underscore.
83+
user = defaultfilters.slugify(str(person)).replace("-", "_")
84+
if email is None:
85+
email = person.email()[1]
86+
# Make sure the username is unique.
87+
# If it already exists,
88+
# 1. if the email is the same then skip, it's the same person
89+
# 2. otherwise, add a number to the end of the username
90+
# and loop.
91+
add = ''
92+
while True:
93+
try:
94+
t = user
95+
if add:
96+
t += "%d" % ( add )
97+
u = User.objects.get(username = t)
98+
except User.DoesNotExist:
99+
u = None
100+
user = t
101+
break
102+
if u.email == email:
103+
break
104+
else:
105+
if add == '':
106+
add = 2
107+
else:
108+
add = add + 1
109+
if not u:
110+
try:
111+
map = UserMap.objects.get(person = person)
112+
u = map.user
113+
except UserMap.DoesNotExist:
114+
pass
115+
if u:
116+
print "Already in system as %s when adding %s (%s)" % ( u.username, user, email )
117+
pass
118+
else:
119+
u = User(username = user, email = email, password = 'crypt$%s$%s' % ( pw[:2], pw[2:] ), first_name = person.first_name, last_name = person.last_name )
120+
#print "Saving user: username='%s', email='%s'" % ( u.username, u.email )
121+
u.save()
122+
umap, created = UserMap.objects.get_or_create(user = u, person = person)
123+
# get_or_create saves umap for us.
124+
if iesg:
125+
try:
126+
group, created = Group.objects.get_or_create(name = level2group[iesg.user_level])
127+
except KeyError:
128+
group = None
129+
if group:
130+
u.groups.add(group)
131+
else:
132+
print "Could not map %s to person" % ( user )
133+
line = f.readline()

0 commit comments

Comments
 (0)