Ejemplo n.º 1
0
def register(request, target_object=DEFAULT_PARAM):
    """ OAuth registration prep.
    
    Fetch request token then redirect to authorization page.
    """
    # fetch request token
    client = OAuthClient(request.application)

    # redirect to authorization url, next param specifies final redirect URL.
    callback = request.build_absolute_uri(reverse("authorize"))
    next = request.GET.get("next", HOME_URL)
    callback = parameterize_url(callback, {"next": next})

    token = client.fetch_request_token(callback)
    request.session["request_token"] = token.to_string()

    if target_object is DEFAULT_PARAM:
        if request.group:
            target_object = request.group.id
        else:
            target_object = None
    if target_object is None:
        if hasattr(settings, "TYPEPAD_ACCESS") and settings.TYPEPAD_ACCESS:
            authz_params = {"access": settings.TYPEPAD_ACCESS}
        else:
            authz_params = {}
    else:
        authz_params = {"target_object": target_object}

    url = client.authorize_token(authz_params)
    # url = client.authorize_token({ 'access': 'app_full' })

    return http.HttpResponseRedirect(url)
Ejemplo n.º 2
0
def authorize(request):
    """ OAuth authorization.
    
    Exchange request token for an access token,
    login user and store token in user session.
    """
    # request token
    request_token = request.session.get("request_token", None)
    if not request_token:
        return http.HttpResponse("No un-authed token cookie")
    del request.session["request_token"]

    # exchange request token for access token
    client = OAuthClient(request.application)
    client.set_token_from_string(request_token)
    verifier = request.GET.get("oauth_verifier")
    access_token = client.fetch_access_token(verifier=verifier)

    # authorize and login user
    from typepadapp.auth import authenticate, login

    authed_user = authenticate(oauth_client=client)
    login(request, authed_user)

    # store the token key / secret in the database so we can recover
    # it later if the session expires
    # store the token key / secret in the database so we can recover
    # it later if the session expires
    sst = request.GET["session_sync_token"]
    token = Token.get(sst)
    if token is None:
        token = Token()
        token.session_sync_token = sst
        token.key = access_token.key
        token.secret = access_token.secret
        token.save()
        created = True
    else:
        created = False

    if created:
        # this is a new user or at least a new session sync token
        signals.member_joined.send(sender=authorize, instance=authed_user, group=request.group, token=token)
    else:
        # update token with current access token
        token.key = access_token.key
        token.secret = access_token.secret
        token.save()

    # oauth token in authed user session
    request.session["oauth_token"] = token

    # go to the welcome url, next url, or home.
    abs_home_url = request.build_absolute_uri(HOME_URL)
    next_url = request.GET.get("next", abs_home_url)
    if settings.WELCOME_URL is not None:
        if not next_url or next_url == abs_home_url:
            next_url = settings.WELCOME_URL
    return http.HttpResponseRedirect(next_url)
Ejemplo n.º 3
0
def synchronize(request):
    """Session synchronization.

    If a nonce is present, make sure it exists in the user's session and
    verify the signature. If successful, try to log the user in using the
    oauth token key specified in the query string.

    """
    from typepadapp.auth import authenticate, login
    from django.contrib.auth import logout

    # check query string, then session for next param. default to index.
    next = request.GET.get("callback_next", HOME_URL)
    nonce = request.GET.get("callback_nonce")

    if not nonce:
        return http.HttpResponse("No nonce.")
    else:
        callback_nonce = request.session.get("callback_nonce")
        if callback_nonce is not None:
            # Delete the nonce to prevent replay attacks.
            del request.session["callback_nonce"]

        session_sync_token = request.GET.get("session_sync_token")

        # log the user out / clear the existing session.
        logout(request)

        # Validate the request.
        if nonce != callback_nonce:
            # nonce's don't match, either a bug or someone's playing games
            return http.HttpResponseRedirect(next)

        oauth_request = oauth.OAuthRequest.from_request(
            request.method,
            request.build_absolute_uri(),
            parameters=dict(request.GET.items()),
            query_string=request.environ.get("QUERY_STRING", ""),
        )
        oauth_server = oauth.OAuthServer(StupidDataStore())
        oauth_server.add_signature_method(oauth.OAuthSignatureMethod_HMAC_SHA1())
        try:
            consumer, gp_token, params = oauth_server.verify_request(oauth_request)
        except oauth.OAuthError, ex:
            # OAuth signature is invalid. Something's fishy. Don't log them in.
            return http.HttpResponse(ex.message, status=400)

        # The register URL needs to retain the 'next' querystring param so we
        # can redirect to the correct place once registeration is complete.
        register_url = parameterize_url(reverse("register"), {"next": next})

        if session_sync_token:
            # If a token was returned, create a session loggin the user
            # in with the new token. Otherwise we just log the user out.
            token = Token.get(session_sync_token)
            if token is None:
                # We lost the token somehow.
                if request.GET.get("signin", False):
                    # They clicked sign in, but we don't have the token
                    # so we redirect to the register auth flow so we're issued
                    # a new token.
                    return http.HttpResponseRedirect(register_url)
                else:
                    # In this case we store the lost token in the user's session. In future
                    # session sync requests this "lost" token will be used instead of the
                    # logged in users' token for the `current_token` param. That way we don't
                    # get stuck in a loop.
                    request.session["lost_session_sync_token"] = session_sync_token
                    return http.HttpResponseRedirect(next)
            client = OAuthClient(request.application)
            client.token = token

            # Everything's copasetic. Authorize and login user.
            authed_user = authenticate(oauth_client=client)
            login(request, authed_user)
            request.session["oauth_token"] = token
        else:
            if request.GET.get("signin", False):
                # If there's no token returned and the user clicked 'signin' then
                # they haven't auth'd this site to access their info. Send them
                # to register instead.
                return http.HttpResponseRedirect(register_url)

        return http.HttpResponseRedirect(next)