Skip to content

Instantly share code, notes, and snippets.

@theladyjaye
Last active August 29, 2015 14:07
Show Gist options
  • Save theladyjaye/4467ff97fb4300c3a87d to your computer and use it in GitHub Desktop.
Save theladyjaye/4467ff97fb4300c3a87d to your computer and use it in GitHub Desktop.
django-oauth2-provider scheme patch

How to Install

New files:

  • There are 3 new files you will need to add.
  • You will need to vendor in django-oauth2-provider into your project.

Once done, add a folder in provider/oauth2 called ext. In the end this path will exist: provider/oauth2/ext.

Place the 3 files below into that folder with an __init__.py

Modify existing files:

Now it's time to integrate the new files into the existing file. There are 2 files we need to change ever so slightly:

  • provider.oauth2.admin
  • provider.oauth2.models

provider.oauth2.admin

We just need to register our custom admin form we added in the above 3 files:

# ... existing imports ...
from .ext import forms as x_forms

# ... existing code ...

class ClientAdmin(admin.ModelAdmin):
    form = x_forms.x_ClientAdminForm
    list_display = ('url', 'user', 'redirect_uri', 'client_id', 'client_type')
    raw_id_fields = ('user',)

# ... existing code ...

provider.oauth2.models

# ... existing imports ...
from .ext import fields as x_models

# ... existing code ...
# We just need to change the redirect_uri field of the Client model to the following:

class Client(models.Model):
    # ... existing fields ...
    redirect_uri = x_models.x_URLField(help_text="Your application's callback URL")
    # ... existing fields ...

# ... existing code ...

That's it.. you should now be able to set custom schemes from the admin UI

from django.db import models
from .validators import x_URLValidator
class x_URLField(models.URLField):
default_validators = [x_URLValidator()]
from django import forms
from ..models import Client
from .validators import x_URLValidator
from django.contrib.admin.widgets import AdminURLFieldWidget
class x_ClientAdminForm(forms.ModelForm):
"""
Form to create new consumers.
"""
redirect_uri = forms.CharField(
max_length=200,
widget=AdminURLFieldWidget,
validators=[x_URLValidator()])
class Meta:
model = Client
fields = ('user', 'name', 'url', 'redirect_uri', 'client_id', 'client_secret', 'client_type')
from django.utils.encoding import force_text
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit
# exactly the same as validators.URLValidator
# with 2 exceptions:
class x_URLValidator(validators.URLValidator):
def __init__(self, schemes=None, **kwargs):
super(validators.URLValidator, self).__init__(**kwargs)
# -----> DIFFERS 1
self.schemes = schemes
def __call__(self, value):
value = force_text(value)
# Check first if the scheme is valid
scheme = value.split('://')[0].lower()
# -----> DIFFERS 2
if self.schemes and scheme not in self.schemes:
raise ValidationError(self.message, code=self.code)
# Then check full URL
try:
super(validators.URLValidator, self).__call__(value)
except ValidationError as e:
# Trivial case failed. Try for possible IDN domain
if value:
scheme, netloc, path, query, fragment = urlsplit(value)
try:
netloc = netloc.encode('idna').decode('ascii') # IDN -> ACE
except UnicodeError: # invalid domain part
raise e
url = urlunsplit((scheme, netloc, path, query, fragment))
super(validators.URLValidator, self).__call__(url)
else:
raise
else:
url = value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment