def profile_authenticate(self, facebook_id=None, facebook_email=None): ''' Authenticate the facebook user by id OR facebook_email We filter using an OR to allow existing members to connect with their facebook ID using email. :param facebook_id: Optional string representing the facebook id :param facebook_email: Optional string with the facebook email :return: The signed in :class:`User`. ''' logger.info("PA01 Inside profile authentication") if facebook_id or facebook_email: profile_class = get_profile_model() logger.info("PA02 Profile class %s" % profile_class) profile_query = profile_class.objects.all().order_by('user') profile_query = profile_query.select_related('user') logger.info("PA03 Profile query %s" % profile_query) profile = None # filter on email or facebook id, two queries for better # queryplan with large data sets if facebook_id: profiles = profile_query.filter(facebook_id=facebook_id)[:1] logger.info("PA04 Profiles from facebook_id %s" % profiles) profile = profiles[0] if profiles else None logger.info("PA05 Profile %s" % profile) if profile is None and facebook_email: try: profiles = profile_query.filter( user__email__iexact=facebook_email)[:1] logger.info("PA06 Profiles from email %s" % profiles) profile = profiles[0] if profiles else None logger.info("PA07 Profile %s" % profile) except DatabaseError: logger.info("PA08 Database error") try: user = get_user_model( ).objects.get(email=facebook_email) logger.info("PA09 User from model %s" % user) except get_user_model().DoesNotExist: logger.info("PA10 No model") user = None profile = try_get_profile(user) if user else None logger.info("PA11 Profile %s" % profile) if profile: # populate the profile cache while we're getting it anyway user = profile.user logger.info("PA07 User from profile %s" % user) user._profile = profile if facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN: logger.info("UA10 Require user update") user.fb_update_required = True return user
def clean_username(self): """ Validate that the username is alphanumeric and is not already in use. """ try: get_user_model().objects.get( username__iexact=self.cleaned_data['username']) except get_user_model().DoesNotExist: return self.cleaned_data['username'] raise forms.ValidationError( _("A user with that username already exists."))
def test_follow_og_share_error(self): user_url = 'http://www.fashiolista.com/style/neni/' kwargs = dict(item=user_url) user = get_user_model().objects.all()[:1][0] profile = try_get_profile(user) user_or_profile = get_instance_for_attribute( user, profile, 'facebook_open_graph') user_or_profile.facebook_open_graph = True user_or_profile.save() some_content_type = ContentType.objects.all()[:1][0] share = OpenGraphShare.objects.create( user_id=user.id, facebook_user_id=13123123, action_domain='fashiolista:follow', content_type=some_content_type, object_id=user.id, ) share.set_share_dict(kwargs) share.save() update_user_attributes(user, profile, dict(new_token_required=False)) from open_facebook.exceptions import FacebookUnreachable, OAuthException with mock.patch('open_facebook.api.OpenFacebook') as mocked: instance = mocked.return_value instance.set = Mock(side_effect=FacebookUnreachable('broken')) share.send(graph=instance) self.assertEqual(share.error_message, 'broken') self.assertFalse(share.completed_at) user = get_user_model().objects.get(id=user.id) if profile: profile = get_profile_model().objects.get(id=profile.id) new_token_required = get_user_attribute( user, profile, 'new_token_required') self.assertEqual(new_token_required, False) # now try with an oauth exception return # Can't figure out how to test this with mock.patch('open_facebook.api.OpenFacebook') as mocked: instance = mocked.return_value instance.set = Mock(side_effect=OAuthException('permissions')) share.send(graph=instance) self.assertEqual(share.error_message, 'permissions') self.assertFalse(share.completed_at) user = get_user_model().objects.get(id=user.id) if profile: profile = get_profile_model().objects.get(id=profile.id) new_token_required = get_user_attribute( user, profile, 'new_token_required') self.assertEqual(new_token_required, True)
def create_profile(sender, instance, created, **kwargs): #Create a matching profile whenever a user object is created. if sender == get_user_model(): user = instance profile_model = get_profile_model() if profile_model == BotaniserProfile and created: profile, new = BotaniserProfile.objects.get_or_create(user=instance)
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=get_user_model()) 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') facebook = FacebookUserConverter(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 profile_or_self(self): user_or_profile_model = get_model_for_attribute('facebook_id') user_model = get_user_model() if user_or_profile_model == user_model: return self else: return self.get_profile()
def create_profile(sender, instance, created, **kwargs): """Create a matching profile whenever a user object is created.""" if sender == get_user_model(): user = instance profile_model = get_profile_model() if profile_model == MyCustomProfile and created: profile, new = MyCustomProfile.objects.get_or_create(user=instance)
def test_follow_og_share_error(self): from django_facebook.models import OpenGraphShare user_url = 'http://www.fashiolista.com/style/neni/' kwargs = dict(item=user_url) user = get_user_model().objects.all()[:1][0] profile = try_get_profile(user) user_or_profile = get_instance_for_attribute( user, profile, 'facebook_open_graph') user_or_profile.facebook_open_graph = True user_or_profile.save() from django.contrib.contenttypes.models import ContentType some_content_type = ContentType.objects.all()[:1][0] share = OpenGraphShare.objects.create( user_id=user.id, facebook_user_id=13123123, action_domain='fashiolista:follow', content_type=some_content_type, object_id=user.id, ) share.set_share_dict(kwargs) share.save() from open_facebook.exceptions import FacebookUnreachable with mock.patch('open_facebook.api.OpenFacebook') as mocked: instance = mocked.return_value instance.set = Mock(side_effect=FacebookUnreachable('broken')) share.send(graph=instance) self.assertEqual(share.error_message, 'broken') self.assertFalse(share.completed_at)
def setUp(self): from django_facebook.test_utils.mocks import MockFacebookAPI, MockFacebookAuthorization, RequestMock import sys import StringIO self.prints = sys.stdout = StringIO.StringIO() from open_facebook import api import open_facebook self.originalAPI = open_facebook.OpenFacebook self.originalAuthorization = open_facebook.FacebookAuthorization open_facebook.OpenFacebook = api.OpenFacebook = MockFacebookAPI open_facebook.FacebookAuthorization = api.FacebookAuthorization = MockFacebookAuthorization rf = RequestMock() self.request = rf.get('/') self.client = Client() # time to setup the test user user_model = get_user_model() user_dict = dict( username='******', is_staff=False, is_active=True, email="*****@*****.**", ) test_ip = '127.0.0.1' # hack to make fashiolista tests run ok if is_user_attribute('registration_ip'): user_dict['registration_ip'] = test_ip user_dict['last_login_ip'] = test_ip user_model.objects.create(**user_dict)
def profile_or_self(self): user_or_profile_model = get_model_for_attribute('facebook_id') user_model = get_user_model() if user_or_profile_model == user_model: return self else: return get_profile(self)
class FacebookProfile(FacebookProfileModel): ''' Not abstract version of the facebook profile model Use this by setting AUTH_PROFILE_MODULE = 'django_facebook.FacebookProfile' ''' user = models.OneToOneField(get_user_model())
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, user, profile, facebook_data, **kwargs): user.pre_update_signal = True def post_update(sender, user, profile, facebook_data, **kwargs): user.post_update_signal = True Profile = get_profile_model() user_model = get_user_model() signals.facebook_user_registered.connect( user_registered, sender=user_model) signals.facebook_pre_update.connect(pre_update, sender=user_model) signals.facebook_post_update.connect(post_update, sender=user_model) graph = get_facebook_graph(access_token='short_username') facebook = FacebookUserConverter(graph) user = _register_user(self.request, facebook) self.assertEqual(hasattr(user, 'registered_signal'), True) self.assertEqual(hasattr(user, 'pre_update_signal'), True) self.assertEqual(hasattr(user, 'post_update_signal'), True)
def test_follow_og_share_error(self): from django_facebook.models import OpenGraphShare user_url = 'http://www.fashiolista.com/style/neni/' kwargs = dict(item=user_url) user = get_user_model().objects.all()[:1][0] profile = user.get_profile() profile.facebook_open_graph = True profile.save() from django.contrib.contenttypes.models import ContentType love_content_type = ContentType.objects.get(app_label='auth', model='user') share = OpenGraphShare.objects.create( user_id=user.id, facebook_user_id=13123123, action_domain='fashiolista:follow', content_type=love_content_type, object_id=user.id, ) share.set_share_dict(kwargs) share.save() from open_facebook.exceptions import FacebookUnreachable with mock.patch('open_facebook.api.OpenFacebook') as mocked: instance = mocked.return_value instance.set = Mock(side_effect=FacebookUnreachable('broken')) share.send(graph=instance) self.assertEqual(share.error_message, 'broken') self.assertFalse(share.completed_at)
def user_authenticate(self, facebook_id=None, facebook_email=None): ''' Authenticate the facebook user by id OR facebook_email We filter using an OR to allow existing members to connect with their facebook ID using email. This decorator works with django's custom user model :param facebook_id: Optional string representing the facebook id. :param facebook_email: Optional string with the facebook email. :return: The signed in :class:`User`. ''' logger.info("UA01 Inside User Authenticate function") user_model = get_user_model() logger.info("UA02 User model %s" % user_model) if facebook_id or facebook_email: # match by facebook id or email auth_conditions = [] if facebook_id: logger.info("UA03 facebook id %s" % facebook_id) auth_conditions.append(Q(facebook_id=facebook_id)) if facebook_email: logger.info("UA04 facebook email %s" % facebook_email) auth_conditions.append(Q(email__iexact=facebook_email)) # or the operations auth_condition = reduce(operator.or_, auth_conditions) logger.info("UA05 Auth conditions %s" % auth_condition) # get the users in one query users = list(user_model.objects.filter(auth_condition)) logger.info("UA06 Users from query %s" % users) # id matches vs email matches id_matches = [u for u in users if u.facebook_id == facebook_id] email_matches = [u for u in users if u.facebook_id != facebook_id] logger.info("UA07 Id matches %s" % id_matches) logger.info("UA08 email model %s" % email_matches) # error checking if len(id_matches) > 1: raise ValueError( 'found multiple facebook id matches. this shouldnt be allowed, check your unique constraints. users found %s' % users) # give the right user user = None if id_matches: user = id_matches[0] logger.info("UA09 User matches from id %s" % user) elif email_matches: user = email_matches[0] logger.info("UA09 User matches from email %s" % user) if user and facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN: logger.info("UA10 Require user update") user.fb_update_required = True return user
def register(self, request, form=None, **kwargs): """ Create and immediately log in a new user. """ username, email, password = kwargs['username'], kwargs[ 'email'], kwargs['password1'] # Create user doesn't accept additional parameters, user_model = get_user_model() new_user = get_user_model( ).objects.create_user(username, email, password) signals.user_registered.send(sender=self.__class__, user=new_user, request=request) authenticated_user = self.authenticate(request, username, password) return authenticated_user
def clean_email(self): """ Validate that the supplied email address is unique for the site. """ if get_user_model().objects.filter(email__iexact=self.cleaned_data['email']): raise forms.ValidationError(_("This email address is already in use. Please supply a different email address.")) return self.cleaned_data['email']
def profile_authenticate(self, facebook_id=None, facebook_email=None): ''' Authenticate the facebook user by id OR facebook_email We filter using an OR to allow existing members to connect with their facebook ID using email. :param facebook_id: Optional string representing the facebook id :param facebook_email: Optional string with the facebook email :return: The signed in :class:`User`. ''' if facebook_id or facebook_email: profile_class = get_profile_model() profile_query = profile_class.objects.all().order_by('user') profile_query = profile_query.select_related('user') profile = None # filter on email or facebook id, two queries for better # queryplan with large data sets if facebook_id: profiles = profile_query.filter(facebook_id=facebook_id)[:1] profile = profiles[0] if profiles else None if profile is None and facebook_email: try: profiles = profile_query.filter( user__email__iexact=facebook_email)[:1] profile = profiles[0] if profiles else None except DatabaseError: try: user = get_user_model( ).objects.get(email=facebook_email) except get_user_model().DoesNotExist: user = None profile = user.get_profile() if user else None if profile: # populate the profile cache while we're getting it anyway user = profile.user user._profile = profile if facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN: user.fb_update_required = True return user
def profile_authenticate(self, facebook_id=None, facebook_email=None): ''' Authenticate the facebook user by id OR facebook_email We filter using an OR to allow existing members to connect with their facebook ID using email. :param facebook_id: Optional string representing the facebook id :param facebook_email: Optional string with the facebook email :return: The signed in :class:`User`. ''' if facebook_id or facebook_email: profile_class = get_profile_model() profile_query = profile_class.objects.all().order_by('user') profile_query = profile_query.select_related('user') profile = None # filter on email or facebook id, two queries for better # queryplan with large data sets if facebook_id: profiles = profile_query.filter(facebook_id=facebook_id)[:1] profile = profiles[0] if profiles else None if profile is None and facebook_email: try: profiles = profile_query.filter( user__email__iexact=facebook_email)[:1] profile = profiles[0] if profiles else None except DatabaseError: try: user = get_user_model().objects.get( email=facebook_email) except get_user_model().DoesNotExist: user = None profile = user.get_profile() if user else None if profile: # populate the profile cache while we're getting it anyway user = profile.user user._profile = profile if facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN: user.fb_update_required = True return user
def clean_email(self): """ Validate that the supplied email address is unique for the site. """ if get_user_model().objects.filter( email__iexact=self.cleaned_data['email']): user = get_user_model().objects.get( email__iexact=self.cleaned_data['email']) request = get_request() my_login(request, user) print("email already in use, logged in!") raise facebook_exceptions.AlreadyRegistered( _("This email address is already in use. Please supply a different email address." )) #raise forms.ValidationError(_( # "This email address is already in use. Please supply a different email address.")) return self.cleaned_data['email']
def clean_email(self): """ Validate that the supplied email address is unique for the site. """ if get_user_model().objects.filter(email__iexact=self.cleaned_data['email']): raise forms.ValidationError(_( "This email address is already in use. Please supply a different email address.")) return self.cleaned_data['email']
def test_connect(self): ''' Test if we can do logins django_facebook.connect.connect_user ''' user = get_user_model().objects.all()[:1][0] url = self.url # test registration flow from django_facebook.connect import connect_user with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?register=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('register', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) # user register next instead of next with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user)) as wrapped_connect: post_data = dict(access_token='short_username', register_next='%s?register=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('register', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) # test login with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.LOGIN, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('?loggggg=1', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) # test connect with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.CONNECT, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) assert '?loggggg=1' in response.redirect_chain[0][0] self.assertEqual(response.status_code, 200) # test connect from django_facebook import exceptions as facebook_exceptions profile_error = facebook_exceptions.IncompleteProfileError() profile_error.form = None with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user), side_effect=profile_error) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertEqual(response.status_code, 200) self.assertTrue(response.context) assert response.template.name in facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE or response.template.name == facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE
def register(self, request, form=None, **kwargs): """ Create and immediately log in a new user. """ if username_as_username_field(): username, email, password = kwargs["username"], kwargs["email"], kwargs["password1"] # Create user doesn't accept additional parameters, new_user = get_user_model().objects.create_user(username, email, password) username_field = username else: email, password = kwargs["email"], kwargs["password1"] # Create user doesn't accept additional parameters, new_user = get_user_model().objects.create_user(email, password) username_field = email signals.user_registered.send(sender=self.__class__, user=new_user, request=request) authenticated_user = self.authenticate(request, username_field, password) return authenticated_user
def create_profile(sender, instance, created, **kwargs): ''' Create a matching profile whenever a user object is created. ''' print '=======', sender,instance,created if sender == get_user_model(): user = instance profile_model = get_profile_model() if profile_model == STUserProfile and created: profile, new = STUserProfile.objects.get_or_create(user=instance)
def user_authenticate(self, facebook_id=None, facebook_email=None): ''' Authenticate the facebook user by id OR facebook_email We filter using an OR to allow existing members to connect with their facebook ID using email. This decorator works with django's custom user model :param facebook_id: Optional string representing the facebook id. :param facebook_email: Optional string with the facebook email. :return: The signed in :class:`User`. ''' logger.info('user_authenticate') user_model = get_user_model() if facebook_id or facebook_email: # match by facebook id or email auth_conditions = [] if facebook_id: auth_conditions.append(Q(profile__facebook_id=facebook_id)) if facebook_email: auth_conditions.append(Q(email__iexact=facebook_email)) # or the operations auth_condition = reduce(operator.or_, auth_conditions) # get the users in one query users = list(user_model.objects.filter(auth_condition)) # id matches vs email matches id_matches = [u for u in users if u.profile.facebook_id == facebook_id] email_matches = [u for u in users if u.profile.facebook_id != facebook_id] # error checking if len(id_matches) > 1: raise ValueError( 'found multiple facebook id matches. this shouldnt be allowed, check your unique constraints. users found %s' % users) # give the right user user = None if id_matches: user = id_matches[0] elif email_matches: user = email_matches[0] if user and facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN: user.fb_update_required = True if user: logger.info('returning user %s', user.username) return user
def test_update_access_token(self): request = RequestMock().get('/') request.session = {} request.user = AnonymousUser() graph = get_persistent_graph(request, access_token='paul') action, user = connect_user(self.request, facebook_graph=graph) first_user_id = user.id # new token required should start out as False profile = try_get_profile(user) new_token_required = get_user_attribute(user, profile, 'new_token_required') self.assertEqual(new_token_required, False) # we manually set it to true update_user_attributes(user, profile, dict(new_token_required=True), save=True) if profile: profile = get_profile_model().objects.get(id=profile.id) user = get_user_model().objects.get(id=user.id) new_token_required = get_user_attribute(user, profile, 'new_token_required') self.assertEqual(new_token_required, True) # another update should however set it back to False request.facebook = None graph = get_facebook_graph(request, access_token='paul2') logger.info('and the token is %s', graph.access_token) action, user = connect_user(self.request, facebook_graph=graph) user = get_user_model().objects.get(id=user.id) self.assertEqual(user.id, first_user_id) if profile: profile = get_profile_model().objects.get(id=profile.id) user = get_user_model().objects.get(id=user.id) new_token_required = get_user_attribute(user, profile, 'new_token_required') self.assertEqual(new_token_required, False)
def _create_unique_username(cls, base_username): ''' Check the database and add numbers to the username to ensure its unique ''' usernames = list(get_user_model().objects.filter( username__istartswith=base_username).values_list( 'username', flat=True)) usernames_lower = [str(u).lower() for u in usernames] username = str(base_username) i = 1 while base_username.lower() in usernames_lower: base_username = username + str(i) i += 1 return base_username
def _create_unique_username(cls, base_username): ''' Check the database and add numbers to the username to ensure its unique ''' usernames = list(get_user_model().objects.filter( username__istartswith=base_username).values_list('username', flat=True)) usernames_lower = [str(u).lower() for u in usernames] username = str(base_username) i = 1 while base_username.lower() in usernames_lower: base_username = username + str(i) i += 1 return base_username
def test_update_access_token(self): request = RequestMock().get('/') request.session = {} request.user = AnonymousUser() graph = get_persistent_graph(request, access_token='paul') action, user = connect_user(self.request, facebook_graph=graph) first_user_id = user.id # new token required should start out as False profile = try_get_profile(user) new_token_required = get_user_attribute( user, profile, 'new_token_required') self.assertEqual(new_token_required, False) # we manually set it to true update_user_attributes( user, profile, dict(new_token_required=True), save=True) if profile: profile = get_profile_model().objects.get(id=profile.id) user = get_user_model().objects.get(id=user.id) new_token_required = get_user_attribute( user, profile, 'new_token_required') self.assertEqual(new_token_required, True) # another update should however set it back to False request.facebook = None graph = get_facebook_graph(request, access_token='paul2') logger.info('and the token is %s', graph.access_token) action, user = connect_user(self.request, facebook_graph=graph) user = get_user_model().objects.get(id=user.id) self.assertEqual(user.id, first_user_id) if profile: profile = get_profile_model().objects.get(id=profile.id) user = get_user_model().objects.get(id=user.id) new_token_required = get_user_attribute( user, profile, 'new_token_required') self.assertEqual(new_token_required, False)
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
def test_follow_og_share(self): user_url = 'http://www.fashiolista.com/style/neni/' kwargs = dict(item=user_url) user = get_user_model().objects.all()[:1][0] from django.contrib.contenttypes.models import ContentType some_content_type = ContentType.objects.all()[:1][0] share = OpenGraphShare.objects.create( user_id=user.id, facebook_user_id=13123123, action_domain='fashiolista:follow', content_type=some_content_type, object_id=user.id, ) share.set_share_dict(kwargs) share.save() share.send()
def test_fb_update_required(self): def pre_update(sender, user, profile, facebook_data, **kwargs): user.pre_update_signal = True Profile = get_profile_model() user_model = get_user_model() signals.facebook_pre_update.connect(pre_update, sender=user_model) facebook = get_facebook_graph(access_token='tschellenbach') facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN = True action, user = connect_user(self.request, facebook_graph=facebook) self.assertEqual(action, CONNECT_ACTIONS.LOGIN) self.assertTrue(hasattr(user, 'pre_update_signal')) facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN = False action, user = connect_user(self.request, facebook_graph=facebook) self.assertEqual(action, CONNECT_ACTIONS.LOGIN) self.assertFalse(hasattr(user, 'pre_update_signal'))
def register(self, request, form=None, **kwargs): """ Create and immediately log in a new user. """ email = kwargs['email'] # Create user doesn't accept additional parameters, new_user = get_user_model( ).objects.create(email=email, username=email, password='') signals.user_registered.send(sender=self.__class__, user=new_user, request=request) # Create facebook user profile as we do not use special signal anymore FacebookUserProfile.objects.create(user=new_user) # Dirty fix to return user authenticated_user = new_user return authenticated_user
def _get_old_connections(facebook_id, current_user_id=None): """ Gets other accounts connected to this facebook id, which are not attached to the current user """ user_or_profile_model = get_model_for_attribute("facebook_id") other_facebook_accounts = user_or_profile_model.objects.filter(facebook_id=facebook_id) kwargs = {} if current_user_id: # if statement since we need to support both user_model = get_user_model() if user_or_profile_model == user_model: kwargs["id"] = current_user_id else: kwargs["user"] = current_user_id other_facebook_accounts = other_facebook_accounts.exclude(**kwargs) return other_facebook_accounts
class FacebookInvite(CreatedAtAbstractBase): user = models.ForeignKey(get_user_model()) user_invited = models.CharField(max_length=255) message = models.TextField(blank=True, null=True) type = models.CharField(blank=True, null=True, max_length=255) #status data wallpost_id = models.CharField(blank=True, null=True, max_length=255) error = models.BooleanField(default=False) error_message = models.TextField(blank=True, null=True) last_attempt = models.DateTimeField(blank=True, null=True, auto_now_add=True) #reminder data reminder_wallpost_id = models.CharField(blank=True, null=True, max_length=255) reminder_error = models.BooleanField(default=False) reminder_error_message = models.TextField(blank=True, null=True) reminder_last_attempt = models.DateTimeField(blank=True, null=True, auto_now_add=True) def __unicode__(self): message = 'user %s invited fb id %s' % (self.user, self.user_invited) return message def resend(self, graph=None): from django_facebook.invite import post_on_profile if not graph: graph = self.user.get_profile().get_offline_graph() if not graph: return facebook_id = self.user_invited invite_result = post_on_profile(self.user, graph, facebook_id, self.message, force_send=True) return invite_result class Meta: unique_together = ('user', 'user_invited')
def test_send(error, expected_error_message, expected_new_token, has_permissions=False): user, profile, share = self.share_details update_user_attributes( user, profile, dict(new_token_required=False), save=True) with mock.patch('open_facebook.api.OpenFacebook') as mocked: instance = mocked.return_value instance.set = Mock(side_effect=error) instance.has_permissions = Mock(return_value=has_permissions) instance.access_token = get_user_attribute( user, profile, 'access_token') share.send(graph=instance) self.assertEqual(share.error_message, expected_error_message) self.assertFalse(share.completed_at) user = get_user_model().objects.get(id=user.id) if profile: profile = get_profile_model().objects.get(id=profile.id) new_token_required = get_user_attribute( user, profile, 'new_token_required') self.assertEqual(new_token_required, expected_new_token)
def pre_save(self, obj): print 'trying to save a report....' species = self.request.DATA['name'] obj.species = Species.objects.get(name=species) obj.points = obj.species.calculate_score() obj.user = get_user_model().objects.get(username='******') lat = self.request.DATA['lat'] lon = self.request.DATA['lon'] obj.location = Location.objects.get_or_create(lat=lat, lon=lon)[0] print 'saved most things....' img_string = self.request.DATA['imageSrc'] img_data = img_string.decode("base64") filename = str(obj.species.name.replace(' ', '_')) + 'photo.jpg' img_file = open(filename, "wb") img_file.write(img_data) img_file.close() print 'after photo process' obj.photo = img_file print 'after photo...'
def _get_old_connections(facebook_id, current_user_id=None): ''' Gets other accounts connected to this facebook id, which are not attached to the current user ''' user_or_profile_model = get_model_for_attribute('facebook_id') other_facebook_accounts = user_or_profile_model.objects.filter( facebook_id=facebook_id) kwargs = {} if current_user_id: # if statement since we need to support both user_model = get_user_model() if user_or_profile_model == user_model: kwargs['id'] = current_user_id else: kwargs['user'] = current_user_id other_facebook_accounts = other_facebook_accounts.exclude(**kwargs) return other_facebook_accounts
def user_authenticate(self, facebook_id=None, facebook_email=None): ''' Authenticate the facebook user by id OR facebook_email We filter using an OR to allow existing members to connect with their facebook ID using email. This decorator works with django's custom user model ''' user_model = get_user_model() if facebook_id or facebook_email: # match by facebook id or email auth_conditions = [] if facebook_id: auth_conditions.append(Q(facebook_id=facebook_id)) if facebook_email: auth_conditions.append(Q(email__iexact=facebook_email)) # or the operations auth_condition = reduce(operator.or_, auth_conditions) # get the users in one query users = list(user_model.objects.filter(auth_condition)) # id matches vs email matches id_matches = [u for u in users if u.facebook_id == facebook_id] email_matches = [u for u in users if u.facebook_id != facebook_id] # error checking if len(id_matches) > 1: raise ValueError( 'found multiple facebook id matches. this shouldnt be allowed, check your unique constraints. users found %s' % users) # give the right user user = None if id_matches: user = id_matches[0] elif email_matches: user = email_matches[0] if user and facebook_settings.FACEBOOK_FORCE_PROFILE_UPDATE_ON_LOGIN: user.fb_update_required = True return user
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token = results['access_token'] old_token = self.access_token token_changed = access_token != old_token message = 'a new' if token_changed else 'the same' log_format = 'Facebook provided %s token, which expires at %s' expires_delta = timedelta(days=60) logger.info(log_format, message, expires_delta) if token_changed: logger.info('Saving the new access token') self.update_access_token(access_token) self.save() from django_facebook.signals import facebook_token_extend_finished facebook_token_extend_finished.send( sender=get_user_model(), user=self.get_user(), profile=self, token_changed=token_changed, old_token=old_token ) return results
def _extend_access_token(self, access_token): from open_facebook.api import FacebookAuthorization results = FacebookAuthorization.extend_access_token(access_token) access_token = results['access_token'] old_token = self.access_token token_changed = access_token != old_token message = 'a new' if token_changed else 'the same' log_format = 'Facebook provided %s token, which expires at %s' expires_delta = timedelta(days=60) logger.info(log_format, message, expires_delta) if token_changed: logger.info('Saving the new access token') self.access_token = access_token self.save() from django_facebook.signals import facebook_token_extend_finished facebook_token_extend_finished.send( sender=get_user_model(), user=self.get_user(), profile=self, token_changed=token_changed, old_token=old_token ) return results
def setUp(self): from django_facebook.test_utils.mocks import MockFacebookAPI, MockFacebookAuthorization, RequestMock import sys import io self.prints = sys.stdout = io.StringIO() from open_facebook import api import open_facebook self.originalAPI = open_facebook.OpenFacebook self.originalAuthorization = open_facebook.FacebookAuthorization open_facebook.OpenFacebook = api.OpenFacebook = MockFacebookAPI open_facebook.FacebookAuthorization = api.FacebookAuthorization = MockFacebookAuthorization rf = RequestMock() self.request = rf.get('/') self.client = Client() # time to setup the test user user_model = get_user_model() user_dict = dict( username='******', is_staff=False, is_active=True, email="*****@*****.**", ) test_ip = '127.0.0.1' # hack to make fashiolista tests run ok if is_user_attribute('registration_ip'): user_dict['registration_ip'] = test_ip user_dict['last_login_ip'] = test_ip user_model.objects.create(**user_dict) from django.conf import settings if getattr(settings, 'MODE', None) == 'userena': from django.core.management import call_command call_command('check_permissions', output=False)
def register(self, request, form=None, **kwargs): """ Create and immediately log in a new user. """ fullname = request.GET.get('fullname', '') first_name = fullname.split(' ')[0] last_name = (' ').join(fullname.split(' ')[1:]) username = email = request.GET.get('email', '') password = request.GET.get('password', '') # Create user doesn't accept additional parameters, new_user = get_user_model().objects.create_user(username, email, password) new_user.first_name = first_name new_user.last_name = last_name new_user.save() signals.user_registered.send(sender=self.__class__, user=new_user, request=request) # don't need to auto authenticate authenticated_user = self.authenticate(request, username, password) return authenticated_user
def setUp(self): FacebookTest.setUp(self) user_url = 'http://www.fashiolista.com/style/neni/' kwargs = dict(item=user_url) user = get_user_model().objects.all()[:1][0] profile = try_get_profile(user) user_or_profile = get_instance_for_attribute( user, profile, 'facebook_open_graph') user_or_profile.facebook_open_graph = True user_or_profile.save() some_content_type = ContentType.objects.all()[:1][0] share = OpenGraphShare.objects.create( user_id=user.id, facebook_user_id=13123123, action_domain='fashiolista:follow', content_type=some_content_type, object_id=user.id, ) share.set_share_dict(kwargs) share.save() self.share = share self.share_details = user, profile, share
def setUp(self): FacebookTest.setUp(self) user_url = 'http://www.fashiolista.com/style/neni/' kwargs = dict(item=user_url) user = get_user_model().objects.all()[:1][0] profile = try_get_profile(user) user_or_profile = get_instance_for_attribute(user, profile, 'facebook_open_graph') user_or_profile.facebook_open_graph = True user_or_profile.save() some_content_type = ContentType.objects.all()[:1][0] share = OpenGraphShare.objects.create( user_id=user.id, facebook_user_id=13123123, action_domain='fashiolista:follow', content_type=some_content_type, object_id=user.id, ) share.set_share_dict(kwargs) share.save() self.share = share self.share_details = user, profile, share
def _update_user(user, facebook, overwrite=True): ''' Updates the user and his/her profile with the data from facebook ''' # if you want to add fields to ur user model instead of the # profile thats fine # partial support (everything except raw_data and facebook_id is included) facebook_data = facebook.facebook_registration_data(username=False) facebook_fields = ['facebook_name', 'facebook_profile_url', 'gender', 'date_of_birth', 'about_me', 'website_url', 'first_name', 'last_name'] profile = try_get_profile(user) # which attributes to update attributes_dict = {} # send the signal that we're updating signals.facebook_pre_update.send(sender=get_user_model(), user=user, profile=profile, facebook_data=facebook_data) # set the facebook id and make sure we are the only user with this id current_facebook_id = get_user_attribute(user, profile, 'facebook_id') facebook_id_changed = facebook_data['facebook_id'] != current_facebook_id overwrite_allowed = overwrite or not current_facebook_id # update the facebook id and access token facebook_id_overwritten = False if facebook_id_changed and overwrite_allowed: # when not overwriting we only update if there is no # profile.facebook_id logger.info('profile facebook id changed from %s to %s', repr(facebook_data['facebook_id']), repr(current_facebook_id)) attributes_dict['facebook_id'] = facebook_data['facebook_id'] facebook_id_overwritten = True if facebook_id_overwritten: _remove_old_connections(facebook_data['facebook_id'], user.id) # update all fields on both user and profile for f in facebook_fields: facebook_value = facebook_data.get(f, False) current_value = get_user_attribute(user, profile, f, None) if facebook_value and not current_value: attributes_dict[f] = facebook_value # write the raw data in case we missed something serialized_fb_data = json.dumps(facebook.facebook_profile_data()) current_raw_data = get_user_attribute(user, profile, 'raw_data') if current_raw_data != serialized_fb_data: attributes_dict['raw_data'] = serialized_fb_data image_url = facebook_data['image'] # update the image if we are allowed and have to if facebook_settings.FACEBOOK_STORE_LOCAL_IMAGE: image_field = get_user_attribute(user, profile, 'image', True) if not image_field: image_name, image_file = _update_image( facebook_data['facebook_id'], image_url) image_field.save(image_name, image_file) # save both models if they changed update_user_attributes(user, profile, attributes_dict) if getattr(user, '_fb_is_dirty', False): user.save() if getattr(profile, '_fb_is_dirty', False): profile.save() signals.facebook_post_update.send(sender=get_user_model(), user=user, profile=profile, facebook_data=facebook_data) return user
def _register_user(request, facebook, profile_callback=None, remove_old_connections=False): ''' Creates a new user and authenticates The registration form handles the registration and validation Other data on the user profile is updates afterwards if remove_old_connections = True we will disconnect old profiles from their facebook flow ''' if not facebook.is_authenticated(): raise ValueError( 'Facebook needs to be authenticated for connect flows') # get the backend on new registration systems, or none # if we are on an older version backend = get_registration_backend() logger.info('running backend %s for registration', backend) # gets the form class specified in FACEBOOK_REGISTRATION_FORM form_class = get_form_class(backend, request) facebook_data = facebook.facebook_registration_data() data = request.POST.copy() for k, v in facebook_data.items(): if not data.get(k): data[k] = v if remove_old_connections: _remove_old_connections(facebook_data['facebook_id']) if request.POST.get('force_registration_hard') or \ request.GET.get('force_registration_hard'): data['email'] = data['email'].replace( '@', '+test%s@' % randint(0, 1000000000)) if not data['email']: data['email'] = '*****@*****.**' % data['username'] form = form_class(data=data, files=request.FILES, initial={'ip': request.META['REMOTE_ADDR']}) if not form.is_valid(): # show errors in sentry form_errors = form.errors error = facebook_exceptions.IncompleteProfileError( 'Facebook signup incomplete') error.form = form raise error try: # for new registration systems use the backends methods of saving new_user = None if backend: new_user = backend.register(request, form=form, **form.cleaned_data) # fall back to the form approach if new_user is None: raise ValueError( 'new_user is None, note that backward compatability for the older versions of django registration has been dropped.') except IntegrityError as e: # this happens when users click multiple times, the first request registers # the second one raises an error raise facebook_exceptions.AlreadyRegistered(e) # update some extra data not yet done by the form new_user = _update_user(new_user, facebook) signals.facebook_user_registered.send(sender=get_user_model(), user=new_user, facebook_data=facebook_data, request=request, converter=facebook) # IS this the correct way for django 1.3? seems to require the backend # attribute for some reason new_user.backend = 'django_facebook.auth_backends.FacebookBackend' auth.login(request, new_user) return new_user
# fall back to the form approach if new_user is None: # For backward compatibility, if django-registration form is used raise ValueError( 'new_user is None, note that backward compatability for the older versions of django registration has been dropped.' ) #try: #new_user = form.save(profile_callback=profile_callback) #except TypeError: #new_user = form.save() except IntegrityError, e: # this happens when users click multiple times, the first request registers # the second one raises an error raise facebook_exceptions.AlreadyRegistered(e) signals.facebook_user_registered.send(sender=get_user_model(), user=new_user, facebook_data=facebook_data, request=request) # update some extra data not yet done by the form new_user = _update_user(new_user, facebook) # IS this the correct way for django 1.3? seems to require the backend # attribute for some reason new_user.backend = 'django_facebook.auth_backends.FacebookBackend' auth.login(request, new_user) return new_user
def test_connect(self): ''' Test if we can do logins django_facebook.connect.connect_user ''' user = get_user_model().objects.all()[:1][0] url = reverse('facebook_connect') #see if the basics don't give errors response = self.client.get('%s?facebook_login=a' % url) self.assertEqual(response.status_code, 200) response = self.client.get('%s?facebook_login=0' % url) self.assertEqual(response.status_code, 200) response = self.client.get('%s?facebook_login='******'django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?register=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('register', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) #user register next instead of next with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user)) as wrapped_connect: post_data = dict(access_token='short_username', register_next='%s?register=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('register', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) #test login with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.LOGIN, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('?loggggg=1', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) #test connect with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.CONNECT, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) assert '?loggggg=1' in response.redirect_chain[0][0] self.assertEqual(response.status_code, 200) #test connect from django_facebook import exceptions as facebook_exceptions profile_error = facebook_exceptions.IncompleteProfileError() profile_error.form = None with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user), side_effect=profile_error) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % url, facebook_login=1) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertEqual(response.status_code, 200) self.assertTrue(response.context) assert response.template.name in facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE or response.template.name == facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE
def test_connect(self): ''' Test if we can do logins django_facebook.connect.connect_user ''' user = get_user_model().objects.all()[:1][0] url = self.url example_url = reverse('facebook_example') # test registration flow with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user)) as wrapped_connect: post_data = dict( access_token='short_username', next='%s?register=1' % example_url, ) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('register', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) # user register next instead of next with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user)) as wrapped_connect: post_data = dict(access_token='short_username', register_next='%s?register=1' % example_url) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('register', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) # test login with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.LOGIN, user)) as wrapped_connect: post_data = dict( access_token='short_username', next='%s?loggggg=1' % example_url, ) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertIn('?loggggg=1', response.redirect_chain[0][0]) self.assertEqual(response.status_code, 200) # test connect with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.CONNECT, user)) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % example_url) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) assert '?loggggg=1' in response.redirect_chain[0][0] self.assertEqual(response.status_code, 200) # test connect from django_facebook import exceptions as facebook_exceptions profile_error = facebook_exceptions.IncompleteProfileError() profile_error.form = None with patch('django_facebook.views.connect_user', return_value=(CONNECT_ACTIONS.REGISTER, user), side_effect=profile_error) as wrapped_connect: post_data = dict(access_token='short_username', next='%s?loggggg=1' % example_url) response = self.client.post(url, post_data, follow=True) self.assertEqual(wrapped_connect.call_count, 1) self.assertEqual(response.status_code, 200) self.assertTrue(response.context) template = self.get_response_template(response) backend = get_registration_backend() assert template.name in backend.get_registration_template()
def test_get_persistent(self): graph = get_persistent_graph(self.request) # fake that we are authenticated and have a facebook graph with patch.object(self.request, 'facebook'): self.request.user = get_user_model().objects.all()[:1][0] graph = get_persistent_graph(self.request)
def _update_user(user, facebook, overwrite=True): ''' Updates the user and his/her profile with the data from facebook ''' # if you want to add fields to ur user model instead of the # profile thats fine # partial support (everything except raw_data and facebook_id is included) facebook_data = facebook.facebook_registration_data(username=False) facebook_fields = [ 'facebook_name', 'facebook_profile_url', 'gender', 'date_of_birth', 'about_me', 'website_url', 'first_name', 'last_name' ] # prepare first_name and last_name name = facebook_data.get('name', ' ').split() if len(name): facebook_data['first_name'] = name[0] if len(name) > 1: facebook_data['last_name'] = ' '.join(name[1:]) facebook_data['facebook_profile_url'] = facebook_data.get('image') profile = try_get_profile(user) # which attributes to update attributes_dict = {} # send the signal that we're updating signals.facebook_pre_update.send(sender=get_user_model(), user=user, profile=profile, facebook_data=facebook_data) # set the facebook id and make sure we are the only user with this id current_facebook_id = get_user_attribute(user, profile, 'facebook_id') facebook_id_changed = facebook_data['facebook_id'] != current_facebook_id overwrite_allowed = overwrite or not current_facebook_id # update the facebook id and access token facebook_id_overwritten = False if facebook_id_changed and overwrite_allowed: # when not overwriting we only update if there is no # profile.facebook_id logger.info('profile facebook id changed from %s to %s', repr(facebook_data['facebook_id']), repr(current_facebook_id)) attributes_dict['facebook_id'] = facebook_data['facebook_id'] facebook_id_overwritten = True if facebook_id_overwritten: _remove_old_connections(facebook_data['facebook_id'], user.id) # update all fields on both user and profile for f in facebook_fields: facebook_value = facebook_data.get(f, False) current_value = get_user_attribute(user, profile, f, None) if facebook_value and not current_value: attributes_dict[f] = facebook_value # write the raw data in case we missed something serialized_fb_data = json.dumps(facebook.facebook_profile_data()) current_raw_data = get_user_attribute(user, profile, 'raw_data') if current_raw_data != serialized_fb_data: attributes_dict['raw_data'] = serialized_fb_data image_url = facebook_data['image'] # update the image if we are allowed and have to if facebook_settings.FACEBOOK_STORE_LOCAL_IMAGE: image_field = get_user_attribute(user, profile, 'image', True) if not image_field: image_name, image_file = _update_image( facebook_data['facebook_id'], image_url) image_field.save(image_name, image_file) # save both models if they changed update_user_attributes(user, profile, attributes_dict) if getattr(user, '_fb_is_dirty', False): user.save() if getattr(profile, '_fb_is_dirty', False): profile.save() signals.facebook_post_update.send(sender=get_user_model(), user=user, profile=profile, facebook_data=facebook_data) return user
invited = userList[0] prize = ConfigKey.get('INVITE_FRIENDS_TOKEN_PRIZE', 1000) invited.inviter.tokens_left += prize invited.inviter.save() tmp = {} tmp['invited_name'] = member.display_name() Notification.objects.create(recipient=invited.inviter, sender=None, notification_type='FriendJoined', message=json.dumps(tmp)) client.update_tokens(member) #add an event to the inviter, to show it the next time he logs in #TODO: change this to transport pubnub eventFriendInvitationAccepted = vo_factory.create_voFriendInvitationAccepted( prize, []) eventFriendInvitationAccepted['users'] = [ vo.User( facebook_data['facebook_id'], facebook_data['facebook_name'], "http://facebook.com/%s" % str(facebook_data['facebook_id']), facebook_data['image_thumb']) ] eventList = vo.EventList() eventList.append(eventFriendInvitationAccepted) invited.inviter.setSession('event', eventList) signals.facebook_user_registered.connect(fb_user_registered_handler, sender=get_user_model())
def _register_user(request, facebook, profile_callback=None, remove_old_connections=False): ''' Creates a new user and authenticates The registration form handles the registration and validation Other data on the user profile is updates afterwards if remove_old_connections = True we will disconnect old profiles from their facebook flow ''' if not facebook.is_authenticated(): raise ValueError( 'Facebook needs to be authenticated for connect flows') # get the backend on new registration systems, or none # if we are on an older version backend = get_registration_backend() logger.info('running backend %s for registration', backend) # gets the form class specified in FACEBOOK_REGISTRATION_FORM form_class = get_form_class(backend, request) facebook_data = facebook.facebook_registration_data() data = request.POST.copy() for k, v in facebook_data.items(): if not data.get(k): data[k] = v if remove_old_connections: _remove_old_connections(facebook_data['facebook_id']) if request.POST.get('force_registration_hard') or \ request.GET.get('force_registration_hard'): data['email'] = data['email'].replace( '@', '+test%s@' % randint(0, 1000000000)) if not data.get('email'): data['email'] = '*****@*****.**' % data['username'] form = form_class(data=data, files=request.FILES, initial={'ip': request.META['REMOTE_ADDR']}) if not form.is_valid(): # show errors in sentry form_errors = form.errors error = facebook_exceptions.IncompleteProfileError( 'Facebook signup incomplete') error.form = form raise error try: # for new registration systems use the backends methods of saving new_user = None if backend: new_user = backend.register(request, form=form, **form.cleaned_data) # fall back to the form approach if new_user is None: raise ValueError( 'new_user is None, note that backward compatability for the older versions of django registration has been dropped.' ) except IntegrityError as e: # this happens when users click multiple times, the first request registers # the second one raises an error raise facebook_exceptions.AlreadyRegistered(e) # update some extra data not yet done by the form new_user = _update_user(new_user, facebook) signals.facebook_user_registered.send(sender=get_user_model(), user=new_user, facebook_data=facebook_data, request=request, converter=facebook) # IS this the correct way for django 1.3? seems to require the backend # attribute for some reason new_user.backend = 'django_facebook.auth_backends.FacebookBackend' auth.login(request, new_user) return new_user
'remove_og_share', name='facebook_remove_og_share'), ) # when developing enable the example views if settings.DEBUG: # only enable example views while developing urlpatterns += dev_patterns # help autodiscovery a bit from django_facebook import admin # putting this here instead of models.py reduces issues with import ordering if getattr(settings, 'AUTH_PROFILE_MODULE', None) == 'django_facebook.FacebookProfile': ''' If we are using the django facebook profile model, create the model and connect it to the user create signal ''' from django.db.models.signals import post_save from django_facebook.models import FacebookProfile from django_facebook.utils import get_user_model # Make sure we create a FacebookProfile when creating a User def create_facebook_profile(sender, instance, created, **kwargs): if created: FacebookProfile.objects.create(user=instance) post_save.connect(create_facebook_profile, sender=get_user_model())
class OpenGraphShare(BaseModel): ''' Object for tracking all shares to Facebook Used for statistics and evaluating how things are going I recommend running this in a task Example usage: from user.models import OpenGraphShare user = UserObject url = 'http://www.fashiolista.com/' kwargs = dict(list=url) share = OpenGraphShare.objects.create( user = user, action_domain='fashiolista:create', content_object=self, ) share.set_share_dict(kwargs) share.save() result = share.send() Advanced usage: share.send() share.update(message='Hello world') share.remove() share.retry() Using this model has the advantage that it allows us to - remove open graph shares (since we store the Facebook id) - retry open graph shares, which is handy in case of - updated access tokens (retry all shares from this user in the last facebook_settings.FACEBOOK_OG_SHARE_RETRY_DAYS) - Facebook outages (Facebook often has minor interruptions, retry in 15m, for max facebook_settings.FACEBOOK_OG_SHARE_RETRIES) ''' objects = model_managers.OpenGraphShareManager() user = models.ForeignKey(get_user_model()) #domain stores action_domain = models.CharField(max_length=255) facebook_user_id = models.BigIntegerField() #what we are sharing, dict and object share_dict = models.TextField(blank=True, null=True) content_type = models.ForeignKey(ContentType, blank=True, null=True) object_id = models.PositiveIntegerField(blank=True, null=True) content_object = generic.GenericForeignKey('content_type', 'object_id') #completion data error_message = models.TextField(blank=True, null=True) last_attempt = models.DateTimeField(blank=True, null=True, auto_now_add=True) retry_count = models.IntegerField(blank=True, null=True) #only written if we actually succeed share_id = models.CharField(blank=True, null=True, max_length=255) completed_at = models.DateTimeField(blank=True, null=True) #tracking removals removed_at = models.DateTimeField(blank=True, null=True) #updated at and created at, last one needs an index updated_at = models.DateTimeField(auto_now=True) created_at = models.DateTimeField(auto_now_add=True, db_index=True) class Meta: db_table = facebook_settings.FACEBOOK_OG_SHARE_DB_TABLE def save(self, *args, **kwargs): if self.user and not self.facebook_user_id: self.facebook_user_id = self.user.get_profile().facebook_id return BaseModel.save(self, *args, **kwargs) def send(self, graph=None): result = None #update the last attempt self.last_attempt = datetime.now() self.save() #see if the graph is enabled profile = self.user.get_profile() graph = graph or profile.get_offline_graph() user_enabled = profile.facebook_open_graph and self.facebook_user_id #start sharing if graph and user_enabled: graph_location = '%s/%s' % (self.facebook_user_id, self.action_domain) share_dict = self.get_share_dict() from open_facebook.exceptions import OpenFacebookException try: result = graph.set(graph_location, **share_dict) share_id = result.get('id') if not share_id: error_message = 'No id in Facebook response, found %s for url %s with data %s' % ( result, graph_location, share_dict) logger.error(error_message) raise OpenFacebookException(error_message) self.share_id = share_id self.error_message = None self.completed_at = datetime.now() self.save() except OpenFacebookException, e: logger.warn('Open graph share failed, writing message %s' % e.message) self.error_message = unicode(e) self.save() elif not graph: self.error_message = 'no graph available' self.save()