wagnerdelima / drf-social-oauth2

drf-social-oauth2 makes it easy to integrate Django social authentication with major OAuth2 providers, i.e., Facebook, Twitter, Google, etc.
https://drf-social-oauth2.readthedocs.io/en/latest/
MIT License
274 stars 34 forks source link

URL namespacing broken within ConvertTokenView: 'drf' is not a registered namespace inside 'drf' #244

Open Eboreg opened 2 months ago

Eboreg commented 2 months ago

Setup

I am including the URLs in a manner similar to that in the docs, i.e. using path("auth/", include("drf_social_oauth2.urls", namespace="drf")). This results in the following URLs:

/auth/authorize/    oauth2_provider.views.base.AuthorizationView    drf:authorize
/auth/complete/<str:backend>/       social_django.views.complete    drf:social:complete
/auth/convert-token/        drf_social_oauth2.views.ConvertTokenView        drf:convert_token
/auth/disconnect-backend/   drf_social_oauth2.views.DisconnectBackendView   drf:disconnect_backend
/auth/disconnect/<str:backend>/     social_django.views.disconnect  drf:social:disconnect
/auth/disconnect/<str:backend>/<int:association_id>/        social_django.views.disconnect  drf:social:disconnect_individual
/auth/invalidate-refresh-tokens/    drf_social_oauth2.views.InvalidateRefreshTokens drf:invalidate_refresh_tokens
/auth/invalidate-sessions/  drf_social_oauth2.views.InvalidateSessions      drf:invalidate_sessions
/auth/login/<str:backend>/  social_django.views.auth        drf:social:begin
/auth/revoke-token/ drf_social_oauth2.views.RevokeTokenView drf:revoke_token
/auth/token/        drf_social_oauth2.views.TokenView       drf:token

This, of course, necessitates that I put SOCIAL_AUTH_URL_NAMESPACE = "drf:social" in the Django settings, or else social_django's views will fail. I do not set DRFSO2_URL_NAMESPACE.

The problem

In SocialTokenGrant.validate_token_request(), which is used by ConvertTokenView, an attempt is made to reverse this URL:

"%s:%s:complete" % (DRFSO2_URL_NAMESPACE, NAMESPACE)

DRFSO2_URL_NAMESPACE has its default value, which is "drf". NAMESPACE is the same as SOCIAL_AUTH_URL_NAMESPACE, i.e. "drf:social". The result is therefore that it tries to reverse the URL "drf:drf:social:complete", which obviously does not exist.

Possible solution

I guess the code above could simply be changed to:

"%s:complete" % (NAMESPACE,)

... but I haven't tested it or given it much thought.

A workaround

Explicitly including the social_django URLs, without namespacing them under "drf:", while also setting SOCIAL_AUTH_URL_NAMESPACE = "social", seems to be working. Of course, this results in "duplicate" URLs (the same URLs are registered in both the drf:social and the social namespaces) which is kind of ugly:

path("auth/", include("drf_social_oauth2.urls", namespace="drf")),
path("auth/", include("social_django.urls")),
/auth/complete/<str:backend>/       social_django.views.complete    drf:social:complete
/auth/complete/<str:backend>/       social_django.views.complete    social:complete
/auth/disconnect/<str:backend>/     social_django.views.disconnect  drf:social:disconnect
/auth/disconnect/<str:backend>/     social_django.views.disconnect  social:disconnect
/auth/disconnect/<str:backend>/<int:association_id>/        social_django.views.disconnect  drf:social:disconnect_individual
/auth/disconnect/<str:backend>/<int:association_id>/        social_django.views.disconnect  social:disconnect_individual
/auth/login/<str:backend>/  social_django.views.auth        drf:social:begin
/auth/login/<str:backend>/  social_django.views.auth        social:begin

Versions