diff --git a/la_facebook/callbacks/base.py b/la_facebook/callbacks/base.py index 9494541..08723c0 100644 --- a/la_facebook/callbacks/base.py +++ b/la_facebook/callbacks/base.py @@ -34,7 +34,7 @@ def __call__(self, request, access, token): else: logger.debug("BaseFacebookCallback.__call__:'\ existing django user found for this facebook identifier") - ret = self.handle_unauthenticated_user(request, user, access, + ret = self.handle_unauthenticated_user(request, user, access, token, user_data) if isinstance(ret, HttpResponse): return ret @@ -55,7 +55,7 @@ def fetch_user_data(self, request, access, token): def lookup_user(self, request, access, user_data): raise NotImplementedError("Callbacks must have a lookup_user method") - def redirect_url(self, request, fallback_url=settings.LOGIN_REDIRECT_URL, + def redirect_url(self, request, fallback_url=settings.LOGIN_REDIRECT_URL, redirect_field_name="next", session_key_value="redirect_to"): """ Returns the URL to be used in login procedures by looking at different @@ -73,10 +73,18 @@ def redirect_url(self, request, fallback_url=settings.LOGIN_REDIRECT_URL, if hasattr(request, "session"): redirect_to = request.session.get(session_key_value) # Heavier security check -- don't allow redirection to a different host. - netloc = urlparse.urlparse(redirect_to)[1] - if netloc and netloc != request.host: - logger.warning("redirect_to host does not match orgin") - redirect_to = fallback_url + if redirect_to: + netloc = urlparse.urlparse(redirect_to)[1] + if netloc and netloc != request.host: + logger.warning("redirect_to host does not match orgin") + redirect_to = fallback_url + else: + # There ought to have been a value in the session. This + # is probably a developer error, so log a warning. + logger.warning("Session found, but no redirect_to. Check " + "that you have set up the facebook_login " + "view with a 'next' querystring " + "parameter. Using fallback.") if not redirect_to: logger.debug("no redirect found, using fallback") redirect_to = fallback_url diff --git a/la_facebook/tests/test_callbacks.py b/la_facebook/tests/test_callbacks.py index d25aa5f..41672de 100644 --- a/la_facebook/tests/test_callbacks.py +++ b/la_facebook/tests/test_callbacks.py @@ -11,7 +11,9 @@ except ImportError: raise ImportError("callback tests require Django > 1.3 for RequestFactory") +from django.conf import settings from django.contrib.auth.models import User, AnonymousUser +from django.contrib.sessions.middleware import SessionMiddleware from la_facebook.access import OAuthAccess, OAuth20Token from la_facebook.callbacks.base import BaseFacebookCallback @@ -56,6 +58,28 @@ def test_redirect_url(self): resp = callback.redirect_url(self.request) self.assertEquals(resp,'dummy') + def test_redirect_url_no_next_no_session(self): + request = factory.get('/callback') + callback = BaseFacebookCallback() + resp = callback.redirect_url(request) + self.assertEquals(resp, settings.LOGIN_REDIRECT_URL) + + def test_redirect_url_no_next_session(self): + request = factory.get('/callback') + callback = BaseFacebookCallback() + SessionMiddleware().process_request(request) + callback = BaseFacebookCallback() + resp = callback.redirect_url(request) + self.assertEquals(resp, settings.LOGIN_REDIRECT_URL) + + def test_redirect_url_in_session(self): + request = factory.get('/callback') + SessionMiddleware().process_request(request) + request.session['redirect_to'] = 'session_redirect' + callback = BaseFacebookCallback() + resp = callback.redirect_url(request) + self.assertEquals(resp, 'session_redirect') + def test_identifier_from_data(self): callback = BaseFacebookCallback() data = {'name':'test name','id':'testid'}