def test_user_registered_signal(self): # Ensure user registered, pre update and post update signals fire def user_registered(sender, user, facebook_data, **kwargs): user.registered_signal = True def pre_update(sender, profile, facebook_data, **kwargs): profile.pre_update_signal = True def post_update(sender, profile, facebook_data, **kwargs): profile.post_update_signal = True Profile = get_profile_class() signals.facebook_user_registered.connect(user_registered, sender=User) signals.facebook_pre_update.connect(pre_update, sender=Profile) signals.facebook_post_update.connect(post_update, sender=Profile) graph = get_facebook_graph(access_token='short_username') klass = get_facebook_user_converter_class() facebook = klass(graph) user = _register_user(self.request, facebook) self.assertEqual(hasattr(user, 'registered_signal'), True) self.assertEqual(hasattr(user.get_profile(), 'pre_update_signal'), True) self.assertEqual(hasattr(user.get_profile(), 'post_update_signal'), True)
def connect_user(request, access_token=None, facebook_graph=None): ''' Given a request either - (if authenticated) connect the user - login - register ''' graph = facebook_graph or get_facebook_graph(request, access_token) klass = get_facebook_user_converter_class() facebook = klass(graph) assert facebook.is_authenticated() facebook_data = facebook.facebook_profile_data() force_registration = request.REQUEST.get('force_registration') or\ request.REQUEST.get('force_registration_hard') connect_facebook = bool(int(request.REQUEST.get('connect_facebook', 0))) logger.debug('force registration is set to %s', force_registration) if connect_facebook and request.user.is_authenticated() and not force_registration: #we should only allow connect if users indicate they really want to connect #only when the request.CONNECT_FACEBOOK = 1 #if this isn't present we just do a login action = CONNECT_ACTIONS.CONNECT user = _connect_user(request, facebook) else: email = facebook_data.get('email', False) email_verified = facebook_data.get('verified', False) kwargs = {} if email and email_verified: kwargs = {'facebook_email': email} auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs) if auth_user and not force_registration: action = CONNECT_ACTIONS.LOGIN # Has the user registered without Facebook, using the verified FB # email address? # It is after all quite common to use email addresses for usernames if not auth_user.get_profile().facebook_id: update = True else: update = getattr(auth_user, 'fb_update_required', False) user = _login_user(request, facebook, auth_user, update=update) else: action = CONNECT_ACTIONS.REGISTER # when force registration is active we should clearout # the old profile user = _register_user(request, facebook, remove_old_connections=force_registration) _update_likes_and_friends(request, user, facebook) _update_access_token(user, graph) return action, user
def test_gender_matching(self): request = RequestMock().get('/') request.session = {} request.user = AnonymousUser() graph = get_persistent_graph(request, access_token='paul') klass = get_facebook_user_converter_class() converter = klass(graph) base_data = converter.facebook_profile_data() self.assertEqual(base_data['gender'], 'male') data = converter.facebook_registration_data() self.assertEqual(data['gender'], 'm') action, user = connect_user(self.request, facebook_graph=graph) self.assertEqual(user.get_profile().gender, 'm')
def update_connection(request, graph): ''' A special purpose view for updating the connection with an existing user - updates the access token (already done in get_graph) - sets the facebook_id if nothing is specified - stores friends and likes if possible ''' klass = get_facebook_user_converter_class() facebook = klass(graph) user = _connect_user(request, facebook, overwrite=False) _update_likes_and_friends(request, user, facebook) _update_access_token(user, graph) return user
def test_full_connect(self): #going for a register, connect and login graph = get_facebook_graph(access_token='short_username') klass = get_facebook_user_converter_class() klass(graph) action, user = connect_user(self.request, facebook_graph=graph) self.assertEqual(action, CONNECT_ACTIONS.REGISTER) action, user = connect_user(self.request, facebook_graph=graph) self.assertEqual(action, CONNECT_ACTIONS.LOGIN) self.request.GET._mutable = True self.request.GET['connect_facebook'] = 1 action, user = connect_user(self.request, facebook_graph=graph) self.assertEqual(action, CONNECT_ACTIONS.CONNECT) self.request.user = AnonymousUser() action, user = connect_user(self.request, facebook_graph=graph) self.assertEqual(action, CONNECT_ACTIONS.LOGIN)
def store_friends(user, friends): ''' Inserting again will not cause any errors, so this is safe for multiple executions :param user: The user for which we are storing :type user: User object :param friends: List of your friends :type friends: list ''' from django_facebook.api import get_facebook_user_converter_class klass = get_facebook_user_converter_class() logger.info('celery is storing %s friends' % len(friends)) klass._store_friends(user, friends) return friends
def store_friends(user, friends): ''' Inserting again will not cause any errors, so this is safe for multiple executions :param user: The user for which we are storing :type user: User object :param friends: List of your friends :type friends: list ''' from django_facebook.api import get_facebook_user_converter_class klass = get_facebook_user_converter_class() logger.info('celery is storing %s friends' % len(friends)) klass._store_friends(user, friends) return friends
def connect_async_ajax(request): ''' Not yet implemented: The idea is to run the entire connect flow on the background using celery Freeing up webserver resources, when facebook has issues ''' from django_facebook import tasks as facebook_tasks graph = get_persistent_graph(request) output = {} if graph: klass = get_facebook_user_converter_class() klass(graph) task = facebook_tasks.async_connect_user(request, graph) output['task_id'] = task.id from open_facebook.utils import json json_dump = json.dumps(output) return HttpResponse(json_dump)
def connect_async_ajax(request): ''' Not yet implemented: The idea is to run the entire connect flow on the background using celery Freeing up webserver resources, when facebook has issues ''' from django_facebook import tasks as facebook_tasks graph = get_persistent_graph(request) output = {} if graph: klass = get_facebook_user_converter_class() klass(graph) task = facebook_tasks.async_connect_user(request, graph) output['task_id'] = task.id from open_facebook.utils import json json_dump = json.dumps(output) return HttpResponse(json_dump)
def test_gender(self): graph = get_facebook_graph(access_token='new_user') klass = get_facebook_user_converter_class() facebook = klass(graph) data = facebook.facebook_registration_data() self.assertEqual(data['gender'], 'm')
def test_utf8(self): graph = get_facebook_graph(access_token='unicode_string') klass = get_facebook_user_converter_class() facebook = klass(graph) action, user = connect_user(self.request, facebook_graph=graph)
def connect(request): ''' Handles the view logic around connect user - (if authenticated) connect the user - login - register ''' backend = get_registration_backend() context = RequestContext(request) assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\ 'and ensure the context processor is enabled' facebook_login = bool(int(request.REQUEST.get('facebook_login', 0))) if facebook_login: require_persistent_graph(request) logger.info('trying to connect using facebook') graph = get_persistent_graph(request) if graph: logger.info('found a graph object') klass = get_facebook_user_converter_class() facebook = klass(graph) if facebook.is_authenticated(): logger.info('facebook is authenticated') facebook_data = facebook.facebook_profile_data() #either, login register or connect the user try: action, user = connect_user(request) logger.info('Django facebook performed action: %s', action) except facebook_exceptions.IncompleteProfileError, e: #show them a registration form to add additional data warning_format = u'Incomplete profile data encountered with error %s' warn_message = warning_format % e.message send_warning(warn_message, e=e, facebook_data=facebook_data) context['facebook_mode'] = True context['form'] = e.form return render_to_response( facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE, context_instance=context, ) if action is CONNECT_ACTIONS.CONNECT: #connect means an existing account was attached to facebook messages.info( request, _("You have connected your account " "to %s's facebook profile") % facebook_data['name']) elif action is CONNECT_ACTIONS.REGISTER: #hook for tying in specific post registration functionality response = backend.post_registration_redirect( request, user) return response else: if 'attempt' in request.GET: return next_redirect( request, next_key=['error_next', 'next'], additional_params=dict(fb_error_or_cancel=1)) else: logger.info('Facebook authentication needed for connect, ' \ 'raising an error') raise OpenFacebookException('please authenticate') #for CONNECT and LOGIN we simple redirect to the next page return next_redirect( request, default=facebook_settings.FACEBOOK_LOGIN_DEFAULT_REDIRECT)
def connect(request): ''' Handles the view logic around connect user - (if authenticated) connect the user - login - register ''' backend = get_registration_backend() context = RequestContext(request) assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\ 'and ensure the context processor is enabled' facebook_login = bool(int(request.REQUEST.get('facebook_login', 0))) if facebook_login: require_persistent_graph(request) logger.info('trying to connect using facebook') graph = get_persistent_graph(request) if graph: logger.info('found a graph object') klass = get_facebook_user_converter_class() facebook = klass(graph) if facebook.is_authenticated(): logger.info('facebook is authenticated') facebook_data = facebook.facebook_profile_data() #either, login register or connect the user try: action, user = connect_user(request) logger.info('Django facebook performed action: %s', action) except facebook_exceptions.IncompleteProfileError, e: #show them a registration form to add additional data warning_format = u'Incomplete profile data encountered with error %s' warn_message = warning_format % e.message send_warning(warn_message, e=e, facebook_data=facebook_data) context['facebook_mode'] = True context['form'] = e.form return render_to_response( facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE, context_instance=context, ) if action is CONNECT_ACTIONS.CONNECT: #connect means an existing account was attached to facebook messages.info(request, _("You have connected your account " "to %s's facebook profile") % facebook_data['name']) elif action is CONNECT_ACTIONS.REGISTER: #hook for tying in specific post registration functionality response = backend.post_registration_redirect(request, user) return response else: if 'attempt' in request.GET: return next_redirect(request, next_key=['error_next', 'next'], additional_params=dict(fb_error_or_cancel=1)) else: logger.info('Facebook authentication needed for connect, ' \ 'raising an error') raise OpenFacebookException('please authenticate') #for CONNECT and LOGIN we simple redirect to the next page return next_redirect(request, default=facebook_settings.FACEBOOK_LOGIN_DEFAULT_REDIRECT)