RealmTeam / django-rest-framework-social-oauth2

python-social-auth and oauth2 support for django-rest-framework
MIT License
1.06k stars 191 forks source link

AttributeError: This QueryDict instance is immutable while setting POST params #192

Open omushpapa opened 5 years ago

omushpapa commented 5 years ago

Steps to reproduce

Set up a test case as follows:

import logging
import json
from django.test import TestCase, Client
from django.urls import reverse
from oauth2_provider.models import Application
from api.factories import *
from api.v1.events.serializers import *
from decouple import config
from rest_framework.test import APITestCase
from django.contrib.auth import get_user_model
from requests.auth import CONTENT_TYPE_FORM_URLENCODED

User = get_user_model()

class SampleTestCase(APITestCase):

    def setUp(self):
        self.superuser = User.objects.create_superuser('giant', 'gaint@giant.com', 'secret')
        app = Application.objects.create(
            user=self.superuser,
            authorization_grant_type='client-credentials',
            name='Test App',
            client_type='public'
        )
        facebook_token = <facebook_test_token>
        url = reverse('convert_token')
        params = {'token': facebook_token,
                  'backend': "facebook",
                  'grant_type': "convert_token",
                  'client_id': app.client_id}
        response = self.client.post(url, params, content_type=CONTENT_TYPE_FORM_URLENCODED)  # Fails here
        self.access_token = response.data['access_token']
        self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + self.access_token)

    def test_anything_using_client(self):
        # Add any test that utilises self.client
        pass

Expected behavior

The request to run successfully.

Actual behavior

The request fails with AttributeError: This QueryDict instance is immutable

Sample stacktrace:

Traceback (most recent call last):
  File "/home/aswa/project/app/tests.py", line 77, in setUp
    response = self.client.post(url, params, content_type=CONTENT_TYPE_FORM_URLENCODED)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/test.py", line 300, in post
    path, data=data, format=format, content_type=content_type, **extra)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/test.py", line 213, in post
    return self.generic('POST', path, data, content_type, **extra)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/test.py", line 238, in generic
    method, path, data, content_type, secure, **extra)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/test/client.py", line 416, in generic
    return self.request(**r)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/test.py", line 289, in request
    return super(APIClient, self).request(**kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/test.py", line 241, in request
    request = super(APIRequestFactory, self).request(**kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/test/client.py", line 501, in request
    six.reraise(*exc_info)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/utils/six.py", line 686, in reraise
    raise value
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/braces/views/_forms.py", line 24, in dispatch
    return super(CsrfExemptMixin, self).dispatch(*args, **kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/views.py", line 466, in raise_uncaught_exception
    raise exc
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/rest_framework_social_oauth2/views.py", line 68, in post
    request._request.POST[key] = value
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/http/request.py", line 434, in __setitem__
    self._assert_mutable()
  File "/home/aswa/.virtualenvs/project-HKu9dTak/lib/python3.6/site-packages/django/http/request.py", line 431, in _assert_mutable
    raise AttributeError("This QueryDict instance is immutable")
AttributeError: This QueryDict instance is immutable
Dylan-Coetzee commented 4 years ago

Hi, could you fix this yet?

wagnerdelima commented 4 years ago

Hi all.

My team and I are constantly using this framework and it seems it has died out there. I contacted the owner by email asking if he would add some of us as maintainers so we could continue to improve it. However we didn't get a response.

I am publishing the project under my profile and we are going to continue to invest time in it.

So I would like to gently ask you to contribute to this project on: https://github.com/wagnerdelima/drf-social-oauth2

Thank you for understanding.

hvalee commented 2 years ago

Hi @wagnerdelima does your project fix this issue ? I tried to use it but without success

wagnerdelima commented 2 years ago

@hvalee are you also stumbling upon this problem? I never really had stumbled upon it myself so it's hard to debug.

hvalee commented 2 years ago

@wagnerdelima I updated a project to python(3.9.7), Django(3.2.7), and all their dependencies. But doing that I am having a weird problem where the apps connect as usual with a bearer token, receive a positive response but when using the received token with other requests it does not recognize the token and returns a 403(Forbidden). With this lib and with yours (already tried it)

Basically, the Django gives that token to a user that just logged in but when the user tries to get some info using that token does not recognize it..

TonyyCruz commented 1 year ago

Hi, I had a similar error, I fixed it like this:

data = json.dumps(<your data>) # your params in the case
response = self.client.post(
            path=self.api_url,
            data=data,
            HTTP_AUTHORIZATION=f"Bearer {jwt_access_token}",
            content_type="application/json", # This content type is for rest_framework, will normally be just "json"
        )

Ps: I know the post is old but I had this problem a few hours ago so this might help someone else.