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
Exemple #2
0
    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."))
Exemple #3
0
    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)
Exemple #5
0
    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)
Exemple #6
0
 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()
Exemple #7
0
 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)
Exemple #8
0
    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)
Exemple #10
0
 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)
Exemple #11
0
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())
Exemple #12
0
    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)
Exemple #13
0
    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
Exemple #15
0
    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
Exemple #16
0
 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
Exemple #18
0
    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
Exemple #19
0
 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']
Exemple #20
0
 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']
Exemple #21
0
    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
Exemple #23
0
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
Exemple #25
0
    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)
Exemple #26
0
 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
Exemple #27
0
 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
Exemple #28
0
    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)
Exemple #29
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
Exemple #30
0
 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()
Exemple #31
0
 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()
Exemple #32
0
    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'))
Exemple #33
0
    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
Exemple #36
0
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')
Exemple #37
0
 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)
Exemple #38
0
 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...'
Exemple #39
0
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
Exemple #40
0
 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 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
Exemple #42
0
    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
Exemple #43
0
    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
Exemple #44
0
    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)
Exemple #45
0
    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
Exemple #46
0
    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
Exemple #47
0
    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
Exemple #50
0
        # 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

Exemple #51
0
    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
Exemple #52
0
    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()
Exemple #53
0
 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)
Exemple #54
0
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
Exemple #55
0
        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())
Exemple #56
0
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
Exemple #57
0
        '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())
Exemple #58
0
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()