oauth_client: add separate forms for Provider Types

This commit is contained in:
Jens Langhammer 2018-12-18 10:40:46 +01:00
parent 8d5abeaede
commit 65bdca30ae
3 changed files with 161 additions and 7 deletions

View File

@ -10,6 +10,11 @@ from passbook.core.models import Source
from passbook.lib.utils.reflection import path_to_class from passbook.lib.utils.reflection import path_to_class
def all_subclasses(cls):
"""Recursively return all subclassess of cls"""
return set(cls.__subclasses__()).union(
[s for c in cls.__subclasses__() for s in all_subclasses(c)])
class SourceListView(AdminRequiredMixin, ListView): class SourceListView(AdminRequiredMixin, ListView):
"""Show list of all sources""" """Show list of all sources"""
@ -18,7 +23,7 @@ class SourceListView(AdminRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs['types'] = { kwargs['types'] = {
x.__name__: x._meta.verbose_name for x in Source.__subclasses__()} x.__name__: x._meta.verbose_name for x in all_subclasses(Source)}
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
def get_queryset(self): def get_queryset(self):
@ -34,7 +39,7 @@ class SourceCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView):
def get_form_class(self): def get_form_class(self):
source_type = self.request.GET.get('type') source_type = self.request.GET.get('type')
model = next(x for x in Source.__subclasses__() if x.__name__ == source_type) model = next(x for x in all_subclasses(Source) if x.__name__ == source_type)
if not model: if not model:
raise Http404 raise Http404
return path_to_class(model.form) return path_to_class(model.form)

View File

@ -1,6 +1,7 @@
"""passbook oauth_client forms""" """passbook oauth_client forms"""
from django import forms from django import forms
from django.utils.translation import gettext as _
from passbook.admin.forms.source import SOURCE_FORM_FIELDS from passbook.admin.forms.source import SOURCE_FORM_FIELDS
from passbook.oauth_client.models import OAuthSource from passbook.oauth_client.models import OAuthSource
@ -9,9 +10,97 @@ from passbook.oauth_client.models import OAuthSource
class OAuthSourceForm(forms.ModelForm): class OAuthSourceForm(forms.ModelForm):
"""OAuthSource Form""" """OAuthSource Form"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if hasattr(self.Meta, 'overrides'):
for overide_field, overide_value in getattr(self.Meta, 'overrides').items():
self.fields[overide_field].initial = overide_value
self.fields[overide_field].widget.attrs['readonly'] = 'readonly'
class Meta: class Meta:
model = OAuthSource model = OAuthSource
fields = SOURCE_FORM_FIELDS + ['provider_type', 'request_token_url', 'authorization_url', fields = SOURCE_FORM_FIELDS + ['provider_type', 'request_token_url', 'authorization_url',
'access_token_url', 'profile_url', 'consumer_key', 'access_token_url', 'profile_url', 'consumer_key',
'consumer_secret'] 'consumer_secret']
widgets = {
'name': forms.TextInput(),
'consumer_key': forms.TextInput(),
'consumer_secret': forms.TextInput(),
}
labels = {
'request_token_url': _('Request Token URL'),
'authorization_url': _('Authorization URL'),
'access_token_url': _('Access Token URL'),
'profile_url': _('Profile URL'),
}
class GitHubOAuthSourceForm(OAuthSourceForm):
"""OAuth Source form with pre-determined URL for GitHub"""
class Meta(OAuthSourceForm.Meta):
overrides = {
'provider_type': 'github',
'request_token_url': '',
'authorization_url': 'https://github.com/login/oauth/authorize',
'access_token_url': 'https://github.com/login/oauth/access_token',
'profile_url': ' https://api.github.com/user',
}
class TwitterOAuthSourceForm(OAuthSourceForm):
"""OAuth Source form with pre-determined URL for Twitter"""
class Meta(OAuthSourceForm.Meta):
overrides = {
'provider_type': 'twitter',
'request_token_url': 'https://api.twitter.com/oauth/request_token',
'authorization_url': 'https://api.twitter.com/oauth/authenticate',
'access_token_url': 'https://api.twitter.com/oauth/access_token',
'profile_url': ' https://api.twitter.com/1.1/account/verify_credentials.json',
}
class FacebookOAuthSourceForm(OAuthSourceForm):
"""OAuth Source form with pre-determined URL for Facebook"""
class Meta(OAuthSourceForm.Meta):
overrides = {
'provider_type': 'facebook',
'request_token_url': '',
'authorization_url': 'https://www.facebook.com/v2.8/dialog/oauth',
'access_token_url': 'https://graph.facebook.com/v2.8/oauth/access_token',
'profile_url': ' https://graph.facebook.com/v2.8/me?fields=name,email,short_name',
}
class DiscordOAuthSourceForm(OAuthSourceForm):
"""OAuth Source form with pre-determined URL for Discord"""
class Meta(OAuthSourceForm.Meta):
overrides = {
'provider_type': 'discord',
'request_token_url': '',
'authorization_url': 'https://discordapp.com/api/oauth2/authorize',
'access_token_url': 'https://discordapp.com/api/oauth2/token',
'profile_url': ' https://discordapp.com/api/users/@me',
}
class GoogleOAuthSourceForm(OAuthSourceForm):
"""OAuth Source form with pre-determined URL for Google"""
class Meta(OAuthSourceForm.Meta):
overrides = {
'provider_type': 'google',
'request_token_url': '',
'authorization_url': 'https://accounts.google.com/o/oauth2/auth',
'access_token_url': 'https://accounts.google.com/o/oauth2/token',
'profile_url': ' https://www.googleapis.com/oauth2/v1/userinfo',
}

View File

@ -1,6 +1,7 @@
"""OAuth Client models""" """OAuth Client models"""
from django.db import models from django.db import models
from django.utils.translation import gettext as _
from passbook.core.models import Source, UserSourceConnection from passbook.core.models import Source, UserSourceConnection
from passbook.oauth_client.clients import get_client from passbook.oauth_client.clients import get_client
@ -17,14 +18,73 @@ class OAuthSource(Source):
consumer_key = models.TextField() consumer_key = models.TextField()
consumer_secret = models.TextField() consumer_secret = models.TextField()
form = 'passbook.oauth_client.forms.OAuthSourceForm' form = 'passbook.oauth_client.forms.GitHubOAuthSourceForm'
class Meta: class Meta:
verbose_name = 'OAuth Source' verbose_name = _('Generic OAuth Source')
verbose_name_plural = 'OAuth Sources' verbose_name_plural = _('Generic OAuth Sources')
class GitHubOAuthSource(OAuthSource):
"""Abstract subclass of OAuthSource to specify GitHub Form"""
form = 'passbook.oauth_client.forms.GitHubOAuthSourceForm'
class Meta:
abstract = True
verbose_name = _('GitHub OAuth Source')
verbose_name_plural = _('GitHub OAuth Sources')
class TwitterOAuthSource(OAuthSource):
"""Abstract subclass of OAuthSource to specify Twitter Form"""
form = 'passbook.oauth_client.forms.TwitterOAuthSourceForm'
class Meta:
abstract = True
verbose_name = _('Twitter OAuth Source')
verbose_name_plural = _('Twitter OAuth Sources')
class FacebookOAuthSource(OAuthSource):
"""Abstract subclass of OAuthSource to specify Facebook Form"""
form = 'passbook.oauth_client.forms.FacebookOAuthSourceForm'
class Meta:
abstract = True
verbose_name = _('Facebook OAuth Source')
verbose_name_plural = _('Facebook OAuth Sources')
class DiscordOAuthSource(OAuthSource):
"""Abstract subclass of OAuthSource to specify Discord Form"""
form = 'passbook.oauth_client.forms.DiscordOAuthSourceForm'
class Meta:
abstract = True
verbose_name = _('Discord OAuth Source')
verbose_name_plural = _('Discord OAuth Sources')
class GoogleOAuthSource(OAuthSource):
"""Abstract subclass of OAuthSource to specify Google Form"""
form = 'passbook.oauth_client.forms.GoogleOAuthSourceForm'
class Meta:
abstract = True
verbose_name = _('Google OAuth Source')
verbose_name_plural = _('Google OAuth Sources')
class UserOAuthSourceConnection(UserSourceConnection): class UserOAuthSourceConnection(UserSourceConnection):
"""Authorized remote OAuth provider.""" """Authorized remote OAuth provider."""
@ -42,5 +102,5 @@ class UserOAuthSourceConnection(UserSourceConnection):
class Meta: class Meta:
verbose_name = 'User OAuth Source Connection' verbose_name = _('User OAuth Source Connection')
verbose_name_plural = 'User OAuth Source Connections' verbose_name_plural = _('User OAuth Source Connections')