django-oauth/django-oauth-toolkit

Support for `prompt=create`

Opened this issue · 1 comments

jaap3 commented

The Initiating User Registration via OpenID Connect 1.0 specification defines that the prompt=create can be used to explicitly signal that user desires to create a new account rather than authenticate using an existing identity.

I was able to hack in support for this parameter in DOT by overriding the AuthorizationView and adding some overrides here and there:

from oauth2_provider import views as oauth2_views

from django.contrib.auth.models import AnonymousUser


def _has_prompt_create(request):
    # Check if the prompt=create parameter is present in the request.
    # This parameter is used to explicitly signal that user desires to
    # create a new account rather than authenticate using an existing identity.
    # https://openid.net/specs/openid-connect-prompt-create-1_0.html
    return request.GET.get("prompt") == "create"


class AuthorizationView(oauth2_views.AuthorizationView):
    registration_url = "accounts:register"

    def get(self, request, *args, **kwargs):
        if _has_prompt_create(request):
            # Switch request.user to AnonymousUser. This forces handle_no_permission
            # to issue a redirect instead of raising a PermissionDenied exception if
            # a user is currently logged-in.
            self.request.user = AnonymousUser()
            return self.handle_no_permission()
        return super().get(request, *args, **kwargs)

    def get_login_url(self):
        if _has_prompt_create(self.request):
            # The current URL is used as the redirect URL after registration.
            # Drop the prompt=create parameter to return to the authorization flow,
            # without ending up in a redirect loop.
            query = self.request.GET.copy()
            query.pop("prompt")
            self.request.META["QUERY_STRING"] = query.urlencode()
            return self.registration_url
        return super().get_login_url()

This might not be the ideal solution, but it's the best I could think of given how this view is implemented.

I'm opening this as a feature request, fully understanding that this is not a feature every user of DOT requires. I would've started a discussion instead, but this repository doesn't have github discussions enabled.