We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
/api/v1/auth broke with django-oauth-toolkit 0.9.0
https://github.com/evonove/django-oauth-toolkit/compare/0.8.1...0.9.0


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `apps/sso/views.py`
Content:
```
1 # -*- encoding: utf-8 -*-
2 
3 import logging
4 
5 from braces.views import CsrfExemptMixin, LoginRequiredMixin
6 from django.contrib.auth.decorators import login_required
7 from django.http import HttpResponse
8 from django.shortcuts import render
9 from django.utils import timezone
10 from django.utils.decorators import method_decorator
11 from django.views.decorators.debug import sensitive_post_parameters
12 from django.views.generic import FormView, View
13 from oauth2_provider.backends import OAuth2Backend
14 from oauth2_provider.exceptions import OAuthToolkitError
15 from oauth2_provider.forms import AllowForm
16 from oauth2_provider.http import HttpResponseUriRedirect
17 from oauth2_provider.models import get_application_model
18 from oauth2_provider.oauth2_validators import OAuth2Validator
19 from oauth2_provider.settings import oauth2_settings
20 from oauth2_provider.views.mixins import OAuthLibMixin
21 from oauthlib.oauth2 import Server
22 
23 from apps.sso.models import Client
24 
25 _log = logging.getLogger('SSO')
26 
27 
28 @login_required
29 def index(request):
30     """
31     This is the main SSO view
32     """
33 
34     context = {}
35 
36     return render(request, 'sso/index.html', context)
37 
38 
39 class BaseAuthorizationView(LoginRequiredMixin, OAuthLibMixin, View):
40     """
41     Implements a generic endpoint to handle *Authorization Requests* as in :rfc:`4.1.1`. The view
42     does not implement any strategy to determine *authorize/do not authorize* logic.
43     The endpoint is used in the following flows:
44     * Authorization code
45     * Implicit grant
46     """
47 
48     def dispatch(self, request, *args, **kwargs):
49         self.oauth2_data = {}
50         return super(BaseAuthorizationView, self).dispatch(request, *args, **kwargs)
51 
52     def error_response(self, error, **kwargs):
53         """
54         Handle errors either by redirecting to redirect_uri with a json in the body containing
55         error details or providing an error response
56         """
57         redirect, error_response = super(BaseAuthorizationView, self).error_response(error, **kwargs)
58 
59         if redirect:
60             return HttpResponseUriRedirect(error_response['url'])
61 
62         status = error_response['error'].status_code
63         return self.render_to_response(error_response, status=status)
64 
65 
66 class AuthorizationView(BaseAuthorizationView, FormView):
67     """
68     Implements and endpoint to handle *Authorization Requests* as in :rfc:`4.1.1` and prompting the
69     user with a form to determine if she authorizes the client application to access her data.
70     This endpoint is reached two times during the authorization process:
71     * first receive a ``GET`` request from user asking authorization for a certain client
72     application, a form is served possibly showing some useful info and prompting for
73     *authorize/do not authorize*.
74     * then receive a ``POST`` request possibly after user authorized the access
75     Some informations contained in the ``GET`` request and needed to create a Grant token during
76     the ``POST`` request would be lost between the two steps above, so they are temporary stored in
77     hidden fields on the form.
78     A possible alternative could be keeping such informations in the session.
79     The endpoint is used in the followin flows:
80     * Authorization code
81     * Implicit grant
82     """
83     template_name = 'sso/authorize.html'
84     form_class = AllowForm
85 
86     server_class = Server
87     validator_class = OAuth2Validator
88     oauthlib_backend_class = OAuth2Backend
89 
90     skip_authorization_completely = False
91 
92     def get_initial(self):
93         scopes = self.oauth2_data.get('scope', self.oauth2_data.get('scopes', []))
94         initial_data = {
95             'redirect_uri': self.oauth2_data.get('redirect_uri', None),
96             'scope': ' '.join(scopes),
97             'client_id': self.oauth2_data.get('client_id', None),
98             'state': self.oauth2_data.get('state', None),
99             'response_type': self.oauth2_data.get('response_type', None),
100         }
101         return initial_data
102 
103     def form_valid(self, form):
104         try:
105             credentials = {
106                 'client_id': form.cleaned_data.get('client_id'),
107                 'redirect_uri': form.cleaned_data.get('redirect_uri'),
108                 'response_type': form.cleaned_data.get('response_type', None),
109                 'state': form.cleaned_data.get('state', None),
110             }
111 
112             scopes = Client.objects.get(client_id=credentials['client_id']).scopes
113             if not scopes:
114                 scopes = 'null'
115             allow = form.cleaned_data.get('allow')
116             uri, headers, body, status = self.create_authorization_response(
117                 request=self.request, scopes=scopes, credentials=credentials, allow=allow)
118             self.success_url = uri
119             _log.debug("Success url for the request: {0}".format(self.success_url))
120             return HttpResponseUriRedirect(self.success_url)
121 
122         except OAuthToolkitError as error:
123             return self.error_response(error)
124 
125     def get(self, request, *args, **kwargs):
126         try:
127             scopes, credentials = self.validate_authorization_request(request)
128             scopes = Client.objects.get(client_id=credentials['client_id']).get_scopes()
129             if not scopes:
130                 scopes = ['null']
131             kwargs['scopes_descriptions'] = [oauth2_settings.SCOPES[scope] for scope in scopes]
132             kwargs['scopes'] = scopes
133             # at this point we know an Application instance with such client_id exists in the database
134             application = get_application_model().objects.get(client_id=credentials['client_id'])  # TODO: cache it!
135             kwargs['application'] = application
136             kwargs.update(credentials)
137             self.oauth2_data = kwargs
138             # following two loc are here only because of https://code.djangoproject.com/ticket/17795
139             form = self.get_form(self.get_form_class())
140             kwargs['form'] = form
141 
142             # Check to see if the user has already granted access and return
143             # a successful response depending on 'approval_prompt' url parameter
144             require_approval = request.GET.get('approval_prompt', oauth2_settings.REQUEST_APPROVAL_PROMPT)
145 
146             # If skip_authorization field is True, skip the authorization screen even
147             # if this is the first use of the application and there was no previous authorization.
148             # This is useful for in-house applications-> assume an in-house applications
149             # are already approved.
150             if application.skip_authorization:
151                 uri, headers, body, status = self.create_authorization_response(
152                     request=self.request, scopes=" ".join(scopes),
153                     credentials=credentials, allow=True)
154                 return HttpResponseUriRedirect(uri)
155 
156             elif require_approval == 'auto':
157                 tokens = request.user.accesstoken_set.filter(application=kwargs['application'],
158                                                              expires__gt=timezone.now()).all()
159                 # check past authorizations regarded the same scopes as the current one
160                 for token in tokens:
161                     if token.allow_scopes(scopes):
162                         uri, headers, body, status = self.create_authorization_response(
163                             request=self.request, scopes=" ".join(scopes),
164                             credentials=credentials, allow=True)
165                         return HttpResponseUriRedirect(uri)
166 
167             return self.render_to_response(self.get_context_data(**kwargs))
168 
169         except OAuthToolkitError as error:
170             return self.error_response(error)
171 
172 
173 class TokenView(CsrfExemptMixin, OAuthLibMixin, View):
174     """
175     Implements an endpoint to provide access tokens
176     The endpoint is used in the following flows:
177     * Authorization code
178     * Password
179     * Client credentials
180     """
181     server_class = Server
182     validator_class = OAuth2Validator
183     oauthlib_backend_class = OAuth2Backend
184 
185     @method_decorator(sensitive_post_parameters('password'))
186     def post(self, request, *args, **kwargs):
187         url, headers, body, status = self.create_token_response(request)
188         response = HttpResponse(content=body, status=status)
189 
190         for k, v in headers.items():
191             response[k] = v
192         return response
193 
194 
195 class RevokeTokenView(CsrfExemptMixin, OAuthLibMixin, View):
196     """
197     Implements an endpoint to revoke access or refresh tokens
198     """
199     server_class = Server
200     validator_class = OAuth2Validator
201     oauthlib_backend_class = OAuth2Backend
202 
203     def post(self, request, *args, **kwargs):
204         url, headers, body, status = self.create_revocation_response(request)
205         response = HttpResponse(content=body or '', status=status)
206 
207         for k, v in headers.items():
208             response[k] = v
209         return response
210
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/apps/sso/views.py b/apps/sso/views.py
--- a/apps/sso/views.py
+++ b/apps/sso/views.py
@@ -10,7 +10,6 @@
 from django.utils.decorators import method_decorator
 from django.views.decorators.debug import sensitive_post_parameters
 from django.views.generic import FormView, View
-from oauth2_provider.backends import OAuth2Backend
 from oauth2_provider.exceptions import OAuthToolkitError
 from oauth2_provider.forms import AllowForm
 from oauth2_provider.http import HttpResponseUriRedirect
@@ -85,7 +84,6 @@
 
     server_class = Server
     validator_class = OAuth2Validator
-    oauthlib_backend_class = OAuth2Backend
 
     skip_authorization_completely = False
 
@@ -180,7 +178,6 @@
     """
     server_class = Server
     validator_class = OAuth2Validator
-    oauthlib_backend_class = OAuth2Backend
 
     @method_decorator(sensitive_post_parameters('password'))
     def post(self, request, *args, **kwargs):
@@ -198,7 +195,6 @@
     """
     server_class = Server
     validator_class = OAuth2Validator
-    oauthlib_backend_class = OAuth2Backend
 
     def post(self, request, *args, **kwargs):
         url, headers, body, status = self.create_revocation_response(request)

{"golden_diff": "diff --git a/apps/sso/views.py b/apps/sso/views.py\n--- a/apps/sso/views.py\n+++ b/apps/sso/views.py\n@@ -10,7 +10,6 @@\n from django.utils.decorators import method_decorator\n from django.views.decorators.debug import sensitive_post_parameters\n from django.views.generic import FormView, View\n-from oauth2_provider.backends import OAuth2Backend\n from oauth2_provider.exceptions import OAuthToolkitError\n from oauth2_provider.forms import AllowForm\n from oauth2_provider.http import HttpResponseUriRedirect\n@@ -85,7 +84,6 @@\n \n     server_class = Server\n     validator_class = OAuth2Validator\n-    oauthlib_backend_class = OAuth2Backend\n \n     skip_authorization_completely = False\n \n@@ -180,7 +178,6 @@\n     \"\"\"\n     server_class = Server\n     validator_class = OAuth2Validator\n-    oauthlib_backend_class = OAuth2Backend\n \n     @method_decorator(sensitive_post_parameters('password'))\n     def post(self, request, *args, **kwargs):\n@@ -198,7 +195,6 @@\n     \"\"\"\n     server_class = Server\n     validator_class = OAuth2Validator\n-    oauthlib_backend_class = OAuth2Backend\n \n     def post(self, request, *args, **kwargs):\n         url, headers, body, status = self.create_revocation_response(request)\n", "issue": "/api/v1/auth broke with django-oauth-toolkit 0.9.0\nhttps://github.com/evonove/django-oauth-toolkit/compare/0.8.1...0.9.0\n\n", "before_files": [{"content": "# -*- encoding: utf-8 -*-\n\nimport logging\n\nfrom braces.views import CsrfExemptMixin, LoginRequiredMixin\nfrom django.contrib.auth.decorators import login_required\nfrom django.http import HttpResponse\nfrom django.shortcuts import render\nfrom django.utils import timezone\nfrom django.utils.decorators import method_decorator\nfrom django.views.decorators.debug import sensitive_post_parameters\nfrom django.views.generic import FormView, View\nfrom oauth2_provider.backends import OAuth2Backend\nfrom oauth2_provider.exceptions import OAuthToolkitError\nfrom oauth2_provider.forms import AllowForm\nfrom oauth2_provider.http import HttpResponseUriRedirect\nfrom oauth2_provider.models import get_application_model\nfrom oauth2_provider.oauth2_validators import OAuth2Validator\nfrom oauth2_provider.settings import oauth2_settings\nfrom oauth2_provider.views.mixins import OAuthLibMixin\nfrom oauthlib.oauth2 import Server\n\nfrom apps.sso.models import Client\n\n_log = logging.getLogger('SSO')\n\n\n@login_required\ndef index(request):\n    \"\"\"\n    This is the main SSO view\n    \"\"\"\n\n    context = {}\n\n    return render(request, 'sso/index.html', context)\n\n\nclass BaseAuthorizationView(LoginRequiredMixin, OAuthLibMixin, View):\n    \"\"\"\n    Implements a generic endpoint to handle *Authorization Requests* as in :rfc:`4.1.1`. The view\n    does not implement any strategy to determine *authorize/do not authorize* logic.\n    The endpoint is used in the following flows:\n    * Authorization code\n    * Implicit grant\n    \"\"\"\n\n    def dispatch(self, request, *args, **kwargs):\n        self.oauth2_data = {}\n        return super(BaseAuthorizationView, self).dispatch(request, *args, **kwargs)\n\n    def error_response(self, error, **kwargs):\n        \"\"\"\n        Handle errors either by redirecting to redirect_uri with a json in the body containing\n        error details or providing an error response\n        \"\"\"\n        redirect, error_response = super(BaseAuthorizationView, self).error_response(error, **kwargs)\n\n        if redirect:\n            return HttpResponseUriRedirect(error_response['url'])\n\n        status = error_response['error'].status_code\n        return self.render_to_response(error_response, status=status)\n\n\nclass AuthorizationView(BaseAuthorizationView, FormView):\n    \"\"\"\n    Implements and endpoint to handle *Authorization Requests* as in :rfc:`4.1.1` and prompting the\n    user with a form to determine if she authorizes the client application to access her data.\n    This endpoint is reached two times during the authorization process:\n    * first receive a ``GET`` request from user asking authorization for a certain client\n    application, a form is served possibly showing some useful info and prompting for\n    *authorize/do not authorize*.\n    * then receive a ``POST`` request possibly after user authorized the access\n    Some informations contained in the ``GET`` request and needed to create a Grant token during\n    the ``POST`` request would be lost between the two steps above, so they are temporary stored in\n    hidden fields on the form.\n    A possible alternative could be keeping such informations in the session.\n    The endpoint is used in the followin flows:\n    * Authorization code\n    * Implicit grant\n    \"\"\"\n    template_name = 'sso/authorize.html'\n    form_class = AllowForm\n\n    server_class = Server\n    validator_class = OAuth2Validator\n    oauthlib_backend_class = OAuth2Backend\n\n    skip_authorization_completely = False\n\n    def get_initial(self):\n        scopes = self.oauth2_data.get('scope', self.oauth2_data.get('scopes', []))\n        initial_data = {\n            'redirect_uri': self.oauth2_data.get('redirect_uri', None),\n            'scope': ' '.join(scopes),\n            'client_id': self.oauth2_data.get('client_id', None),\n            'state': self.oauth2_data.get('state', None),\n            'response_type': self.oauth2_data.get('response_type', None),\n        }\n        return initial_data\n\n    def form_valid(self, form):\n        try:\n            credentials = {\n                'client_id': form.cleaned_data.get('client_id'),\n                'redirect_uri': form.cleaned_data.get('redirect_uri'),\n                'response_type': form.cleaned_data.get('response_type', None),\n                'state': form.cleaned_data.get('state', None),\n            }\n\n            scopes = Client.objects.get(client_id=credentials['client_id']).scopes\n            if not scopes:\n                scopes = 'null'\n            allow = form.cleaned_data.get('allow')\n            uri, headers, body, status = self.create_authorization_response(\n                request=self.request, scopes=scopes, credentials=credentials, allow=allow)\n            self.success_url = uri\n            _log.debug(\"Success url for the request: {0}\".format(self.success_url))\n            return HttpResponseUriRedirect(self.success_url)\n\n        except OAuthToolkitError as error:\n            return self.error_response(error)\n\n    def get(self, request, *args, **kwargs):\n        try:\n            scopes, credentials = self.validate_authorization_request(request)\n            scopes = Client.objects.get(client_id=credentials['client_id']).get_scopes()\n            if not scopes:\n                scopes = ['null']\n            kwargs['scopes_descriptions'] = [oauth2_settings.SCOPES[scope] for scope in scopes]\n            kwargs['scopes'] = scopes\n            # at this point we know an Application instance with such client_id exists in the database\n            application = get_application_model().objects.get(client_id=credentials['client_id'])  # TODO: cache it!\n            kwargs['application'] = application\n            kwargs.update(credentials)\n            self.oauth2_data = kwargs\n            # following two loc are here only because of https://code.djangoproject.com/ticket/17795\n            form = self.get_form(self.get_form_class())\n            kwargs['form'] = form\n\n            # Check to see if the user has already granted access and return\n            # a successful response depending on 'approval_prompt' url parameter\n            require_approval = request.GET.get('approval_prompt', oauth2_settings.REQUEST_APPROVAL_PROMPT)\n\n            # If skip_authorization field is True, skip the authorization screen even\n            # if this is the first use of the application and there was no previous authorization.\n            # This is useful for in-house applications-> assume an in-house applications\n            # are already approved.\n            if application.skip_authorization:\n                uri, headers, body, status = self.create_authorization_response(\n                    request=self.request, scopes=\" \".join(scopes),\n                    credentials=credentials, allow=True)\n                return HttpResponseUriRedirect(uri)\n\n            elif require_approval == 'auto':\n                tokens = request.user.accesstoken_set.filter(application=kwargs['application'],\n                                                             expires__gt=timezone.now()).all()\n                # check past authorizations regarded the same scopes as the current one\n                for token in tokens:\n                    if token.allow_scopes(scopes):\n                        uri, headers, body, status = self.create_authorization_response(\n                            request=self.request, scopes=\" \".join(scopes),\n                            credentials=credentials, allow=True)\n                        return HttpResponseUriRedirect(uri)\n\n            return self.render_to_response(self.get_context_data(**kwargs))\n\n        except OAuthToolkitError as error:\n            return self.error_response(error)\n\n\nclass TokenView(CsrfExemptMixin, OAuthLibMixin, View):\n    \"\"\"\n    Implements an endpoint to provide access tokens\n    The endpoint is used in the following flows:\n    * Authorization code\n    * Password\n    * Client credentials\n    \"\"\"\n    server_class = Server\n    validator_class = OAuth2Validator\n    oauthlib_backend_class = OAuth2Backend\n\n    @method_decorator(sensitive_post_parameters('password'))\n    def post(self, request, *args, **kwargs):\n        url, headers, body, status = self.create_token_response(request)\n        response = HttpResponse(content=body, status=status)\n\n        for k, v in headers.items():\n            response[k] = v\n        return response\n\n\nclass RevokeTokenView(CsrfExemptMixin, OAuthLibMixin, View):\n    \"\"\"\n    Implements an endpoint to revoke access or refresh tokens\n    \"\"\"\n    server_class = Server\n    validator_class = OAuth2Validator\n    oauthlib_backend_class = OAuth2Backend\n\n    def post(self, request, *args, **kwargs):\n        url, headers, body, status = self.create_revocation_response(request)\n        response = HttpResponse(content=body or '', status=status)\n\n        for k, v in headers.items():\n            response[k] = v\n        return response\n", "path": "apps/sso/views.py"}], "after_files": [{"content": "# -*- encoding: utf-8 -*-\n\nimport logging\n\nfrom braces.views import CsrfExemptMixin, LoginRequiredMixin\nfrom django.contrib.auth.decorators import login_required\nfrom django.http import HttpResponse\nfrom django.shortcuts import render\nfrom django.utils import timezone\nfrom django.utils.decorators import method_decorator\nfrom django.views.decorators.debug import sensitive_post_parameters\nfrom django.views.generic import FormView, View\nfrom oauth2_provider.exceptions import OAuthToolkitError\nfrom oauth2_provider.forms import AllowForm\nfrom oauth2_provider.http import HttpResponseUriRedirect\nfrom oauth2_provider.models import get_application_model\nfrom oauth2_provider.oauth2_validators import OAuth2Validator\nfrom oauth2_provider.settings import oauth2_settings\nfrom oauth2_provider.views.mixins import OAuthLibMixin\nfrom oauthlib.oauth2 import Server\n\nfrom apps.sso.models import Client\n\n_log = logging.getLogger('SSO')\n\n\n@login_required\ndef index(request):\n    \"\"\"\n    This is the main SSO view\n    \"\"\"\n\n    context = {}\n\n    return render(request, 'sso/index.html', context)\n\n\nclass BaseAuthorizationView(LoginRequiredMixin, OAuthLibMixin, View):\n    \"\"\"\n    Implements a generic endpoint to handle *Authorization Requests* as in :rfc:`4.1.1`. The view\n    does not implement any strategy to determine *authorize/do not authorize* logic.\n    The endpoint is used in the following flows:\n    * Authorization code\n    * Implicit grant\n    \"\"\"\n\n    def dispatch(self, request, *args, **kwargs):\n        self.oauth2_data = {}\n        return super(BaseAuthorizationView, self).dispatch(request, *args, **kwargs)\n\n    def error_response(self, error, **kwargs):\n        \"\"\"\n        Handle errors either by redirecting to redirect_uri with a json in the body containing\n        error details or providing an error response\n        \"\"\"\n        redirect, error_response = super(BaseAuthorizationView, self).error_response(error, **kwargs)\n\n        if redirect:\n            return HttpResponseUriRedirect(error_response['url'])\n\n        status = error_response['error'].status_code\n        return self.render_to_response(error_response, status=status)\n\n\nclass AuthorizationView(BaseAuthorizationView, FormView):\n    \"\"\"\n    Implements and endpoint to handle *Authorization Requests* as in :rfc:`4.1.1` and prompting the\n    user with a form to determine if she authorizes the client application to access her data.\n    This endpoint is reached two times during the authorization process:\n    * first receive a ``GET`` request from user asking authorization for a certain client\n    application, a form is served possibly showing some useful info and prompting for\n    *authorize/do not authorize*.\n    * then receive a ``POST`` request possibly after user authorized the access\n    Some informations contained in the ``GET`` request and needed to create a Grant token during\n    the ``POST`` request would be lost between the two steps above, so they are temporary stored in\n    hidden fields on the form.\n    A possible alternative could be keeping such informations in the session.\n    The endpoint is used in the followin flows:\n    * Authorization code\n    * Implicit grant\n    \"\"\"\n    template_name = 'sso/authorize.html'\n    form_class = AllowForm\n\n    server_class = Server\n    validator_class = OAuth2Validator\n\n    skip_authorization_completely = False\n\n    def get_initial(self):\n        scopes = self.oauth2_data.get('scope', self.oauth2_data.get('scopes', []))\n        initial_data = {\n            'redirect_uri': self.oauth2_data.get('redirect_uri', None),\n            'scope': ' '.join(scopes),\n            'client_id': self.oauth2_data.get('client_id', None),\n            'state': self.oauth2_data.get('state', None),\n            'response_type': self.oauth2_data.get('response_type', None),\n        }\n        return initial_data\n\n    def form_valid(self, form):\n        try:\n            credentials = {\n                'client_id': form.cleaned_data.get('client_id'),\n                'redirect_uri': form.cleaned_data.get('redirect_uri'),\n                'response_type': form.cleaned_data.get('response_type', None),\n                'state': form.cleaned_data.get('state', None),\n            }\n\n            scopes = Client.objects.get(client_id=credentials['client_id']).scopes\n            if not scopes:\n                scopes = 'null'\n            allow = form.cleaned_data.get('allow')\n            uri, headers, body, status = self.create_authorization_response(\n                request=self.request, scopes=scopes, credentials=credentials, allow=allow)\n            self.success_url = uri\n            _log.debug(\"Success url for the request: {0}\".format(self.success_url))\n            return HttpResponseUriRedirect(self.success_url)\n\n        except OAuthToolkitError as error:\n            return self.error_response(error)\n\n    def get(self, request, *args, **kwargs):\n        try:\n            scopes, credentials = self.validate_authorization_request(request)\n            scopes = Client.objects.get(client_id=credentials['client_id']).get_scopes()\n            if not scopes:\n                scopes = ['null']\n            kwargs['scopes_descriptions'] = [oauth2_settings.SCOPES[scope] for scope in scopes]\n            kwargs['scopes'] = scopes\n            # at this point we know an Application instance with such client_id exists in the database\n            application = get_application_model().objects.get(client_id=credentials['client_id'])  # TODO: cache it!\n            kwargs['application'] = application\n            kwargs.update(credentials)\n            self.oauth2_data = kwargs\n            # following two loc are here only because of https://code.djangoproject.com/ticket/17795\n            form = self.get_form(self.get_form_class())\n            kwargs['form'] = form\n\n            # Check to see if the user has already granted access and return\n            # a successful response depending on 'approval_prompt' url parameter\n            require_approval = request.GET.get('approval_prompt', oauth2_settings.REQUEST_APPROVAL_PROMPT)\n\n            # If skip_authorization field is True, skip the authorization screen even\n            # if this is the first use of the application and there was no previous authorization.\n            # This is useful for in-house applications-> assume an in-house applications\n            # are already approved.\n            if application.skip_authorization:\n                uri, headers, body, status = self.create_authorization_response(\n                    request=self.request, scopes=\" \".join(scopes),\n                    credentials=credentials, allow=True)\n                return HttpResponseUriRedirect(uri)\n\n            elif require_approval == 'auto':\n                tokens = request.user.accesstoken_set.filter(application=kwargs['application'],\n                                                             expires__gt=timezone.now()).all()\n                # check past authorizations regarded the same scopes as the current one\n                for token in tokens:\n                    if token.allow_scopes(scopes):\n                        uri, headers, body, status = self.create_authorization_response(\n                            request=self.request, scopes=\" \".join(scopes),\n                            credentials=credentials, allow=True)\n                        return HttpResponseUriRedirect(uri)\n\n            return self.render_to_response(self.get_context_data(**kwargs))\n\n        except OAuthToolkitError as error:\n            return self.error_response(error)\n\n\nclass TokenView(CsrfExemptMixin, OAuthLibMixin, View):\n    \"\"\"\n    Implements an endpoint to provide access tokens\n    The endpoint is used in the following flows:\n    * Authorization code\n    * Password\n    * Client credentials\n    \"\"\"\n    server_class = Server\n    validator_class = OAuth2Validator\n\n    @method_decorator(sensitive_post_parameters('password'))\n    def post(self, request, *args, **kwargs):\n        url, headers, body, status = self.create_token_response(request)\n        response = HttpResponse(content=body, status=status)\n\n        for k, v in headers.items():\n            response[k] = v\n        return response\n\n\nclass RevokeTokenView(CsrfExemptMixin, OAuthLibMixin, View):\n    \"\"\"\n    Implements an endpoint to revoke access or refresh tokens\n    \"\"\"\n    server_class = Server\n    validator_class = OAuth2Validator\n\n    def post(self, request, *args, **kwargs):\n        url, headers, body, status = self.create_revocation_response(request)\n        response = HttpResponse(content=body or '', status=status)\n\n        for k, v in headers.items():\n            response[k] = v\n        return response\n", "path": "apps/sso/views.py"}]}