commit 415ec6c2733c9a26b47fe3b6b0298c96e7718a3c Author: dtroeder Date: Wed May 3 13:26:53 2017 +0000 Bug #43019: add all exam users to their groups in one go git-svn-id: svn+ssh://billy.knut.univention.de/var/univention/svn/dev/branches/ucs-4.2/ucs-school-4.2@79049 1b283449-9f2f-0410-b571-8eb228e1a901 diff --git a/ucs-school-umc-exam/umc/python/schoolexam-master/__init__.py b/ucs-school-umc-exam/umc/python/schoolexam-master/__init__.py index 3b8ae99..f3eba59 100644 --- a/ucs-school-umc-exam/umc/python/schoolexam-master/__init__.py +++ b/ucs-school-umc-exam/umc/python/schoolexam-master/__init__.py @@ -43,12 +43,14 @@ import subprocess import tempfile from ldap.filter import filter_format +from ldap import explode_dn +from collections import defaultdict from univention.management.console.config import ucr from univention.management.console.log import MODULE from univention.management.console.modules import UMC_Error from univention.management.console.modules.decorators import sanitize -from univention.management.console.modules.sanitizers import StringSanitizer +from univention.management.console.modules.sanitizers import StringSanitizer, DNSanitizer, ListSanitizer from ucsschool.lib.schoolldap import LDAP_Connection, SchoolBaseModule, ADMIN_WRITE, USER_READ from ucsschool.lib.models import School, ComputerRoom, Student, ExamStudent, MultipleObjectsError @@ -200,7 +202,7 @@ def create_exam_user(self, request, ldap_user_read=None, ldap_admin_write=None, return # Ok, we have a valid target uid, so start cloning the user - # deepcopy(user_orig) soes not help much, as we cannot use users.user.object.create() + # deepcopy(user_orig) does not help much, as we cannot use users.user.object.create() # because it currently cannot be convinced to preserve the password. So we do it manually: try: # Allocate new uidNumber @@ -328,26 +330,6 @@ def getBlacklistSet(ucrvar): MODULE.error('Creation of exam user account failed: %s' % (traceback.format_exc(),)) raise - # Add exam_user to groups - if 'groups/group' in self._udm_modules: - module_groups_group = self._udm_modules['groups/group'] - else: - module_groups_group = univention.admin.modules.get('groups/group') - univention.admin.modules.init(ldap_admin_write, ldap_position, module_groups_group) - self._udm_modules['groups/group'] = module_groups_group - - if 'posix' in user_orig.options: - grpobj = module_groups_group.object(None, ldap_admin_write, ldap_position, user_orig['primaryGroup']) - grpobj.fast_member_add([exam_user_dn], [exam_user_uid]) - - for group in user_orig.info.get('groups', []): - grpobj = module_groups_group.object(None, ldap_admin_write, ldap_position, group) - grpobj.fast_member_add([exam_user_dn], [exam_user_uid]) - - # Add exam_user to examGroup - examGroup = self.examGroup(ldap_admin_write, ldap_position, user.school or school) - examGroup.fast_member_add([exam_user_dn], [exam_user_uid]) - # finally confirm allocated IDs univention.admin.allocators.confirm(ldap_admin_write, ldap_position, 'uid', exam_user_uid) if 'samba' in user_orig.options: @@ -359,7 +341,52 @@ def getBlacklistSet(ucrvar): success=True, userdn=userdn, examuserdn=exam_user_dn, - ), success=True) + examuseruid=exam_user_uid, + )) + + @sanitize( + users=ListSanitizer(DNSanitizer(required=True), required=True), + school=StringSanitizer(required=True) + ) + @LDAP_Connection(USER_READ, ADMIN_WRITE) + def add_exam_users_to_groups(self, request, ldap_user_read=None, ldap_admin_write=None, ldap_position=None): + """ + Add previously created exam users to groups. + """ + groups = defaultdict(dict) + exam_group = self.examGroup(ldap_admin_write, ldap_position, request.options['school']) + + for user_dn in request.options['users']: + try: + ori_student = Student.from_dn(user_dn, None, ldap_admin_write) + exam_student = ExamStudent.from_student_dn(ldap_admin_write, ori_student.school, ori_student.dn) + except univention.admin.uexceptions.noObject: + raise UMC_Error(_('Student %r not found.') % (user_dn,)) + except univention.admin.uexceptions.ldapError: + raise + + udm_ori_student = ori_student.get_udm_object(ldap_admin_write) + if 'posix' in udm_ori_student.options: # why only if posix? + groups[udm_ori_student['primaryGroup']].setdefault('dns', set()).add(exam_student.dn) + groups[udm_ori_student['primaryGroup']].setdefault('uids', set()).add(exam_student.name) + for grp in udm_ori_student.info.get('groups', []): + groups[grp].setdefault('dns', set()).add(exam_student.dn) + groups[grp].setdefault('uids', set()).add(exam_student.name) + + groups[exam_group.dn].setdefault('dns', set()).add(exam_student.dn) + groups[exam_group.dn].setdefault('uids', set()).add(exam_student.name) + + if 'groups/group' not in self._udm_modules: + self._udm_modules['groups/group'] = univention.admin.modules.get('groups/group') + univention.admin.modules.init(ldap_admin_write, ldap_position, self._udm_modules['groups/group']) + module_groups_group = self._udm_modules['groups/group'] + + for group_dn, users in groups.items(): + grpobj = module_groups_group.object(None, ldap_admin_write, ldap_position, group_dn) + MODULE.info('Adding users %r to group %r...' % (users['uids'], group_dn)) + grpobj.fast_member_add(users['dns'], users['uids']) + + self.finished(request.id, None) @sanitize( userdn=StringSanitizer(required=True), diff --git a/ucs-school-umc-exam/umc/python/schoolexam/__init__.py b/ucs-school-umc-exam/umc/python/schoolexam/__init__.py index 3e55d6a..14a11df 100644 --- a/ucs-school-umc-exam/umc/python/schoolexam/__init__.py +++ b/ucs-school-umc-exam/umc/python/schoolexam/__init__.py @@ -253,22 +253,30 @@ def _thread(): progress.component(_('Preparing exam accounts')) percentPerUser = 25.0 / (1 + len(users)) examUsers = set() + student_dns = set() usersReplicated = set() for iuser in users: progress.info('%s, %s (%s)' % (iuser.lastname, iuser.firstname, iuser.username)) try: ires = client.umc_command('schoolexam-master/create-exam-user', dict( school=request.options['school'], - userdn=iuser.dn + userdn=iuser.dn, )).result - examUsers.add(ires.get('examuserdn')) - MODULE.info('Exam user has been created: %s' % ires.get('examuserdn')) + examuser_dn = ires.get('examuserdn') + examUsers.add(examuser_dn) + student_dns.add(iuser.dn) + MODULE.info('Exam user has been created: %r' % examuser_dn) except (ConnectionError, HTTPError) as exc: MODULE.warn('Could not create exam user account for %r: %s' % (iuser.dn, exc)) # indicate the the user has been processed progress.add_steps(percentPerUser) + client.umc_command('schoolexam-master/add-exam-users-to-groups', dict( + users=list(student_dns), + school=request.options['school'], + )) + progress.add_steps(percentPerUser) # wait for the replication of all users to be finished diff --git a/ucs-school-umc-exam/umc/schoolexam-master.xml b/ucs-school-umc-exam/umc/schoolexam-master.xml index dd188db..2c38c4d 100644 --- a/ucs-school-umc-exam/umc/schoolexam-master.xml +++ b/ucs-school-umc-exam/umc/schoolexam-master.xml @@ -4,18 +4,10 @@ Start exam Starts a new exam for a specified computer room - - - - - - - - - - - - - + + + + +