django-publicauth / publicauth / backends / openid.py

from __future__ import absolute_import 

from openid.consumer import consumer, discover
from openid.extensions.sreg import SRegRequest, SRegResponse
from openid.extensions.ax import FetchRequest, AttrInfo, FetchResponse

from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.contrib import messages
from django.contrib import auth
from django import forms

from annoying.exceptions import Redirect

from publicauth.backends import BaseBackend
from publicauth.utils import str_to_class
from publicauth import settings
from publicauth import lang


class OpenIDBackend(BaseBackend):

    def begin(self, request, data):
        try:
            openid_url = data['openid_url'].strip()
        except KeyError:
            messages.error(request, lang.FILL_OPENID_URL)
            raise Redirect('publicauth-login')

        # allow user to type openid provider without http:// prefix
        if not openid_url.startswith("http"):
            openid_url = "http://%s" % openid_url

        return_url = request.build_absolute_uri(reverse('publicauth-complete', args=[self.provider]))
        request.session['openid_return_to'] = return_url
        client = consumer.Consumer(request.session, None)

        try:
            openid_request = client.begin(openid_url)
            sreg_extra = [i for i in self.PROFILE_MAPPING]
            sreg = SRegRequest(required=sreg_extra)
            openid_request.addExtension(sreg)
            ax_msg = FetchRequest()
            for detail in self.PROFILE_MAPPING:
                ax_msg.add(AttrInfo(settings.AX_URIS[detail], required=True))
            openid_request.addExtension(ax_msg)

            redirect_url = openid_request.redirectURL(realm='http://' + request.get_host(), return_to=return_url)
            raise Redirect(redirect_url)

        except discover.DiscoveryFailure:
            messages.error(request, _('Could not find OpenID server'))
            raise Redirect('publicauth-login')

    def validate(self, request, data):
        """
        Validate response from OpenID server.
        Set identity in case of successfull validation.
        """
        client = consumer.Consumer(request.session, None)

        try:
            resp = client.complete(data, request.session['openid_return_to'])
        except KeyError:
            messages.error(request, lang.INVALID_RESPONSE_FROM_OPENID)
            raise Redirect('publicauth-login')
        if resp.status == consumer.CANCEL:
            messages.warning(request, lang.OPENID_CANCELED)
            raise Redirect('publicauth-login')
        elif resp.status == consumer.FAILURE:
            messages.error(request, lang.OPENID_FAILED % resp.message)
            raise Redirect('publicauth-login')
        elif resp.status == consumer.SUCCESS:
            self.identity = resp.identity_url
            del request.session['openid_return_to']
            return resp

    def complete(self, request, response):
        data = self.fill_extra_fields(request, self.get_extra_data(response))
        request.session['extra'] = data
        request.session['identity'] = self.identity
        return redirect('publicauth-extra', self.provider)

    def get_extra_data(self, response):
        return SRegResponse.fromSuccessResponse(response)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.