예제 #1
0
파일: account.py 프로젝트: krinndnz/floof
def account_login_browserid(context, request):
    return_key = key_from_request(request)

    def fail(msg=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 {'next_url': next_url}

    ## Verify the identity assertion

    assertion = request.POST.get('assertion')
    try:
        data = verify_browserid(assertion, request)
    except BrowserIDError as e:
        flash_browserid_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("BrowserID 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 {'next_url': request.route_url('account.register'),
                'post_id': 'postform'}

    ## Attempt to log in

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

    except BrowserIDNotFoundError:
        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 BrowserIDAuthDisabledError:
        return fail("Your BrowserID is no longer accepted as your account has "
                    "disabled BrowserID authentication.")

    # An existing user has logged in successfully.  Bravo!
    request.response.headerlist.extend(auth_headers)
    log.debug("User {0} logged in via BrowserID: {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 {'next_url': next_url}

        return {'next_url': request.route_url('root')}

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

    return {'next_url': request.route_url('root')}
예제 #2
0
파일: account.py 프로젝트: silky/floof
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,
    }
예제 #3
0
파일: account.py 프로젝트: krinndnz/floof
def login_finish(context, request):
    """Step two of logging in; the OpenID provider redirects back here."""

    def retry():
        """Redirect to the login page, preserving the return key (if any)."""
        location = request.route_url('account.login')
        if return_key:
            location = update_params(location, return_key=return_key)
        return HTTPSeeOther(location=location)

    return_url = request.route_url('account.login_finish')

    return_key = key_from_request(request)
    if return_key is not None:
        return_url = update_params(return_url, return_key=return_key)

    try:
        identity_url, identity_webfinger, auth_time, sreg_res = openid_end(
            return_url=return_url,
            request=request)
    except OpenIDError as exc:
        request.session.flash(exc.message,
            level='error', icon='key--exclamation')
        return retry()

    # Find who owns this URL, if anyone
    identity_owner = model.session.query(User) \
        .filter(User.identity_urls.any(url=identity_url)) \
        .limit(1).first()

    if not identity_owner:
        if return_key:
            request.session.flash('Unknown OpenID URL.',
                level='error', icon='key--exclamation')
            return retry()
        # Someone is either registering a new account, or adding a new OpenID
        # to an existing account
        request.session['pending_identity_url'] = identity_url
        request.session.changed()

        # Try to pull a name and email address out of the SReg response
        username = re.sub(u'[^_a-z0-9]', u'',
            sreg_res.get('nickname', u'').lower())
        form = RegistrationForm(
            username=username,
            email=sreg_res.get('email', u''),
            timezone=sreg_res.get('timezone', u'UTC'),
        )
        return render_to_response(
            'account/register.mako',
            dict(
                form=form,
                identity_url=identity_url,
                identity_webfinger=identity_webfinger,
                identity_email=None),
            request=request)

    elif identity_owner == request.user:
        # Someone is just freshening up their cookie
        auth_headers = safe_openid_login(request, identity_owner, identity_url)
        if auth_headers is None:
            return retry()

        request.session.flash(u'Re-authentication successful', icon='user')

        if return_key:
            # Fetch a stashed request
            old_url = fetch_stash(request, key=return_key)['url']
            if old_url:
                location = update_params(old_url, return_key=return_key)
                log.debug('Following Return Key \'{0}\' to URL: {1}'
                          .format(return_key, location))
                return HTTPSeeOther(location, headers=auth_headers)
        return HTTPSeeOther(request.route_url('root'), headers=auth_headers)

    else:
        # Existing user; new login
        # Log the successful OpenID authentication, mindful of users that may
        # have OpenID logins disabled, for instance.
        # XXX should we deny a logged-in user to authenticate as another user?
        auth_headers = security.forget(request)
        headers = safe_openid_login(request, identity_owner, identity_url)

        if headers is None:
            return retry()

        auth_headers += headers

        # An existing user has logged in successfully.  Bravo!
        log.debug("User {0!r} logged in via OpenID: {1!r}"
                  .format(identity_owner.name, identity_url))

        request.session.flash(
            u"Welcome back, {0}!"
            .format(identity_owner.display_name or identity_owner.name),
            level=u'success', icon='user')

        # XXX this should ALSO probably do the return_key redirect, good grief
        return HTTPSeeOther(
            location=request.route_url('root'),
            headers=auth_headers)
예제 #4
0
파일: account.py 프로젝트: silky/floof
def login_finish(context, request):
    """Step two of logging in; the OpenID provider redirects back here."""

    def retry():
        """Redirect to the login page, preserving the return key (if any)."""
        location = request.route_url('account.login')
        if return_key:
            location = update_params(location, return_key=return_key)
        return HTTPSeeOther(location=location)

    return_url = request.route_url('account.login_finish')

    return_key = key_from_request(request)
    if return_key is not None:
        return_url = update_params(return_url, return_key=return_key)

    try:
        identity_url, identity_webfinger, auth_time, sreg_res = openid_end(
            return_url=return_url,
            request=request)
    except OpenIDError as exc:
        request.session.flash(exc.message,
            level='error', icon='key--exclamation')
        return retry()

    # Find who owns this URL, if anyone
    identity_owner = model.session.query(User) \
        .filter(User.identity_urls.any(url=identity_url)) \
        .limit(1).first()

    if not identity_owner:
        if return_key:
            request.session.flash('Unknown OpenID URL.',
                level='error', icon='key--exclamation')
            return retry()
        # Someone is either registering a new account, or adding a new OpenID
        # to an existing account
        request.session['pending_identity_url'] = identity_url
        request.session.changed()

        # Try to pull a name and email address out of the SReg response
        username = re.sub(u'[^_a-z0-9]', u'',
            sreg_res.get('nickname', u'').lower())
        form = RegistrationForm(
            username=username,
            email=sreg_res.get('email', u''),
            timezone=sreg_res.get('timezone', u'UTC'),
        )
        return render_to_response(
            'account/register.mako',
            dict(
                form=form,
                identity_url=identity_url,
                identity_webfinger=identity_webfinger,
                identity_email=None),
            request=request)

    elif identity_owner == request.user:
        # Someone is just freshening up their cookie
        auth_headers = safe_openid_login(request, identity_owner, identity_url)
        if auth_headers is None:
            return retry()

        request.session.flash(u'Re-authentication successful', icon='user')

        if return_key:
            # Fetch a stashed request
            old_url = fetch_stash(request, key=return_key)['url']
            if old_url:
                location = update_params(old_url, return_key=return_key)
                log.debug('Following Return Key \'{0}\' to URL: {1}'
                          .format(return_key, location))
                return HTTPSeeOther(location, headers=auth_headers)
        return HTTPSeeOther(request.route_url('root'), headers=auth_headers)

    else:
        # Existing user; new login
        # Log the successful OpenID authentication, mindful of users that may
        # have OpenID logins disabled, for instance.
        # XXX should we deny a logged-in user to authenticate as another user?
        auth_headers = security.forget(request)
        headers = safe_openid_login(request, identity_owner, identity_url)

        if headers is None:
            return retry()

        auth_headers += headers

        # An existing user has logged in successfully.  Bravo!
        log.debug("User {0!r} logged in via OpenID: {1!r}"
                  .format(identity_owner.name, identity_url))

        request.session.flash(
            u"Welcome back, {0}!"
            .format(identity_owner.display_name or identity_owner.name),
            level=u'success', icon='user')

        # XXX this should ALSO probably do the return_key redirect, good grief
        return HTTPSeeOther(
            location=request.route_url('root'),
            headers=auth_headers)