@@ -, +, @@
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
--- a/ucs-school-umc-exam/umc/python/schoolexam-master/__init__.py
+++ a/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),
--- a/ucs-school-umc-exam/umc/python/schoolexam/__init__.py
+++ a/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
--- a/ucs-school-umc-exam/umc/schoolexam-master.xml
+++ a/ucs-school-umc-exam/umc/schoolexam-master.xml
@@ -4,18 +4,10 @@
Start exam
Starts a new exam for a specified computer room
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+