def post_to_fb_async(access_token, msg):
    
    
    
    fb = OpenFacebook(access_token)
    
    fb.set("me/feed", message=msg)
 def get_offline_graph(self):
     """Returns a open_facebook graph client based on the
     access_token stored in the user's profile.
     """
     from open_facebook.api import OpenFacebook
     if self.access_token:
         graph = OpenFacebook(access_token=self.access_token)
         graph.current_user_id = self.facebook_id
         return graph
Example #3
0
	def publish(self, text):
	
		
		graph = OpenFacebook(access_token)
		try:
			graph.set('me/feed',message=text)
		except:
			www = "https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s&scope=publish_actions"%(settings.FACEBOOK_APP_ID,self.redirect_uri)
			return 'perm', www
Example #4
0
 def get_offline_graph(self):
     '''
     Returns a open facebook graph client based on the access token stored
     in the user's profile
     '''
     from open_facebook.api import OpenFacebook
     if self.access_token:
         graph = OpenFacebook(access_token=self.access_token)
         graph.current_user_id = self.facebook_id
         return graph
Example #5
0
def get_persistent_graph(request, *args, **kwargs):
    '''
    Wraps itself around get facebook graph
    But stores the graph in the session, allowing usage across multiple
    pageviews.
    Note that Facebook session's expire at some point, you can't store this
    for permanent usage
    Atleast not without asking for the offline_access permission
    '''
    from open_facebook.api import OpenFacebook
    if not request:
        logger.info("GPG01 no request")
        raise(ValidationError,
              'Request is required if you want to use persistent tokens')

    graph = None
    # some situations like an expired access token require us to refresh our
    # graph
    require_refresh = False
    code = request.REQUEST.get('code')
    logger.info("GPG02 code = %s" % code)
    if code:
        require_refresh = True

    local_graph = getattr(request, 'facebook', None)
    logger.info("GPG03 local_graph %s" % local_graph)
    if local_graph:
        # gets the graph from the local memory if available
        graph = local_graph

    if not graph:
        logger.info("GPG04 no graph")
        # search for the graph in the session
        cached_graph_dict = request.session.get('graph_dict')
        if cached_graph_dict:
            logger.info("GPG05 graph in session")
            graph = OpenFacebook()
            graph.__setstate__(cached_graph_dict)
            graph._me = None

    if not graph or require_refresh:
        # gets the new graph, note this might do token conversions (slow)
        logger.info("GPG06 getting graph")
        graph = get_facebook_graph(request, *args, **kwargs)
        # if it's valid replace the old cache
        if graph is not None and graph.access_token:
            logger.info("GPG07 put graph into session")
            request.session['graph_dict'] = graph.__getstate__()

    # add the current user id and cache the graph at the request level
    _add_current_user_id(graph, request.user)
    request.facebook = graph

    return graph
Example #6
0
    def check_permissions(self, access_token):
        graph = OpenFacebook(access_token)
        permissions = set(graph.permissions())
        scope_list = set(settings.FACEBOOK_DEFAULT_SCOPE)
        missing_perms = scope_list - permissions
        if missing_perms:
            permissions_string = ', '.join(missing_perms)
            error_format = 'Permissions Missing: %s'
            raise MissingPermissionsError(error_format % permissions_string)

        return graph
Example #7
0
    def friends_events(self, request):
        facebook = OpenFacebook(request._auth)
        friends = facebook.get('me/friends')
        friends_ids = []
        for friend in friends[u'data']:
            friends_ids.append(friend[u'id'])

        events = Event.objects.filter(social_user_uid__in=friends_ids)

        serializer = self.get_serializer(events, many=True)
        return Response(serializer.data)
Example #8
0
    def check_permissions(self, access_token):
        graph = OpenFacebook(access_token)
        permissions = set(graph.permissions())
        scope_list = set(settings.FACEBOOK_DEFAULT_SCOPE)
        missing_perms = scope_list - permissions
        if missing_perms:
            permissions_string = ', '.join(missing_perms)
            error_format = 'Permissions Missing: %s'
            raise MissingPermissionsError(error_format % permissions_string)

        return graph
Example #9
0
 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)
Example #10
0
	def save(self, *args, **kwargs):
		from open_facebook.api import OpenFacebook
		from project_dante import settings


		if self.id is None:
			self.member_pk = Profile.objects.get(username="******")
			graph = OpenFacebook(settings.FACEBOOK_APP_ID+'|'+settings.FACEBOOK_APP_SECRET)
			data = graph.get(self.page_link)
			self.page_id = data['id']
			self.page_name = data['name']

		super(FacebookFeed,self).save(*args, **kwargs)
Example #11
0
	def code2token(self, code):
		me = {}
		www = "https://graph.facebook.com/oauth/access_token?client_id=%s&redirect_uri=%s&client_secret=%s&code=%s"%(settings.FACEBOOK_APP_ID, self.redirect_uri, settings.FACEBOOK_APP_SECRET, code)
		response = cgi.parse_qs(urllib.urlopen(www).read())
		access_token = response['access_token'][-1]
		expires = response['expires'][-1]
		#print response
		#print access_token
		#print expires
		graph = OpenFacebook(access_token)
		me = dict(graph.get('me'))

		return access_token, me
Example #12
0
    def check_permissions(self, access_token):
        logger.info("CHP01 check permissions access_token = %s" % access_token)
        graph = OpenFacebook(access_token)
        permissions = set(graph.permissions())
        scope_list = set(settings.FACEBOOK_DEFAULT_SCOPE)
        missing_perms = scope_list - permissions
        if missing_perms:
            permissions_string = ', '.join(missing_perms)
            error_format = 'Permissions Missing: %s'
            logger.info("CHP02 missed permissions: %s" % permissions_string)
            raise MissingPermissionsError(error_format % permissions_string)

        logger.info("CHP03 permissions OK")
        return graph
Example #13
0
    def check_permissions(self, access_token):
        logger.info("CHP01 check permissions access_token = %s" % access_token)
        graph = OpenFacebook(access_token)
        permissions = set(graph.permissions())
        scope_list = set(settings.FACEBOOK_DEFAULT_SCOPE)
        missing_perms = scope_list - permissions
        if missing_perms:
            permissions_string = ", ".join(missing_perms)
            error_format = "Permissions Missing: %s"
            logger.info("CHP02 missed permissions: %s" % permissions_string)
            raise MissingPermissionsError(error_format % permissions_string)

        logger.info("CHP03 permissions OK")
        return graph
Example #14
0
	def handle(self, *args, **kwargs):
		from deal.models import *
		from datetime import date, datetime, timedelta
		from project_dante import settings
		from open_facebook.api import OpenFacebook
		from django.core.files.base import ContentFile
		from django.core.paginator import Paginator
		import re, urllib2

		graph 			= OpenFacebook(settings.FACEBOOK_APP_ID + '|' + settings.FACEBOOK_APP_SECRET)
		facebook_pages 	= Paginator(FacebookFeed.objects.all(),20)
		page_num 		= 1


		while page_num <= facebook_pages.num_pages:
			queries 		= {}
			current_page 	= facebook_pages.page(page_num)
			for p in current_page:
				query 	= "SELECT post_id, attachment, message FROM stream WHERE source_id = %s and type = 247" % (p.page_id)
				queries[unicode('p_'+p.page_id)] = query

			query_result = graph.batch_fql(queries)
			keyword = r'\b(hot|deal|sale|promotion|off|free|[\d]{1,3}%{1})+'

			for p in current_page:
				if query_result[unicode('p_'+p.page_id)]:
					result = query_result[unicode('p_'+p.page_id)]
					for data in result:
						if (data['post_id'] != p.recent_feed) and (p.recent_feed != ''):
							if (re.search(keyword,data['message'],flags=re.I)):
								media 				= data['attachment']['media'][0]
								deal 				= Deal()
								deal.title 			= "%s : %s ..." % (p.page_name[:25], data['message'][:115]) 
								deal.link 			= media['href']
								deal.content 		= '<p>' + data['message'].replace('\n','<br>') + '</p>'
								deal.date_started	= date.today()
								image_content 		= ContentFile(urllib2.urlopen(media['src'].replace('_s.','_n.')).read())
								deal.promo_image.save(media['src'].split('/')[-1].replace('_s.','_n.'), image_content, save=False)
								deal.category_pk	= p.category_pk
								deal.member_pk		= p.member_pk
								deal.save()
						else:
							break
					p.recent_feed = result[0]['post_id'] #updates entry to the most recent feed
					p.save()

			print "page num : %s" %(page_num)
			page_num+=1
Example #15
0
	def authenticate(self, fn, request, *args, **kwargs):
		redirect_uri = self.get_redirect_uri(request)
		oauth_url = get_oauth_url(
			self.scope_list, redirect_uri, extra_params=self.extra_params)

		graph = None
		try:
			# call get persistent graph and convert the
			# token with correct redirect uri
			graph = require_persistent_graph(
				request, redirect_uri=redirect_uri)
			# Note we're not requiring a persistent graph here
			# You should require a persistent graph in the view when you start
			# using this

			facebook = OpenFacebook(graph.access_token)
			user = facebook.get('me')
			email = user.get('email')

			user_model = get_user_model()
			user = user_model.objects.filter(email=email)
			a = 0
			if user:
				response = self.execute_view(
					fn, request, graph=graph, *args, **kwargs)
			else:
				response = HttpResponse("Voce nao tem permissao para acessar o sistema<br>Para ter acesso repasse esse email para o administrador: " + email)
		except open_facebook_exceptions.OpenFacebookException as e:
			permission_granted = has_permissions(graph, self.scope_list)
			if permission_granted:
				# an error if we already have permissions
				# shouldn't have been caught
				# raise to prevent bugs with error mapping to cause issues
				a = 0
				if a == 0:
					response = self.authentication_failed(
					fn, request, *args, **kwargs)
				else:
					raise
			elif request.REQUEST.get('attempt') == '1':
				# Doing a redirect could end up causing infinite redirects
				# If Facebook is somehow not giving permissions
				# Time to show an error page
				response = self.authentication_failed(
					fn, request, *args, **kwargs)
			else:
				response = self.oauth_redirect(oauth_url, redirect_uri, e)
		return response
Example #16
0
def get_persistent_graph(request, *args, **kwargs):
    '''
    Wraps itself around get facebook graph
    But stores the graph in the session, allowing usage across multiple
    pageviews.
    Note that Facebook session's expire at some point, you can't store this
    for permanent usage
    Atleast not without asking for the offline_access permission
    '''
    if not request:
        raise(ValidationError,
              'Request is required if you want to use persistent tokens')

    graph = None
    # some situations like an expired access token require us to refresh our
    # graph
    require_refresh = False
    code = request.REQUEST.get('code')
    if code:
        require_refresh = True

    local_graph = getattr(request, 'facebook', None)
    if local_graph:
        # gets the graph from the local memory if available
        graph = local_graph

    if not graph:
        # search for the graph in the session
        cached_graph_dict = request.session.get('graph_dict')
        if cached_graph_dict:
            cached_graph = OpenFacebook()
            cached_graph.__setstate__(cached_graph_dict)
            cached_graph._me = None

    if not graph or require_refresh:
        # gets the new graph, note this might do token conversions (slow)
        graph = get_facebook_graph(request, *args, **kwargs)
        # if it's valid replace the old cache
        if graph is not None and graph.access_token:
            request.session['graph_dict'] = graph.__getstate__()

    # add the current user id and cache the graph at the request level
    _add_current_user_id(graph, request.user)
    request.facebook = graph

    return graph
Example #17
0
def get_fb_events(user, fb_access_token=None, limit=5000):
    """
    Parses the facebook response and returns the likes
    """
    if user:
        access_token = user.access_token
    else:
        access_token = fb_access_token

    open_facebook = OpenFacebook(access_token)
    fields = settings.FACEBOOK_DEFAULT_EVENTS_FIELDS
    events_response = open_facebook.get('me/events',
                                        limit=limit,
                                        fields=','.join(fields))
    events = events_response and events_response.get('data')
    logger.info('found %s events', len(events))
    return events
Example #18
0
	def post(self, request, format=None):
		serializer = FacebookSerializer(data=request.data)
		if serializer.is_valid():
			access_token = serializer.data['access_token']
			facebook = OpenFacebook(access_token)
			try:
				user = User.objects.get(username=facebook.get('me')['id'])
				user.last_name = serializer.data['access_token']
				user.save()
			except ObjectDoesNotExist:
				user = User.objects.create_user(facebook.get('me')['id'])
				user.first_name = 'facebook'
				user.last_name = serializer.data['access_token']
				user.save()
			token = Token.objects.get_or_create(user=user)
			return Response({'token': token[0].key})
		return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Example #19
0
def add_candidate_from_fb(request):

    if request.method == 'POST':
        form = FacebookCreateCandidateForm(request.POST)
        if form.is_valid():
            fb = OpenFacebook()
            # fb_url = request.POST.get('fb_page')
            fb_url = form.cleaned_data['url']
            # party = Party.objects.get(id=request.POST.get('party'))
            party = form.cleaned_data['party']
            try:
                res = fb.get(fb_url, fields='name, website, picture.type(large)')
                sites = res.get('website', None).split(' ')
                for site in sites:
                    try:
                        if site == '':
                            continue
                        URLValidator(site)
                        val = site
                        break
                    except ValidationError as e:
                        print site, "is not a valid url"
                        continue

                # add another validation
                c = Candidate(name=res['name'],
                              image_url=res['picture']['data']['url'],
                              personal_site=val,
                              facebook_page=fb_url,
                              party=party)
                c.save()
                messages.info(request, "Added Successfully")
                return redirect(c.get_absolute_url())
            except ParameterException as e:
                messages.error(request, e.message)
    else:
        form = FacebookCreateCandidateForm()

    return render(request,
                  'votes/candidate_fb_form.html',
                  {'form': form})
Example #20
0
def publisher_join_campaign_like_campaign(request, campaign_id):
    try:
        publisher = Publisher.objects.get(user=request.user)
        campaign = Campaign.objects.get(id=campaign_id)
        account = Social_Data.objects.get(publisher=publisher, account_type='0')
    except:
        return HttpResponseRedirect('/sorry')

    try:
        facebook = OpenFacebook(account.account_token)
        last_liked_page_id = facebook.get('me/likes/')['data'][0]['id']
        advertiser_page_id = facebook.get(campaign.campaign_data+'/')['id']
        if last_liked_page_id == advertiser_page_id:
            published_advert = Published_Adverts(social_data=account, campaign=campaign, message_link=advertiser_page_id)
            published_advert.save()
        else:
            return HttpResponseRedirect('/publisher/publisher_join_campaign/' + str(campaign_id))
    except:
        return HttpResponseRedirect('/publisher/publisher_join_campaign/' + str(campaign_id))

    return HttpResponseRedirect('/publisher/my_published_adverts')
Example #21
0
    def get(self, request, *args, **kwargs):
        post_id = self.kwargs['post_id']
        profile = self.kwargs['profile']

        graph = OpenFacebook(access_token)
        post = graph.get('{0}'.format(post_id))
        comments = graph.get('{0}/comments'.format(post_id))
        context = {}
        measure = []
        for i in comments['data']:
            measure.append(round(self.get_comment_sentiment(i['message']), 2))

        context['comments'] = comments['data']

        for i in range(len(context['comments'])):
            context['comments'][i].update({'measure': measure[i]})

        context['profile'] = profile
        context['post_id'] = post_id

        return render(request, "comments.html", context=context)
Example #22
0
def add_candidate_from_fb(request):

    if request.method == 'POST':
        form = FacebookCreateCandidateForm(request.POST)
        if form.is_valid():
            fb = OpenFacebook()
            # fb_url = request.POST.get('fb_page')
            fb_url = form.cleaned_data['url']
            # party = Party.objects.get(id=request.POST.get('party'))
            party = form.cleaned_data['party']
            try:
                res = fb.get(fb_url,
                             fields='name, website, picture.type(large)')
                sites = res.get('website', None).split(' ')
                for site in sites:
                    try:
                        if site == '':
                            continue
                        URLValidator(site)
                        val = site
                        break
                    except ValidationError as e:
                        print site, "is not a valid url"
                        continue

                # add another validation
                c = Candidate(name=res['name'],
                              image_url=res['picture']['data']['url'],
                              personal_site=val,
                              facebook_page=fb_url,
                              party=party)
                c.save()
                messages.info(request, "Added Successfully")
                return redirect(c.get_absolute_url())
            except ParameterException as e:
                messages.error(request, e.message)
    else:
        form = FacebookCreateCandidateForm()

    return render(request, 'votes/candidate_fb_form.html', {'form': form})
Example #23
0
    def post(self, request, *args, **kwargs):
        """
        Handles POST requests, instantiating a form instance with the passed
        POST variables and then checked for validity.
        """
        form = self.get_form()
        if form.is_valid():
            profile_id = form.cleaned_data['profile_id']
            # print profile_id

            graph = OpenFacebook(access_token)
            profile = graph.get('{0}'.format(profile_id))
            posts = graph.get('{0}/posts'.format(profile_id))
            context = self.get_context_data()
            context['profile'] = profile_id
            context['posts'] = posts['data']
            context['next_posts'] = posts['paging']['next']

            return render(request, "posts.html", context=context)
            # return self.form_valid(form)
        else:
            return self.form_invalid(form)
Example #24
0
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')
Example #25
0
def publisher_join_campaign_share_campaign(request, campaign_id):
    try:
        publisher = Publisher.objects.get(user=request.user)
        campaign = Campaign.objects.get(id=campaign_id)
        account = Social_Data.objects.get(publisher=publisher, account_type='0')
    except Exception as e:
        print e
        return HttpResponseRedirect('/sorry')

    form = send_fb_post_form
    if request.method == 'POST':
        form = send_fb_post_form(request.POST)
        if form.is_valid():
            post_text = request.POST.get('post_text')
            try:
                facebook = OpenFacebook(account.account_token)
                facebook.set('me/feed', message=str(post_text)+' '+str(campaign.campaign_data), url=campaign.campaign_data)
                published_advert = Published_Adverts(social_data=account, campaign=campaign, message_link=facebook.get('me/links')['data'][0]['link'])
                published_advert.save()
            except Exception as e:
                print e
                return HttpResponseRedirect('/sorry')

    return HttpResponseRedirect('/publisher/my_published_adverts')
Example #26
0
def publisher_join_campaign(request, campaign_id):
    try:
        publisher = Publisher.objects.get(user=request.user)
        campaign = Campaign.objects.get(id=campaign_id)
    except:
        return HttpResponseRedirect('/sorry')

    if not len(Published_Adverts.objects.filter(social_data__publisher=publisher, campaign=campaign)) == 0: #Every campaign, just one once
        return HttpResponseRedirect('/publisher/my_published_adverts')

    if campaign.campaign_type in ['0', '1', '4']:
        try:
            account_tw = Social_Data.objects.get(publisher=publisher, account_type='1')
        except:
            return HttpResponseRedirect('/sorry')
        api = twitter.Api(consumer_key='zsqVde4f4vkRNopoj8zGvVM7x',
                      consumer_secret='3pcD1MNmQNyHAZrDjmNQmHdnUNfZywbA4Lbomh3ofxqzO3e6o8',
                      access_token_key=account_tw.account_id,
                      access_token_secret=account_tw.account_token)

        if campaign.campaign_type == '0':
            html_message_code = api.GetStatusOembed(id=campaign.campaign_data)['html']
        elif campaign.campaign_type == '1':
            form = send_tweet_form
        else:
            html_message_code = campaign.campaign_data
    else:
        try:
            account_fb = Social_Data.objects.get(publisher=publisher, account_type='0')
        except:
            return HttpResponseRedirect('/sorry')
        facebook = OpenFacebook(account_fb.account_token)

        if campaign.campaign_type == '2':
            form2 = send_fb_post_form
        else:
            html_message_code = campaign.campaign_data

    return render_to_response('publisher_join_campaign.html', locals(), context_instance=RequestContext(request))
Example #27
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
Example #28
0
def post_to_fb_async(access_token, msg):

    fb = OpenFacebook(access_token)

    fb.set("me/feed", message=msg)
Example #29
0
                            'GFaG13 Couldnt find an access token in the request or the users profile'
                        )
                        raise open_facebook_exceptions.OAuthException(message)
                    else:
                        return None
            else:
                if raise_:
                    logger.info(
                        'GFaG14 Couldnt find an access token in the request or cookies'
                    )
                    message = 'Couldnt find an access token in the request or cookies'
                    raise open_facebook_exceptions.OAuthException(message)
                else:
                    return None

    graph = OpenFacebook(access_token, signed_data, expires=expires)
    # add user specific identifiers
    if request:
        _add_current_user_id(graph, request.user)

    return graph


def _add_current_user_id(graph, user):
    '''
    set the current user id, convenient if you want to make sure you
    fb session and user belong together
    '''
    if graph:
        graph.current_user_id = None
Example #30
0
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:
            if code:
                cache_key = hash_key('convert_code_%s' % code)
                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,
                            open_facebook_exceptions.ParameterException) as 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 = try_get_profile(request.user)
                access_token = get_user_attribute(request.user, profile,
                                                  'access_token')
                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

    graph = OpenFacebook(access_token, signed_data, expires=expires)
    # add user specific identifiers
    if request:
        _add_current_user_id(graph, request.user)

    return graph
Example #31
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