Bug 51907 - udm/add (users/user): AttributeError: 'NoneType' object has no attribute 'lower'
udm/add (users/user): AttributeError: 'NoneType' object has no attribute 'lower'
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: UDM (Generic)
UCS 4.4
Other Linux
: P5 normal (vote)
: UCS 4.4-6-errata
Assigned To: Florian Best
Dirk Wiesenthal
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2020-08-26 15:29 CEST by Christian Castens
Modified: 2020-10-14 15:28 CEST (History)
7 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 4: Minor Usability: Impairs usability in secondary scenarios
Who will be affected by this bug?: 3: Will affect average number of installed domains
How will those affected feel about the bug?: 4: A User would return the product
User Pain: 0.274
Enterprise Customer affected?: Yes
School Customer affected?: Yes
ISV affected?:
Waiting Support: Yes
Flags outvoted (downgraded) after PO Review:
Ticket number: 2020082521000433, 2020091421000078
Bug group (optional): Error handling, External feedback
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Castens univentionstaff 2020-08-26 15:29:36 CEST
Version: 4.4-5 errata712 (Blumenthal) - UCS@school 4.4 v6

Remark: Anlegen eines neuen Benutzers fehlgeschlagen

Error:
Interner Server-Fehler in "udm/add (users/user)".
Request: udm/add (users/user)

  File "%PY2.7%/notifier/threads.py", line 80, in _run
    result = self._function()
  File "%PY2.7%/notifier/__init__.py", line 104, in __call__
    return self._function(*tmp, **self._kwargs)
  File "%PY2.7%/univention/management/console/modules/udm/__init__.py", line 402, in _thread
    dn = module.create(properties, container=options.get('container'), superordinate=options.get('superordinate'))
  File "%PY2.7%/univention/management/console/modules/udm/udm_ldap.py", line 566, in create
    obj.create()
  File "%PY2.7%/univention/admin/handlers/__init__.py", line 554, in create
    self._ldap_pre_ready()
  File "%PY2.7%/univention/admin/handlers/users/user.py", line 1649, in _ldap_pre_ready
    if self['mailPrimaryAddress'] and self['mailPrimaryAddress'].lower() != self.oldinfo.get('mailPrimaryAddress', '').lower():
AttributeError: 'NoneType' object has no attribute 'lower'

Role: domaincontroller_master
Comment 1 Dirk Schnick univentionstaff 2020-09-15 16:11:04 CEST
Another customer with that Traceback. Importer fails during creation of new users.
Comment 3 Sönke Schwardt-Krummrich univentionstaff 2020-09-15 17:13:04 CEST
Currently, we (Daniel + Sönke) suspect that the OX-UDM hook in conjunction with a past UDM change is responsible for the traceback.
Comment 4 Dirk Schnick univentionstaff 2020-10-07 13:22:19 CEST
The customer asks not completely unjustified when something will happen in this regard.
Comment 5 Florian Best univentionstaff 2020-10-08 11:15:21 CEST
See Bug #44944: Accessing a property sets the default value:

>>> import univention.admin.modules
>>> lo, po = univention.admin.uldap.getMachineConnection()
>>> univention.admin.modules.update()
>>> u = univention.admin.modules.get('users/user')
>>> us = u.object(None, lo, po) 
>>> us.info
{}
>>> us['mailPrimaryAddress']
>>> us.info
{'mailPrimaryAddress': None}

We see that this is done in the UDM Hook for OX:
/usr/lib/python2.7/dist-packages/univention/admin/hooks.d/oxAccess.py
        @staticmethod
        def check_mailaddr(module):
                if module['mailPrimaryAddress']:
                        domain = module['mailPrimaryAddress'].rsplit('@')[-1]


univentionAppID=oxseforucs_7.10.2-ucs3,cn=oxseforucs,cn=apps,cn=univention
Comment 6 Florian Best univentionstaff 2020-10-08 13:05:32 CEST
Executing the following code:

import univention.admin.modules
lo, po = univention.admin.uldap.getMachineConnection()
univention.admin.modules.update()
u = univention.admin.modules.get('users/user')
univention.admin.modules.init(lo, po, u)
us = u.object(None, lo, po)
us.open()
print(us.info)

We can see:
{'oxLanguage': 'de_DE', 'mailPrimaryAddress': None, 'firstname': None, 'lastname': None, 'oxTimeZone': 'Europe/Berlin', 'primaryGroup': 'cn=Domain Users,cn=groups,', 'oxDisplayName': '  ()', 'isOxUser': 'Not', 'oxAccess': 'premium', 'UniventionOffice365ADConnections': []}

In a regular UCS System, mailPrimaryAddress is not set after this. OX accesses the mailPrimaryAddress in hook_open().

/usr/lib/python2.7/dist-packages/univention/admin/hooks.d/oxUserDefaults.py has hook_open() which is causing this.
We can see that the default for 'oxDisplayName' is '<firstname> <lastname> (<mailPrimaryAddress>)'.

We can reproduce it with:
/usr/lib/python2.7/dist-packages/univention/admincli/admin.py users/user create --set username=fbest --set lastname=univention --set password=univention --set mailPrimaryAddress=fbest@foobar.com

The exception is triggered by `self.oldinfo.get('mailPrimaryAddress', '').lower()`

A reproducer-script is in the commit message. The error has been fixed in UDM, so OX doesn't have to be adjusted:

univention-directory-manager-modules (14.0.16-5)
93fc7f9d4e91 | Bug #51907: fix crash in users/user if mailPrimaryAddress property default value is set in open()

univention-system-setup (8.0.2-1)
r51907 | Bug #35145: Bug #35267: remove dependency and build-dependency on

univention-directory-manager-modules.yaml
d16b713710aa | YAML Bug #51907
Comment 7 Florian Best univentionstaff 2020-10-08 13:08:30 CEST
Forgot to mention the technical reason:
self['mailPrimaryAddress'] sets self.info['mailPrimaryAddress'] during open().
open() calls self.save() at the end, which stores self.info in self.oldinfo.
Comment 8 Dirk Wiesenthal univentionstaff 2020-10-14 10:17:48 CEST
Tests: OK
YAML: OK
Code: OK
Manual test: OK