Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve registration #1037

Merged
merged 4 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions frontend/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,6 @@ <h3 class="module-title">Start Ungluing Now!</h3>
<label>Email</label>
<input id="id_email_main" type="text" class="required" name="email" maxlength="75" size="30" />
</div>
<div class="password">
<label>Password</label>
<input id="id_password1_main" type="password" class="required" name="password1" size="30" />
</div>
<div class="password">
<label>Password (again):</label>
<input id="id_password2_main" type="password" class="required" name="password2" size="30" />
</div>
<div class="button">
<input type="submit" class="signup" value="Sign Up Now" onclick="this.disabled=true,this.form.submit();" />
Expand Down
9 changes: 8 additions & 1 deletion frontend/templates/registration/from_pledge.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% extends "registration/registration_base.html" %}

{% load humanize %}
{% load puzzle %}

{% block title %}Pledge Step 1: Login or Create an Account{% endblock %}

Expand Down Expand Up @@ -32,7 +33,8 @@
</script>
{% endblock %}

{% block content %}
{% block content %}
{% puzz %}
<div class="jsmodule rounded clearfix widecolumn">
{% block login_pitch %}<h3>You'll need an account, since we won't charge your card unless the campaign succeeds!</h3>{% endblock %}
<div class="halfcolumn2 login_box">
Expand All @@ -55,6 +57,11 @@ <h3>Get an Unglue.it account:</h3>
<label>Password (again):</label>
<input id="id_password2_main" type="password" class="required" name="password2" size="30" />
</div>
<div>
{{puzznum1}} + {{puzznum2}} =
<input type="text" name="notarobot" style="width: 2em" required="" id="id_notarobot">
<input type="hidden" name="tries" value="{{ puzzans }}" />
</div>
<div class="button">
<input type="submit" class="signup" value="Sign Up" onclick="this.disabled=true,this.form.submit();" />
</div>
Expand Down
7 changes: 7 additions & 0 deletions frontend/templates/registration/registration_form.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% extends "registration/registration_base.html" %}
{% load puzzle %}

{% block title %}Register for an account{% endblock %}
{% block extra_js %}
Expand All @@ -11,6 +12,7 @@
</script>
{% endblock %}
{% block doccontent %}
{% puzz %}
{% if not user.is_authenticated %}

<h3>Sign up for a Unglue.it account:</h3>
Expand All @@ -20,6 +22,11 @@ <h3>Sign up for a Unglue.it account:</h3>
<div>{{ form.email.label }}: {{ form.email.errors }}<br />{{ form.email }}</div>
<div>{{ form.password1.label }}: {{ form.password1.errors }}<br />{{ form.password1 }}</div>
<div>{{ form.password2.label }}: {{ form.password2.errors }}<br />{{ form.password2 }}</div>

{{ form.notarobot.label }}{{ form.notarobot.errors }}: {{puzznum1}} + {{puzznum2}} =
{{ form.notarobot }}</br />
{{ form.non_field_errors }}<br />
<input type="hidden" name="tries" value="{{ puzzans }}" />
<input type="submit" value="Send activation email" onclick="this.disabled=true,this.form.submit();" />
</form>

Expand Down
57 changes: 56 additions & 1 deletion libraryauth/forms.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,51 @@
import logging
from random import randint

from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
from django.core.cache import cache
from django.utils.translation import ugettext_lazy as _


# hack to fix bug in old version of django-registration
from registration.validators import CONFUSABLE_EMAIL
from confusable_homoglyphs import confusables
def validate_confusables_email(value):
if '@' not in value:
return
parts = value.split('@')
if len(parts) != 2:
raise forms.ValidationError(CONFUSABLE_EMAIL, code='invalid')
local_part, domain = value.split('@')
if confusables.is_dangerous(local_part) or \
confusables.is_dangerous(domain):
raise forms.ValidationError(CONFUSABLE_EMAIL, code='invalid')

import registration
registration.validators.validate_confusables_email = validate_confusables_email
# end hack

from registration.forms import RegistrationFormUniqueEmail
from .emailcheck import is_disposable
from .models import Library

logger = logging.getLogger(__name__)

rands = [randint(0,99) for i in range(0, 21)]
encoder = {k:v for (k,v) in zip(range(0, 21), rands)}
decoder = {v:k for (k,v) in zip(range(0, 21), rands)}

encode_answers = cache.get('encode_answers')
decode_answers = cache.get('decode_answers')
if not encode_answers:
cache.set('encode_answers', encoder, None)
if not decode_answers:
cache.set('decode_answers', decoder, None)
decode_answers = decoder


class UserData(forms.Form):
username = forms.RegexField(
label=_("New Username"),
Expand Down Expand Up @@ -42,14 +78,33 @@ class UserNamePass(UserData):
help_text=_("Enter the same password as above, for verification.")
)
allow_same = True
notarobot = forms.IntegerField(
label="Please show you're not a robot.",
error_messages={
'required': "",
},
widget=forms.TextInput(attrs={'style': 'width: 2em'}),
)
encode_answers = cache.get('encode_answers')

def clean_password2(self):
password1 = self.cleaned_data.get("password1", "")
password2 = self.cleaned_data["password2"]
if password1 != password2:
raise forms.ValidationError(_("The two passwords don't match."))

return password2

class RegistrationFormNoDisposableEmail(RegistrationFormUniqueEmail):
def clean_notarobot(self):
notarobot = int(self.data["notarobot"])
encoded_answer = self.encode_answers.get(notarobot, 'miss')
tries = self.data.get("tries", -1)
if str(encoded_answer) != tries:
raise forms.ValidationError("(Hint: it's addition)")

return notarobot

class RegistrationFormNoDisposableEmail(RegistrationFormUniqueEmail, UserNamePass):
def clean_email(self):
"""
Check the supplied email address against a list of known disposable
Expand Down
30 changes: 30 additions & 0 deletions libraryauth/templatetags/puzzle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from random import randint

from django.core.cache import cache
from django.template import Library

register = Library()

digits = {
0: '⓪',
1: '1',
2: '⓶',
3: '③',
4: '⑷',
5: '⒌',
6: 'six',
7: '⑦',
8: '8️⃣',
9: '𝟫',
10: '10',
}
encode_answers = cache.get('encode_answers')

@register.simple_tag(takes_context=True)
def puzz(context):
num1 = randint(0, 10)
num2 = randint(0, 10)
context['puzznum1'] = digits[num1]
context['puzznum2'] = digits[num2]
context['puzzans'] = encode_answers[num1 + num2]
return ''
8 changes: 7 additions & 1 deletion libraryauth/tests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.urls import reverse
from django.test import TestCase
from django.contrib.auth.models import User
from django.core.cache import cache


class TestLibraryAuth(TestCase):
fixtures = ['initial_data.json']
Expand All @@ -27,11 +29,15 @@ def test_registration(self):
sends an activation email.

"""
encode_answers = cache.get('encode_answers')
resp = self.client.post(reverse('registration_register'),
data={'username': 'bob',
'email': 'bob@example.com',
'password1': 'secret',
'password2': 'secret'})
'password2': 'secret',
'notarobot': '11',
'tries': str(encode_answers.get(11)),
})
self.assertRedirects(resp, reverse('registration_complete'))

new_user = User.objects.get(username='bob')
Expand Down
6 changes: 5 additions & 1 deletion libraryauth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,11 @@ def form_valid(self, form):
logger.info('special login from %s' % self.request.META['REMOTE_ADDR'])
return self.pretend_success()
try:
return super(CustomRegistrationView, self).form_valid(form)
if form.cleaned_data['password1']:
return super(CustomRegistrationView, self).form_valid(form)
else:
# it's just the user and password
return self.render_to_response({'form':form})
except IntegrityError:
# probably rapid double click
return self.pretend_success()
Expand Down