def social_register(request, backend, disallowed_url="registration_disallowed"): backend = BACKENDS[backend] backend = backend() if request.method == "POST": # The user has posted a registration request # The access token will provide us with the information from the users' social network account access_token = request.POST.get("access_token", None) # The form data will provide us with additional information form = SocialRegistrationForm(request.POST) if form.is_valid(): # User agreed to tos, and if he provided password, they match if access_token: # We also need to check if the additional information provided by the user is valid try: user_info = backend.get_user_info(access_token) except PermissionDenied: messages.add_message( request, messages.INFO, _( "You cannot use this type of " + backend.name() + " account to register on Seasoning. Please try another..." ), ) return redirect("/register/") if user_info: try: # Check if a user with this social id already exists User.objects.get(**{backend.ID_FIELD: user_info["id"]}) messages.add_message( request, messages.INFO, _( "A user has already registered with your " + backend.name() + " account. If this is you, please log in, otherwise, contact an administrator" ), ) return redirect("/login/") except User.DoesNotExist: pass try: # Check if a user with this Facebook email is already registered User.objects.get(email=user_info["email"]) messages.add_message( request, messages.INFO, _( "A user has already registered on Seasoning with the email in your " + backend.name() + ". If this is your account, would you like to connect it to your " + backend.name() + "account?" ), ) return redirect(backend.connect_url) except User.DoesNotExist: # A user with this Google email does not exist, so we will register a new one pass # Check if registration is allowed if not backend.registration_allowed(request): return redirect(disallowed_url) # Register the user password = form.cleaned_data["password"] or None user = backend.register( request, social_id=user_info["id"], givenname=user_info["givenname"], surname=user_info["surname"], email=user_info["email"], date_of_birth=user_info["date_of_birth"], password=password, ) # And log him in, because we don't need to validate his information user = authenticate(**{backend.ID_FIELD: user_info["id"]}) auth_login(request, user) messages.add_message( request, messages.INFO, _( "You have successfully registered your " + backend.name() + " account on Seasoning. Have fun!" ), ) return redirect(home) # If we're here, we had a faulty access token. Set the access token to None so as not to get caught in the if condition below and display the error # message as expected access_token = None else: # User wants to register using his social account code = request.GET.get("code", None) redirect_uri = "http://" + str(get_current_site(request)) + backend.registration_url if code is None: # User has just click the 'Register with ...' button to start a social registration. # Redirect him to the social network, so we may get an authorization code. return redirect(backend.get_auth_code_url(redirect_uri=redirect_uri)) else: # User has been redirected to the social network, and has come back with a code # We now need to exchange this code for an access token in our backend form = SocialRegistrationForm() access_token = backend.get_access_token(code, redirect_uri=redirect_uri) if access_token: # We now have an access token either by getting one with an authorization code, or by extracting it from the # POST parameters try: user_info = backend.get_user_info(access_token) except PermissionDenied: messages.add_message( request, messages.INFO, _( "You cannot use this type of " + backend.name() + " account to register on Seasoning. Please try another..." ), ) return redirect("/register/") try: # Check if a user with this social id already exists User.objects.get(**{backend.ID_FIELD: user_info["id"]}) messages.add_message( request, messages.INFO, _( "A user has already registered with your " + backend.name() + " account. If this is you, please log in, otherwise, contact an administrator" ), ) return redirect("/login/") except User.DoesNotExist: pass try: # Check if a user with this Facebook email is already registered User.objects.get(email=user_info["email"]) messages.add_message( request, messages.INFO, _( "A user has already registered on Seasoning with the email in your " + backend.name() + ". If this is your account, please log in to connect it to your " + backend.name() + " account?" ), ) return redirect(backend.connect_url) except User.DoesNotExist: # A user with this Google email does not exist, so we will register a new one pass context = {"backend": backend, "form": form, "access_token": access_token} context.update(user_info) if user_info: return render(request, "authentication/social_register.html", context) # If we're here, something above must have gone wrong... messages.add_message( request, messages.INFO, _("An error occurred while checking your identity with " + backend.name() + ". Please try again."), ) return redirect(backend.registration_url)
def social_registration(request): name = setting('SOCIAL_AUTH_PARTIAL_PIPELINE_KEY', 'partial_pipeline') data = request.session.get(name) if not data: return redirect('login') details = data['kwargs']['details'] response = data['kwargs']['response'] email = details['email'] location = None # Check whether email is verified if data['backend'] == 'google-oauth2': email_verified = data['kwargs']['response']['verified_email'] link = response['link'] picture = response['picture'] gender = response['gender'] elif data['backend'] == 'facebook': email_verified = True link = response['link'] picture = response['picture'] gender = response['gender'] # TODO: use location to autofill form field (hometown/location); elif data['backend'] == 'vkontakte-oauth2': email_verified = False link = 'http://vk.com/id' + str(response['user_id']) picture = response['photo'] gender = '' # TODO: get more data http://vk.com/developers.php?oid=-1&p=%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9_%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D0%B0_fields # TODO: use link, picture, gender # Check if account with this email already exists try: user = User.objects.get(email=email) except (User.DoesNotExist, User.MultipleObjectsReturned): pass else: if email_verified: return finish_social_registration(request, data, user) else: pass # TODO: what to do? form_params = {'email_verified': email_verified} if email_verified: form_params['email'] = email if request.method == 'POST': form = SocialRegistrationForm(request.POST, **form_params) if form.is_valid(): profile = form.save() if email_verified: return finish_social_registration(request, data, profile.user) else: # TODO: redirect to registration_completed before logging in return finish_social_registration(request, data, profile.user) # TODO: if email needs to be confirmed, redirect to registration_completed or /complete/<backend>/, # else - profile return redirect('registration_completed') else: form = SocialRegistrationForm(**form_params) form.initial['first_name'] = details['first_name'] form.initial['last_name'] = details['last_name'] if not email_verified: form.initial['email'] = email return TemplateResponse(request, 'auth/register.html', {'form': form})