Implement OpenID signups.

This allows users on signup-eligible domains to sign up for Humbug using
Google Apps.

As part of this, we wrap the openid done view in our own code in order to
handle the "Unknown user" error. Therein, we create a PreregistrationUser
and then shunt the user through the rest of the confirmation process, pre-
filling in their name.

(imported from commit 066d9a1021384a6da2662352e62a701451bd6f44)
This commit is contained in:
Luke Faraone 2013-04-23 14:46:12 -07:00
parent c044282af5
commit c48ff1784c
4 changed files with 44 additions and 3 deletions

View File

@ -16,6 +16,7 @@ import zephyr.forms
urlpatterns = patterns('',
url(r'^$', 'zephyr.views.home'),
url(r'^accounts/login/openid/$', 'django_openid_auth.views.login_begin', name='openid-login'),
url(r'^accounts/login/openid/done/$', 'zephyr.views.process_openid_login', name='openid-complete'),
url(r'^accounts/login/openid/done/$', 'django_openid_auth.views.login_complete', name='openid-complete'),
# We have two entries for accounts/login to allow reverses on the Django
# view we're wrapping to continue to function.

View File

@ -12,6 +12,7 @@ post to another view which executes in our code to produce the desired form.
{% csrf_token %}
<input type="hidden" value="{{ key }}" name="key"/>
<input type="hidden" value="1" name="from_confirmation"/>
<input type="hidden" value="{{ gafyd_name }}" name="gafyd_name"/>
</form>
<script type="text/javascript">

View File

@ -36,7 +36,7 @@ Form is validated both client-side using jquery-validate (see signup.js) and ser
<label for="id_full_name" class="control-label">Full name</label>
<div class="controls">
<input id="id_full_name" class="required" type="text" name="full_name"
value="{% if form.full_name.value %}{{ form.full_name.value }}{% endif %}"
value="{% if form.full_name.value %}{{ form.full_name.value }}{% else %}{{ gafyd_name }}{% endif %}"
maxlength="100" />
{% if form.full_name.errors %}
{% for error in form.full_name.errors %}
@ -51,6 +51,10 @@ Form is validated both client-side using jquery-validate (see signup.js) and ser
<input id="id_password" class="required" type="password" name="password"
value="{% if form.password.value %}{{ form.password.value }}{% endif %}"
maxlength="100" />
{% if gafyd_name %}
<span class="help-inline">This is used for mobile applications and other tools that don't support Google Apps authentication.</span>
<input type="hidden" value="{{ gafyd_name }}" name="gafyd_name"/>
{% endif %}
{% if form.password.errors %}
{% for error in form.password.errors %}
<div class="alert alert-error">{{ error }}</div>

View File

@ -33,6 +33,9 @@ from zephyr.lib.actions import do_add_subscription, do_remove_subscription, \
from zephyr.forms import RegistrationForm, HomepageForm, ToSForm, is_unique, \
is_inactive, isnt_mit
from django.views.decorators.csrf import csrf_exempt
from django_openid_auth.views import default_render_failure, login_complete, parse_openid_response
from openid.consumer.consumer import SUCCESS as openid_SUCCESS
from openid.extensions import ax
from zephyr.decorator import require_post, \
authenticated_api_view, authenticated_json_post_view, \
@ -256,12 +259,17 @@ def accounts_register(request):
return HttpResponseRedirect(reverse('zephyr.views.home'))
return render_to_response('zephyr/register.html',
{ 'form': form, 'company_name': domain, 'email': email, 'key': key },
{'form': form,
'company_name': domain,
'email': email,
'key': key,
'gafyd_name': request.POST.get('gafyd_name', False),
},
context_instance=RequestContext(request))
@login_required(login_url = settings.HOME_NOT_LOGGED_IN)
def accounts_accept_terms(request):
email = request.email
email = request.user.email
company_name = email.split('@')[-1]
if request.method == "POST":
form = ToSForm(request.POST)
@ -390,6 +398,33 @@ so we didn't send them an invitation. We did send invitations to everyone else!"
else:
return json_success()
def handle_openid_errors(request, issue, openid_response=None):
if issue == "Unknown user":
if openid_response is not None and openid_response.status == openid_SUCCESS:
ax_response = ax.FetchResponse.fromSuccessResponse(openid_response)
google_email = openid_response.getSigned('http://openid.net/srv/ax/1.0', 'value.email')
full_name = " ".join((
ax_response.get('http://axschema.org/namePerson/first')[0],
ax_response.get('http://axschema.org/namePerson/last')[0]))
form = HomepageForm({'email': google_email})
request.verified_email = None
if form.is_valid():
# Construct a PreregistrationUser object and send the user over to
# the confirmation view.
prereg_user = PreregistrationUser()
prereg_user.email = google_email
prereg_user.save()
return redirect("".join((
Confirmation.objects.get_link_for_object(prereg_user),
'?gafyd_name=',
urllib.quote_plus(full_name))))
else:
return render_to_response('zephyr/accounts_home.html', {'form': form})
return default_render_failure(request, issue)
def process_openid_login(request):
return login_complete(request, render_failure=handle_openid_errors)
def login_page(request, **kwargs):
template_response = django_login_page(request, **kwargs)
try: