python-social-auth / social-app-django

Python Social Auth - Application - Django
BSD 3-Clause "New" or "Revised" License
2.04k stars 380 forks source link

TypeError on complete callback [MediaWiki] #256

Open yurkobb opened 4 years ago

yurkobb commented 4 years ago

Getting a TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead. after an upgrade from 3.1 to 3.4.

It seems the new version is relying on functionality that was removed in Django 2.0? Full traceback:

Internal Server Error: /oauth/complete/mediawiki/
Traceback (most recent call last):
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_django/utils.py", line 49, in wrapper
    return func(request, backend, *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_django/views.py", line 33, in complete
    *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/actions.py", line 45, in do_complete
    user = backend.complete(user=user, *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/backends/base.py", line 40, in complete
    return self.auth_complete(*args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/utils.py", line 251, in wrapper
    return func(*args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/backends/oauth.py", line 184, in auth_complete
    return self.do_auth(access_token, *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/utils.py", line 251, in wrapper
    return func(*args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/backends/oauth.py", line 195, in do_auth
    return self.strategy.authenticate(*args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_django/strategy.py", line 107, in authenticate
    return authenticate(*args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/contrib/auth/__init__.py", line 73, in authenticate
    user = backend.authenticate(request, **credentials)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/backends/base.py", line 80, in authenticate
    return self.pipeline(pipeline, *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/backends/base.py", line 83, in pipeline
    out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/backends/base.py", line 113, in run_pipeline
    result = func(*args, **out) or {}
  File "/usr/src/python/.venv/lib/python3.7/site-packages/social_core/pipeline/user.py", line 112, in user_details
    setattr(user, name, value)
  File "/usr/src/python/.venv/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 538, in __set__
    % self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead.
yurkobb commented 4 years ago

Okay, this seems to be an issue with social-core; specifically the MediaWiki backend trying to set a many-to-many attribute (groups) on the User model.

That seems dangerous, shouldn't groups be protected anyway?

Adding groups to SOCIAL_AUTH_PROTECTED_USER_FIELDS fixes the crash.

Can this issue be moved to social-core?

roysmith commented 2 years ago

Was there ever a resolution to this? I'm seeing the same issue

roysmith commented 2 years ago

OK, I finally got my head around this. The SOCIAL_AUTH_PROTECTED_USER_FIELDS setting mentioned above is described here in the docs. Adding:

SOCIAL_AUTH_PROTECTED_USER_FIELDS = ['groups']

to my django settings.py fixed the problem.

I disagree that this is something that should be fixed in social-core. It seems to me that the issue is specific to the django ORM and/or User model, even though the exception is ultimately raised in social-core code. Maybe the right thing to do would be to have something in the social-app-django startup code verify that SOCIAL_AUTH_PROTECTED_USER_FIELDS is set properly and refuse to run (with an explanatory message) if it's not. A hard fail at startup is better than a mysterious failure at runtime.