# -*- coding: utf-8 -*- # import logging from django.conf import settings from django.core.cache import cache from django.views.generic.base import RedirectView from django.contrib.auth import authenticate, login from django.http.response import ( HttpResponseBadRequest, HttpResponseServerError, HttpResponseRedirect ) from .utils import new_client from .models import Nonce from .signals import post_openid_login_success logger = logging.getLogger(__name__) client = new_client() __all__ = ['OpenIDLoginView', 'OpenIDLoginCompleteView'] class OpenIDLoginView(RedirectView): def get_redirect_url(self, *args, **kwargs): redirect_uri = settings.BASE_SITE_URL + str(settings.LOGIN_COMPLETE_URL) nonce = Nonce( redirect_uri=redirect_uri, next_path=self.request.GET.get('next') ) cache.set(str(nonce.state), nonce, 24*3600) self.request.session['openid_state'] = str(nonce.state) authorization_url = client.openid_connect_client.\ authorization_url( redirect_uri=nonce.redirect_uri, scope='code', state=str(nonce.state) ) return authorization_url class OpenIDLoginCompleteView(RedirectView): def get(self, request, *args, **kwargs): if 'error' in request.GET: return HttpResponseServerError(self.request.GET['error']) if 'code' not in self.request.GET and 'state' not in self.request.GET: return HttpResponseBadRequest() if self.request.GET['state'] != self.request.session['openid_state']: return HttpResponseBadRequest() nonce = cache.get(self.request.GET['state']) if not nonce: return HttpResponseBadRequest() user = authenticate( request=self.request, code=self.request.GET['code'], redirect_uri=nonce.redirect_uri ) cache.delete(str(nonce.state)) if not user: return HttpResponseBadRequest() login(self.request, user) post_openid_login_success.send( sender=self.__class__, user=user, request=self.request ) return HttpResponseRedirect(nonce.next_path or '/')