Django-allauth: Provide docs for custom provider

Created on 4 Sep 2016  路  4Comments  路  Source: pennersr/django-allauth

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)

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

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)

All 4 comments

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)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

gitdeepak picture gitdeepak  路  5Comments

slimaidarismail picture slimaidarismail  路  3Comments

aliabbas-2012 picture aliabbas-2012  路  6Comments

hyunwoona picture hyunwoona  路  4Comments

peterhn picture peterhn  路  4Comments