def test_register(self): return 'currently this doesnt work reliably with the live facebook api' #setup the test user permissions = facebook_settings.FACEBOOK_DEFAULT_SCOPE app_access_token = FacebookAuthorization.get_cached_app_access_token() test_user = FacebookAuthorization.get_or_create_test_user(app_access_token, permissions) #test the connect view in the registration mode (empty db) c = Client() url = reverse('facebook_connect') access_token = test_user.access_token response = c.get(url, {'facebook_login': '******', 'access_token': access_token}) self.assertEqual(response.status_code, 302) user = User.objects.all().order_by('-id')[:1][0] profile = user.get_profile() self.assertEqual(access_token, profile.access_token) #test the login flow response = c.get(url, {'facebook_login': '******', 'access_token': access_token}) self.assertEqual(response.status_code, 302) new_user = User.objects.all().order_by('-id')[:1][0] new_profile = user.get_profile() self.assertEqual(access_token, new_profile.access_token) self.assertEqual(user, new_user)
def test_register(self): return 'currently this doesnt work reliably with the live facebook api' #setup the test user permissions = facebook_settings.FACEBOOK_DEFAULT_SCOPE app_access_token = FacebookAuthorization.get_cached_app_access_token() test_user = FacebookAuthorization.get_or_create_test_user( app_access_token, permissions) #test the connect view in the registration mode (empty db) c = Client() url = reverse('facebook_connect') access_token = test_user.access_token response = c.get(url, { 'facebook_login': '******', 'access_token': access_token }) self.assertEqual(response.status_code, 302) user = User.objects.all().order_by('-id')[:1][0] profile = user.get_profile() self.assertEqual(access_token, profile.access_token) #test the login flow response = c.get(url, { 'facebook_login': '******', 'access_token': access_token }) self.assertEqual(response.status_code, 302) new_user = User.objects.all().order_by('-id')[:1][0] new_profile = user.get_profile() self.assertEqual(access_token, new_profile.access_token) self.assertEqual(user, new_user)
def test_extend_token(self): return 'this doesnt work in travis, but locally its fine... weird' app_access_token = FacebookAuthorization.get_cached_app_access_token() test_user = FacebookAuthorization.get_or_create_test_user(app_access_token) access_token = test_user.access_token results = FacebookAuthorization.extend_access_token(access_token) if 'access_token' not in results: raise ValueError('we didnt get a fresh token')
def test_extend_token(self): return 'this doesnt work in travis, but locally its fine... weird' app_access_token = FacebookAuthorization.get_cached_app_access_token() test_user = FacebookAuthorization.get_or_create_test_user( app_access_token) access_token = test_user.access_token results = FacebookAuthorization.extend_access_token(access_token) if 'access_token' not in results: raise ValueError('we didnt get a fresh token')
def fb_test_user(request): token = FacebookAuthorization.get_app_access_token() test_user = FacebookAuthorization.create_test_user(token, 'email') django_facebook.connect.connect_user(request, test_user['access_token']) #add bids by default member = request.user member.bids_left = 1000 member.tokens_left = 1000 member.save() return HttpResponseRedirect(reverse('bidding_home'))
def test_create_test_user(self): #Also, somehow unittest.skip doesnt work with travis ci? return 'Skipping since you might have created test users manually, lets not delete them :)' #start by clearing out our test users (maybe this isnt safe to use in testing) #if other people create test users manualy this could be annoying app_access_token = FacebookAuthorization.get_cached_app_access_token() FacebookAuthorization.delete_test_users(app_access_token) #the permissions for which we want a test user permissions = ['email', 'publish_actions'] #gets the test user object test_user = FacebookAuthorization.get_or_create_test_user(app_access_token, permissions) graph = test_user.graph() me = graph.me() assert me
def test_create_test_user(self): # Also, somehow unittest.skip doesnt work with travis ci? return 'Skipping since you might have created test users manually, lets not delete them :)' # start by clearing out our test users (maybe this isnt safe to use in testing) # if other people create test users manualy this could be annoying app_access_token = FacebookAuthorization.get_cached_app_access_token() FacebookAuthorization.delete_test_users(app_access_token) # the permissions for which we want a test user permissions = ['email', 'publish_actions'] # gets the test user object test_user = FacebookAuthorization.get_or_create_test_user( app_access_token, permissions) graph = test_user.graph() me = graph.me() assert me
def get_signed_request(request): """ Función utilitaria que descifra y recoge el request firmado que Facebook entrega en algunos escenarios. .. note:: Requiere la instalación del módulo` ``django_facebook``. :param request: Una instancia de ``django.request``. :return: TODO """ try: if request.session.get('signed_request', None) \ and request.method.upper() != 'POST': sgr = request.session['signed_request'] else: if not 'signed_request' in request.POST: sgr = request.session['signed_request'] else: sgr = request.POST.get('signed_request') request.session['signed_request'] = sgr result = FacebookAuthorization.parse_signed_data(sgr) # } return result except Exception as e: # print e return None
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token = results['access_token'] self.access_token = access_token self.save() return results
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token, expires = results['access_token'], results['expires'] self.access_token = access_token self.save() return results
def obj_create(self, bundle, request=None, **kwargs): bundle.obj = Obj() bundle.obj.id = 1 code = bundle.data.get('code') redirect_uri = bundle.data.get('redirectUri', '') if not code: self.create_response( bundle.request, bundle, response_class=BadRequest('code is required')) logger.error('code is required') # TODO: Add catch errors token_response = FacebookAuthorization.convert_code( code, redirect_uri=redirect_uri) # TODO: Add access_token to cache access_token = token_response['access_token'] action, user = connect_user(bundle.request, access_token=access_token) from events.tasks import store_fb_events, refresh_fb_events store_fb_events.delay(user) refresh_fb_events.delay(user) payload = jwt_payload_handler(user) payload['access_token'] = user.access_token bundle.obj.token = jwt_encode_handler(payload) # TODO: clean up response return bundle
def parse_signed_request(signed_request_string): ''' Just here for your convenience, actual logic is in the FacebookAuthorization class ''' from open_facebook.api import FacebookAuthorization signed_request = FacebookAuthorization.parse_signed_data( signed_request_string) return signed_request
def deauthorized_callback(request): """ View for handling the deauthorization callback. """ if FacebookAuthorization.parse_signed_data(request.POST['signed_request']): user_id = json.load(request.POST['user_id']) member = get_object_or_404(Member, user_id) member.delete() request.session.flush()
def extend_access_tokens(): for user in UserEx.objects.filter(facebook_id__isnull=False): results = FacebookAuthorization.extend_access_token(user.access_token) access_token = results['access_token'] old_token = user.access_token token_changed = access_token != old_token if token_changed: user.access_token = access_token user.new_token_required = False user.save()
def handle_existing_user(self, provider, user, access, info): """Here we store the access token for the facebook page that we got from facebook.""" if len(Token.objects.all()) < 5: fb = OpenFacebook(access.access_token.split("=")[1]) me = fb.get('me/accounts') for page in me['data']: if 'Roseniuskyrkan' in page.values(): token = FacebookAuthorization.extend_access_token(page['access_token'])['access_token'] Token.objects.create(token = token) return super(LoginCallback, self).handle_existing_user(provider, user, access, info)
def setupFBUpdates(request): graph = get_facebook_graph(request) #get app's access token access_token = FacebookAuthorization.get_app_access_token() params = {'access_token': access_token} postdata = {'object': 'user', 'fields': "friends,music,books,movies,tv,likes", 'callback_url':"http://www.popcore.me/realtime/receive_fb_updates", 'verify_token':VERIFY_TOKEN } url = '%s%s?%s' % ("https://graph.facebook.com/", FACEBOOK_APP_ID + "/subscriptions", urllib.urlencode(params)) res= graph._request(url, post_data=postdata) #now check the new update configuration #import pprint response = graph._request(url) return HttpResponse(pprint.pformat(response))
def test_users(request): ''' Create test users for facebook ''' if not request.user.is_staff: raise Http404("access denied") context = RequestContext(request) if request.POST: from open_facebook.api import FacebookAuthorization token = FacebookAuthorization.get_app_access_token() fb_response = '' if request.POST.get('create_user', None): name = request.POST.get('user_name', None) app_access = request.POST.get('app_access', None) if app_access == 'on': app_access = True else: app_access = False fb_response = FacebookAuthorization.create_test_user(token, name=name, app_access=app_access) if request.POST.get('get_users', None): fb_response = FacebookAuthorization.get_test_users(token) test_users = [] if len(fb_response) > 0: test_users = fb_response context['test_users'] = test_users # test_users = FacebookTestUser.objects.filter(app_access_token=token) if request.POST.get('delete_user', None): user_id = request.POST.get('delete_user_id', None) fb_response = FacebookAuthorization.delete_test_user(token, user_id) context['fb_response'] = fb_response return render_to_response('django_facebook/test_users.html', context)
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token, expires = results['access_token'], int(results['expires']) new_token = access_token != self.access_token message = 'a new' if new_token else 'the same' log_format = 'Facebook provided %s token, which expires at %s' expires_delta = datetime.timedelta(seconds=expires) logger.info(log_format, message, expires_delta) if new_token: logger.info('Saving the new access token') self.access_token = access_token self.save() return results
def setupFBUpdates(request): graph = get_facebook_graph(request) #get app's access token access_token = FacebookAuthorization.get_app_access_token() params = {'access_token': access_token} postdata = { 'object': 'user', 'fields': "friends,music,books,movies,tv,likes", 'callback_url': "http://www.popcore.me/realtime/receive_fb_updates", 'verify_token': VERIFY_TOKEN } url = '%s%s?%s' % ("https://graph.facebook.com/", FACEBOOK_APP_ID + "/subscriptions", urllib.urlencode(params)) res = graph._request(url, post_data=postdata) #now check the new update configuration #import pprint response = graph._request(url) return HttpResponse(pprint.pformat(response))
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token, expires = results["access_token"], int(results["expires"]) old_token = self.access_token token_changed = access_token != old_token message = "a new" if token_changed else "the same" log_format = "Facebook provided %s token, which expires at %s" expires_delta = datetime.timedelta(seconds=expires) logger.info(log_format, message, expires_delta) if token_changed: logger.info("Saving the new access token") self.access_token = access_token self.save() from django_facebook.signals import facebook_token_extend_finished facebook_token_extend_finished.send(sender=self, profile=self, token_changed=token_changed, old_token=old_token) return results
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token = results['access_token'] old_token = self.access_token token_changed = access_token != old_token message = 'a new' if token_changed else 'the same' log_format = 'Facebook provided %s token, which expires at %s' expires_delta = datetime.timedelta(days=60) logger.info(log_format, message, expires_delta) if token_changed: logger.info('Saving the new access token') self.access_token = access_token self.save() from django_facebook.signals import facebook_token_extend_finished facebook_token_extend_finished.send(sender=self, profile=self, token_changed=token_changed, old_token=old_token ) return results
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token = results['access_token'] old_token = self.access_token token_changed = access_token != old_token message = 'a new' if token_changed else 'the same' log_format = 'Facebook provided %s token, which expires at %s' expires_delta = timedelta(days=60) logger.info(log_format, message, expires_delta) if token_changed: logger.info('Saving the new access token') self.access_token = access_token self.save() from django_facebook.signals import facebook_token_extend_finished facebook_token_extend_finished.send(sender=self, profile=self, token_changed=token_changed, old_token=old_token ) return results
def registered_facebook(request): try: publisher = Publisher.objects.get(user=request.user) except: return HttpResponseRedirect('/sorry') try: token = request.POST.get('access_token') long_access_token = FacebookAuthorization.extend_access_token(token)['access_token'] print 'long is generated' except: long_access_token = token print long_access_token try: graph = OpenFacebook(long_access_token) profile = graph.get('me') profile_id = profile['id'] friends = graph.get('me/friends') total_follower = int(friends['summary']['total_count']) except Exception as e: return HttpResponse(e) try: #control every account just one once if not len(Social_Data.objects.filter(publisher=publisher, account_type=0)) == 0: social_network = Social_Data.objects.get(publisher=publisher, account_type=0) social_network.account_id = profile_id social_network.account_token = long_access_token social_network.total_follower = total_follower else: social_network = Social_Data(publisher=publisher, account_type=0, account_id=profile_id, account_token=long_access_token, total_follower=total_follower) social_network.save() return HttpResponse(True, content_type='application/json') except Exception as e: return HttpResponse(e, content_type='application/json')
def process_request(self, request): """ This middleware authenticates the facebook user when he/she is accessing the app from facebook (not an internal page) The flow is show below: if referer is facebook: it's a canvas app and the first hit on the app If error: attempt to reauthenticate using authorization dialog if signed_request not sent or does not have the user_id and the access_token: user has not authorized app redirect to authorization dialog else: check permissions if user is authenticated (in django): check if current facebook user is the same that is authenticated if not: logout authenticated user if user is not authenticated: connect_user (django_facebook.connect module) changed method to GET. Facebook always sends a POST first. else: It's an internal page. No signed_request is sent. Return """ logger.info("PR01 process_request in django-facebook middleware") # This call cannot be global'ized or Django will return an empty response # after the first one redirect_login_oauth = ScriptRedirect(redirect_to=generate_oauth_url(), show_body=False) # check referer to see if this is the first access # or it's part of navigation in app # facebook always sends a POST reuqest referer = request.META.get("HTTP_REFERER", None) if referer: logger.info("PR02 referrer %s" % referer) urlparsed = urlparse(referer) is_facebook = urlparsed.netloc.endswith("facebook.com") # facebook redirect if is_facebook and urlparsed.path.endswith("/l.php"): logger.info("PR03 is_facebook = True") return if not is_facebook: logger.info("PR04 is_facebook = False") return # when there is an error, we attempt to allow user to # reauthenticate if "error" in request.GET: logger.info("PR05 errors in request.GET") return redirect_login_oauth else: logger.info("PR06 no referrer") return # get signed_request signed_request = request.POST.get("signed_request", None) try: # get signed_request parsed_signed_request = FacebookAuthorization.parse_signed_data(signed_request) access_token = parsed_signed_request["oauth_token"] facebook_id = long(parsed_signed_request["user_id"]) logger.info("PR07 facebook_id = %s" % facebook_id) except: logger.info("PR08 app is not authorized by user") # redirect to authorization dialog # if app not authorized by user return redirect_login_oauth # check for permissions try: graph = self.check_permissions(access_token) logger.info("PR09 got graph") except MissingPermissionsError: logger.info("PR010 no graph") return redirect_login_oauth # check if user authenticated and if it's the same if request.user.is_authenticated(): logger.info("PR11 use is authenticated, user_id = %s" % request.user.id) if not self.check_django_facebook_user(request, facebook_id, access_token): logger.info("PR12 check django facebook user failed") return request.facebook = graph if not request.user.is_authenticated(): logger.info("PR13 user is not authenticated") _action, _user = connect_user(request, access_token, graph) # override http method, since this actually is a GET if request.method == "POST": logger.info("PR14 overwrite POST to GET") request.method = "GET" return
def process_request(self, request): """Process requests for Facebook apps. This is expecially useful for canvas apps, since it handles signed_request logins, application requests, etc. Information about the current interaction status with Facebook is stored into ``request.fb_info`` as a dict with following keys: - ``is_canvas`` - Whether we are running inside canvas or not. This is determined by the presence of a signed request via POST. - ``is_signed_request`` - Whether we received a signed request, either via POST parameter (canvas) or cookie (js sdk method). - ``signed_request_type`` - ``"post"`` or ``"cookie"`` - ``app_request_ids`` - If a ``request_ids`` GET was passed, the IDs of requests to be processed. - ``is_authenticated`` - Whether we have a valid access_token for this user, or not. - Validate signed requests from Facebook - Login when running in canvas - For the deauthorize_callback ping - Process the requests execution when a request_ids parameter is passed -> redirect to somewhere - We should also prevent CSRF code to be checked if the request is using ``signed_request``. .. NOTE:: This middleware should go before CsrfMiddleware in order to skip CSRF validation for POSTs inside canvas apps, in case a valid signed_request was received. """ logger.debug("Running FacebookRequest Middleware") request.fb_info = { "is_canvas": False, "is_signed_request": None, "signed_request_type": None, "app_request_ids": None, "is_authenticated": None, } ## Set ``request.csrf_processing_done = True`` to skip CSRF checking for signed_request ## Check signed request _sr_from = None _sr_data = None if request.POST.has_key('signed_request'): logger.debug("Got a signed_request via POST") _sr_from = 'post' _sr_data = request.POST['signed_request'] elif request.GET.has_key('signed_request'): logger.debug("Got a signed_request via GET -- strange, but valid..") _sr_from = 'get' _sr_data = request.GET['signed_request'] else: pass # Disabled as this would generate _sr_data for every image, # css, etc """ cookie_name = 'fbsr_%s' % facebook_settings.FACEBOOK_APP_ID cookie_data = request.COOKIES.get(cookie_name) if cookie_data: logger.debug("Got a signed_request via cookie") _sr_from = 'cookie' _sr_data = cookie_data """ if _sr_data: parsed_data = FacebookAuthorization.parse_signed_data(_sr_data) if parsed_data: if _sr_from in ('post', 'get'): request.fb_info['is_canvas'] = True request.fb_info['is_signed_request'] = True request.fb_info['signed_request_type'] = _sr_from request.fb_info['signed_request_data'] = parsed_data ## Skip CSRF validation in case of valid signed request request.csrf_processing_done = True ## Login the user user = authenticate(facebook_id=parsed_data['user_id']) if user and (not request.user.is_authenticated() or request.user != user): # If the FB user is registered with the app and isn't logged in- login(request, user) ## --- Application requests -------------------------------------------- if request.REQUEST.has_key('request_ids'): request.fb_info['app_request_ids'] = request.REQUEST['request_ids'].split(',') return###===================================== STOP HERE =============== ## TODO: Check whether we are running inside canvas ## - if we have a signed_request, we are inside canvas ## TODO: If we have a valid authentication from signed request, do that ## TODO: If we received arguments from a completed OAuth process, handle that ## TODO: We should skip CSRF checking for signed requests inside canvas ## TODO: If we received ``request_ids``, store them somewhere access_token = _get_access_token_from_request(request) if not access_token: request.fb_info['is_authenticated'] = False else: request.fb_info['is_authenticated'] = True fb = get_facebook_graph(request, access_token) pass
def process_request(self, request): """ check if referer is facebook. If yes, this is the canvas page: if not return. if yes: 1) look for error. if error=permission denied -> redirect to permission. if other error: check what it can be 2) get signed_request and parse it. 3) if user_id and access_token not it parsed data -> redirect to permission page 4) check permissions 5) user: a) if user is authenticated: check if it's the same b) user is not authenticated: connect """ #check referer to see if this is the first access #or it's part of navigation in app #facebook always sends a POST reuqest referer = request.META.get('HTTP_REFERER', None) if referer: urlparsed = urlparse(referer) if not urlparsed.netloc.endswith('facebook.com'): return #when there is an error, we attempt to allow user to reauthenticate if 'error' in request.GET: return redirect_login_oauth else: return #get signed_request signed_request = request.POST.get('signed_request', None) #not sure if this can happen, but better check anyway if not signed_request: return redirect_login_oauth #get signed_request and redirect to authorization dialog if app not authorized by user parsed_signed_request = FacebookAuthorization.parse_signed_data( signed_request) if 'user_id' not in parsed_signed_request or 'oauth_token' not in parsed_signed_request: return redirect_login_oauth access_token = parsed_signed_request['oauth_token'] facebook_id = long(parsed_signed_request['user_id']) #check for permissions graph = OpenFacebook(access_token) permissions = set(graph.permissions()) scope_list = set(settings.FACEBOOK_DEFAULT_SCOPE) if scope_list - permissions: return redirect_login_oauth #check if user authenticated and if it's the same if request.user.is_authenticated(): try: current_user = request.user.get_profile() except: current_facebook_id = None else: current_facebook_id = current_user.facebook_id if not current_facebook_id or current_facebook_id != facebook_id: logout(request) #clear possible caches if hasattr(request, 'facebook'): del request.facebook if request.session.get('graph', None): del request.session['graph'] else: #save last access_token to make sure we always have the most recent one current_user.access_token = access_token current_user.save() request.facebook = graph if not request.user.is_authenticated(): _action, _user = connect_user(request, access_token, graph) #override http method, since this actually is a GET if request.method == 'POST': request.method = 'GET' return
# -*- coding: utf-8 -*- import requests from django.conf import settings settings.configure() from django_facebook import settings as facebook_settings from open_facebook import OpenFacebook from open_facebook.api import FacebookAuthorization import json facebook_settings.FACEBOOK_APP_ID ='611406969009887' facebook_settings.FACEBOOK_APP_SECRET ='6be22272c73f9a90f8ded333fbb0ff4d' access_token=FacebookAuthorization.get_app_access_token() graph=OpenFacebook(access_token) fb_name='HongKongPoliceForce' target=graph.get(fb_name) fields='reactions.limit(100){id,name,type},comments.limit(100){id,name}' id=target['id'] print id posts=graph.get(id+'/posts',limit=100,fields=fields,version='v2.6') def getUrl(url): if '\\' in url: url=eval('u'+"'"+url+"'") url=url.replace('\\','') return url
def fb_oauth(request): """View to process the OAuth login via Facebook. This view accepts a GET argument "next" to specify the page where to go upon successful OAuth authentication. This defaults to '/' in order to prevent infinite redirects. """ if request.GET.get('next'): request.session['facebook_oauth_next'] = request.GET['next'] if not request.session['facebook_oauth_next']: request.session['facebook_oauth_next'] = '/' next_url = request.session['facebook_oauth_next'] oauth_code = request.GET.get('code') or None redirect_uri = reversed("django_facebook.views.fb_oauth") error_info = { 'error': request.GET.get('error') or None, 'error_reason': request.GET.get('error_reason') or None, 'error_description': request.GET.get('error_description') or None, } if error_info['error']: if error_info['error_reason'] == 'user_denied': messages.warning(request, "You must click on the 'Authorize' button in order to log in with Facebook!") else: messages.error(request, "An error occurred while trying to authenticate on Facebook: %s (%s)" \ % (error_info['error_reason'], error_info['error_description'])) return HttpResponseRedirect(next_url) if not oauth_code: ## Start redirecting to the OAuth dialog.. import uuid, hashlib ## CSRF prevention _state = str(hashlib.md5(uuid.uuid1()).hexdigest()) request.session['facebook_oauth_state'] = _state qd = QueryDict('', True) qd['client_id'] = settings.FACEBOOK_APP_ID qd['redirect_uri'] = redirect_uri qd['state'] = _state dialog_url = "https://www.facebook.com/dialog/oauth?%s" % qd.urlencode() return CanvasRedirect(dialog_url) # Is this needed?? - what about HttpResponseRedirect .. ? else: ## We got an OAuth code if request.REQUEST.get('state') == request.session['facebook_oauth_state']: result = FacebookAuthorization.convert_code(code=oauth_code, redirect_uri=redirect_uri) access_token = result['access_token'] request.session['facebook_access_token'] = access_token ## TODO : Trigger a signal here to allow user registration etc. ## TODO: Redirect somewhere else.. return HttpResponseRedirect(next_url) else: raise HttpResponseNotAllowed("State doesn't match - you might be victim of CSRF") #https://www.facebook.com/dialog/oauth? #client_id=YOUR_APP_ID&redirect_uri=YOUR_URL #&scope=... #http://YOUR_URL?error_reason=user_denied& #error=access_denied&error_description=The+user+denied+your+request. #https://graph.facebook.com/oauth/access_token? # client_id=YOUR_APP_ID&redirect_uri=YOUR_URL& # client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE pass
def get_facebook_graph(request=None, access_token=None, redirect_uri=None, raise_=False): ''' given a request from one of these - js authentication flow (signed cookie) - facebook app authentication flow (signed cookie) - facebook oauth redirect (code param in url) - mobile authentication flow (direct access_token) - offline access token stored in user profile returns a graph object redirect path is the path from which you requested the token for some reason facebook needs exactly this uri when converting the code to a token falls back to the current page without code in the request params specify redirect_uri if you are not posting and recieving the code on the same page ''' # this is not a production flow, but very handy for testing if not access_token and request.REQUEST.get('access_token'): access_token = request.REQUEST['access_token'] # should drop query params be included in the open facebook api, # maybe, weird this... from open_facebook import OpenFacebook, FacebookAuthorization from django.core.cache import cache expires = None if hasattr(request, 'facebook') and request.facebook: graph = request.facebook _add_current_user_id(graph, request.user) return graph # parse the signed request if we have it signed_data = None if request: signed_request_string = request.REQUEST.get('signed_data') if signed_request_string: logger.info('Got signed data from facebook') signed_data = parse_signed_request(signed_request_string) if signed_data: logger.info('We were able to parse the signed data') # the easy case, we have an access token in the signed data if signed_data and 'oauth_token' in signed_data: access_token = signed_data['oauth_token'] if not access_token: # easy case, code is in the get code = request.REQUEST.get('code') if code: logger.info('Got code from the request data') if not code: # signed request or cookie leading, base 64 decoding needed cookie_name = 'fbsr_%s' % facebook_settings.FACEBOOK_APP_ID cookie_data = request.COOKIES.get(cookie_name) if cookie_data: signed_request_string = cookie_data if signed_request_string: logger.info('Got signed data from cookie') signed_data = parse_signed_request(signed_request_string) if signed_data: logger.info('Parsed the cookie data') # the javascript api assumes a redirect uri of '' redirect_uri = '' if signed_data: # parsed data can fail because of signing issues if 'oauth_token' in signed_data: logger.info('Got access_token from parsed data') # we already have an active access token in the data access_token = signed_data['oauth_token'] else: logger.info('Got code from parsed data') # no access token, need to use this code to get one code = signed_data.get('code', None) if not access_token: import hashlib if code: cache_key = 'convert_code_%d' % int(hashlib.md5(code).hexdigest(), 16) logger.info(pprint.pformat(cache)+cache_key) access_token = cache.get(cache_key) if not access_token: # exchange the code for an access token # based on the php api # https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php # create a default for the redirect_uri # when using the javascript sdk the default # should be '' an empty string # for other pages it should be the url if not redirect_uri: redirect_uri = '' # we need to drop signed_data, code and state redirect_uri = cleanup_oauth_url(redirect_uri) try: logger.info( 'trying to convert the code with redirect uri: %s', redirect_uri) # This is realy slow, that's why it's cached token_response = FacebookAuthorization.convert_code( code, redirect_uri=redirect_uri) expires = token_response.get('expires') access_token = token_response['access_token'] # would use cookies instead, but django's cookie setting # is a bit of a mess cache.set(cache_key, access_token, 60 * 60 * 2) except open_facebook_exceptions.OAuthException, e: # this sometimes fails, but it shouldnt raise because # it happens when users remove your # permissions and then try to reauthenticate logger.warn('Error when trying to convert code %s', unicode(e)) if raise_: raise else: return None elif request.user.is_authenticated(): # support for offline access tokens stored in the users profile profile = request.user.get_profile() access_token = getattr(profile, 'access_token', None) if not access_token: if raise_: message = 'Couldnt find an access token in the request or the users profile' raise open_facebook_exceptions.OAuthException(message) else: return None else: if raise_: message = 'Couldnt find an access token in the request or cookies' raise open_facebook_exceptions.OAuthException(message) else: return None
def get_facebook_friends(request): app_access_token = FacebookAuthorization.get_cached_app_access_token() graph = get_persistent_graph(request, access_token=app_access_token) converter = FacebookUserConverter(graph) friends_uids = ','.join([str(f['uid']) for f in converter.get_friends()]) return graph.fql('SELECT name, username, pic_square, pic FROM user WHERE uid IN (%s)' % friends_uids)
def get_facebook_graph(request=None, access_token=None, redirect_uri=None, raise_=False): ''' given a request from one of these - js authentication flow (signed cookie) - facebook app authentication flow (signed cookie) - facebook oauth redirect (code param in url) - mobile authentication flow (direct access_token) - offline access token stored in user profile returns a graph object redirect path is the path from which you requested the token for some reason facebook needs exactly this uri when converting the code to a token falls back to the current page without code in the request params specify redirect_uri if you are not posting and recieving the code on the same page ''' # this is not a production flow, but very handy for testing if not access_token and request.REQUEST.get('access_token'): access_token = request.REQUEST['access_token'] # should drop query params be included in the open facebook api, # maybe, weird this... from open_facebook import OpenFacebook, FacebookAuthorization from django.core.cache import cache expires = None if hasattr(request, 'facebook') and request.facebook: graph = request.facebook _add_current_user_id(graph, request.user) return graph # parse the signed request if we have it signed_data = None if request: signed_request_string = request.REQUEST.get('signed_data') if signed_request_string: logger.info('Got signed data from facebook') signed_data = parse_signed_request(signed_request_string) if signed_data: logger.info('We were able to parse the signed data') # the easy case, we have an access token in the signed data if signed_data and 'oauth_token' in signed_data: access_token = signed_data['oauth_token'] if not access_token: # easy case, code is in the get code = request.REQUEST.get('code') if code: logger.info('Got code from the request data') if not code: # signed request or cookie leading, base 64 decoding needed cookie_name = 'fbsr_%s' % facebook_settings.FACEBOOK_APP_ID cookie_data = request.COOKIES.get(cookie_name) if cookie_data: signed_request_string = cookie_data if signed_request_string: logger.info('Got signed data from cookie') signed_data = parse_signed_request(signed_request_string) if signed_data: logger.info('Parsed the cookie data') # the javascript api assumes a redirect uri of '' redirect_uri = '' if signed_data: # parsed data can fail because of signing issues if 'oauth_token' in signed_data: logger.info('Got access_token from parsed data') # we already have an active access token in the data access_token = signed_data['oauth_token'] else: logger.info('Got code from parsed data') # no access token, need to use this code to get one code = signed_data.get('code', None) if not access_token: import hashlib if code: cache_key = 'convert_code_%d' % int( hashlib.md5(code).hexdigest(), 16) logger.info(pprint.pformat(cache) + cache_key) access_token = cache.get(cache_key) if not access_token: # exchange the code for an access token # based on the php api # https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php # create a default for the redirect_uri # when using the javascript sdk the default # should be '' an empty string # for other pages it should be the url if not redirect_uri: redirect_uri = '' # we need to drop signed_data, code and state redirect_uri = cleanup_oauth_url(redirect_uri) try: logger.info( 'trying to convert the code with redirect uri: %s', redirect_uri) # This is realy slow, that's why it's cached token_response = FacebookAuthorization.convert_code( code, redirect_uri=redirect_uri) expires = token_response.get('expires') access_token = token_response['access_token'] # would use cookies instead, but django's cookie setting # is a bit of a mess cache.set(cache_key, access_token, 60 * 60 * 2) except open_facebook_exceptions.OAuthException, e: # this sometimes fails, but it shouldnt raise because # it happens when users remove your # permissions and then try to reauthenticate logger.warn('Error when trying to convert code %s', unicode(e)) if raise_: raise else: return None elif request.user.is_authenticated(): # support for offline access tokens stored in the users profile profile = request.user.get_profile() access_token = getattr(profile, 'access_token', None) if not access_token: if raise_: message = 'Couldnt find an access token in the request or the users profile' raise open_facebook_exceptions.OAuthException(message) else: return None else: if raise_: message = 'Couldnt find an access token in the request or cookies' raise open_facebook_exceptions.OAuthException(message) else: return None
def canvashome(request): redirectTo = request.session.get('redirect_to', False) if redirectTo: del request.session['redirect_to'] return HttpResponseRedirect(str(redirectTo)) member = None fb_url = settings.FACEBOOK_APP_URL #.format(appname=settings.FACEBOOK_APP_NAME) share_title = ConfigKey.get('SHARE_APP_TITLE', 'iBidGames') share_description = ConfigKey.get( 'SHARE_APP_DESC', 'iBidGames is the first true online Interactive Auction, is the only interactive auction game within Facebook framework that allows players to win real items' ) if not request.user.is_authenticated(): if not request.GET.get('facebook_login', None) and not request.GET.get( 'code', None): return render_response(request, 'login.html') else: if not request.GET.get('code', None): return redirect(generate_oauth_url()) access_token = FacebookAuthorization.convert_code( request.GET.get('code', None), fb_url)['access_token'] #Here the user dont came from facebook. The dj-middleware redirects to this poin without authentication data = { 'authorization_url': fb_url, 'app_url': fb_url, 'site_url': settings.SITE_NAME, 'share_title': share_title, 'share_description': share_description, } _action, _user = connect_user(request, access_token) return render_response(request, 'fb_redirect.html', data) #else: # social_auth_user = UserSocialAuth.objects.filter(provider='google-oauth2').filter(user_id=request.user.id) # if social_auth_user.count() > 0: # social_auth_user = social_auth_user[0] # data = get_data(social_auth_user.uid,social_auth_user.extra_data['access_token']) # google_profile = Google_profile.objects.filter(user_id=social_auth_user.user_id) # if google_profile.count() ==0: # google_profile = Google_profile.objects.create( # user_id= social_auth_user.user_id, # profile_url = data['url'], # profile_picture_url = data['image']['url'], # displayName = data['displayName'], # email = data['emails'][0]['value'], # gender =data['gender'] # ) # member=Member.objects.get(id=social_auth_user.user_id) # member.bids_left = 0 # member.tokens_left = 2000 # member.save() # client.update_tokens(member) # else: # google_profile = google_profile[0] # profile_picture_url = data['image']['url'] # google_profile.save() if not member: member = Member.objects.get(id=request.user.id) #give free tokens from promo freeExtraTokens = request.session.get('freeExtraTokens', 0) if freeExtraTokens and not member.getSession('freeExtraTokens', None): member.tokens_left += freeExtraTokens member.setSession('freeExtraTokens', 'used') member.save() del request.session['freeExtraTokens'] display_popup = False if not member.getSession('revisited'): display_popup = True member.setSession('revisited', True) try: auction_type = request.GET['auction_type'] except Exception: auction_type = 'token' response = render_response( request, 'bidding/mainpage.html', { 'FACEBOOK_APP_URL': settings.FACEBOOK_APP_URL.format( appname=settings.FACEBOOK_APP_NAME), 'SITE_NAME_WOUT_BACKSLASH': settings.SITE_NAME_WOUT_BACKSLASH, 'display_popup': display_popup, 'facebook_user_id': member.facebook_id, 'tosintro': FlatPage.objects.filter(title="tacintro")[0].content, 'member': member, 'auction_type': auction_type, 'app_url': fb_url, 'site_url': settings.SITE_NAME, 'share_title': share_title, 'share_description': share_description, 'inCanvas': False }) return response
def process_request(self, request): """ This middleware authenticates the facebook user when he/she is accessing the app from facebook (not an internal page) The flow is show below: if referer is facebook: it's a canvas app and the first hit on the app If error: attempt to reauthenticate using authorization dialog if signed_request not sent or does not have the user_id and the access_token: user has not authorized app redirect to authorization dialog else: check permissions if user is authenticated (in django): check if current facebook user is the same that is authenticated if not: logout authenticated user if user is not authenticated: connect_user (django_facebook.connect module) changed method to GET. Facebook always sends a POST first. else: It's an internal page. No signed_request is sent. Return """ # This call cannot be global'ized or Django will return an empty response # after the first one redirect_login_oauth = ScriptRedirect(redirect_to=generate_oauth_url(), show_body=False) # check referer to see if this is the first access # or it's part of navigation in app # facebook always sends a POST reuqest referer = request.META.get('HTTP_REFERER', None) if referer: urlparsed = urlparse(referer) is_facebook = urlparsed.netloc.endswith('facebook.com') # facebook redirect if is_facebook and urlparsed.path.endswith('/l.php'): return if not is_facebook: return # when there is an error, we attempt to allow user to # reauthenticate if 'error' in request.GET: return redirect_login_oauth else: return # get signed_request signed_request = request.POST.get('signed_request', None) try: # get signed_request parsed_signed_request = FacebookAuthorization.parse_signed_data( signed_request) access_token = parsed_signed_request['oauth_token'] facebook_id = long(parsed_signed_request['user_id']) except: # redirect to authorization dialog # if app not authorized by user return redirect_login_oauth # check for permissions try: graph = self.check_permissions(access_token) except MissingPermissionsError: return redirect_login_oauth # check if user authenticated and if it's the same if request.user.is_authenticated(): self.check_django_facebook_user(request, facebook_id, access_token) request.facebook = graph if not request.user.is_authenticated(): _action, _user = connect_user(request, access_token, graph) # override http method, since this actually is a GET if request.method == 'POST': request.method = 'GET' return
def process_request(self, request): """ This middleware authenticates the facebook user when he/she is accessing the app from facebook (not an internal page) The flow is show below: if referer is facebook: it's a canvas app and the first hit on the app If error: attempt to reauthenticate using authorization dialog if signed_request not sent or does not have the user_id and the access_token: user has not authorized app redirect to authorization dialog else: check permissions if user is authenticated (in django): check if current facebook user is the same that is authenticated if not: logout authenticated user if user is not authenticated: connect_user (django_facebook.connect module) changed method to GET. Facebook always sends a POST first. else: It's an internal page. No signed_request is sent. Return """ # This call cannot be global'ized or Django will return an empty response # after the first one redirect_login_oauth = ScriptRedirect(redirect_to=generate_oauth_url(), show_body=False) # check referer to see if this is the first access # or it's part of navigation in app # facebook always sends a POST reuqest referer = request.META.get('HTTP_REFERER', None) if referer: urlparsed = urlparse(referer) if not urlparsed.netloc.endswith('facebook.com'): return # when there is an error, we attempt to allow user to # reauthenticate if 'error' in request.GET: return redirect_login_oauth else: return # get signed_request signed_request = request.POST.get('signed_request', None) try: # get signed_request parsed_signed_request = FacebookAuthorization.parse_signed_data( signed_request) access_token = parsed_signed_request['oauth_token'] facebook_id = int(parsed_signed_request['user_id']) except: # redirect to authorization dialog # if app not authorized by user return redirect_login_oauth # check for permissions try: graph = self.check_permissions(access_token) except MissingPermissionsError: return redirect_login_oauth # check if user authenticated and if it's the same if request.user.is_authenticated(): self.check_django_facebook_user(request, facebook_id, access_token) request.facebook = graph if not request.user.is_authenticated(): _action, _user = connect_user(request, access_token, graph) # override http method, since this actually is a GET if request.method == 'POST': request.method = 'GET' return
def get_users_fb_email(request): app_access_token = FacebookAuthorization.get_cached_app_access_token() graph = get_persistent_graph(request, access_token=app_access_token) return graph.me()['email']