Please provide a detailed documentation in your wiki site on how to create a custom provider with OAuth2... i tried to have a look into other providers with OAuth2, but i'm no python coder, so i still can't create a new account when using OAuth2, in fact i get this error:
Traceback (most recent call last):
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/django/utils/decorators.py", line 145, in inner
return func(*args, **kwargs)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 62, in view
return self.dispatch(request, *args, **kwargs)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 116, in dispatch
error=error)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/allauth/socialaccount/helpers.py", line 75, in render_authentication_error
extra_context=extra_context)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/pootle/apps/accounts/social_adapter.py", line 77, in authentication_error
log_exception(request, exception, tb)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/pootle/middleware/errorpages.py", line 49, in log_exception
msg_args = (unicode(exception.args[0]), tb,
AttributeError: 'NoneType' object has no attribute 'args'
These are my files, and this is the OAuth Server used: https://github.com/wohali/ips4-oauth2-server
provider.py
from allauth.socialaccount import providers
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
class TUitAccount(ProviderAccount):
def get_profile_url(self):
return self.account.extra_data.get('profileUrl')
def get_avatar_url(self):
return self.account.extra_data.get('avatar')
def to_str(self):
dflt = super(TUitAccount, self).to_str()
return self.account.extra_data.get('username', dflt)
class TUitProvider(OAuth2Provider):
id = 'tuit'
name = 'Tamriel Unlimited IT'
account_class = TUitAccount
def extract_uid(self, data):
return str(data['id'])
def extract_common_fields(self, data):
return dict(username=data.get('username'),
name=data.get('displayName'),
email=data.get('email'))
def get_default_scope(self):
scope = ['user.profile', 'user.email']
return scope
providers.registry.register(TUitProvider)
urls.py
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from .provider import TUitProvider
urlpatterns = default_urlpatterns(TUitProvider)
views.py
import requests
from allauth.socialaccount.providers.oauth2.views import (OAuth2Adapter,
OAuth2LoginView,
OAuth2CallbackView)
from .provider import TUitProvider
class TUitOAuth2Adapter(OAuth2Adapter):
provider_id = TUitProvider.id
access_token_url = 'https://example.com/applications/oauth2server/interface/oauth/token.php'
authorize_url = 'https://example.com/applications/oauth2server/interface/oauth/authorize.php'
profile_url = 'https://example.com/applications/oauth2server/interface/oauth/me.php'
headers = {"User-Agent": "django-allauth-header"}
# After successfully logging in, use access token to retrieve user info
def complete_login(self, request, app, token, **kwargs):
headers = {
"Authorization": "bearer " + token.token}
headers.update(self.headers)
extra_data = requests.get(self.profile_url, headers=headers)
# This only here because of weird response from the test suite
if isinstance(extra_data, list):
extra_data = extra_data[0]
return self.get_provider().sociallogin_from_response(
request,
extra_data.json()
)
oauth2_login = OAuth2LoginView.adapter_view(TUitOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(TUitOAuth2Adapter)
While I agree that the documentation is indeed lacking in various areas, I am adhering to the debatable principle that keeping open issues around with respect to documentation is not very helpful in improving things. Feel free to submit a pull request...
I have no idea how to code PROPERLY in python and you ask to make a pull request to create docs which i have no idea how to start with, since probably i made mistakes in the code above... and the reason I came here asking for help was to solve and to understand what I was doing wrong... good job closing the ticket... nice debate... i will gladly help to provide docs for custom oauth, but you don't help to understand the wrong code... so thank you... and good luck
I am sorry, no offense intended.... but I have do have to keep a strict policy on the issue tracker, otherwise this project wouldn't get anywhere as I would only be spending all time on support.
As for your particular issue... have a look at these lines:
...
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/pootle/apps/accounts/social_adapter.py", line 77, in authentication_error
log_exception(request, exception, tb)
File "/home/desktop/Pubblici/Envs/pootle/lib/python2.7/site-packages/pootle/middleware/errorpages.py", line 49, in log_exception
msg_args = (unicode(exception.args[0]), tb,
AttributeError: 'NoneType' object has no attribute 'args'
It seems pootle is causing the AttributeError.. that clearly is beyond scope of allauth.
Fixed with this edit in views.py (i post the fix if someone needs it)... this is a working code for IPS oauth now ;) cheers
class TUitOAuth2Adapter(OAuth2Adapter):
provider_id = TUitProvider.id
access_token_url = 'https://example.com/applications/oauth2server/interface/oauth/token.php'
authorize_url = 'https://example.com/applications/oauth2server/interface/oauth/authorize.php'
profile_url = 'https://example.com/applications/oauth2server/interface/oauth/me.php'
# After successfully logging in, use access token to retrieve user info
def complete_login(self, request, app, token, **kwargs):
resp = requests.get(self.profile_url,
params={'access_token': token.token})
extra_data = resp.json()
if app_settings.QUERY_EMAIL and not extra_data.get('email'):
extra_data['email'] = self.get_email(token)
return self.get_provider().sociallogin_from_response(request,
extra_data)
oauth2_login = OAuth2LoginView.adapter_view(TUitOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(TUitOAuth2Adapter)
Most helpful comment
Fixed with this edit in views.py (i post the fix if someone needs it)... this is a working code for IPS oauth now ;) cheers