Bug 42445

Summary: Create student with school classes in two schools failed
Product: UCS@school Reporter: Michel Smidt <michelsmidt>
Component: Ucsschool-libAssignee: Daniel Tröder <troeder>
Status: CLOSED DUPLICATE QA Contact: Florian Best <best>
Severity: normal    
Priority: P5 CC: grandjean, schwardt, troeder
Version: UCS@school 4.1 R2Keywords: interim-2
Target Milestone: UCS@school 4.1 R2 vXXX   
Hardware: Other   
OS: Linux   
What kind of report is it?: Development Internal What type of bug is this?: ---
Who will be affected by this bug?: --- How will those affected feel about the bug?: ---
User Pain: Enterprise Customer affected?:
School Customer affected?: ISV affected?:
Waiting Support: Flags outvoted (downgraded) after PO Review:
Ticket number: Bug group (optional):
Max CVSS v3 score:

Description Michel Smidt 2016-09-20 13:59:42 CEST
appcenter/apps/ucsschool/version: 4.1 R2 v4

First created two schools in UMC.

root@dc:~# python
Python 2.7.3 (default, Aug 29 2016, 16:34:01) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ucsschool.lib.models import Student
>>> from univention.admin import uldap
>>> connection, position = uldap.getAdminConnection()
>>> school_classes2 = {}
>>> school_classes2["Schule1"] = ['1A']
>>> student2 = Student(school="Schule1", schools=["Schule1", "Schule2"], name="student2", lastname="Student2lastname", firstname="Student2firstname", school_classes=school_classes2)
>>> student2.create(lo=connection)
True
>>> udm_student2 = student2.get_udm_object(lo=connection)
>>> print udm_student2['groups']
['cn=schueler-schule1,cn=groups,ou=Schule1,dc=prog,dc=int', 'cn=Domain Users Schule1,cn=groups,ou=Schule1,dc=prog,dc=int', 'cn=Schule1-1A,cn=klassen,cn=schueler,cn=groups,ou=Schule1,dc=prog,dc=int']

<- OK. Class "Schule1-1A" will be automatically created.

>>> school_classes3 = {}
>>> school_classes3["Schule1"] = ['1A']
>>> school_classes3["Schule2"] = ['2A']
>>> student3 = Student(school="Schule1", schools=["Schule1", "Schule2"], name="student3", lastname="Student3lastname", firstname="Student3firstname", school_classes=school_classes3)
>>> student3.create(lo=connection)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 417, in create
    success = self.create_without_hooks(lo, validate)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 443, in create_without_hooks
    self.do_create(udm_obj, lo)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/user.py", line 247, in do_create
    success = super(User, self).do_create(udm_obj, lo)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 460, in do_create
    udm_obj.create()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/__init__.py", line 295, in create
    return self._create()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/__init__.py", line 722, in _create
    self._ldap_post_create()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/users/user.py", line 1845, in _ldap_post_create
    self.__update_groups()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/users/user.py", line 1643, in __update_groups
    grpobj.fast_member_add( [ self.dn ], [ new_uid ] )
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/groups/group.py", line 433, in fast_member_add
    return self.lo.modify(self.dn, ml)
  File "/usr/lib/pymodules/python2.7/univention/admin/uldap.py", line 393, in modify
    raise univention.admin.uexceptions.noObject(dn)
univention.admin.uexceptions.noObject: cn=Schule2-2A,cn=klassen,cn=schueler,cn=groups,ou=Schule2,dc=prog,dc=int

<- Not OK

I would expect that the class "Schule2-2A" will be automatically created as well.
Comment 1 Daniel Tröder univentionstaff 2016-09-21 11:04:58 CEST
While there is conversion code for backwards compatibility to create Users with an argument school_classes={<ou>: [<class_name>, ...]}, using the ucsschool.lib like that is not actually correct.

Please create Users with school_classes={<ou>: [<ou>-<class_name>, ...]}. That will also work with multiple OUs.
Comment 2 Michel Smidt 2016-09-21 11:23:47 CEST
(In reply to Daniel Tröder from comment #1)
> Please create Users with school_classes={<ou>: [<ou>-<class_name>, ...]}.
> That will also work with multiple OUs.

Would be great and completely sufficient but I got a traceback as well:

>>> school_classes3 = {}
>>> school_classes3["Schule1"] = ['Schule1-1A']
>>> school_classes3["Schule2"] = ['Schule2-2A']
>>> print school_classes3
{'Schule1': ['Schule1-1A'], 'Schule2': ['Schule2-2A']}                                                       
>>> student3 = Student(school="Schule1", schools=["Schule1", "Schule2"], name="student3", lastname="Student3lastname", firstname="Student3firstname", school_classes=school_classes3)
>>> student3.create(lo=connection)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 417, in create
    success = self.create_without_hooks(lo, validate)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 443, in create_without_hooks
    self.do_create(udm_obj, lo)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/user.py", line 247, in do_create
    success = super(User, self).do_create(udm_obj, lo)
  File "/usr/lib/pymodules/python2.7/ucsschool/lib/models/base.py", line 460, in do_create
    udm_obj.create()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/__init__.py", line 295, in create
    return self._create()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/__init__.py", line 722, in _create
    self._ldap_post_create()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/users/user.py", line 1845, in _ldap_post_create
    self.__update_groups()
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/users/user.py", line 1643, in __update_groups
    grpobj.fast_member_add( [ self.dn ], [ new_uid ] )
  File "/usr/lib/pymodules/python2.7/univention/admin/handlers/groups/group.py", line 433, in fast_member_add
    return self.lo.modify(self.dn, ml)
  File "/usr/lib/pymodules/python2.7/univention/admin/uldap.py", line 393, in modify
    raise univention.admin.uexceptions.noObject(dn)
univention.admin.uexceptions.noObject: cn=Schule2-2A,cn=klassen,cn=schueler,cn=groups,ou=Schule2,dc=schulen-fulda,dc=intranet
Comment 3 Daniel Tröder univentionstaff 2016-09-22 15:40:24 CEST
I tried out your code and it works for me. This seems to be fixed in the unreleased errata scope. Please update and retest.

Not sure in which bug this was fixed...

*** This bug has been marked as a duplicate of bug 40870 ***
Comment 4 Florian Best univentionstaff 2016-10-24 17:37:37 CEST
Thank you Michel for the detailed bug information!

I could not reproduce this either:
# dpkg -l python-ucs-school
ii  python-ucs-school                                              9.0.26-1.266.201610241307
# /usr/share/ucs-school-import/scripts/create_ou Schule1
# /usr/share/ucs-school-import/scripts/create_ou Schule2
# python
>>> from ucsschool.lib.models import Student
>>> import univention.admin.uldap
>>> lo, po = univention.admin.uldap.getMachineConnection()
>>> school_classes = {"Schule1": ["Schule1-1A"], "Schule2": ["Schule2-1B"]}
>>> s = Student(school="Schule1", schools=["Schule1", "Schule2"], name="student1", lastname="Student1lastname", firstname="Student1firstname", school_classes=school_classes)
>>> s.create(lo)
True
>>> s_udm = s.get_udm_object(lo)
>>> print s_udm['groups']
['cn=schueler-schule1,cn=groups,ou=Schule1,dc=school,dc=local', 'cn=Domain Users schule1,cn=groups,ou=Schule1,dc=school,dc=local', 'cn=schueler-schule2,cn=groups,ou=Schule2,dc=school,dc=local', 'cn=Domain Users schule2,cn=groups,ou=Schule2,dc=school,dc=local', 'cn=Schule1-1A,cn=klassen,cn=schueler,cn=groups,ou=Schule1,dc=school,dc=local', 'cn=Schule2-1B,cn=klassen,cn=schueler,cn=groups,ou=Schule2,dc=school,dc=local']