def facebook_login(request, redirect_field_name="next", redirect_to_session_key="redirect_to", display="page"): """ 1. access OAuth 2. set token to none 3. store and redirect to authorization url 4. redirect to OAuth authorization url """ access = OAuthAccess() token = None if hasattr(request, "session"): logger.debug("la_facebook.views.facebook_login: request has session") # this session variable is used by the callback request.session[redirect_to_session_key] = request.GET.get(redirect_field_name) if request.method == "POST": data = parse_signed_request(request.POST['signed_request'], settings.FACEBOOK_APP_SECRET) facebookid = data['user_id'] user_id = UserAssociation.objects.get(identifier=facebookid).user_id profile = Profile.objects.get(user_id=user_id) profile.single = bool(data['registration']['single']) return HttpResponseRedirect(access.authorization_url(token, display=display))
def facebook_login(request, redirect_field_name="next", redirect_to_session_key="redirect_to", display="page"): """ 1. access OAuth 2. set token to none 3. store and redirect to authorization url 4. redirect to OAuth authorization url """ access = OAuthAccess() token = None if hasattr(request, "session"): logger.debug("la_facebook.views.facebook_login: request has session") # this session variable is used by the callback request.session[redirect_to_session_key] = request.GET.get( redirect_field_name) if request.method == "POST": data = parse_signed_request(request.POST['signed_request'], settings.FACEBOOK_APP_SECRET) facebookid = data['user_id'] user_id = UserAssociation.objects.get(identifier=facebookid).user_id profile = Profile.objects.get(user_id=user_id) profile.single = bool(data['registration']['single']) return HttpResponseRedirect( access.authorization_url(token, display=display))
def test_callback_url_external(self): path = "/completely/other/path" oauth = OAuthAccess(fb_callback_path=path) callback_url = oauth.callback_url() current_site = Site.objects.get(pk=settings.SITE_ID) base_url = "http://%s" % current_site.domain expected_url = "%s%s" % (base_url, path) self.assertEquals(callback_url, expected_url)
def test_callback_url(self): oauth = OAuthAccess() callback_url = oauth.callback_url() current_site = Site.objects.get(pk=settings.SITE_ID) base_url = "http://%s" % current_site.domain reversed_url = reverse("la_facebook_callback") expected_url = "%s%s" % (base_url, reversed_url) self.assertEquals(callback_url, expected_url)
def test_api_timeout(self): oauth = OAuthAccess() params = { "kind": "json", "url": "dummy", "token": OAuth20Token("dummy"), "max_retries": 1, "http": HttpMock(), } import socket self.assertRaises(socket.timeout, lambda: oauth.make_api_call(**params))
def test_api_with_retries(self): oauth = OAuthAccess() params = { "kind": "json", "url": "dummy", "token": OAuth20Token("dummy"), "max_retries": 5, "http": HttpMock(), } # NOTE: Raises exception if it doesn't work oauth.make_api_call(**params)
def facebook_login(request, redirect_field_name="next", redirect_to_session_key="redirect_to"): """ 1. access OAuth 2. set token to none 3. store and redirect to authorization url 4. redirect to OAuth authorization url """ access = OAuthAccess() token = None if hasattr(request, "session"): logger.debug("la_facebook.views.facebook_login: request has session") request.session[redirect_to_session_key] = request.GET.get(redirect_field_name) return HttpResponseRedirect(access.authorization_url(token))
def test_callback_url(self): oauth = OAuthAccess() callback_url = oauth.callback_url current_site = Site.objects.get(pk=settings.SITE_ID) base_url = "http://%s" % current_site.domain reversed_url = reverse("la_facebook_callback") expected_url = "%s%s" % (base_url, reversed_url) self.assertEquals(callback_url, expected_url)
def facebook_callback(request, error_template_name="la_facebook/fb_error.html", fb_callback_path=None): """ 1. define RequestContext 2. access OAuth 3. check session 4. autheticate token 5. raise exception if missing token 6. return access callback 7. raise exception if mismatch token 8. render error """ ctx = RequestContext(request) access = OAuthAccess(fb_callback_path=fb_callback_path) # TODO: Check to make sure the session cookie is setting correctly unauth_token = request.session.get("unauth_token", None) try: protocol = "https" if request.is_secure() else "http" auth_token = access.check_token(unauth_token, request.GET, protocol=protocol) except MissingToken: ctx.update({"error": "token_missing"}) logger.error('la_facebook.views.facebook_callback: missing token') else: if auth_token: logger.debug('la_facebook.views.facebook_callback: token success '\ ', sending to callback') return access.callback(request, access, auth_token) else: # @@@ not nice for OAuth 2 ctx.update({"error": "token_mismatch"}) logger.error('la_facebook.views.facebook_callback: token mismatch'\ ', error getting token, or user denied FB login') # we either have a missing token or a token mismatch # Facebook provides some error details in the callback URL fb_errors = [] for fb_error_detail in ['error', 'error_description', 'error_reason']: if fb_error_detail in request.GET: ctx['fb_' + fb_error_detail] = request.GET[fb_error_detail] fb_errors.append(request.GET[fb_error_detail]) logger.warning('la_facebook.views.facebook_callback: %s' % ', '.join(fb_errors)) # Can't change to 401 error because that prompts basic browser auth return render_to_response(error_template_name, ctx)
def facebook_callback(request, error_template_name="la_facebook/fb_error.html"): """ 1. define RequestContext 2. access OAuth 3. check session 4. autheticate token 5. raise exception if missing token 6. return access callback 7. raise exception if mismatch token 8. render error """ ctx = RequestContext(request) access = OAuthAccess() # TODO: Check to make sure the session cookie is setting correctly unauth_token = request.session.get("unauth_token", None) try: auth_token = access.check_token(unauth_token, request.GET) except MissingToken: ctx.update({"error": "token_missing"}) logger.error('la_facebook.views.facebook_callback: missing token') else: if auth_token: logger.debug('la_facebook.views.facebook_callback: token success '\ ', sending to callback') return access.callback(request, access, auth_token) else: # @@@ not nice for OAuth 2 ctx.update({"error": "token_mismatch"}) logger.error('la_facebook.views.facebook_callback: token mismatch'\ ', error getting token, or user denied FB login') # we either have a missing token or a token mismatch # Facebook provides some error details in the callback URL fb_errors = [] for fb_error_detail in ['error', 'error_description', 'error_reason']: if fb_error_detail in request.GET: ctx['fb_' + fb_error_detail] = request.GET[fb_error_detail] fb_errors.append(request.GET[fb_error_detail]) logger.warning('la_facebook.views.facebook_callback: %s' % ', '.join(fb_errors)) # Can't change to 401 error because that prompts basic browser auth return render_to_response(error_template_name, ctx)
def facebook_login(request, redirect_field_name="next", redirect_to_session_key="redirect_to", display="page"): """ 1. access OAuth 2. set token to none 3. store and redirect to authorization url 4. redirect to OAuth authorization url """ access = OAuthAccess() token = None if hasattr(request, "session"): logger.debug("la_facebook.views.facebook_login: request has session") # this session variable is used by the callback request.session[redirect_to_session_key] = request.GET.get(redirect_field_name) return HttpResponseRedirect(access.authorization_url(token, display=display))
def facebook_login(request, redirect_field_name="next", redirect_to_session_key="redirect_to", display="page", fb_callback_path=None): """ 1. access OAuth 2. set token to none 3. store and redirect to authorization url 4. redirect to OAuth authorization url """ access = OAuthAccess(fb_callback_path=fb_callback_path) token = None if hasattr(request, "session"): logger.debug("la_facebook.views.facebook_login: request has session") # this session variable is used by the callback request.session[redirect_to_session_key] = request.GET.get(redirect_field_name) protocol = "https" if request.is_secure() else "http" return HttpResponseRedirect(access.authorization_url(token, display=display, protocol=protocol))
def facebook_callback(request): """ 1. define RequestContext 2. access OAuth 3. check session 4. autheticate token 5. raise exception if missing token 6. return access callback 7. raise exception if mismatch token 8. render error """ ctx = RequestContext(request) access = OAuthAccess() # TODO: Check to make sure the session cookie is setting correctly unauth_token = request.session.get("unauth_token", None) try: auth_token = access.check_token(unauth_token, request.GET) except MissingToken: ctx.update({"error": "token_missing"}) logger.error('la_facebook.views.facebook_login: missing token') else: if auth_token: return access.callback(request, access, auth_token) else: # @@@ not nice for OAuth 2 ctx.update({"error": "token_mismatch"}) logger.error('la_facebook.views.facebook_callback: token mismatch'\ ', error getting token, or user denied FB login') # we either have a missing token or a token mismatch # Facebook provides some error details in the callback URL fb_errors = [] for fb_error_detail in ['error', 'error_description', 'error_reason']: if fb_error_detail in request.GET: ctx['fb_' + fb_error_detail] = request.GET[fb_error_detail] fb_errors.append(request.GET[fb_error_detail]) logger.warning('la_facebook.views.facebook_callback: %s' % ', '.join(fb_errors)) return render_to_response("la_facebook/fb_error.html", ctx)
def setUp(self): # logger.debug("callback test case setup") self.request = factory.get('/callback',data={'next':'dummy'}) test_user = User() test_user.username = '******' test_user.save() self.request.user = test_user assoc = UserAssociation() assoc.user = test_user assoc.token = 'facebooktokenstring' assoc.expires = datetime.datetime.now() + datetime.timedelta(1) assoc.save() self.token = OAuth20Token(assoc.token, 5555) self.access = OAuthAccess()
def post(self, request, format=None): #return 200 if user is already authenticated if request.user is not None : logger.debug("mobileauth invoked with user %s on session" % request.user); if request.user.is_authenticated(): logger.debug("mobileauth invoked with authenticated user on session"); return Response(None,status=204); #validate the access token by hitting graph.facebook.com fbAuthToken = request.DATA['access_token']; if fbAuthToken is None: return Response("access_token is missing", status=400); urlStream = urllib.urlopen("https://graph.facebook.com/me?access_token=%s" % fbAuthToken); raw_data = urlStream.read(); fbResponseCode = urlStream.getcode(); if fbResponseCode <> 200: logger.debug("failed to verify access token. response code: %s. message: %s" % (fbResponseCode, raw_data)); return Response("failed to verify access token", status=500); fbResponse = json.loads(raw_data); fbUserId = fbResponse['id']; #let an instance of the LaFacebook default callback handle Django auth lafbCallback = DefaultFacebookCallback() existing_user = lafbCallback.lookup_user(None, None, fbResponse); logger.debug("existing user? %s" % existing_user); if existing_user is None: #create user record access = OAuthAccess() existing_user = lafbCallback.create_user(request._request, access, OAuth20Token(fbAuthToken), fbResponse); else: username = existing_user.username; logger.debug("query for user %s" % username); userObj = User.objects.get(username=username); lafbCallback.login_user(request._request, userObj); #return success & the user id if everything worked response = {}; response['id'] = fbResponse['id']; logger.debug("existing_user %s", existing_user); authUserPk = existing_user.id; response['token'] = Token.objects.get(user=existing_user).key; logger.debug("csrf dict: %s" % csrf.get_token(request)); if existing_user.is_authenticated(): return Response(response, status=200); else: return Response("Authentication failed for %s" % fbUserId, status=500);
def setUp(self): self.request = factory.get('/callback',data={'next':'dummy'}) test_user = User() test_user.username = '******' test_user.email = '*****@*****.**' test_user.save() self.test_user = test_user self.anon_user = AnonymousUser() self.request.user = test_user assoc = UserAssociation() assoc.user = test_user assoc.token = 'facebooktokenstring' assoc.identifier = 'facebookid' assoc.expires = datetime.datetime.now() + datetime.timedelta(1) assoc.save() self.token = OAuth20Token(str(assoc.token), 5555) self.access = OAuthAccess()
def test_key_in_settings(self): # test if there is a key oauth = OAuthAccess() expected = settings.FACEBOOK_ACCESS_SETTINGS["FACEBOOK_APP_ID"] self.assertEquals(oauth.key, expected)
def test_secret_in_settings(self): oauth = OAuthAccess() expected = settings.FACEBOOK_ACCESS_SETTINGS["FACEBOOK_APP_SECRET"] self.assertEquals(oauth.secret, expected)
def test_access_token_url(self): oauth = OAuthAccess() access_token_endpoint = oauth.access_token_url expected_endpoints_url = "https://graph.facebook.com/oauth/access_token" self.assertEquals(access_token_endpoint, expected_endpoints_url)
def test_authorize_url(self): oauth = OAuthAccess() authorize_url_endpoint = oauth.authorize_url expected_endpoint_url = "https://graph.facebook.com/oauth/authorize" self.assertEquals(authorize_url_endpoint, expected_endpoint_url)
def test_callback(self): oauth = OAuthAccess() callback_endpoint = oauth.callback expected_callback_endpoint = load_path_attr( settings.FACEBOOK_ACCESS_SETTINGS["CALLBACK"]) self.assertEquals(callback_endpoint, expected_callback_endpoint)
def test_provider_scope(self): oauth = OAuthAccess() provider_scope_endpoint = oauth.provider_scope expected_endpoint_url = None self.assertEquals(provider_scope_endpoint, expected_endpoint_url)