pennersr / django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
https://allauth.org
MIT License
9.51k stars 3.03k forks source link

Mutliple apps returned because SITE_ID is not filtered in DefaultSocialAccountAdapter.list_apps() #3576

Closed Razenstein closed 10 months ago

Razenstein commented 10 months ago

I use django-sites model to seperate localhost:8000 and productive_server.de for test purpose.

Django-Allauth with login from e.g. Github throws an exception "MultipleObjectsReturned" even though provider github is twice in the database with 1x "localhost:8000" and 1x "productive_server.de" as SITE_ID.

There is no additional list of providers in settings.py

I have traced down the problem to

env/Lib/site-packages/allauth/socialaccount/adapter.py
   -> DefaultSocialAccountAdapter(object)
     -> list_apps(self, request, provider=None, client_id=None)

  def list_apps(self, request, provider=None, client_id=None):
        """SocialApp's can be setup in the database, or, via
        `settings.SOCIALACCOUNT_PROVIDERS`.  This methods returns a uniform list
        of all known apps matching the specified criteria, and blends both
        (db/settings) sources of data.
        """
        # NOTE: Avoid loading models at top due to registry boot...
        from allauth.socialaccount.models import SocialApp

        # Map provider to the list of apps.
        provider_to_apps = {}

        # First, populate it with the DB backed apps.
        if request:
            db_apps = SocialApp.objects.on_site(request)

            # <-------- filter according "site_id" only if request is given

        else:
            db_apps = SocialApp.objects.all()

in the error trace it turns out that on the way the "request" parameter is not handed over -> so no filter according "site_id" and a thus 2 providers are returned -> exception:

Traceback (most recent call last):
  File "...\env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "...\env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "...\env\lib\site-packages\allauth\socialaccount\providers\oauth2\views.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "...\env\lib\site-packages\allauth\socialaccount\providers\oauth2\views.py", line 162, in dispatch
    return complete_social_login(request, login)
  File "...\env\lib\site-packages\allauth\socialaccount\helpers.py", line 208, in complete_social_login
    sociallogin.lookup()        

    # <-------  from here "request" is lost 

  File "...\env\lib\site-packages\allauth\socialaccount\models.py", line 282, in lookup
    provider_id = self.account.get_provider().id
  File "...\env\lib\site-packages\allauth\socialaccount\models.py", line 141, in get_provider
    provider = self._provider = adapter.get_provider(
  File "...\env\lib\site-packages\allauth\socialaccount\adapter.py", line 205, in get_provider
    app = self.get_app(request, provider=provider)
  File "...\env\lib\site-packages\allauth\socialaccount\adapter.py", line 299, in get_app
    raise MultipleObjectsReturned

I digged deep into the code and it seems a bug to me??

pennersr commented 10 months ago

I think this is fixed over at #3564 -- can you try the current main branch?