Taiga LDAP doesn't authorize only one user

Hello.

My Taiga uses authorization through LDAP (FreePA).

After I switched Taiga from HTTPS to HTTP, one of the users cannot log in.

Here, in the api line I changed HTTPS to HTTP:

@web:/opt/taiga$ cat custom-front/conf.override.json 
{
    "loginFormType": "ldap",
    "api": "http://taiga.corp.xxx.com/api/v1/",
    "eventsUrl": "wss://taiga.corp.xxx.com/events",
    "baseHref": "/",
    "eventsMaxMissedHeartbeats": 5,
    "eventsHeartbeatIntervalTime": 60000,
    "eventsReconnectTryInterval": 10000,
    "debug": false,
    "debugInfo": false,
    "defaultLanguage": "en",
    "themes": ["taiga"],
    "defaultTheme": "taiga",
    "defaultLoginEnabled": true,
    "publicRegisterEnabled": false,
    "feedbackEnabled": true,
    "supportUrl": "https://community.taiga.io/",
    "privacyPolicyUrl": null,
    "termsOfServiceUrl": null,
    "maxUploadFileSize": null,
    "contribPlugins": [],
    "gitHubClientId": "",
    "gitLabClientId": "",
    "gitLabUrl": "",
    "tagManager": { "accountId": null },
    "tribeHost": null,
    "enableAsanaImporter": false,
    "enableGithubImporter": false,
    "enableJiraImporter": false,
    "enableTrelloImporter": false,
    "gravatar": false,
    "rtlLanguages": [
        "ar",
        "fa",
        "he"
    ]
}

If any user tries to log in, everything will be fine.

Here’s what it looks like using a python script that I borrowed from a neighboring topic.

import requests
from getpass import getpass

TAIGA_BASE="http://taiga.corp.xxx.com"

r = requests.post(
    f"{TAIGA_BASE}/api/v1/auth",
    json={
        "type": "ldap",
        "username": input("Username: "),
        "password": getpass(),
    },
)

print(r.status_code)

Execution result

max@max:~/requests.py
Username: mkostromin
Password: 
200
max@max:~/requests.py
Username: ezelenov
Password: 
500
max@max:~/requests.py
Username: ezelenov
Password: 
500

At the same time, in the backend logs

taiga-back             | ERROR:2024-06-26 11:22:47,097: Internal Server Error: /api/v1/auth
taiga-back             | Traceback (most recent call last):
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/taiga_contrib_ldap_auth/services.py", line 41, in ldap_register
taiga-back             |     user = user_model.objects.get(username=username)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/manager.py", line 85, in manager_method
taiga-back             |     return getattr(self.get_queryset(), name)(*args, **kwargs)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/query.py", line 435, in get
taiga-back             |     raise self.model.DoesNotExist(
taiga-back             | taiga.users.models.User.DoesNotExist: User matching query does not exist.
taiga-back             | 
taiga-back             | During handling of the above exception, another exception occurred:
taiga-back             | 
taiga-back             | Traceback (most recent call last):
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute
taiga-back             |     return self.cursor.execute(sql, params)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             | psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "users_user_email_243f6e77_uniq"
taiga-back             | DETAIL:  Key (email)=(ezelenov@xxx.com) already exists.
taiga-back             | 
taiga-back             | 
taiga-back             | The above exception was the direct cause of the following exception:
taiga-back             | 
taiga-back             | Traceback (most recent call last):
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 47, in inner
taiga-back             |     response = get_response(request)
taiga-back             |                ^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 181, in _get_response
taiga-back             |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
taiga-back             |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/taiga-back/taiga/base/api/viewsets.py", line 95, in view
taiga-back             |     return self.dispatch(request, *args, **kwargs)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
taiga-back             |     return view_func(*args, **kwargs)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/taiga-back/taiga/base/api/views.py", line 449, in dispatch
taiga-back             |     response = self.handle_exception(exc)
taiga-back             |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/taiga-back/taiga/base/api/views.py", line 447, in dispatch
taiga-back             |     response = handler(request, *args, **kwargs)
taiga-back             |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/taiga-back/taiga/auth/api.py", line 77, in create
taiga-back             |     data = auth_plugins[login_type]['login_func'](request)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/taiga_contrib_ldap_auth/services.py", line 58, in ldap_login_func
taiga-back             |     user = ldap_register(username=username, email=email, full_name=full_name)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/usr/local/lib/python3.11/contextlib.py", line 81, in inner
taiga-back             |     return func(*args, **kwds)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/taiga_contrib_ldap_auth/services.py", line 45, in ldap_register
taiga-back             |     user = user_model.objects.create(email=email,
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/manager.py", line 85, in manager_method
taiga-back             |     return getattr(self.get_queryset(), name)(*args, **kwargs)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/query.py", line 453, in create
taiga-back             |     obj.save(force_insert=True, using=self.db)
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/contrib/auth/base_user.py", line 67, in save
taiga-back             |     super().save(*args, **kwargs)
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/base.py", line 739, in save
taiga-back             |     self.save_base(using=using, force_insert=force_insert,
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/base.py", line 776, in save_base
taiga-back             |     updated = self._save_table(
taiga-back             |               ^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/base.py", line 881, in _save_table
taiga-back             |     results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
taiga-back             |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/base.py", line 919, in _do_insert
taiga-back             |     return manager._insert(
taiga-back             |            ^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/manager.py", line 85, in manager_method
taiga-back             |     return getattr(self.get_queryset(), name)(*args, **kwargs)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/query.py", line 1270, in _insert
taiga-back             |     return query.get_compiler(using=using).execute_sql(returning_fields)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1416, in execute_sql
taiga-back             |     cursor.execute(sql, params)
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/raven/contrib/django/client.py", line 127, in execute
taiga-back             |     return real_execute(self, sql, params)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 66, in execute
taiga-back             |     return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
taiga-back             |     return executor(sql, params, many, context)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in _execute
taiga-back             |     with self.db.wrap_database_errors:
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/utils.py", line 90, in __exit__
taiga-back             |     raise dj_exc_value.with_traceback(traceback) from exc_value
taiga-back             |   File "/opt/venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute
taiga-back             |     return self.cursor.execute(sql, params)
taiga-back             |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
taiga-back             | django.db.utils.IntegrityError: duplicate key value violates unique constraint "users_user_email_243f6e77_uniq"
taiga-back             | DETAIL:  Key (email)=(ezelenov@xxx.com) already exists.

I see in the logs that DETAIL: Key (email)=(ezelenov@xxx.com) already exists., but I don’t understand how this happened? This user successfully logged in a few days ago.

Please, help me!

Hi there!

It seems, from the logs, that the username does not exist on your Taiga’s db. Please check from the admin that it is indeed ezelenov the username, and not ezelonv123 or something of the sort.

Then, when it tries to create the user, it finds out that there is indeed a user with that email (that is not named ezelenov, because it checked for that before) and throws that error.

So probably, the user exists, but they have a different username on your platform. Perhaps they are using the entire email as a username.

Best regards!