oauth_client: add form, cleanup views

This commit is contained in:
Jens Langhammer 2018-11-22 13:12:24 +01:00
parent 6748241905
commit 20752b4382
4 changed files with 69 additions and 49 deletions

View File

@ -0,0 +1,15 @@
"""passbook oauth_client forms"""
from django import forms
from passbook.oauth_client.models import OAuthSource
class OAuthSourceForm(forms.ModelForm):
"""OAuthSource Form"""
class Meta:
model = OAuthSource
# pylint: disable=modelform-uses-exclude
exclude = []

View File

@ -17,6 +17,8 @@ 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'
class Meta: class Meta:
verbose_name = 'OAuth Source' verbose_name = 'OAuth Source'

View File

@ -3,14 +3,13 @@
from django.urls import path from django.urls import path
from passbook.oauth_client.source_types.manager import RequestKind from passbook.oauth_client.source_types.manager import RequestKind
# from passbook.oauth_client.views import core, settings from passbook.oauth_client.views import core, dispatcher
from passbook.oauth_client.views import dispatcher
urlpatterns = [ urlpatterns = [
path('login/<slug:source_slug>/', dispatcher.DispatcherView.as_view( path('login/<slug:source_slug>/', dispatcher.DispatcherView.as_view(
kind=RequestKind.redirect), name='oauth-client-login'), kind=RequestKind.redirect), name='oauth-client-login'),
path('callback/<slug:source_slug>/', dispatcher.DispatcherView.as_view( path('callback/<slug:source_slug>/', dispatcher.DispatcherView.as_view(
kind=RequestKind.callback), name='oauth-client-callback'), kind=RequestKind.callback), name='oauth-client-callback'),
# path('disconnect/<slug:source_slug>/', core.disconnect, path('disconnect/<slug:source_slug>/', core.DisconnectView.as_view(),
# name='oauth-client-disconnect'), name='oauth-client-disconnect'),
] ]

View File

@ -1,4 +1,4 @@
"""Core Oauth Views""" """Core OAauth Views"""
import base64 import base64
import hashlib import hashlib
@ -7,14 +7,15 @@ from logging import getLogger
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import authenticate, get_user_model, login from django.contrib.auth import authenticate, get_user_model, login
from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import Http404, HttpRequest, HttpResponse from django.http import Http404
from django.shortcuts import redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.encoding import force_text, smart_bytes from django.utils.encoding import force_text, smart_bytes
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic import RedirectView, View from django.views.generic import RedirectView, View
from passbook.lib.utils.reflection import app
from passbook.oauth_client.clients import get_client from passbook.oauth_client.clients import get_client
from passbook.oauth_client.errors import (OAuthClientEmailMissingError, from passbook.oauth_client.errors import (OAuthClientEmailMissingError,
OAuthClientError) OAuthClientError)
@ -193,64 +194,67 @@ class OAuthCallback(OAuthClientMixin, View):
def handle_new_user(self, source, access, info): def handle_new_user(self, source, access, info):
"Create a shell auth.User and redirect." "Create a shell auth.User and redirect."
was_authenticated = False
if self.request.user.is_authenticated: # pylint: disable=no-else-return if self.request.user.is_authenticated: # pylint: disable=no-else-return
# there's already a user logged in, just link them up # there's already a user logged in, just link them up
user = self.request.user user = self.request.user
access.user = user was_authenticated = True
access.save() else:
UserOAuthSourceConnection.objects.filter(pk=access.pk).update(user=user) user = self.get_or_create_user(source, access, info)
access.user = user
access.save()
UserOAuthSourceConnection.objects.filter(pk=access.pk).update(user=user)
if not was_authenticated:
user = authenticate(source=access.source,
identifier=access.identifier, request=self.request)
login(self.request, user)
if app('passbook_audit'):
pass
# from passbook.audit.models import something
# something.event(user=user,)
# Event.create( # Event.create(
# user=user, # user=user,
# message=_("Linked user with OAuth source %s" % self.source.name), # message=_("Linked user with OAuth source %s" % self.source.name),
# request=self.request, # request=self.request,
# hidden=True, # hidden=True,
# current=False) # current=False)
if was_authenticated:
messages.success(self.request, _("Successfully linked %(source)s!" % { messages.success(self.request, _("Successfully linked %(source)s!" % {
'source': self.source.name 'source': self.source.name
})) }))
return redirect(reverse('user_settings')) return redirect(reverse('user_settings'))
else: messages.success(self.request, _("Successfully authenticated with %(source)s!" % {
user = self.get_or_create_user(source, access, info) 'source': self.source.name
access.user = user }))
access.save() return redirect(self.get_login_redirect(source, user, access, True))
UserOAuthSourceConnection.objects.filter(pk=access.pk).update(user=user)
user = authenticate(source=access.source,
identifier=access.identifier, request=self.request)
login(self.request, user)
# Event.create(
# user=user,
# message=_("Authenticated user with OAuth source %s" % self.source.name),
# request=self.request,
# hidden=True,
# current=False)
messages.success(self.request, _("Successfully authenticated with %(source)s!" % {
'source': self.source.name
}))
return redirect(self.get_login_redirect(source, user, access, True))
@login_required class DisconnectView(LoginRequiredMixin, View):
def disconnect(request: HttpRequest, source: str) -> HttpResponse:
"""Delete connection with source""" """Delete connection with source"""
source = OAuthSource.objects.filter(name=source)
if not source.exists():
raise Http404
r_source = source.first()
aas = UserOAuthSourceConnection.objects.filter(source=r_source, user=request.user) source = None
if not aas.exists(): aas = None
raise Http404
r_aas = aas.first()
if request.method == 'POST' and 'confirmdelete' in request.POST: def dispatch(self, request, source):
# User confirmed deletion self.source = get_object_or_404(OAuthSource, name=source)
r_aas.delete() self.aas = get_object_or_404(UserOAuthSourceConnection,
messages.success(request, _('Connection successfully deleted')) source=self.source, user=request.user)
return redirect(reverse('user_settings')) return super().dispatch(request, source)
return render(request, 'generic/delete.html', { def post(self, request, source):
'object': 'OAuth Connection with %s' % r_source.name, """Delete connection object"""
'delete_url': reverse('oauth-client-disconnect', kwargs={ if 'confirmdelete' in request.POST:
'source': r_source.name, # User confirmed deletion
self.aas.delete()
messages.success(request, _('Connection successfully deleted'))
return redirect(reverse('user_settings'))
return self.get(request, source)
def get(self, request, source):
"""Show delete form"""
return render(request, 'generic/delete.html', {
'object': 'OAuth Connection with %s' % self.source.name,
'delete_url': reverse('oauth-client-disconnect', kwargs={
'source': self.source.name,
})
}) })
})