Increased the requirements for account creation, and added a form where the secretariat can add whitelisting to make account creation possible for addresses that don't fulfil the default requirements.

- Legacy-Id: 11374
This commit is contained in:
Henrik Levkowetz 2016-06-14 21:39:12 +00:00
parent b0ddd0daeb
commit fed2a04445
6 changed files with 219 additions and 17 deletions

View file

@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse as urlreverse
import debug # pyflakes:ignore
from ietf.person.models import Person, Email
from ietf.mailinglists.models import Whitelisted
class RegistrationForm(forms.Form):
@ -118,3 +119,9 @@ class ResetPasswordForm(forms.Form):
class TestEmailForm(forms.Form):
email = forms.EmailField(required=False)
class WhitelistForm(ModelForm):
class Meta:
model = Whitelisted
exclude = ['by', 'time' ]

View file

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
import os, shutil
from __future__ import unicode_literals
import os, shutil, time
from urlparse import urlsplit
from pyquery import PyQuery
from unittest import skipIf
@ -15,6 +17,8 @@ from ietf.utils.mail import outbox, empty_outbox
from ietf.person.models import Person, Email
from ietf.group.models import Group, Role, RoleName
from ietf.ietfauth.htpasswd import update_htpasswd_file
from ietf.mailinglists.models import Subscribed
import ietf.ietfauth.views
if os.path.exists(settings.HTPASSWD_COMMAND):
@ -94,7 +98,7 @@ class IetfAuthTests(TestCase):
return False
def test_create_account(self):
def test_create_account_failure(self):
make_test_data()
url = urlreverse(ietf.ietfauth.views.create_account)
@ -103,12 +107,21 @@ class IetfAuthTests(TestCase):
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
# register email
# register email and verify failure
email = 'new-account@example.com'
empty_outbox()
r = self.client.post(url, { 'email': email })
self.assertEqual(r.status_code, 200)
self.assertTrue("Account created" in unicontent(r))
self.assertIn("Account creation failed", unicontent(r))
def register_and_verify(self, email):
url = urlreverse(ietf.ietfauth.views.create_account)
# register email
empty_outbox()
r = self.client.post(url, { 'email': email })
self.assertEqual(r.status_code, 200)
self.assertIn("Account created", unicontent(r))
self.assertEqual(len(outbox), 1)
# go to confirm page
@ -130,6 +143,41 @@ class IetfAuthTests(TestCase):
self.assertTrue(self.username_in_htpasswd_file(email))
def test_create_whitelisted_account(self):
email = "new-account@example.com"
# add whitelist entry
r = self.client.post(urlreverse(django.contrib.auth.views.login), {"username":"secretary", "password":"secretary+password"})
self.assertEqual(r.status_code, 302)
self.assertEqual(urlsplit(r["Location"])[2], urlreverse(ietf.ietfauth.views.profile))
r = self.client.get(urlreverse(ietf.ietfauth.views.add_account_whitelist))
self.assertEqual(r.status_code, 200)
self.assertIn("Add a whitelist entry", unicontent(r))
r = self.client.post(urlreverse(ietf.ietfauth.views.add_account_whitelist), {"address": email})
self.assertEqual(r.status_code, 200)
self.assertIn("Whitelist entry creation successful", unicontent(r))
# log out
r = self.client.get(urlreverse(django.contrib.auth.views.logout))
self.assertEqual(r.status_code, 200)
# register and verify whitelisted email
self.register_and_verify(email)
def test_create_subscribed_account(self):
# verify creation with email in subscribed list
saved_delay = settings.LIST_ACCOUNT_DELAY
settings.LIST_ACCOUNT_DELAY = 1
email = "subscribed@example.com"
s = Subscribed(address=email)
s.save()
time.sleep(1.1)
self.register_and_verify(email)
settings.LIST_ACCOUNT_DELAY = saved_delay
def test_profile(self):
make_test_data()

View file

@ -3,6 +3,8 @@
from django.conf.urls import patterns, url
from django.contrib.auth.views import login, logout
from ietf.ietfauth.views import add_account_whitelist
urlpatterns = patterns('ietf.ietfauth.views',
url(r'^$', 'index'),
# url(r'^login/$', 'ietf_login'),
@ -18,4 +20,5 @@ urlpatterns = patterns('ietf.ietfauth.views',
url(r'^reset/$', 'password_reset'),
url(r'^reset/confirm/(?P<auth>[^/]+)/$', 'confirm_password_reset'),
url(r'^confirmnewemail/(?P<auth>[^/]+)/$', 'confirm_new_email'),
(r'whitelist/add/?$', add_account_whitelist),
)

View file

@ -32,6 +32,8 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from datetime import datetime as DateTime, timedelta as TimeDelta
from django.conf import settings
from django.http import Http404 #, HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
@ -42,10 +44,14 @@ import django.core.signing
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
import debug # pyflakes:ignore
from ietf.group.models import Role
from ietf.ietfauth.forms import RegistrationForm, PasswordForm, ResetPasswordForm, TestEmailForm
from ietf.ietfauth.forms import RegistrationForm, PasswordForm, ResetPasswordForm, TestEmailForm, WhitelistForm
from ietf.ietfauth.forms import get_person_form, RoleEmailForm, NewEmailForm
from ietf.ietfauth.htpasswd import update_htpasswd_file
from ietf.ietfauth.utils import role_required
from ietf.mailinglists.models import Subscribed, Whitelisted
from ietf.person.models import Person, Email, Alias
from ietf.utils.mail import send_mail
@ -85,20 +91,25 @@ def create_account(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
to_email = form.cleaned_data['email']
to_email = form.cleaned_data['email'] # This will be lowercase if form.is_valid()
existing = Subscribed.objects.filter(address=to_email).first()
ok_to_create = ( Whitelisted.objects.filter(address=to_email).exists()
or existing and (existing.time + TimeDelta(seconds=settings.LIST_ACCOUNT_DELAY)) < DateTime.now() )
if ok_to_create:
auth = django.core.signing.dumps(to_email, salt="create_account")
auth = django.core.signing.dumps(to_email, salt="create_account")
domain = Site.objects.get_current().domain
subject = 'Confirm registration at %s' % domain
from_email = settings.DEFAULT_FROM_EMAIL
domain = Site.objects.get_current().domain
subject = 'Confirm registration at %s' % domain
from_email = settings.DEFAULT_FROM_EMAIL
send_mail(request, to_email, from_email, subject, 'registration/creation_email.txt', {
'domain': domain,
'auth': auth,
'username': to_email,
'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK,
})
send_mail(request, to_email, from_email, subject, 'registration/creation_email.txt', {
'domain': domain,
'auth': auth,
'username': to_email,
'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK,
})
else:
return render(request, 'registration/manual.html', { 'account_request_email': settings.ACCOUNT_REQUEST_EMAIL })
else:
form = RegistrationForm()
@ -359,3 +370,22 @@ def test_email(request):
r.set_cookie("testmailcc", cookie)
return r
@role_required('Secretariat')
def add_account_whitelist(request):
success = False
if request.method == 'POST':
form = WhitelistForm(request.POST)
if form.is_valid():
address = form.cleaned_data['address']
entry = Whitelisted(address=address, by=request.user.person)
entry.save()
success = True
else:
form = WhitelistForm()
return render(request, 'ietfauth/whitelist_form.html', {
'form': form,
'success': success,
})

View file

@ -0,0 +1,93 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2016, All Rights Reserved #}
{% load origin %}
{% load bootstrap3 %}
{% block title %}Set up test email address{% endblock %}
{% block content %}
{% origin %}
{% if success %}
<h1>Whitelist entry creation successful</h1>
<p>
Please ask the requestor to try the
<a href="{% url 'ietf.ietfauth.views.create_account'%}">account creation form</a>
again, with the whitelisted email address.
</p>
{% else %}
<h1>Add a whitelist entry for account creation.</h1>
<p>
When an email request comes in for assistance with account creation
because the automated account creation has failed, you can add the
address to an account creation whitelist here.
</p>
<p>
Before you do so, please complete the following 3 verification steps:
<ol>
<li>
Has the person provided relevant information in his request, or has he simply
copied the text from the account creation failure message? All genuine (non-spam)
account creation requests seen between 2009 and 2016 for tools.ietf.org has
contained a reasonable request message, rather than just copy-pasting the account
creation failure message. If there's no proper request message, step 2 below can
be performed to make sure the request is bogus, but if that also fails, no further
effort should be needed.
</li>
<li>
Google for the person's name within the ietf site: "Jane Doe site:ietf.org". If
found, and the email address matches an address used in drafts or discussions,
things are fine, and it's OK to add the address to the whitelist using this form,
and ask the person to please try the <a href="{% url
'ietf.ietfauth.views.create_account' %}">account creation form</a> again.
</li>
<li>
<p>
If google finds no trace of the person being an ietf participant, he or she could
still be somebody who is just getting involved in IETF work. A datatracker account
is probably not necessary, but in case this is a legitimate request, please email
the person and ask:
</p>
<blockquote>
"Which wgs do you require a password for?"
</blockquote>
<p>
This is a bit of a trick question, because it is very unlikely that somebody who
isn't involved in IETF work will give a reasonable response, while almost any answer
from somebody who is doing IETF work will show that they have some clue.
</p>
<p>
If the answer to this question shows clue, then add the address to the whitelist
using this form, and ask the person to please try the <a href="{% url
'ietf.ietfauth.views.create_account' %}"> account creation form</a> again.
</p>
</li>
</ol>
</p>
<form role-"form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button class="btn btn-primary" type="submit">Add address to account creation whitelist</button>
{% endbuttons %}
</form>
{% endif %}
{% endblock %}

View file

@ -0,0 +1,21 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load bootstrap3 %}
{% block title %}Complete account creation{% endblock %}
{% block content %}
{% origin %}
<h1>Account creation failed</h1>
<p>
Manual intervention is needed to enable account creation for you.
Please send an email to {{ account_request_email }}
and explain 1) the situation and 2) your need for an account,
in order to receive further assistance.
</p>
{% endblock %}