social-app-django
social-app-django copied to clipboard
AttributeError: 'NoneType' object has no attribute 'get'
Been trying to fix this for a few days now.
Error:
[api] Internal Server Error: /api/social/azuread-tenant-oauth2/
[api] Traceback (most recent call last):
[api] File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
[api] response = get_response(request)
[api] File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
[api] response = wrapped_callback(request, *callback_args, **callback_kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
[api] return view_func(*args, **kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
[api] return self.dispatch(request, *args, **kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
[api] response = self.handle_exception(exc)
[api] File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
[api] self.raise_uncaught_exception(exc)
[api] File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
[api] raise exc
[api] File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
[api] response = handler(request, *args, **kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/rest_framework/decorators.py", line 50, in handler
[api] return func(*args, **kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/social_django/utils.py", line 49, in wrapper
[api] return func(request, backend, *args, **kwargs)
[api] File "/app/users/views.py", line 85, in exchange_token
[api] user = request.backend.do_auth(
[api] File "/usr/local/lib/python3.8/site-packages/social_core/utils.py", line 251, in wrapper
[api] return func(*args, **kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/social_core/backends/oauth.py", line 410, in do_auth
[api] data = self.user_data(access_token, *args, **kwargs)
[api] File "/usr/local/lib/python3.8/site-packages/social_core/backends/azuread_tenant.py", line 97, in user_data
[api] id_token = response.get('id_token')
[api] AttributeError: 'NoneType' object has no attribute 'get'
[api] HTTP POST /api/social/azuread-tenant-oauth2/ 500 [0.12, 172.17.0.6:36484]
# requirements.py
asgiref==3.2.10
astroid==2.4.2
attrs==20.2.0
autobahn==20.7.1
Automat==20.2.0
autopep8==1.5.4
certifi==2020.6.20
cffi==1.14.3
channels==2.4.0
chardet==3.0.4
constantly==15.1.0
cryptography==3.1.1
daphne==2.5.0
defusedxml==0.7.0rc1
Django==3.1.2
django-oauth-toolkit==1.3.3
djangorestframework==3.12.1
djangorestframework-simplejwt==4.4.0
hyperlink==20.0.1
idna==2.10
incremental==17.5.0
isort==5.6.4
lazy-object-proxy==1.4.3
mccabe==0.6.1
oauthlib==3.1.0
psycopg2-binary==2.8.6
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycodestyle==2.6.0
pycparser==2.20
PyHamcrest==2.0.2
PyJWT==1.7.1
pylint==2.6.0
pyOpenSSL==19.1.0
python3-openid==3.2.0
pytz==2020.1
requests==2.24.0
requests-oauthlib==1.3.0
service-identity==18.1.0
six==1.15.0
social-auth-app-django==4.0.0
social-auth-core==3.3.3
sqlparse==0.4.1
toml==0.10.1
Twisted==20.3.0
txaio==20.4.1
urllib3==1.25.11
whitenoise==5.2.0
wrapt==1.12.1
zope.interface==5.1.2
# settings.py
"""
Django settings for config project.
Generated by 'django-admin startproject' using Django 3.1.2.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
import os
from datetime import timedelta
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ['SECRET_KEY']
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ['DEBUG'] == 'True'
ALLOWED_HOSTS = [
os.environ['DOMAIN'],
'companyapp.local',
'.company.com'
]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Third-party packages
'channels',
'rest_framework',
'rest_framework.authtoken',
'social_django',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
]
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
ASGI_APPLICATION = "config.routing.application"
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['PGDATABASE'],
'USER': os.environ['PGUSER'],
'PASSWORD': os.environ['PGPASSWORD'],
'HOST': os.environ['PGHOST'],
'PORT': 5432
}
}
# REST Framework settings
# https://www.django-rest-framework.org/
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
}
# SIMPLE_JWT Settings
# https://github.com/davesque/django-rest-framework-simplejwt
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=3),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'SIGNING_KEY': os.environ['SECRET_KEY'],
}
AUTHENTICATION_BACKENDS = (
'social_core.backends.azuread_tenant.AzureADTenantOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
# SOCIAL_AUTH_POSTGRES_JSONFIELD = True
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY = '<client_id>'
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET = '<client_secret>'
# SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_RESOURCE = ''
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID = '<tenant_id>'
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.social_auth.associate_by_email',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
)
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/Los_Angeles'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
# STATIC_URL = '/static/'
STATIC_URL = '/api/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# Define the upload and download directories
DOWNLOAD_ROOT = '/mnt/company-files/client-downloads/'
MEDIA_ROOT = '/mnt/company-files/client-submissions/'
# urls.py
from django.contrib import admin
from django.urls import path, include
from users.views import exchange_token
urlpatterns = [
path('api/admin/', admin.site.urls),
path('api/social/<str:backend>/', exchange_token),
]
# views.py
from django.conf import settings
from rest_framework.authentication import TokenAuthentication
from rest_framework import serializers
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from requests.exceptions import HTTPError
from social_django.utils import psa
class SocialSerializer(serializers.Serializer):
"""
Serializer which accepts an OAuth2 access token.
"""
access_token = serializers.CharField(
allow_blank=False,
trim_whitespace=True,
)
@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
@authentication_classes([TokenAuthentication])
@psa()
def exchange_token(request, backend):
"""
Exchange an OAuth2 access token for one for this site.
This simply defers the entire OAuth2 process to the front end.
The front end becomes responsible for handling the entirety of the
OAuth2 process; we just step in at the end and use the access token
to populate some user identity.
The URL at which this view lives must include a backend field, like:
url(API_ROOT + r'social/(?P<backend>[^/]+)/$', exchange_token),
Using that example, you could call this endpoint using i.e.
POST API_ROOT + 'social/facebook/'
POST API_ROOT + 'social/google-oauth2/'
Note that those endpoint examples are verbatim according to the
PSA backends which we configured in settings.py. If you wish to enable
other social authentication backends, they'll get their own endpoints
automatically according to PSA.
## Request format
Requests must include the following field
- `access_token`: The OAuth2 access token provided by the provider
"""
serializer = SocialSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
# set up non-field errors key
# http://www.django-rest-framework.org/api-guide/exceptions/#exception-handling-in-rest-framework-views
try:
nfe = settings.NON_FIELD_ERRORS_KEY
except AttributeError:
nfe = 'non_field_errors'
try:
# this line, plus the psa decorator above, are all that's necessary to
# get and populate a user object for any properly enabled/configured backend
# which python-social-auth can handle.
print(serializer.validated_data['access_token'])
user = request.backend.do_auth(
serializer.validated_data['access_token'])
except HTTPError as e:
# An HTTPError bubbled up from the request to the social auth provider.
# This happens, at least in Google's case, every time you send a malformed
# or incorrect access key.
return Response(
{'errors': {
'token': 'Invalid token',
'detail': str(e),
}},
status=status.HTTP_400_BAD_REQUEST,
)
if user:
if user.is_active:
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
else:
# user is not active; at some point they deleted their account,
# or were banned by a superuser. They can't just log in with their
# normal credentials anymore, so they can't log in with social
# credentials either.
return Response(
{'errors': {nfe: 'This user account is inactive'}},
status=status.HTTP_400_BAD_REQUEST,
)
else:
# Unfortunately, PSA swallows any information the backend provider
# generated as to why specifically the authentication failed;
# this makes it tough to debug except by examining the server logs.
return Response(
{'errors': {nfe: "Authentication Failed"}},
status=status.HTTP_400_BAD_REQUEST,
)
This is the line it refers to in the traceback:
https://github.com/python-social-auth/social-core/blob/9d93069564a60495e0ebd697b33e16fcff14195b/social_core/backends/azuread_tenant.py#L97
I've verified my ReactJS FE is correctly sending the access_token
as I can print it out server-side with print(request.data)
and print(serializer.validated_data['access_token'])
. Everything seems to be flowing properly until it gets to verifying the access_token
server-side at:
user = request.backend.do_auth(
serializer.validated_data['access_token'])
The user it is trying to validate should not be in the database currently, if that helps.
Suggestions for what I'm doing wrong here or how to resolve it?
Quite disappointing this didn't receive any sort of reply ...
I think its supposed to be
serializer.is_valid(raise_exception=True)
serializer.data
Try changing this line user = request.backend.do_auth( serializer.validated_data['access_token'])
with
user = backend.do_auth( access_token, response={"id_token": id_token}) #Id token you will get along with access token.
I am getting the same AttributeError:
AttributeError: 'NoneType' object has no attribute 'get'
Traceback (most recent call last) File "C:\Users\Jayanth.virtualenvs\helloworld-CPu4KsHf\lib\site-packages\flask\app.py", line 2088, in call return self.wsgi_app(environ, start_response) File "C:\Users\Jayanth.virtualenvs\helloworld-CPu4KsHf\lib\site-packages\flask\app.py", line 2073, in wsgi_app response = self.handle_exception(e) File "C:\Users\Jayanth.virtualenvs\helloworld-CPu4KsHf\lib\site-packages\flask\app.py", line 2070, in wsgi_app response = self.full_dispatch_request() File "C:\Users\Jayanth.virtualenvs\helloworld-CPu4KsHf\lib\site-packages\flask\app.py", line 1515, in full_dispatch_request rv = self.handle_user_exception(e) File "C:\Users\Jayanth.virtualenvs\helloworld-CPu4KsHf\lib\site-packages\flask\app.py", line 1513, in full_dispatch_request rv = self.dispatch_request() File "C:\Users\Jayanth.virtualenvs\helloworld-CPu4KsHf\lib\site-packages\flask\app.py", line 1499, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "D:\ExcelSoft\venil\Cognitive-Behavioural-Chatbot-master\helloworld\web.py", line 26, in webhook res = processRequest(req) File "D:\ExcelSoft\venil\Cognitive-Behavioural-Chatbot-master\helloworld\web.py", line 36, in processRequest print ("starting processRequest...",req.get("result").get("action")) AttributeError: 'NoneType' object has no attribute 'get'
The code is: web.txt
How to correct what is written below (python 3):
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Dani Brothers\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "D:/Python/Book Bank/New folder/PyCharm/Final/Excel.py", line 57, in SaveBook
e_pissue.get(),
AttributeError: 'NoneType' object has no attribute 'get'
Process finished with exit code 0