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)
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)
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)