Beispiel #1
0
def persona_add(context, request):
    next_url = request.route_url('controls.persona')

    def fail(msg=None):
        if msg:
            request.session.flash(msg, level=u'error', icon='key--exclamation')
        return next_url

    post = request.stash['post'] if request.stash else request.POST
    assertion = post.get('assertion')

    try:
        data = verify_persona(assertion, request)
    except PersonaError as e:
        flash_persona_error(e, request)
        return fail()

    email = data.get('email')
    if not email:
        return fail("Persona authentication failed.")

    extant_email = model.session.query(model.IdentityEmail) \
        .filter_by(email=email) \
        .limit(1).first()

    if extant_email:
        if extant_email.user == request.user:
            other_account = 'your account'
        else:
            other_account = "the account '{0}'".format(extant_email.user.name)
        return fail("The email address '{0}' already belongs to {1}.".format(
            email, other_account))

    persona_id = model.IdentityEmail(email=email)
    request.user.identity_emails.append(persona_id)
    request.session.flash("Added Persona email address '{0}'".format(email),
                          level=u'success',
                          icon='user')

    return next_url
Beispiel #2
0
def persona_add(context, request):
    next_url = request.route_url('controls.persona')

    def fail(msg=None):
        if msg:
            request.session.flash(msg, level=u'error', icon='key--exclamation')
        return next_url

    post = request.stash['post'] if request.stash else request.POST
    assertion = post.get('assertion')

    try:
        data = verify_persona(assertion, request)
    except PersonaError as e:
        flash_persona_error(e, request)
        return fail()

    email = data.get('email')
    if not email:
        return fail("Persona authentication failed.")

    extant_email = model.session.query(model.IdentityEmail) \
        .filter_by(email=email) \
        .limit(1).first()

    if extant_email:
        if extant_email.user == request.user:
            other_account = 'your account'
        else:
            other_account = "the account '{0}'".format(extant_email.user.name)
        return fail("The email address '{0}' already belongs to {1}."
                    .format(email, other_account))

    persona_id = model.IdentityEmail(email=email)
    request.user.identity_emails.append(persona_id)
    request.session.flash("Added Persona email address '{0}'".format(email),
                          level=u'success', icon='user')

    return  next_url
Beispiel #3
0
def account_login_persona(context, request):
    return_key = key_from_request(request)

    def fail(msg=None, exc=None):
        if msg:
            request.session.flash(msg, level=u'error', icon='key--exclamation')
        # XXX setting the status to 403 triggers Pyramid's exception view
        next_url = request.route_url('account.login')
        if return_key is not None:
            next_url = update_params(next_url, return_key=return_key)
        return {
            'status': 'redirect',
            'redirect-to': next_url,
        }

    ## Verify the identity assertion

    assertion = request.POST.get('assertion')
    try:
        data = verify_persona(assertion, request)
    except PersonaError as e:
        flash_persona_error(e, request)
        return fail()

    ## Attempt to resolve the identity to a local user

    email = data.get('email')
    if data.get('status') != 'okay' or not email:
        return fail("Persona authentication failed.")

    identity_email = model.session.query(IdentityEmail) \
        .filter_by(email=email) \
        .limit(1).first()

    if not identity_email:
        # New user or new ID
        request.session['pending_identity_email'] = email
        return {
            'status': 'redirect',
            'redirect-to': request.route_url('account.register'),
        }

    ## Attempt to log in

    try:
        auth_headers = security.remember(
            request, identity_email.user, persona_addr=email)
        request.session.changed()

    except PersonaNotFoundError:
        return fail("The email address '{0}' is registered against the account "
                    "'{1}'.  To log in as '{1}', log out then back in."
                    .format(email, identity_email.user.name))

    except PersonaAuthDisabledError:
        return fail("Your Persona is no longer accepted as your account has "
                    "disabled Persona authentication.")

    # An existing user has logged in successfully.  Bravo!
    request.response.headerlist.extend(auth_headers)
    log.debug("User {0} logged in via Persona: {1}"
              .format(identity_email.user.name, identity_email))

    ## Handle redirection

    if identity_email.user == request.user:
        # Someone is just freshening up their cookie
        request.session.flash(u'Re-authentication successful', icon='user')

        if return_key is not None:
            old_url = fetch_stash(request, key=return_key)['url']
            if old_url:
                next_url = update_params(old_url, return_key=return_key)
                log.debug('Following Return Key \'{0}\' to URL: {1}'
                          .format(return_key, next_url))
                return {
                    'status': 'redirect',
                    'redirect-to': next_url,
                }

    else:
        # Existing user; new login
        request.session.flash(
                'Logged in with Persona', level=u'success', icon='user')

    # XXX this seems a mite fragile
    redirect = request.route_url('root')
    pathq = request.POST.get('pathq')
    if pathq and not pathq.startswith(request.route_path('account.login')):
        scheme, netloc = urlparse(redirect)[:2]
        redirect = urlunparse((scheme, netloc, pathq, '', '', ''))

    return {
        'status': 'redirect',
        'redirect-to': redirect,
    }