View | Details | Raw Unified | Return to bug 41934
Collapse All | Expand All

(-)ucs-school-import/debian/changelog (+6 lines)
Lines 1-3 Link Here
1
ucs-school-import (14.0.16-25) unstable; urgency=low
2
3
  * Bug #41934: do not normalize given name and family name in legacy import
4
5
 -- Daniel Troeder <troeder@univention.de>  Wed, 28 Sep 2016 10:39:07 +0200
6
1
ucs-school-import (14.0.16-24) unstable; urgency=low
7
ucs-school-import (14.0.16-24) unstable; urgency=low
2
8
3
  * Bug #42105: change email argument name
9
  * Bug #42105: change email argument name
(-)ucs-school-import/modules/ucsschool/importer/legacy/legacy_import_user.py (+22 lines)
Lines 48-53 Link Here
48
		"""
48
		"""
49
		pass
49
		pass
50
50
51
	def make_firstname(self):
52
		"""
53
		Do not normalize given names.
54
		"""
55
		if self.firstname:
56
			return
57
		elif "firstname" in self.config["scheme"]:
58
			self.firstname = self.format_from_scheme("firstname", self.config["scheme"]["firstname"])
59
		else:
60
			self.firstname = ""
61
62
	def make_lastname(self):
63
		"""
64
		Do not normalize family names.
65
		"""
66
		if self.lastname:
67
			return
68
		elif "lastname" in self.config["scheme"]:
69
			self.lastname = self.format_from_scheme("lastname", self.config["scheme"]["lastname"])
70
		else:
71
			self.lastname = ""
72
51
	def make_username(self):
73
	def make_username(self):
52
		super(LegacyImportUser, self).make_username()
74
		super(LegacyImportUser, self).make_username()
53
		self.old_name = self.name  # for LegacyNewUserPasswordCsvExporter.serialize()
75
		self.old_name = self.name  # for LegacyNewUserPasswordCsvExporter.serialize()
(-)ucs-test-ucsschool/90_ucsschool/34_import-users-legacy (-23 / +67 lines)
Lines 6-12 Link Here
6
## exposure: dangerous
6
## exposure: dangerous
7
## packages:
7
## packages:
8
##   - ucs-school-import
8
##   - ucs-school-import
9
## bugs: [42288]
9
## bugs: [41934, 42288]
10
10
11
import shutil
11
import shutil
12
import logging
12
import logging
Lines 13-18 Link Here
13
import sys
13
import sys
14
import subprocess
14
import subprocess
15
import tempfile
15
import tempfile
16
import random
16
17
17
import univention.testing.ucr
18
import univention.testing.ucr
18
import univention.testing.strings as uts
19
import univention.testing.strings as uts
Lines 45-65 Link Here
45
		return str(self)
46
		return str(self)
46
47
47
48
48
def write_user_line(fd, ou, is_teacher, is_staff):
49
	data = {
50
		'username': uts.random_string(),
51
		'firstname': uts.random_string(),
52
		'lastname': uts.random_string(),
53
		'ou': ou,
54
		'teacher': '1' if is_teacher else '0',
55
		'staff': '1' if is_staff else '0',
56
	}
57
	line = 'A	%(username)s	%(lastname)s	%(firstname)s	%(ou)s				%(teacher)s	1	%(staff)s\n'
58
	fd.write(line % data)
59
60
61
class CLI_Legacy_Import_Tester(object):
49
class CLI_Legacy_Import_Tester(object):
62
	ucr = univention.testing.ucr.UCSTestConfigRegistry()
50
	ucr = univention.testing.ucr.UCSTestConfigRegistry()
51
	line = 'A	%(username)s	%(lastname)s	%(firstname)s	%(ou)s				%(teacher)s	1	%(staff)s\n'
63
52
64
	def __init__(self):
53
	def __init__(self):
65
		self.tmpdir = tempfile.mkdtemp(prefix='34_import-users-legacy.', dir='/tmp/')
54
		self.tmpdir = tempfile.mkdtemp(prefix='34_import-users-legacy.', dir='/tmp/')
Lines 67-72 Link Here
67
		self.ucr.load()
56
		self.ucr.load()
68
		self.ou_A = Bunch()
57
		self.ou_A = Bunch()
69
58
59
	def create_user_data(self, ou, is_teacher, is_staff, user_data=None):
60
		data = {
61
			'username': uts.random_string(),
62
			'firstname': uts.random_string(),
63
			'lastname': uts.random_string(),
64
			'ou': ou,
65
			'teacher': '1' if is_teacher else '0',
66
			'staff': '1' if is_staff else '0',
67
		}
68
		if user_data:
69
			data.update(user_data)
70
		self.log.debug('user data=%r', data)
71
		return data
72
70
	def cleanup(self):
73
	def cleanup(self):
71
		self.log.info('Purging %r', self.tmpdir)
74
		self.log.info('Purging %r', self.tmpdir)
72
		shutil.rmtree(self.tmpdir, ignore_errors=True)
75
		shutil.rmtree(self.tmpdir, ignore_errors=True)
Lines 85-110 Link Here
85
			utils.fail('Import failed with exit code %r' % (exitcode,))
88
			utils.fail('Import failed with exit code %r' % (exitcode,))
86
		return exitcode
89
		return exitcode
87
90
88
	def import_users_with_empty_class(self):
91
	def test_import_users_with_empty_class(self):
89
		"""
92
		"""
90
		Import users with empty class
93
		Bug #42288: Import users with empty class
91
		"""
94
		"""
92
		self.log.info('*** Importing users without specified class')
95
		self.log.info('*** Importing users without specifying class')
93
		fn = tempfile.mkstemp(prefix='empty_class.', dir=self.tmpdir)[1]
96
		fn = tempfile.mkstemp(prefix='empty_class.', dir=self.tmpdir)[1]
94
		with open(fn, 'w') as fd:
97
		with open(fn, 'w') as fd:
95
			write_user_line(fd, self.ou_A.name, False, False)
98
			fd.write(self.line % self.create_user_data(self.ou_A.name, False, False))
96
			write_user_line(fd, self.ou_A.name, True, False)
99
			fd.write(self.line % self.create_user_data(self.ou_A.name, True, False))
97
			write_user_line(fd, self.ou_A.name, False, True)
100
			fd.write(self.line % self.create_user_data(self.ou_A.name, False, True))
98
			write_user_line(fd, self.ou_A.name, True, True)
101
			fd.write(self.line % self.create_user_data(self.ou_A.name, True, True))
99
		self.run_import(fn)
102
		self.run_import(fn)
100
		self.log.info('*** TEST WAS SUCCESSFUL')
103
		self.log.info('*** import_users_with_empty_class WAS SUCCESSFUL')
101
104
105
	def test_no_name_normalization(self):
106
		"""
107
		Bug #41934: Import users with umlauts in given name and family name.
108
		They should not be normalized to ASCII.
109
		"""
110
		umlauts = u'äöüßáàñ'
111
112
		def names_with_umlauts():
113
			fn = list(uts.random_string() + umlauts)
114
			random.shuffle(fn)
115
			ln = list(uts.random_string() + umlauts)
116
			random.shuffle(ln)
117
			return dict(
118
				firstname=u''.join(fn),
119
				lastname=u''.join(ln)
120
			)
121
122
		self.log.info('*** Importing users with umlauts in given name and family name')
123
		users = [
124
			self.create_user_data(self.ou_A.name, False, False, names_with_umlauts()),
125
			self.create_user_data(self.ou_A.name, True, False, names_with_umlauts()),
126
			self.create_user_data(self.ou_A.name, False, True, names_with_umlauts()),
127
			self.create_user_data(self.ou_A.name, True, True, names_with_umlauts())
128
		]
129
		fn = tempfile.mkstemp(prefix='no_normalization.', dir=self.tmpdir)[1]
130
		with open(fn, 'w') as fd:
131
			fd.writelines([self.line % user for user in users])
132
		self.run_import(fn)
133
		for user in users:
134
			dn = self.lo.searchDn(filter='uid={}'.format(user['username']), base='cn=users,{}'.format(self.ou_A.dn))
135
			if not dn:
136
				utils.fail('Could not find user with "uid={}" below "cn=users,{}".'.format(user['username'], self.ou_A.dn))
137
			utils.verify_ldap_object(
138
				dn[0],
139
				expected_attr={'givenName': [user['firstname'].encode('utf-8')], 'sn': [user['lastname'].encode('utf-8')]},
140
				strict=False,
141
				should_exist=True)
142
		self.log.info('*** test_no_name_normalization WAS SUCCESSFUL')
143
102
	def run(self):
144
	def run(self):
103
		try:
145
		try:
104
			with utu.UCSTestSchool() as schoolenv:
146
			with utu.UCSTestSchool() as schoolenv:
105
				self.ou_A.name, self.ou_A.dn = schoolenv.create_ou(name_edudc=self.ucr.get('hostname'))
147
				self.ou_A.name, self.ou_A.dn = schoolenv.create_ou(name_edudc=self.ucr.get('hostname'))
148
				self.lo = schoolenv.open_ldap_connection(admin=True)
106
149
107
				self.import_users_with_empty_class()
150
				# self.test_import_users_with_empty_class()
151
				self.test_no_name_normalization()
108
		finally:
152
		finally:
109
			self.cleanup()
153
			self.cleanup()
110
154

Return to bug 41934