예제 #1
0
def login_begin(request,
                template_name='openid/login.html',
                login_complete_view='openid-complete',
                form_class=OpenIDLoginForm,
                render_failure=default_render_failure,
                redirect_field_name=REDIRECT_FIELD_NAME):
    """Begin an OpenID login request, possibly asking for an identity URL."""
    data = get_request_data(request)
    redirect_to = data.get(redirect_field_name, '')

    # Get the OpenID URL to try.  First see if we've been configured
    # to use a fixed server URL.
    openid_url = getattr(settings, 'OPENID_SSO_SERVER_URL', None)

    if openid_url is None:
        if request.POST:
            login_form = form_class(data=request.POST)
            if login_form.is_valid():
                openid_url = login_form.cleaned_data['openid_identifier']
        else:
            login_form = form_class()

        # Invalid or no form data:
        if openid_url is None:
            context = RequestContext(request).flatten()
            context.update({
                'form': login_form,
                redirect_field_name: redirect_to,
            })
            return render(request, template_name, context)

    consumer = make_consumer(request)
    try:
        openid_request = consumer.begin(openid_url)
    except DiscoveryFailure as exc:
        return render_failure(request,
                              "OpenID discovery error: %s" % (str(exc), ),
                              status=500,
                              exception=exc)

    # Request some user details.  If the provider advertises support
    # for attribute exchange, use that.
    endpoint = openid_request.endpoint
    if endpoint.supportsType(ax.AXMessage.ns_uri):
        fetch_request = ax.FetchRequest()
        # We mark all the attributes as required, since Google ignores
        # optional attributes.  We request both the full name and
        # first/last components since some providers offer one but not
        # the other.
        for (attr, alias) in [
            ('http://axschema.org/contact/email', 'email'),
            ('http://axschema.org/namePerson', 'fullname'),
            ('http://axschema.org/namePerson/first', 'firstname'),
            ('http://axschema.org/namePerson/last', 'lastname'),
            ('http://axschema.org/namePerson/friendly', 'nickname'),
                # The myOpenID provider advertises AX support, but uses
                # attribute names from an obsolete draft of the
                # specification.  We request them for compatibility.
            ('http://schema.openid.net/contact/email', 'old_email'),
            ('http://schema.openid.net/namePerson', 'old_fullname'),
            ('http://schema.openid.net/namePerson/friendly', 'old_nickname')
        ]:
            fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True))

        # conditionally require account_verified attribute
        verification_scheme_map = getattr(settings,
                                          'OPENID_VALID_VERIFICATION_SCHEMES',
                                          {})
        valid_schemes = verification_scheme_map.get(
            endpoint.server_url, verification_scheme_map.get(None, ()))
        if valid_schemes:
            # there are valid schemes configured for this endpoint, so
            # request account_verified status
            fetch_request.add(
                ax.AttrInfo(
                    'http://ns.login.ubuntu.com/2013/validation/account',
                    alias='account_verified',
                    required=True))

        openid_request.addExtension(fetch_request)
    else:
        sreg_required_fields = []
        sreg_required_fields.extend(
            getattr(settings, 'OPENID_SREG_REQUIRED_FIELDS', []))
        sreg_optional_fields = ['email', 'fullname', 'nickname']
        sreg_optional_fields.extend(
            getattr(settings, 'OPENID_SREG_EXTRA_FIELDS', []))
        sreg_optional_fields = [
            field for field in sreg_optional_fields
            if field not in sreg_required_fields
        ]
        openid_request.addExtension(
            sreg.SRegRequest(optional=sreg_optional_fields,
                             required=sreg_required_fields))

    if getattr(settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False):
        preferred_auth = [
            pape.AUTH_MULTI_FACTOR_PHYSICAL,
        ]
        pape_request = pape.Request(preferred_auth_policies=preferred_auth)
        openid_request.addExtension(pape_request)

    # Request team info
    teams_mapping_auto = getattr(settings,
                                 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
    teams_mapping_auto_blacklist = getattr(
        settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
    launchpad_teams = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
    if teams_mapping_auto:
        # ignore launchpad teams. use all django-groups
        launchpad_teams = dict()
        all_groups = Group.objects.exclude(
            name__in=teams_mapping_auto_blacklist)
        for group in all_groups:
            launchpad_teams[group.name] = group.name

    if launchpad_teams:
        openid_request.addExtension(teams.TeamsRequest(launchpad_teams.keys()))

    # Construct the request completion URL, including the page we
    # should redirect to.
    return_to = request.build_absolute_uri(reverse(login_complete_view))
    if redirect_to:
        if '?' in return_to:
            return_to += '&'
        else:
            return_to += '?'
        # Django gives us Unicode, which is great.  We must encode URI.
        # urllib enforces str. We can't trust anything about the default
        # encoding inside  str(foo) , so we must explicitly make foo a str.
        return_to += urlencode(
            {redirect_field_name: redirect_to.encode("UTF-8")})

    return render_openid_request(request, openid_request, return_to)
예제 #2
0
    else:
        openid_request.addExtension(
            sreg.SRegRequest(optional=['email', 'fullname', 'nickname']))

    # Request team info
    launchpad_teams = conf.LAUNCHPAD_TEAMS_MAPPING
    if conf.LAUNCHPAD_TEAMS_MAPPING_AUTO:
        #ignore launchpad teams. use all django-groups
        launchpad_teams = dict()
        all_groups = Group.objects.exclude(
            name__in=conf.LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST)
        for group in all_groups:
            launchpad_teams[group.name] = group.name

    if launchpad_teams:
        openid_request.addExtension(teams.TeamsRequest(launchpad_teams.keys()))

    # Construct the request completion URL, including the page we
    # should redirect to.
    return_to = request.build_absolute_uri(
        str(getattr(settings, 'OPENID_SSO_RETURN_URL', login_complete_url)))
    if redirect_to:
        if '?' in return_to:
            return_to += '&'
        else:
            return_to += '?'
        return_to += urllib.urlencode({redirect_field_name: redirect_to})

    return render_openid_request(request, openid_request, return_to)

예제 #3
0
def login_begin(request,
                template_name='openid/login.html',
                login_complete_view='openid-complete',
                form_class=AstrometryLoginForm,
                render_failure=default_render_failure,
                redirect_field_name=REDIRECT_FIELD_NAME):
    """Begin an OpenID login request, possibly asking for an identity URL."""
    redirect_to = request.REQUEST.get(redirect_field_name, '')

    # Get the OpenID URL to try.  First see if we've been configured
    # to use a fixed server URL.
    openid_url = getattr(settings, 'OPENID_SSO_SERVER_URL', None)

    if openid_url is None:
        if request.POST:
            #login_form = form_class(data=request.POST)
            #if login_form.is_valid():
            #    openid_url = login_form.cleaned_data['openid_identifier']
            #    username = login_form.cleaned_data['username']
            #    openid_url = openid_url.replace("username", username)

            openid_url = request.POST['openid_identifier']
            logmsg("OpenID url: " + openid_url)
        else:
            pass
            #login_form = form_class()

        # Invalid or no form data:
        if openid_url is None:
            return djrender(
                request,
                template_name,
                {
                    #'form': login_form,
                    #'openid_suggestions': choicify(OPENID_PROVIDERS,
                    #                               'url','suggestion'),
                    redirect_field_name: redirect_to
                })

    error = None
    consumer = make_consumer(request)
    try:
        openid_request = consumer.begin(openid_url)
    except DiscoveryFailure as exc:
        return render_failure(request,
                              "OpenID discovery error: %s" % (str(exc), ),
                              status=500)

    # Request some user details.  If the provider advertises support
    # for attribute exchange, use that.
    if openid_request.endpoint.supportsType(ax.AXMessage.ns_uri):
        fetch_request = ax.FetchRequest()
        # We mark all the attributes as required, since Google ignores
        # optional attributes.  We request both the full name and
        # first/last components since some providers offer one but not
        # the other.
        for (attr, alias) in [
            ('http://axschema.org/contact/email', 'email'),
            ('http://axschema.org/namePerson', 'fullname'),
            ('http://axschema.org/namePerson/first', 'firstname'),
            ('http://axschema.org/namePerson/last', 'lastname'),
            ('http://axschema.org/namePerson/friendly', 'nickname'),
                # The myOpenID provider advertises AX support, but uses
                # attribute names from an obsolete draft of the
                # specification.  We request them for compatibility.
            ('http://schema.openid.net/contact/email', 'old_email'),
            ('http://schema.openid.net/namePerson', 'old_fullname'),
            ('http://schema.openid.net/namePerson/friendly', 'old_nickname')
        ]:
            fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True))
        openid_request.addExtension(fetch_request)
    else:
        openid_request.addExtension(
            sreg.SRegRequest(optional=['email', 'fullname', 'nickname']))

    # Request team info
    teams_mapping_auto = getattr(settings,
                                 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
    teams_mapping_auto_blacklist = getattr(
        settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
    launchpad_teams = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
    if teams_mapping_auto:
        #ignore launchpad teams. use all django-groups
        launchpad_teams = dict()
        all_groups = Group.objects.exclude(
            name__in=teams_mapping_auto_blacklist)
        for group in all_groups:
            launchpad_teams[group.name] = group.name

    if launchpad_teams:
        openid_request.addExtension(teams.TeamsRequest(launchpad_teams.keys()))

    # Construct the request completion URL, including the page we
    # should redirect to.
    return_to = request.build_absolute_uri(reverse(login_complete_view))
    if redirect_to:
        if '?' in return_to:
            return_to += '&'
        else:
            return_to += '?'
        return_to += urlencode({redirect_field_name: redirect_to})
    logmsg('login_begin done')
    return render_openid_request(request, openid_request, return_to)