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