Пример #1
0
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
Пример #2
0
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
Пример #3
0
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()
Пример #4
0
    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
Пример #5
0
    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
Пример #7
0
    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
Пример #8
0
    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
Пример #9
0
    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