Repository: spacetelescope/jwql

Issue:
Authentication is currently broken 
When attempting to log into the web app when running locally, we encounter this error:

```
Traceback (most recent call last):
  File "python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "d/jwql/jwql/website/apps/jwql/oauth.py", line 113, in authorize
    request, headers={'Accept': 'application/json'}
  File "python3.6/site-packages/authlib/integrations/django_client/remote_app.py", line 63, in authorize_access_token
    return self.fetch_access_token(**params)
  File "python3.6/site-packages/authlib/integrations/_client/remote_app.py", line 106, in fetch_access_token
    token = client.fetch_token(token_endpoint, **kwargs)
  File "python3.6/site-packages/authlib/oauth2/client.py", line 202, in fetch_token
    headers=headers, **session_kwargs
  File "python3.6/site-packages/authlib/oauth2/client.py", line 223, in _fetch_token
    return self.parse_response_token(resp.json())
  File "python3.6/site-packages/requests/models.py", line 898, in json
    return complexjson.loads(self.text, **kwargs)
  File "python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```


Discussion:

Resolving patch:
diff --git a/jwql/website/apps/jwql/oauth.py b/jwql/website/apps/jwql/oauth.py
--- a/jwql/website/apps/jwql/oauth.py
+++ b/jwql/website/apps/jwql/oauth.py
@@ -8,6 +8,7 @@
 
     - Matthew Bourque
     - Christian Mesh
+    - Ben Falk
 
 Use
 ---
@@ -41,8 +42,9 @@ def login(request):
 import os
 import requests
 
-from authlib.django.client import OAuth
+from authlib.integrations.django_client import OAuth
 from django.shortcuts import redirect, render
+from django.urls import reverse
 
 import jwql
 from jwql.utils.constants import MONITORS
@@ -71,14 +73,15 @@ def register_oauth():
 
     # Register with auth.mast
     oauth = OAuth()
-    client_kwargs = {'scope': 'mast:user:info'}
+    client_kwargs = {
+        'scope': 'mast:user:info',
+        'token_endpoint_auth_method': 'client_secret_basic',
+        'token_placement': 'header'}
     oauth.register(
         'mast_auth',
         client_id='{}'.format(client_id),
         client_secret='{}'.format(client_secret),
-        access_token_url='https://{}/oauth/access_token?client_secret={}'.format(
-            auth_mast, client_secret
-        ),
+        access_token_url='https://{}/oauth/token'.format(auth_mast),
         access_token_params=None,
         refresh_token_url=None,
         authorize_url='https://{}/oauth/authorize'.format(auth_mast),
@@ -109,9 +112,7 @@ def authorize(request):
     """
 
     # Get auth.mast token
-    token = JWQL_OAUTH.mast_auth.authorize_access_token(
-        request, headers={'Accept': 'application/json'}
-    )
+    token = JWQL_OAUTH.mast_auth.authorize_access_token(request)
 
     # Determine domain
     base_url = get_base_url()
@@ -259,7 +260,7 @@ def login(request, user):
     # Redirect to oauth login
     global PREV_PAGE
     PREV_PAGE = request.META.get('HTTP_REFERER')
-    redirect_uri = os.path.join(get_base_url(), 'authorize')
+    redirect_uri = f"{get_base_url()}{reverse('jwql:authorize')}"
 
     return JWQL_OAUTH.mast_auth.authorize_redirect(request, redirect_uri)
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -20,6 +20,7 @@
     'bokeh>=1.0,<1.4',
     'codecov',
     'crds',
+    'cryptography',
     'django>=2.0,<3.0',
     'flake8',
     'inflection',


Test patch: