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