1
|
from __future__ import absolute_import
|
2
|
|
3
|
import os
|
4
|
import csv
|
5
|
import json
|
6
|
import ldif
|
7
|
import logging
|
8
|
from optparse import make_option
|
9
|
|
10
|
from django.core.management.base import BaseCommand, CommandError
|
11
|
from django.db import IntegrityError
|
12
|
from django.contrib.auth.models import User
|
13
|
from django.core.exceptions import ImproperlyConfigured
|
14
|
|
15
|
from mandayejs.mandaye.models import UserCredentials
|
16
|
from mellon.models import UserSAMLIdentifier
|
17
|
from mellon.utils import get_idps
|
18
|
|
19
|
|
20
|
logger = logging.getLogger(__name__)
|
21
|
|
22
|
|
23
|
def get_issuer():
|
24
|
idps = list(get_idps())
|
25
|
if not idps:
|
26
|
raise ImproperlyConfigured('ENTITY_ID or METADATA_URL required in settings.MELLON_IDENTITY_PROVIDERS')
|
27
|
idp = idps[0]
|
28
|
issuer = idp.get('METADATA_URL', None) or idp.get('ENTITY_ID', None)
|
29
|
return issuer
|
30
|
|
31
|
|
32
|
class Command(BaseCommand):
|
33
|
args = '<filename>'
|
34
|
help = 'Migrate users from ldif file or csv file'
|
35
|
|
36
|
option_list = BaseCommand.option_list +(
|
37
|
make_option(
|
38
|
'--ldap',
|
39
|
action='store_true',
|
40
|
default=False,
|
41
|
help='Migrate users from a ldap dump file'
|
42
|
),
|
43
|
make_option(
|
44
|
'--csv',
|
45
|
action='store_true',
|
46
|
default=False,
|
47
|
help='Migrate users from a csv file'
|
48
|
)
|
49
|
)
|
50
|
|
51
|
def handle(self, *args, **kwargs):
|
52
|
if len(args) < 1:
|
53
|
self.stdout.write('An input file is required')
|
54
|
return False
|
55
|
|
56
|
if kwargs.get('csv'):
|
57
|
for filename in args:
|
58
|
data = self.get_csv_data(filename)
|
59
|
self.migrate(data)
|
60
|
else:
|
61
|
for filename in args:
|
62
|
data = self.get_ldif_data(filename)
|
63
|
data = [ d[1] for d in data]
|
64
|
data = [
|
65
|
{ k : ''.join(v) for k,v in d.items()} for d in data
|
66
|
]
|
67
|
self.migrate(data)
|
68
|
|
69
|
def get_ldif_data(self, filename):
|
70
|
with open(filename, 'rb') as fd:
|
71
|
return ldif.ParseLDIF(fd)
|
72
|
|
73
|
def get_csv_data(self, filename):
|
74
|
with open(filename, 'rb') as fd:
|
75
|
fieldnames = ['idpUniqueID', 'spPostValues']
|
76
|
reader = csv.DictReader(fd, delimiter=';', quotechar='|', fieldnames=fieldnames)
|
77
|
return list(reader)
|
78
|
|
79
|
|
80
|
def migrate(self, parsed_data):
|
81
|
issuer = get_issuer()
|
82
|
|
83
|
for data in parsed_data:
|
84
|
try:
|
85
|
name_id = data.get('idpUniqueID')
|
86
|
credentials = json.loads(data.get('spPostValues'))
|
87
|
|
88
|
user, created = User.objects.get_or_create(username=name_id,
|
89
|
last_name=data.get('spLogin', ''))
|
90
|
|
91
|
uc = UserCredentials(user=user, locators=credentials)
|
92
|
uc.save()
|
93
|
|
94
|
saml_id, created = UserSAMLIdentifier.objects.get_or_create(user=user, name_id=name_id, issuer=issuer)
|
95
|
|
96
|
logger.debug('{idpUniqueID} imported'.format(**data))
|
97
|
except (IntegrityError,) as e:
|
98
|
logger.debug(e)
|
99
|
continue
|