What happened?
Summary
I have an error when I try to log in with my OpenLDAP server because parse_python_ldap_record function doesn't like jpegPhoto attribute.
2026-07-23 19:22:59,820 <48609> [INFO][werkzeug][_internal.py:_log:97]: 192.168.13.50 - - [23/Jul/2026 19:22:59] "POST /api/user/v1/auth/login HTTP/1.1" 500 -
Traceback (most recent call last):
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/app.py", line 1536, in __call__
return self.wsgi_app(environ, start_response)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/app.py", line 1514, in wsgi_app
response = self.handle_exception(e)
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask_cors/extension.py", line 206, in wrapped_function
return cors_after_request(app_any.make_response(f(*args, **kwargs)))
~^^^^^^^^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/app.py", line 1511, in wsgi_app
response = self.full_dispatch_request()
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/app.py", line 919, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask_cors/extension.py", line 206, in wrapped_function
return cors_after_request(app_any.make_response(f(*args, **kwargs)))
~^^^^^^^^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/views.py", line 110, in view
return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask/views.py", line 191, in dispatch_request
return current_app.ensure_sync(meth)(**kwargs) # type: ignore[no-any-return]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/webargs/core.py", line 652, in wrapper
return func(*args, **kwargs)
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask_smorest/arguments.py", line 85, in wrapper
return current_app.ensure_sync(func)(*f_args, **f_kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File "/root/.cache/pypoetry/virtualenvs/sogo-JX6dU3c6-py3.14/lib/python3.14/site-packages/flask_smorest/response.py", line 89, in wrapper
current_app.ensure_sync(func)(*args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/var/sogo6/server/app/api/v1/auth/AuthUserApi.py", line 66, in post
return interface_api.plain_login(new_data)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/var/sogo6/server/app/interface/auth/InterfaceAuthUser.py", line 91, in plain_login
success, user, module_us = self._check_login(uid, password)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "/var/sogo6/server/app/interface/auth/InterfaceAuthUser.py", line 77, in _check_login
return module_us.check_login(user), user, module_us
~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/var/sogo6/server/app/module/auth/ModuleUserSource.py", line 99, in check_login
auth, raw_policy, raw_contact = self._make_us_check_login(source_settings, user)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/var/sogo6/server/app/module/auth/ModuleUserSource.py", line 72, in _make_us_check_login
return client_us.check_login(user.uid, user.password, user.domain)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/sogo6/server/app/manager/ldap/ClientLdap.py", line 299, in check_login
contact = parse_python_ldap_record(list_records[0])
File "/var/sogo6/server/app/manager/ldap/ClientLdap.py", line 90, in parse_python_ldap_record
user_dict[attribute] = [x.decode() for x in values]
~~~~~~~~^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
But if I exclude this attribute, I no longer get that error.
diff --git a/app/manager/ldap/ClientLdap.py b/app/manager/ldap/ClientLdap.py
index 7a8f141..6549195 100644
--- a/app/manager/ldap/ClientLdap.py
+++ b/app/manager/ldap/ClientLdap.py
@@ -87,7 +87,8 @@ def parse_python_ldap_record(record: tuple[str, dict[str, list[bytes]]]) -> dict
"""
user_dict: dict[str, list[str]] = {}
for attribute, values in record[1].items():
- user_dict[attribute] = [x.decode() for x in values]
+ if attribute != "jpegPhoto":
+ user_dict[attribute] = [x.decode() for x in values]
user_dict["dn"] = [record[0]]
return user_dict
Environment
- Rocky Linux 9
- Sogo v6 (#3d25472)
- python3.14-3.14.5-1.el9_8.x86_64
- postgresql-server-13.23-2.el9_7.x86_64
- openldap-servers-2.6.8-2.el9.x86_64
- redis-8.8.0-1.x86_64 (from official Redis DNF repo)
Steps to reproduce
- Clone git repository
- Copy and edit process file in
/etc/sogo/
- Edit domain_settings.json config file (see below)
- Run poetry with
poetry run start
{
"settings": {
"USER_SOURCE": {
"ldap_ex": {
"US_UID": "ldap_ex",
"US_KIND": "description",
"US_MAIL": [
"mail"
],
"US_NAME": "ldap1.drupalista.lan",
"US_TYPE": "ldap",
"US_LDAP_CN": "cn",
"US_LDAP_ID": "mail",
"US_CAN_AUTH": true,
"US_LDAP_UID": "uid",
"US_LDAP_PORT": 389,
"US_LDAP_SCOPE": "SUB",
"US_PWD_POLICY": false,
"US_AUTO_SEARCH": true,
"US_PWD_LEN_MAX": 0,
"US_PWD_LEN_MIN": 3,
"US_HAS_RESOURCE": true,
"US_LDAP_BASE_DN": "ou=Users,domainName=xxxxxxxx,o=domains,dc=xxxxxxxx,dc=xxxxxxxx",
"US_LDAP_BIND_DN": "cn=xxxxxx,dc=xxxxxx,dc=xxxxxx",
"US_LDAP_HOSTNAME": "ldap1.drupalista.lan",
"US_IS_ADDRESSBOOK": true,
"US_PWD_DIGITS_MIN": 0,
"US_LDAP_ATTR_FIELD": [
"*"
],
"US_LDAP_ENCRYPTION": "None",
"US_LDAP_PWD_POLICY": false,
"US_PWD_SPECIAL_MIN": 0,
"US_AUTO_QUERY_LIMIT": 0,
"US_LDAP_BIND_DN_PWD": "xxxxxxxxxxxxxxxxxxxxx",
"US_LDAP_GROUP_CLASS": [
"group",
"groupOfNames",
"groupOfUniqueNames",
"posixGroup"
],
"US_LDAP_BIND_AS_USER": false,
"US_PWD_LOWERCASE_MIN": 0,
"US_PWD_UPPERCASE_MIN": 0,
"US_LDAP_QUERY_TIMEOUT": 0,
"US_PWD_SPECIAL_ALLOWED": "%$&*(){}[]!?\\/@#.,:;+=<>-_",
"US_LDAP_PWD_UPDATE_SAMBA": false,
"US_RESOURCE_MULTIBOOKING": "departmentNumber"
}
},
[...]
}
}
Version
6.0.0-alpha1
Relevant log output
Upload screenshots
No response
What happened?
Summary
I have an error when I try to log in with my OpenLDAP server because
parse_python_ldap_recordfunction doesn't likejpegPhotoattribute.But if I exclude this attribute, I no longer get that error.
Environment
Steps to reproduce
/etc/sogo/poetry run start{ "settings": { "USER_SOURCE": { "ldap_ex": { "US_UID": "ldap_ex", "US_KIND": "description", "US_MAIL": [ "mail" ], "US_NAME": "ldap1.drupalista.lan", "US_TYPE": "ldap", "US_LDAP_CN": "cn", "US_LDAP_ID": "mail", "US_CAN_AUTH": true, "US_LDAP_UID": "uid", "US_LDAP_PORT": 389, "US_LDAP_SCOPE": "SUB", "US_PWD_POLICY": false, "US_AUTO_SEARCH": true, "US_PWD_LEN_MAX": 0, "US_PWD_LEN_MIN": 3, "US_HAS_RESOURCE": true, "US_LDAP_BASE_DN": "ou=Users,domainName=xxxxxxxx,o=domains,dc=xxxxxxxx,dc=xxxxxxxx", "US_LDAP_BIND_DN": "cn=xxxxxx,dc=xxxxxx,dc=xxxxxx", "US_LDAP_HOSTNAME": "ldap1.drupalista.lan", "US_IS_ADDRESSBOOK": true, "US_PWD_DIGITS_MIN": 0, "US_LDAP_ATTR_FIELD": [ "*" ], "US_LDAP_ENCRYPTION": "None", "US_LDAP_PWD_POLICY": false, "US_PWD_SPECIAL_MIN": 0, "US_AUTO_QUERY_LIMIT": 0, "US_LDAP_BIND_DN_PWD": "xxxxxxxxxxxxxxxxxxxxx", "US_LDAP_GROUP_CLASS": [ "group", "groupOfNames", "groupOfUniqueNames", "posixGroup" ], "US_LDAP_BIND_AS_USER": false, "US_PWD_LOWERCASE_MIN": 0, "US_PWD_UPPERCASE_MIN": 0, "US_LDAP_QUERY_TIMEOUT": 0, "US_PWD_SPECIAL_ALLOWED": "%$&*(){}[]!?\\/@#.,:;+=<>-_", "US_LDAP_PWD_UPDATE_SAMBA": false, "US_RESOURCE_MULTIBOOKING": "departmentNumber" } }, [...] } }Version
6.0.0-alpha1
Relevant log output
Upload screenshots
No response