adapters: do not exclude already linked users (#76083)
gitea/django-mellon/pipeline/head This commit looks good Details

When two IdP are used with common directory accounts of if we migrate
from a test IdP to a production IdP, it can be useful to relink existing
users to the new source.
This commit is contained in:
Benjamin Dauvergne 2023-04-01 17:25:09 +02:00
parent ada3eda21e
commit 0f7044e7a0
2 changed files with 22 additions and 3 deletions

View File

@ -437,9 +437,8 @@ class DefaultAdapter:
key = user_field
if ignore_case:
key += '__iexact'
users_found = self.get_users_queryset(idp, saml_attributes).filter(
saml_identifiers__isnull=True, **{key: value}
)
users_qs = self.get_users_queryset(idp, saml_attributes)
users_found = users_qs.filter(**{key: value})
if not users_found:
logger.warning(
'mellon: looking for users by attribute %r and user field %r with value %r: not found',

View File

@ -25,6 +25,7 @@ import pytest
from django.contrib import auth
from django.db import connection
from mellon import models
from mellon.adapters import DefaultAdapter
from mellon.backends import SAMLBackend
@ -351,6 +352,25 @@ def test_lookup_user_by_attributes_ignore_case(settings, idp, saml_attributes, j
assert adapter.lookup_user(idp, saml_attributes) == jane
def test_lookup_user_by_attributes_two_idps(settings, idp, saml_attributes, john, jane, caplog):
'''Check that with lookup by attributes we can link an user with an
existing link with another IdP, use case: migrating from a test IdP to a
production IdP without having to unlink all already loaded users.'''
settings.MELLON_PROVISION = False
adapter = DefaultAdapter()
saml_attributes['saml_at1'] = ['john.doe']
settings.MELLON_LOOKUP_BY_ATTRIBUTES = [
{'user_field': 'username', 'saml_attribute': 'saml_at1'},
]
assert models.UserSAMLIdentifier.objects.count() == 0
assert adapter.lookup_user(idp, saml_attributes) == john
assert models.UserSAMLIdentifier.objects.count() == 1
saml_attributes['issuer'] = 'http://idp6/metadata'
assert adapter.lookup_user(idp, saml_attributes) == john
assert models.UserSAMLIdentifier.objects.count() == 2
@pytest.fixture
def adapter():
return DefaultAdapter()