Ejemplo n.º 1
0
    def test_check_connect_facebook(self):
        graph = get_facebook_graph(access_token='new_user')
        facebook = FacebookUserConverter(graph)
        data = facebook.facebook_registration_data()
        self.assertEqual(data['gender'], 'm')

        response = self.client.get(reverse('login:index'))
Ejemplo n.º 2
0
    def connect_user(self):
        """Main functionality
        """

        #TODO, instead of using access_token this should probably accept a facebook_graph as well
        user = None
        facebook = self.facebook_graph or get_facebook_graph(self.request, self.access_token)
        assert facebook.is_authenticated(), 'Facebook not authenticated'

        facebook_user_converter = FacebookUserConverter(facebook)

        facebook_data = facebook_user_converter.facebook_profile_data()

        force_registration = self.request.REQUEST.get('force_registration') or self.request.REQUEST.get('force_registration_hard')

        logger.debug('force registration is set to %s', force_registration)
        if self.request.user.is_authenticated() and not force_registration:
            action = CONNECT_ACTIONS.CONNECT
            user = self._connect_user(facebook)
        else:
            email = facebook_data.get('email', False)
            email_verified = facebook_data.get('verified', False)
            kwargs = {}
            if email and email_verified:
                kwargs = {'facebook_email': email}
            authenticated_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
            if authenticated_user and not force_registration:
                action = CONNECT_ACTIONS.LOGIN

                ## Has the user registered without Facebook, using the verified FB email address?
                # It is after all quite common to use email addresses for usernames
                if not authenticated_user.get_profile().facebook_id:
                    update = True
                else:
                    update = getattr(authenticated_user, 'fb_update_required', False)
                user = self._login_user(facebook, authenticated_user, update=update)
            else:
                action = CONNECT_ACTIONS.REGISTER
                user = self._register_user(facebook)

        #store likes and friends if configured
        sid = transaction.savepoint()
        try:
            if facebook_settings.FACEBOOK_STORE_LIKES:
                likes = facebook.get_likes()
                facebook.store_likes(user, likes)
            if facebook_settings.FACEBOOK_STORE_FRIENDS:
                friends = facebook.get_friends()
                facebook.store_friends(user, friends)
            transaction.savepoint_commit(sid)
        except IntegrityError, e:
            logger.warn(u'Integrity error encountered during registration, probably a double submission %s' % e, 
                exc_info=sys.exc_info(), extra={
                'request': request,
                'data': {
                     'body': unicode(e),
                 }
            })

            transaction.savepoint_rollback(sid)
Ejemplo n.º 3
0
def build_graph_view(request, graph):
    if graph: 
        try:
            graph.is_authenticated()
        except:
            update_connection(request,graph)
        user = FacebookUserConverter(graph)
        friends = user.get_friends()
        friend_requests = [
            u'me/mutualfriends/{0}'.format(friend['id']) 
            for friend in friends
        ]
        mutual_friends = []
        batch_size = 50
        batches = defaultdict(list)
        for i,friend_request in enumerate(friend_requests):
            batch_request = {
                'method': 'GET','relative_url':friend_request
            }
            batches[i/batch_size].append(batch_request)
        counter = 0 
        for batch in batches.values():
            batch = json.dumps(batch)
            responses = graph.request(
                "", post_data = {'batch':batch}, fields='id'
            )
            mutual_friends += responses
            print counter, 'success'
            counter += 1
        print len(mutual_friends)
        json_data = process_fb_response(friends, mutual_friends, graph)
    else:
        return HttpResponse('Error')
    return HttpResponse(json_data, mimetype='text/javascript')
Ejemplo n.º 4
0
def _connect(request, facebook_login):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    backend = get_registration_backend()
    context = RequestContext(request)

    if facebook_login:
        logger.info('trying to connect using Facebook')
        graph = require_persistent_graph(request)
        authenticated = False
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)
            authenticated = facebook.is_authenticated()

            if authenticated:
                logger.info('Facebook is authenticated')
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    #show them a registration form to add additional data
                    warning_format = u'Incomplete profile data encountered with error %s'
                    warn_message = warning_format % e.message
                    send_warning(warn_message, e=e,
                                 facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )
                except facebook_exceptions.AlreadyConnectedError, e:
                    user_ids = [u.id for u in e.users]
                    ids_string = ','.join(map(str, user_ids))
                    return error_next_redirect(
                        request,
                        additional_params=dict(already_connected=ids_string))

                if action is CONNECT_ACTIONS.CONNECT:
                    #connect means an existing account was attached to facebook
                    messages.info(request, _("You have connected your account "
                                             "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    #hook for tying in specific post registration functionality
                    response = backend.post_registration_redirect(
                        request, user)
                    #compatibility for Django registration backends which return redirect tuples instead of a response
                    if not isinstance(response, HttpResponse):
                        to, args, kwargs = response
                        response = redirect(to, *args, **kwargs)
                    return response
Ejemplo n.º 5
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    '''
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or\
        request.REQUEST.get('force_registration_hard')

    connect_facebook = to_bool(request.REQUEST.get('connect_facebook'))

    logger.debug('force registration is set to %s', force_registration)
    if connect_facebook and request.user.is_authenticated() and not force_registration:
        #we should only allow connect if users indicate they really want to connect
        #only when the request.CONNECT_FACEBOOK = 1
        #if this isn't present we just do a login
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            update = getattr(auth_user, 'fb_update_required', False)
            if not auth_user.get_profile().facebook_id:
                update = True
            #login the user
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            # when force registration is active we should remove the old profile
            try:
                user = _register_user(request, facebook,
                                      remove_old_connections=force_registration)
            except facebook_exceptions.AlreadyRegistered, e:
                #in Multithreaded environments it's possible someone beats us to
                #the punch, in that case just login
                logger.info('parallel register encountered, slower thread is doing a login')
                auth_user = authenticate(
                    facebook_id=facebook_data['id'], **kwargs)
                action = CONNECT_ACTIONS.LOGIN
                user = _login_user(request, facebook, auth_user, update=False)
Ejemplo n.º 6
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    backend = get_registration_backend()
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))
    
    if facebook_login:
        logger.info('trying to connect using facebook')
        graph = require_persistent_graph(request)
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)
            
            if facebook.is_authenticated():
                logger.info('facebook is authenticated')
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    #show them a registration form to add additional data
                    warning_format = u'Incomplete profile data encountered with error %s'
                    warn_message = warning_format % e.message
                    send_warning(warn_message, e=e,
                                 facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )
                except facebook_exceptions.AlreadyConnectedError, e:
                    user_ids = [u.id for u in e.users]
                    ids_string = ','.join(map(str, user_ids))
                    return next_redirect(request, next_key=['error_next', 'next'],
                        additional_params=dict(already_connected=ids_string))

                if action is CONNECT_ACTIONS.CONNECT:
                    #connect means an existing account was attached to facebook
                    messages.info(request, _("You have connected your account "
                        "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    #hook for tying in specific post registration functionality
                    response = backend.post_registration_redirect(request, user)
                    #compatability for django registration backends which return tuples instead of a response
                    #alternatively we could wrap django registration backends, but that would be hard to understand
                    response = response if isinstance(response, HttpResponse) else redirect(response)
                    return response
Ejemplo n.º 7
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    backend = get_registration_backend()
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))
    
    if facebook_login:
        require_persistent_graph(request)
        logger.info('trying to connect using facebook')
        graph = get_persistent_graph(request)
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)
            
            if facebook.is_authenticated():
                logger.info('facebook is authenticated')
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    warn_message = u'Incomplete profile data encountered '\
                        u'with error %s' % e.message.decode('utf-8', 'replace')
                    send_warning(warn_message, e=e,
                                 facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    messages.info(request, _("You have connected your account "
                        "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    response = backend.post_registration_redirect(request, user)
                    return response
        else:
            if 'attempt' in request.GET:
                return next_redirect(request, next_key=['error_next', 'next'],
                    additional_params=dict(fb_error_or_cancel=1))
            else:
                logger.info('Facebook authentication needed for connect, ' \
                            'raising an error')
                raise OpenFacebookException('please authenticate')

        return next_redirect(request)
Ejemplo n.º 8
0
def test_open_facebook(request):
    from django_facebook.api import FacebookUserConverter

    fb = get_persistent_graph(request)

    instace = FacebookUserConverter(fb)

    #Get Friends
    return HttpResponse(instace.get_friends())
Ejemplo n.º 9
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    '''
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or\
        request.REQUEST.get('force_registration_hard')
        
    connect_facebook = bool(int(request.REQUEST.get('connect_facebook', 0)))

    logger.debug('force registration is set to %s', force_registration)
    if connect_facebook and request.user.is_authenticated() and not force_registration:
        #we should only allow connect if users indicate they really want to connect
        #only when the request.CONNECT_FACEBOOK = 1
        #if this isn't present we just do a login   
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN
            

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            if not auth_user.get_profile().facebook_id:
                update = True
            else:
                update = getattr(auth_user, 'fb_update_required', False)
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            # when force registration is active we should clearout
            # the old profile
            user = _register_user(request, facebook,
                                  remove_old_connections=force_registration)
            
    _update_likes_and_friends(request, user, facebook)

    _update_access_token(user, graph)
    
    return action, user
Ejemplo n.º 10
0
def test_open_facebook(request):
    from django_facebook.api import FacebookUserConverter

    fb = get_persistent_graph(request)

    instace = FacebookUserConverter(fb)

    # Get Friends
    return HttpResponse(instace.get_friends())
Ejemplo n.º 11
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    #test code time to remove
    uri = 'http://%s%s?facebook_login=1' % (request.META['HTTP_HOST'],
            request.path)
    if request.GET.get('redirect'):
        return facebook_login_required(uri, scope='read_stream')
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))

    if facebook_login:
        graph = get_facebook_graph(request)
        if graph:
            facebook = FacebookUserConverter(graph)
            if facebook.is_authenticated():
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                except facebook_exceptions.IncompleteProfileError, e:
                    warn_message = u'Incomplete profile data encountered '\
                        'with error %s' % e
                    logger.warn(warn_message,
                        exc_info=sys.exc_info(), extra={
                        'request': request,
                        'data': {
                             'username': request.user.username,
                             'facebook_data': facebook.facebook_profile_data(),
                             'body': unicode(e),
                         }
                    })

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        'registration/registration_form.html',
                        context_instance=context,
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    messages.info(request, _("You have connected your account "
                        "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    return user.get_profile().post_facebook_registration(request)
        else:
            return next_redirect(request, next_key=['error_next', 'next'],
                additional_params=dict(fb_error_or_cancel=1))

        return next_redirect(request)
Ejemplo n.º 12
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    '''
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or\
        request.REQUEST.get('force_registration_hard')

    connect_facebook = bool(int(request.REQUEST.get('connect_facebook', 0)))

    logger.debug('force registration is set to %s', force_registration)
    if connect_facebook and request.user.is_authenticated() and not force_registration:
        #we should only allow connect if users indicate they really want to connect
        #only when the request.CONNECT_FACEBOOK = 1
        #if this isn't present we just do a login   
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            if not auth_user.get_profile().facebook_id:
                update = True
            else:
                update = getattr(auth_user, 'fb_update_required', False)
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            # when force registration is active we should clearout
            # the old profile
            user = _register_user(request, facebook,
                                  remove_old_connections=force_registration)

    _update_likes_and_friends(request, user, facebook)

    _update_access_token(user, graph)

    return action, user
Ejemplo n.º 13
0
    def _register_user(self, facebook, profile_callback=None):
        '''
        Creates a new user and authenticates
        The registration form handles the registration and validation
        Other data on the user profile is updates afterwards
        '''
        if not facebook.is_authenticated():
            raise ValueError, 'Facebook needs to be authenticated for connect flows'

        facebook_user_converter = FacebookUserConverter(facebook)

        from registration.forms import RegistrationFormUniqueEmail
        #get the backend on new registration systems, or none if we are on an older version
        backend = get_registration_backend()

        #get the form used for registration and fall back to uniqueemail version
        form_class = RegistrationFormUniqueEmail
        if backend:
            form_class = backend.get_form_class(request)

        facebook_data = facebook_user_converter.facebook_registration_data()

        data = self.request.POST.copy()
        for k, v in facebook_data.items():
            if not data.get(k):
                data[k] = v

        if self.request.REQUEST.get('force_registration_hard'):
            data['email'] = data['email'].replace('@',
                                                  '+%s@' % randint(0, 100000))

        form = form_class(data=data,
                          files=self.request.FILES,
                          initial={'ip': self.request.META['REMOTE_ADDR']})

        if not form.is_valid():
            error = facebook_exceptions.IncompleteProfileError(
                'Facebook data %s gave error %s' %
                (facebook_data, form.errors))
            error.form = form
            raise error

        #for new registration systems use the backends methods of saving
        if backend:
            new_user = backend.register(request, **form.cleaned_data)
        else:
            new_user = form.save(profile_callback=profile_callback)

        #update some extra data not yet done by the form
        new_user = self._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(self.request, new_user)

        return new_user
Ejemplo n.º 14
0
def retrieve_friends(request, field='uid'):
    try:
        open_graph = get_persistent_graph(request)
        converter = FacebookUserConverter(open_graph)
        friends = converter.get_friends()
        friends_data = [u[field] for u in friends]
        return friends_data
    except Exception as e:
        return []
        print e
Ejemplo n.º 15
0
 def create(self, request, **kwargs):
     user = None
     access_token = request.DATA.get('access_token', None)
     graph = get_facebook_graph(request, access_token)
     facebook = FacebookUserConverter(graph)
     try:
         assert facebook.is_authenticated()
     except OAuthException, ex:
         return Response({"error": ex.message},
                         status=status.HTTP_401_UNAUTHORIZED)
Ejemplo n.º 16
0
def retrieve_friends_dict(request):
    try:
        open_graph = get_persistent_graph(request)
        converter = FacebookUserConverter(open_graph)
        friends = converter.get_friends()
        friends_data = {u['name'].strip().upper(): u['uid'] for u in friends}
        return friends_data
    except Exception as e:
        return {}
        print e
Ejemplo n.º 17
0
def connect(request):
    """
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    """
    context = RequestContext(request)

    assert context.get("FACEBOOK_APP_ID"), (
        "Please specify a facebook app id " "and ensure the context processor is enabled"
    )
    facebook_login = bool(int(request.REQUEST.get("facebook_login", 0)))

    if facebook_login:
        # code to redirect if we don't have adequate permissions
        from django_facebook.utils import test_permissions

        scope_list = facebook_settings.FACEBOOK_DEFAULT_SCOPE
        # standardizing the url to prevent things like attempt from being included
        redirect_uri = request.build_absolute_uri(request.path) + "?facebook_login=1"
        oauth_url, redirect_uri = get_oauth_url(request, scope_list, redirect_uri=redirect_uri)
        if not test_permissions(request, scope_list, redirect_uri):
            return HttpResponseRedirect(oauth_url)

        graph = get_persistent_graph(request)
        if graph:
            facebook = FacebookUserConverter(graph)
            if facebook.is_authenticated():
                facebook_data = facebook.facebook_profile_data()
                # either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info("Django facebook, action was %s", action)
                except facebook_exceptions.IncompleteProfileError, e:
                    warn_message = u"Incomplete profile data encountered " u"with error %s" % e
                    send_warning(warn_message, e=e, facebook_data=facebook.facebook_profile_data())

                    context["facebook_mode"] = True
                    context["form"] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE, context_instance=context
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    messages.info(
                        request,
                        _("You have connected your account " "to %s's facebook profile") % facebook_data["name"],
                    )
                elif action is CONNECT_ACTIONS.REGISTER:
                    return user.get_profile().post_facebook_registration(request)
        else:
            return next_redirect(request, next_key=["error_next", "next"], additional_params=dict(fb_error_or_cancel=1))

        return next_redirect(request)
Ejemplo n.º 18
0
def connect_user(request, access_token=None, facebook_graph=None):
    """
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    """
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get("force_registration") or request.REQUEST.get("force_registration_hard")

    logger.debug("force registration is set to %s", force_registration)
    if request.user.is_authenticated() and not force_registration:
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get("email", False)
        email_verified = facebook_data.get("verified", False)
        kwargs = {}
        if email and email_verified:
            kwargs = {"facebook_email": email}
        auth_user = authenticate(facebook_id=facebook_data["id"], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            if not auth_user.get_profile().facebook_id:
                update = True
            else:
                update = getattr(auth_user, "fb_update_required", False)
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            user = _register_user(request, facebook)

    # store likes and friends if configured
    sid = transaction.savepoint()
    try:
        if facebook_settings.FACEBOOK_STORE_LIKES:
            likes = facebook.get_likes()
            facebook.store_likes(user, likes)
        if facebook_settings.FACEBOOK_STORE_FRIENDS:
            friends = facebook.get_friends()
            facebook.store_friends(user, friends)
        transaction.savepoint_commit(sid)
    except IntegrityError, e:
        logger.warn(
            u"Integrity error encountered during registration, " "probably a double submission %s" % e,
            exc_info=sys.exc_info(),
            extra={"request": request, "data": {"body": unicode(e)}},
        )
        transaction.savepoint_rollback(sid)
Ejemplo n.º 19
0
 def test_gender_matching(self):
     request = RequestMock().get('/')
     request.session = {}
     request.user = AnonymousUser()
     graph = get_persistent_graph(request, access_token='paul')
     converter = FacebookUserConverter(graph)
     base_data = converter.facebook_profile_data()
     self.assertEqual(base_data['gender'], 'male')
     data = converter.facebook_registration_data()
     self.assertEqual(data['gender'], 'm')
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(user.get_profile().gender, 'm')
Ejemplo n.º 20
0
 def test_long_username(self):
     request = RequestMock().get('/')
     request.session = {}
     request.user = AnonymousUser()
     graph = get_persistent_graph(request, access_token='long_username')
     converter = FacebookUserConverter(graph)
     base_data = converter.facebook_registration_data()
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(len(base_data['username']), 30)
     self.assertEqual(len(user.username), 30)
     self.assertEqual(len(user.first_name), 30)
     self.assertEqual(len(user.last_name), 30)
Ejemplo n.º 21
0
 def test_gender_matching(self):
     request = RequestMock().get('/')
     request.session = {}
     request.user = AnonymousUser()
     graph = get_persistent_graph(request, access_token='paul')
     converter = FacebookUserConverter(graph)
     base_data = converter.facebook_profile_data()
     self.assertEqual(base_data['gender'], 'male')
     data = converter.facebook_registration_data()
     self.assertEqual(data['gender'], 'm')
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(user.get_profile().gender, 'm')
Ejemplo n.º 22
0
 def test_long_username(self):
     request = RequestMock().get('/')
     request.session = {}
     request.user = AnonymousUser()
     graph = get_persistent_graph(request, access_token='long_username')
     converter = FacebookUserConverter(graph)
     base_data = converter.facebook_registration_data()
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(len(base_data['username']), 30)
     self.assertEqual(len(user.username), 30)
     self.assertEqual(len(user.first_name), 30)
     self.assertEqual(len(user.last_name), 30)
Ejemplo n.º 23
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))

    if facebook_login:
        logger.info('trying to connect using facebook')
        graph = get_persistent_graph(request)
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)
            if facebook.is_authenticated():
                logger.info('facebook is authenticated')
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    warn_message = u'Incomplete profile data encountered '\
                        u'with error %s' % e
                    send_warning(warn_message, e=e, facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    messages.info(request, _("You have connected your account "
                        "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    return user.get_profile().post_facebook_registration(request)
        else:
            if 'attempt' in request.GET:
                return next_redirect(request, next_key=['error_next', 'next', 'redirect_url'],
                    additional_params=dict(fb_error_or_cancel=1))
            else:
                logger.info('Facebook authentication needed for connect, raising an error')
                raise OpenFacebookException('please authenticate')

        return next_redirect(request)
Ejemplo n.º 24
0
    def _register_user(self, facebook, profile_callback=None):
        '''
        Creates a new user and authenticates
        The registration form handles the registration and validation
        Other data on the user profile is updates afterwards
        '''
        if not facebook.is_authenticated():
            raise ValueError, 'Facebook needs to be authenticated for connect flows'

        facebook_user_converter = FacebookUserConverter(facebook)

        from registration.forms import RegistrationFormUniqueEmail
        #get the backend on new registration systems, or none if we are on an older version
        backend = get_registration_backend()

        #get the form used for registration and fall back to uniqueemail version
        form_class = RegistrationFormUniqueEmail
        if backend:
            form_class = backend.get_form_class(request)
            
        facebook_data = facebook_user_converter.facebook_registration_data()

        data = self.request.POST.copy()
        for k, v in facebook_data.items():
            if not data.get(k):
                data[k] = v

        if self.request.REQUEST.get('force_registration_hard'):
            data['email'] = data['email'].replace('@', '+%s@' % randint(0, 100000))

        form = form_class(data=data, files=self.request.FILES,
            initial={'ip': self.request.META['REMOTE_ADDR']})

        if not form.is_valid():
            error = facebook_exceptions.IncompleteProfileError('Facebook data %s gave error %s' % (facebook_data, form.errors))
            error.form = form
            raise error

        #for new registration systems use the backends methods of saving
        if backend:
            new_user = backend.register(request, **form.cleaned_data)
        else:
            new_user = form.save(profile_callback=profile_callback)

        #update some extra data not yet done by the form
        new_user = self._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(self.request, new_user)

        return new_user
Ejemplo n.º 25
0
    def _update_user(self, facebook):
        '''
        Updates the user and his/her profile with the data from facebook
        '''
        user = self.request.user
        #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_user_converter = FacebookUserConverter(facebook)
        facebook_data = facebook_user_converter.facebook_registration_data()

        user_dirty = profile_dirty = False
        profile = user.get_profile()
        profile_field_names = [f.name for f in profile._meta.fields]
        user_field_names = [f.name for f in user._meta.fields]

        #set the facebook id and make sure we are the only user with this id
        if facebook_data['facebook_id'] != profile.facebook_id:
            profile.facebook_id = facebook_data['facebook_id']
            profile_dirty = True
            #like i said, me and only me
            profile_class = get_profile_class()
            profile_class.objects.filter(
                facebook_id=profile.facebook_id).exclude(
                    user__id=user.id).update(facebook_id=None)

        #update all fields on both user and profile
        for f in self.facebook_fields:
            facebook_value = facebook_data.get(f, False)
            if facebook_value:
                if f in profile_field_names and not getattr(profile, f, False):
                    setattr(profile, f, facebook_value)
                    profile_dirty = True
                elif f in user_field_names and not getattr(user, f, False):
                    setattr(user, f, facebook_value)
                    user_dirty = True

        #write the raw data in case we missed something
        if hasattr(profile, 'raw_data'):
            serialized_fb_data = json.dumps(
                facebook_user_converter.facebook_profile_data())
            profile.raw_data = serialized_fb_data
            profile_dirty = True

        #save both models if they changed
        if user_dirty:
            user.save()
        if profile_dirty:
            profile.save()

        return user
Ejemplo n.º 26
0
def store_friends(user, friends):
    '''
    Inserting again will not cause any errors, so this is safe
    for multiple executions

    :param user: The user for which we are storing
    :type user: User object

    :param friends: List of your friends
    :type friends: list
    '''
    from django_facebook.api import FacebookUserConverter
    logger.info('celery is storing %s friends' % len(friends))
    FacebookUserConverter._store_friends(user, friends)
    return friends
Ejemplo n.º 27
0
def store_friends(user, friends):
    '''
    Inserting again will not cause any errors, so this is safe
    for multiple executions

    :param user: The user for which we are storing
    :type user: User object

    :param friends: List of your friends
    :type friends: list
    '''
    from django_facebook.api import FacebookUserConverter
    logger.info('celery is storing %s friends' % len(friends))
    FacebookUserConverter._store_friends(user, friends)
    return friends
Ejemplo n.º 28
0
    def _update_user(self, facebook):
        '''
        Updates the user and his/her profile with the data from facebook
        '''
        user = self.request.user
        #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_user_converter = FacebookUserConverter(facebook)
        facebook_data = facebook_user_converter.facebook_registration_data()

        user_dirty = profile_dirty = False
        profile = user.get_profile()
        profile_field_names = [f.name for f in profile._meta.fields]
        user_field_names = [f.name for f in user._meta.fields]

        #set the facebook id and make sure we are the only user with this id
        if facebook_data['facebook_id'] != profile.facebook_id:
            profile.facebook_id = facebook_data['facebook_id']
            profile_dirty = True
            #like i said, me and only me
            profile_class = get_profile_class()
            profile_class.objects.filter(facebook_id=profile.facebook_id).exclude(user__id=user.id).update(facebook_id=None)

        #update all fields on both user and profile
        for f in self.facebook_fields:
            facebook_value = facebook_data.get(f, False)
            if facebook_value:
                if f in profile_field_names and not getattr(profile, f, False):
                    setattr(profile, f, facebook_value)
                    profile_dirty = True
                elif f in user_field_names and not getattr(user, f, False):
                    setattr(user, f, facebook_value)
                    user_dirty = True

        #write the raw data in case we missed something
        if hasattr(profile, 'raw_data'):
            serialized_fb_data = json.dumps(facebook_user_converter.facebook_profile_data())
            profile.raw_data = serialized_fb_data
            profile_dirty = True

        #save both models if they changed
        if user_dirty:
            user.save()
        if profile_dirty:
            profile.save()

        return user
Ejemplo n.º 29
0
    def test_parallel_register(self):
        '''
        Adding some testing for the case when one person tries to register
        multiple times in the same second
        '''
        graph = get_facebook_graph(access_token='short_username')
        FacebookUserConverter(graph)
        action, user = connect_user(self.request, facebook_graph=graph)
        self.assertEqual(action, CONNECT_ACTIONS.REGISTER)

        self.request.user.is_authenticated = lambda: False
        with patch('django_facebook.connect.authenticate') as patched:
            return_sequence = [user, None]

            def side(*args, **kwargs):
                value = return_sequence.pop()
                return value

            patched.side_effect = side
            with patch('django_facebook.connect._register_user'
                       ) as patched_register:
                patched_register.side_effect = facebook_exceptions.AlreadyRegistered(
                    'testing parallel registers')
                action, user = connect_user(self.request, facebook_graph=graph)
                self.assertEqual(action, CONNECT_ACTIONS.LOGIN)
Ejemplo n.º 30
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)
Ejemplo n.º 31
0
def store_likes(user, likes):
    """
    Inserting again will not cause any errors, so this is safe
    for multiple executions

    :param user: The user for which we are storing
    :type user: User object

    :param friends: List of your likes
    :type friends: list
    """
    from django_facebook.api import FacebookUserConverter

    logger.info("celery is storing %s likes" % len(likes))
    FacebookUserConverter._store_likes(user, likes)
    return likes
Ejemplo n.º 32
0
    def test_persistent_graph(self):
        request = RequestMock().get('/')
        request.session = {}
        request.user = AnonymousUser()

        graph = get_facebook_graph(access_token='short_username')
        FacebookUserConverter(graph)
        action, user = connect_user(self.request, facebook_graph=graph)
        self.assertEqual(action, CONNECT_ACTIONS.REGISTER)
Ejemplo n.º 33
0
 def test_full_connect(self):
     #going for a register, connect and login
     graph = get_facebook_graph(access_token='short_username')
     FacebookUserConverter(graph)
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(action, CONNECT_ACTIONS.REGISTER)
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(action, CONNECT_ACTIONS.CONNECT)
     self.request.user = AnonymousUser()
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(action, CONNECT_ACTIONS.LOGIN)
Ejemplo n.º 34
0
def update_connection(request, graph):
    '''
    A special purpose view for updating the connection with an existing user
    - updates the access token (already done in get_graph)
    - sets the facebook_id if nothing is specified
    - stores friends and likes if possible
    '''
    facebook = FacebookUserConverter(graph)
    user = _connect_user(request, facebook, overwrite=False)
    _update_likes_and_friends(request, user, facebook)
    _update_access_token(user, graph)
    return user
Ejemplo n.º 35
0
	def get_queryset(self):
		if not self.request.user.is_authenticated():
			return UserData.objects.none()
		try:
			graph = require_facebook_graph(self.request)
		except:
			logout(self.request)
			return UserData.objects.none()

		my_info = graph.get('me')
		converter = FacebookUserConverter(graph)
		my_friends = converter.get_friends()
		my_friends_facebook_id = []
		for friend in my_friends:
			if not friend["id"]:
				continue
			else:
				my_friends_facebook_id.append(friend["id"])

		users = UserData.objects.all().filter(facebook_id__in = my_friends_facebook_id)
		return users
Ejemplo n.º 36
0
def connect_async_ajax(request):
    '''
    Not yet implemented:
    The idea is to run the entire connect flow on the background using celery
    Freeing up webserver resources, when facebook has issues
    '''
    from django_facebook import tasks as facebook_tasks
    graph = get_persistent_graph(request)
    output = {}
    if graph:
        facebook = FacebookUserConverter(graph)
        task = facebook_tasks.async_connect_user(request, graph)
        output['task_id'] = task.id
    from open_facebook.utils import json
    json_dump = json.dumps(output)
    return HttpResponse(json_dump)
Ejemplo n.º 37
0
 def test_full_connect(self):
     # going for a register, connect and login
     graph = get_facebook_graph(request=self.request, access_token='short_username')
     FacebookUserConverter(graph)
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(action, CONNECT_ACTIONS.REGISTER)
     # and now we do a login, not a connect
     action, user = connect_user(self.request, facebook_graph=graph)
     self.assertEqual(action, CONNECT_ACTIONS.LOGIN)
     self.request.GET._mutable = True
     self.request.GET['connect_facebook'] = 1
     action, user = connect_user(
         self.request, facebook_graph=graph, connect_facebook=True)
     self.assertEqual(action, CONNECT_ACTIONS.CONNECT)
     self.request.user = AnonymousUser()
     action, user = connect_user(
         self.request, facebook_graph=graph, connect_facebook=True)
     self.assertEqual(action, CONNECT_ACTIONS.LOGIN)
Ejemplo n.º 38
0
def store_friends(user, friends):
    from django_facebook.api import FacebookUserConverter
    logger.info('celery is storing %s friends' % len(friends))
    FacebookUserConverter._store_friends(user, friends)
    
    return friends
Ejemplo n.º 39
0
def connect(request):
    """
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    """
    backend = get_registration_backend()
    context = RequestContext(request)

    assert context.get("FACEBOOK_APP_ID"), (
        "Please specify a facebook app id " "and ensure the context processor is enabled"
    )
    facebook_login = bool(int(request.REQUEST.get("facebook_login", 0)))

    if facebook_login:
        logger.info("trying to connect using facebook")
        graph = require_persistent_graph(request)
        if graph:
            logger.info("found a graph object")
            facebook = FacebookUserConverter(graph)

            if facebook.is_authenticated():
                logger.info("facebook is authenticated")
                facebook_data = facebook.facebook_profile_data()
                # either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info("Django facebook performed action: %s", action)
                except facebook_exceptions.IncompleteProfileError, e:
                    # show them a registration form to add additional data
                    warning_format = u"Incomplete profile data encountered with error %s"
                    warn_message = warning_format % e.message
                    send_warning(warn_message, e=e, facebook_data=facebook_data)

                    context["facebook_mode"] = True
                    context["form"] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE, context_instance=context
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    # connect means an existing account was attached to facebook
                    messages.info(
                        request,
                        _("You have connected your account " "to %s's facebook profile") % facebook_data["name"],
                    )
                elif action is CONNECT_ACTIONS.REGISTER:
                    # hook for tying in specific post registration functionality
                    response = backend.post_registration_redirect(request, user)
                    # compatability for django registration backends which return tuples instead of a response
                    # alternatively we could wrap django registration backends, but that would be hard to understand
                    response = response if isinstance(response, HttpResponse) else redirect(response)
                    return response
        else:
            if "attempt" in request.GET:
                return next_redirect(
                    request, next_key=["error_next", "next"], additional_params=dict(fb_error_or_cancel=1)
                )
            else:
                logger.info("Facebook authentication needed for connect, " "raising an error")
                raise OpenFacebookException("please authenticate")
Ejemplo n.º 40
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    '''
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or\
        request.REQUEST.get('force_registration_hard')

    logger.debug('force registration is set to %s', force_registration)
    if request.user.is_authenticated() and not force_registration:
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            if not auth_user.get_profile().facebook_id:
                update = True
            else:
                update = getattr(auth_user, 'fb_update_required', False)
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            #when force registration is active we should clearout the old profile
            user = _register_user(request, facebook, remove_old_connections=force_registration)

    #store likes and friends if configured
    sid = transaction.savepoint()
    try:
        if facebook_settings.FACEBOOK_STORE_LIKES:
            facebook.get_and_store_likes(user)
        if facebook_settings.FACEBOOK_STORE_FRIENDS:
            facebook.get_and_store_friends(user)
        transaction.savepoint_commit(sid)
    except IntegrityError, e:
        logger.warn(u'Integrity error encountered during registration, '
                'probably a double submission %s' % e,
            exc_info=sys.exc_info(), extra={
            'request': request,
            'data': {
                 'body': unicode(e),
             }
        })
        transaction.savepoint_rollback(sid)
Ejemplo n.º 41
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    '''
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or\
        request.REQUEST.get('force_registration_hard')

    logger.debug('force registration is set to %s', force_registration)
    if request.user.is_authenticated() and not force_registration:
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            if not auth_user.get_profile().facebook_id:
                update = True
            else:
                update = getattr(auth_user, 'fb_update_required', False)
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            # when force registration is active we should clearout
            # the old profile
            user = _register_user(request, facebook,
                                  remove_old_connections=force_registration)

    #store likes and friends if configured
    sid = transaction.savepoint()
    try:
        if facebook_settings.FACEBOOK_STORE_LIKES:
            facebook.get_and_store_likes(user)
        if facebook_settings.FACEBOOK_STORE_FRIENDS:
            facebook.get_and_store_friends(user)
        transaction.savepoint_commit(sid)
    except IntegrityError, e:
        logger.warn(u'Integrity error encountered during registration, '
                'probably a double submission %s' % e,
            exc_info=sys.exc_info(), extra={
            'request': request,
            'data': {
                 'body': unicode(e),
             }
        })
        transaction.savepoint_rollback(sid)
Ejemplo n.º 42
0
def fbapphome(request):
    '''
        facebook app canvas. Potentially comes throught this view twice
        1. If the user does not have the app installed request is a valid signed request
           with no 'code' on the url and we have no app permissions and so no access_token.
           So setup oauth_url and pass it to the template to redirect to with js (not ideal).
        2. User has accepted app install permissions request, fb redirect to the
           redirect_uri (back here) now with a code on the url. Call test_permissions
           and get_persistant_graph to convert this code into an access_token. Then
           call connect_user to create and/or log them in.
    '''

    logging.debug('RM: fbapphome request %s' % (request))
    oauth_url = None

    verification_code = request.GET.get('code', None)
    logging.debug('RM: fbapphome verification_code %s' % (verification_code))

    #set up the permission required oauth_url and redirect uri, ideally shouldn't do this
    #every tme through but get_oauth_url returns both urls and adds attempt=1 to redirect_uri
    scope_list = settings.FACEBOOK_DEFAULT_SCOPE
    redirect_uri = 'http://apps.facebook.com/' + settings.FACEBOOK_APP_NAME + '/?facebook_login=1'
    from django_facebook.utils import get_oauth_url
    oauth_url, redirect_uri = get_oauth_url(request,
                                            scope_list,
                                            redirect_uri=redirect_uri)
    logging.debug('IAB: redirect_uri %s' % (redirect_uri))

    #useful to test that access_token is being retrieved
    #if verification_code:
    #    parms_dict = QueryDict('', True)
    #    parms_dict['client_id'] = settings.FACEBOOK_APP_ID
    #    parms_dict['client_secret'] = settings.FACEBOOK_APP_SECRET
    #    parms_dict['redirect_uri'] = redirect_uri
    #    parms_dict['code'] = verification_code
    #    url = 'https://graph.facebook.com/oauth/access_token?'
    #    url += parms_dict.urlencode()
    #    logging.debug('RM: access_token URL: %s' % url)
    #    access_token = urllib2.urlopen(url).read()
    #    logging.debug('RM: fbapphome access_token %s' % (access_token))

    #test for permissions if we have them the user has authorised the app so set them up as a django user
    from django_facebook.utils import test_permissions
    if test_permissions(request, scope_list, redirect_uri):
        oauth_url = None  #sadly have to reset this because it is set everytime through by get_oauth_url
        logging.debug('IAB: found required facebook permissions.')
        from django_facebook.api import get_persistent_graph, FacebookUserConverter
        graph = get_persistent_graph(request=request,
                                     redirect_uri=redirect_uri)
        facebook = FacebookUserConverter(graph)
        if facebook.is_authenticated():
            facebook_data = facebook.facebook_profile_data()
            from django_facebook.connect import connect_user
            #either, login register or connect the user
            action, user = connect_user(request)
            logging.debug('IAB: fbapphome user returned %s  with action %s' %
                          (user, action))
        else:
            #TODO: handle this situation
            logging.error(
                'IAB: fbapphome failed to authenticate the user from request: %s'
                % (request))
    else:  #no permissions so construct oauth url and redirect to it in the template
        logging.debug('IAB: no app permissions so setting up oauth_url: %s.' %
                      oauth_url)

    return render_to_response('welcome.html', {'oauth_url': oauth_url},
                              context_instance=RequestContext(request))
Ejemplo n.º 43
0
 def test_utf8(self):
     graph = get_facebook_graph(access_token='unicode_string')
     facebook = FacebookUserConverter(graph)
     action, user = connect_user(self.request, facebook_graph=graph)
Ejemplo n.º 44
0
 def test_gender(self):
     graph = get_facebook_graph(access_token='new_user')
     facebook = FacebookUserConverter(graph)
     data = facebook.facebook_registration_data()
     self.assertEqual(data['gender'], 'm')
Ejemplo n.º 45
0
 def test_utf8(self):
     graph = get_facebook_graph(access_token='unicode_string')
     facebook = FacebookUserConverter(graph)
     profile_data = facebook.facebook_profile_data()
     action, user = connect_user(self.request, facebook_graph=graph)
Ejemplo n.º 46
0
    def connect_user(self):
        """Main functionality
        """

        #TODO, instead of using access_token this should probably accept a facebook_graph as well
        user = None
        facebook = self.facebook_graph or get_facebook_graph(
            self.request, self.access_token)
        assert facebook.is_authenticated(), 'Facebook not authenticated'

        facebook_user_converter = FacebookUserConverter(facebook)

        facebook_data = facebook_user_converter.facebook_profile_data()

        force_registration = self.request.REQUEST.get(
            'force_registration') or self.request.REQUEST.get(
                'force_registration_hard')

        logger.debug('force registration is set to %s', force_registration)
        if self.request.user.is_authenticated() and not force_registration:
            action = CONNECT_ACTIONS.CONNECT
            user = self._connect_user(facebook)
        else:
            email = facebook_data.get('email', False)
            email_verified = facebook_data.get('verified', False)
            kwargs = {}
            if email and email_verified:
                kwargs = {'facebook_email': email}
            authenticated_user = authenticate(facebook_id=facebook_data['id'],
                                              **kwargs)
            if authenticated_user and not force_registration:
                action = CONNECT_ACTIONS.LOGIN

                ## Has the user registered without Facebook, using the verified FB email address?
                # It is after all quite common to use email addresses for usernames
                if not authenticated_user.get_profile().facebook_id:
                    update = True
                else:
                    update = getattr(authenticated_user, 'fb_update_required',
                                     False)
                user = self._login_user(facebook,
                                        authenticated_user,
                                        update=update)
            else:
                action = CONNECT_ACTIONS.REGISTER
                user = self._register_user(facebook)

        #store likes and friends if configured
        sid = transaction.savepoint()
        try:
            if facebook_settings.FACEBOOK_STORE_LIKES:
                likes = facebook.get_likes()
                facebook.store_likes(user, likes)
            if facebook_settings.FACEBOOK_STORE_FRIENDS:
                friends = facebook.get_friends()
                facebook.store_friends(user, friends)
            transaction.savepoint_commit(sid)
        except IntegrityError, e:
            logger.warn(
                u'Integrity error encountered during registration, probably a double submission %s'
                % e,
                exc_info=sys.exc_info(),
                extra={
                    'request': request,
                    'data': {
                        'body': unicode(e),
                    }
                })

            transaction.savepoint_rollback(sid)
Ejemplo n.º 47
0
def _connect(request, facebook_login):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    backend = get_registration_backend()
    context = RequestContext(request)

    if facebook_login:
        logger.info('trying to connect using Facebook')
        try:
            graph = require_persistent_graph(request)
        except:
            return HttpResponseRedirect('https://www.facebook.com')
        authenticated = False
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)
            authenticated = facebook.is_authenticated()

            if authenticated:
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    #show them a registration form to add additional data
                    warning_format = u'Incomplete profile data encountered with error %s'
                    warn_message = warning_format % e.message
                    send_warning(warn_message, e=e,facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    m = re.search(r'{(?P<hello>.*)}',str(e).replace('\t','').replace('\n',''))
                    all_d = smart_str(m.group('hello'))
                    #return HttpResponse(all_d)
                    all_data = splitting(all_d)
                    
                    sec = get_random_string(250)
                    all_data['sec'] = sec
                    error = False
                    try:
                        bb = all_data['birthday'].split('/')
                        birthday = bb[2] +'-' + bb[0] + '-' + bb[1]
                    except:
                        error = True
                    ###############################################################################
                    pss = hashlib.sha512(str(all_data['password1'])).hexdigest()
                    #,avatar2=all_data['image']
                    try:
                        if not error:
                            cix = Account.objects.create(name=all_data['facebook_name'],email=all_data['email'],gender2=all_data['gender'].upper(),facebook_data=str(all_d),secret=sec,password=pss,facebook_page=all_data['link'])
                        else:
                            cix = Account.objects.create(name=all_data['facebook_name'],birthday=birthday,email=all_data['email'],gender2=all_data['gender'].upper(),facebook_data=str(all_d),secret=sec,password=pss,facebook_page=all_data['link'])
                    except IntegrityError:
                        pass
                    try:
                        cix.facebook_data=str(all_d)
                        cix.save()
                    except:
                        pass
                    ##############################################################################3
                    xt = Account.objects.is_valid3(all_data['email'])
                    if not xt[0]:
                        request.META['authenticated2'] = str(all_data['link'])
                    else:
                        request.META['authenticated2'] = xt[1]
                    #c = { 'form' : all_data }
                    #featured = BaseCourse.objects.filter(featured=True)
                    #c['f1'] = featured[:3]
                    #c['f2'] = featured[3:6]
                    #c['f3'] = featured[6:9]
                    #c['number_of_courses'] = BaseCourse.objects.all().count()
                    return HttpResponseRedirect('/coursewall')
                except facebook_exceptions.AlreadyConnectedError, e:
                    user_ids = [u.user_id for u in e.users]
                    ids_string = ','.join(map(str, user_ids))
                    return error_next_redirect(
                        request,
                        additional_params=dict(already_connected=ids_string))

                if action is CONNECT_ACTIONS.CONNECT:
                    #connect means an existing account was attached to facebook
                    messages.info(request, _("You have connected your account "
                                             "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    #hook for tying in specific post registration functionality
                    response = backend.post_registration_redirect(
                        request, user)
                    #compatibility for Django registration backends which return redirect tuples instead of a response
                    if not isinstance(response, HttpResponse):
                        to, args, kwargs = response
                        response = redirect(to, *args, **kwargs)
                    return response
Ejemplo n.º 48
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))

    if facebook_login:
        #code to redirect if we don't have adequate permissions
        from django_facebook.utils import test_permissions
        scope_list = facebook_settings.FACEBOOK_DEFAULT_SCOPE
        #standardizing the url to prevent things like attempt from being included
        redirect_uri = request.build_absolute_uri(
            request.path) + '?facebook_login=1'
        oauth_url, redirect_uri = get_oauth_url(request,
                                                scope_list,
                                                redirect_uri=redirect_uri)
        if not test_permissions(request, scope_list, redirect_uri):
            return HttpResponseRedirect(oauth_url)

        graph = get_persistent_graph(request)
        if graph:
            facebook = FacebookUserConverter(graph)
            if facebook.is_authenticated():
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook, action was %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    warn_message = u'Incomplete profile data encountered '\
                        u'with error %s' % e
                    send_warning(
                        warn_message,
                        e=e,
                        facebook_data=facebook.facebook_profile_data())

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    messages.info(
                        request,
                        _("You have connected your account "
                          "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    return user.get_profile().post_facebook_registration(
                        request)
        else:
            return next_redirect(request,
                                 next_key=['error_next', 'next'],
                                 additional_params=dict(fb_error_or_cancel=1))

        return next_redirect(request)
Ejemplo n.º 49
0
def store_likes(user, likes):
    from django_facebook.api import FacebookUserConverter
    logger.info('celery is storing %s likes' % len(likes))
    FacebookUserConverter._store_likes(user, likes)
    
    return likes
Ejemplo n.º 50
0
def connect_user(request, access_token=None, facebook_graph=None):
    '''
    Given a request either

    - (if authenticated) connect the user
    - login
    - register
    '''
    user = None
    graph = facebook_graph or get_facebook_graph(request, access_token)
    facebook = FacebookUserConverter(graph)

    assert facebook.is_authenticated()
    facebook_data = facebook.facebook_profile_data()
    force_registration = request.REQUEST.get('force_registration') or\
        request.REQUEST.get('force_registration_hard')

    connect_facebook = to_bool(request.REQUEST.get('connect_facebook'))

    logger.debug('force registration is set to %s', force_registration)
    if connect_facebook and request.user.is_authenticated(
    ) and not force_registration:
        #we should only allow connect if users indicate they really want to connect
        #only when the request.CONNECT_FACEBOOK = 1
        #if this isn't present we just do a login
        action = CONNECT_ACTIONS.CONNECT
        user = _connect_user(request, facebook)
    else:
        email = facebook_data.get('email', False)
        email_verified = facebook_data.get('verified', False)
        kwargs = {}
        if email and email_verified:
            kwargs = {'facebook_email': email}
        auth_user = authenticate(facebook_id=facebook_data['id'], **kwargs)
        if auth_user and not force_registration:
            action = CONNECT_ACTIONS.LOGIN

            # Has the user registered without Facebook, using the verified FB
            # email address?
            # It is after all quite common to use email addresses for usernames
            update = getattr(auth_user, 'fb_update_required', False)
            if not auth_user.get_profile().facebook_id:
                update = True
            #login the user
            user = _login_user(request, facebook, auth_user, update=update)
        else:
            action = CONNECT_ACTIONS.REGISTER
            # when force registration is active we should remove the old profile
            try:
                user = _register_user(
                    request,
                    facebook,
                    remove_old_connections=force_registration)
            except facebook_exceptions.AlreadyRegistered, e:
                #in Multithreaded environments it's possible someone beats us to
                #the punch, in that case just login
                logger.info(
                    'parallel register encountered, slower thread is doing a login'
                )
                auth_user = authenticate(facebook_id=facebook_data['id'],
                                         **kwargs)
                action = CONNECT_ACTIONS.LOGIN
                user = _login_user(request, facebook, auth_user, update=False)
Ejemplo n.º 51
0
def fbapphome(request):
    
    '''
        facebook app canvas. Potentially comes throught this view twice
        1. If the user does not have the app installed request is a valid signed request
           with no 'code' on the url and we have no app permissions and so no access_token.
           So setup oauth_url and pass it to the template to redirect to with js (not ideal).
        2. User has accepted app install permissions request, fb redirect to the
           redirect_uri (back here) now with a code on the url. Call test_permissions
           and get_persistant_graph to convert this code into an access_token. Then
           call connect_user to create and/or log them in.
    '''
    
    logging.debug('RM: fbapphome request %s' % (request))    
    oauth_url = None
    
    verification_code = request.GET.get('code', None)
    logging.debug('RM: fbapphome verification_code %s' % (verification_code))


    #set up the permission required oauth_url and redirect uri, ideally shouldn't do this
    #every tme through but get_oauth_url returns both urls and adds attempt=1 to redirect_uri
    scope_list = settings.FACEBOOK_DEFAULT_SCOPE
    redirect_uri = 'http://apps.facebook.com/' + settings.FACEBOOK_APP_NAME + '/?facebook_login=1'
    from django_facebook.utils import get_oauth_url
    oauth_url, redirect_uri = get_oauth_url(request, scope_list, redirect_uri=redirect_uri)
    logging.debug('IAB: redirect_uri %s' % (redirect_uri))
    
    #useful to test that access_token is being retrieved
    #if verification_code:
    #    parms_dict = QueryDict('', True)
    #    parms_dict['client_id'] = settings.FACEBOOK_APP_ID
    #    parms_dict['client_secret'] = settings.FACEBOOK_APP_SECRET
    #    parms_dict['redirect_uri'] = redirect_uri  
    #    parms_dict['code'] = verification_code
    #    url = 'https://graph.facebook.com/oauth/access_token?'
    #    url += parms_dict.urlencode()
    #    logging.debug('RM: access_token URL: %s' % url)
    #    access_token = urllib2.urlopen(url).read()
    #    logging.debug('RM: fbapphome access_token %s' % (access_token))

    #test for permissions if we have them the user has authorised the app so set them up as a django user
    from django_facebook.utils import test_permissions
    if test_permissions(request, scope_list, redirect_uri):
        oauth_url = None #sadly have to reset this because it is set everytime through by get_oauth_url
        logging.debug('IAB: found required facebook permissions.')
        from django_facebook.api import get_persistent_graph, FacebookUserConverter
        graph = get_persistent_graph(request=request, redirect_uri=redirect_uri)
        facebook = FacebookUserConverter(graph)
        if facebook.is_authenticated():
            facebook_data = facebook.facebook_profile_data()
            from django_facebook.connect import connect_user
            #either, login register or connect the user
            action, user = connect_user(request)
            logging.debug('IAB: fbapphome user returned %s  with action %s' % (user, action))
        else:
            #TODO: handle this situation
            logging.error('IAB: fbapphome failed to authenticate the user from request: %s' % (request))
    else: #no permissions so construct oauth url and redirect to it in the template
        logging.debug('IAB: no app permissions so setting up oauth_url: %s.' % oauth_url)

    return render_to_response('welcome.html', {'oauth_url': oauth_url}, context_instance=RequestContext(request))
Ejemplo n.º 52
0
def _connect(request, facebook_login):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    backend = get_registration_backend()
    context = RequestContext(request)

    if True:
        logger.info('trying to connect using Facebook')
        graph = require_persistent_graph(request)
        authenticated = False
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)
            authenticated = facebook.is_authenticated()

            if authenticated:
                logger.info('Facebook is authenticated')
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user : This is where it interfaces with Django
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                    print user
                    print request.user
                except facebook_exceptions.IncompleteProfileError, e:
                    #show them a registration form to add additional data
                    warning_format = u'Incomplete profile data encountered with error %s'
                    warn_message = warning_format % e.message
                    send_warning(warn_message, e=e,
                                 facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )
                except facebook_exceptions.AlreadyConnectedError, e:
                    user_ids = [u.user_id for u in e.users]
                    ids_string = ','.join(map(str, user_ids))
                    return error_next_redirect(
                        request,
                        additional_params=dict(already_connected=ids_string))

                if action is CONNECT_ACTIONS.CONNECT:
                    #connect means an existing account was attached to facebook
                    messages.info(request, _("You have connected your account "
                                             "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    #hook for tying in specific post registration functionality
                    #response = backend.post_registration_redirect(
                    #    request, user)
                    return HttpResponseRedirect(reverse('home_logged_home'))
                    #compatibility for Django registration backends which return redirect tuples instead of a response
                    if not isinstance(response, HttpResponse):
                        to, args, kwargs = response
                        response = redirect(to, *args, **kwargs)
                    return response
Ejemplo n.º 53
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    backend = get_registration_backend()
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))

    if facebook_login:
        logger.info('trying to connect using facebook')
        graph = require_persistent_graph(request)
        if graph:
            logger.info('found a graph object')
            facebook = FacebookUserConverter(graph)

            if facebook.is_authenticated():
                logger.info('facebook is authenticated')
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                    logger.info('Django facebook performed action: %s', action)
                except facebook_exceptions.IncompleteProfileError, e:
                    #show them a registration form to add additional data
                    warning_format = u'Incomplete profile data encountered with error %s'
                    warn_message = warning_format % e.message
                    send_warning(warn_message,
                                 e=e,
                                 facebook_data=facebook_data)

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        facebook_settings.FACEBOOK_REGISTRATION_TEMPLATE,
                        context_instance=context,
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    #connect means an existing account was attached to facebook
                    messages.info(
                        request,
                        _("You have connected your account "
                          "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    #hook for tying in specific post registration functionality
                    response = backend.post_registration_redirect(
                        request, user)
                    #compatability for django registration backends which return tuples instead of a response
                    #alternatively we could wrap django registration backends, but that would be hard to understand
                    response = response if isinstance(
                        response, HttpResponse) else redirect(response)
                    return response
        else:
            if 'attempt' in request.GET:
                return next_redirect(
                    request,
                    next_key=['error_next', 'next'],
                    additional_params=dict(fb_error_or_cancel=1))
            else:
                logger.info('Facebook authentication needed for connect, ' \
                            'raising an error')
                raise OpenFacebookException('please authenticate')

        #for CONNECT and LOGIN we simple redirect to the next page
        return next_redirect(
            request, default=facebook_settings.FACEBOOK_LOGIN_DEFAULT_REDIRECT)
Ejemplo n.º 54
0
def connect(request):
    '''
    Handles the view logic around connect user
    - (if authenticated) connect the user
    - login
    - register
    '''
    context = RequestContext(request)

    assert context.get('FACEBOOK_APP_ID'), 'Please specify a facebook app id '\
        'and ensure the context processor is enabled'
    facebook_login = bool(int(request.REQUEST.get('facebook_login', 0)))

    if facebook_login:
        #code to redirect if we don't have adequate permissions
        from django_facebook.utils import test_permissions
        scope_list = ['email','user_about_me','user_birthday','user_website']
        #standardizing the url to prevent things like attempt from being included
        redirect_uri = request.build_absolute_uri(request.path) + '?facebook_login=1'
        oauth_url, redirect_uri = get_oauth_url(request, scope_list, redirect_uri=redirect_uri)
        if not test_permissions(request, scope_list, redirect_uri):
            return HttpResponseRedirect(oauth_url)
        
        graph = get_persistent_graph(request)
        if graph:
            facebook = FacebookUserConverter(graph)
            if facebook.is_authenticated():
                facebook_data = facebook.facebook_profile_data()
                #either, login register or connect the user
                try:
                    action, user = connect_user(request)
                except facebook_exceptions.IncompleteProfileError, e:
                    warn_message = u'Incomplete profile data encountered '\
                        'with error %s' % e
                    logger.warn(warn_message,
                        exc_info=sys.exc_info(), extra={
                        'request': request,
                        'data': {
                             'username': request.user.username,
                             'facebook_data': facebook.facebook_profile_data(),
                             'body': unicode(e),
                         }
                    })

                    context['facebook_mode'] = True
                    context['form'] = e.form
                    return render_to_response(
                        'registration/registration_form.html',
                        context_instance=context,
                    )

                if action is CONNECT_ACTIONS.CONNECT:
                    messages.info(request, _("You have connected your account "
                        "to %s's facebook profile") % facebook_data['name'])
                elif action is CONNECT_ACTIONS.REGISTER:
                    return user.get_profile().post_facebook_registration(request)
        else:
            return next_redirect(request, next_key=['error_next', 'next'],
                additional_params=dict(fb_error_or_cancel=1))

        return next_redirect(request)
Ejemplo n.º 55
0
 def test_gender(self):
     graph = get_facebook_graph(access_token='new_user')
     facebook = FacebookUserConverter(graph)
     data = facebook.facebook_registration_data()
     self.assertEqual(data['gender'], 'm')