Skip to content

[Bug]: Probleme with jpegPhoto ldap attribute #60

Description

@wallon-ines

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

  1. Clone git repository
  2. Copy and edit process file in /etc/sogo/
  3. Edit domain_settings.json config file (see below)
  4. 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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions