Пример #1
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)
Пример #2
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.REQUEST.get('force_registration_hard'):
        data['email'] = data['email'].replace(
            '@', '+test%s@' % randint(0, 1000000000))

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

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

    #for new registration systems use the backends methods of saving
    new_user = None
    if backend:
        new_user = backend.register(request, **form.cleaned_data)
    #fall back to the form approach
    if not new_user:
        # For backward compatibility, if django-registration form is used
        try:
            new_user = form.save(profile_callback=profile_callback)
        except TypeError:
            new_user = form.save()

    signals.facebook_user_registered.send(sender=auth.models.User,
        user=new_user, facebook_data=facebook_data)

    #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 = 'greenroom.apps.django_facebook_patched.auth_backends.FacebookBackend'
    auth.login(request, new_user)

    return new_user