263 lines
10 KiB
Python
263 lines
10 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os, shutil
|
|
from urlparse import urlsplit
|
|
|
|
from pyquery import PyQuery
|
|
|
|
from django.core.urlresolvers import reverse as urlreverse
|
|
from django.contrib.auth.models import User
|
|
from django.conf import settings
|
|
|
|
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
|
|
from ietf.utils.test_data import make_test_data
|
|
from ietf.utils.mail import outbox, empty_outbox
|
|
from ietf.person.models import Person, Email
|
|
from ietf.group.models import Group, Role, RoleName
|
|
|
|
class IetfAuthTests(TestCase):
|
|
def setUp(self):
|
|
self.saved_htpasswd_file = settings.HTPASSWD_FILE
|
|
self.htpasswd_dir = os.path.abspath("tmp-htpasswd-dir")
|
|
os.mkdir(self.htpasswd_dir)
|
|
settings.HTPASSWD_FILE = os.path.join(self.htpasswd_dir, "htpasswd")
|
|
open(settings.HTPASSWD_FILE, 'a').close() # create empty file
|
|
self.saved_htdigest_realm = getattr(settings, "HTDIGEST_REALM", None)
|
|
settings.HTDIGEST_REALM = "test-realm"
|
|
|
|
def tearDown(self):
|
|
shutil.rmtree(self.htpasswd_dir)
|
|
settings.HTPASSWD_FILE = self.saved_htpasswd_file
|
|
settings.HTDIGEST_REALM = self.saved_htdigest_realm
|
|
|
|
def test_index(self):
|
|
self.assertEqual(self.client.get(urlreverse("ietf.ietfauth.views.index")).status_code, 200)
|
|
|
|
def test_login_and_logout(self):
|
|
make_test_data()
|
|
|
|
# try logging in without a next
|
|
r = self.client.get(urlreverse("account_login"))
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
r = self.client.post(urlreverse("account_login"), {"username":"plain", "password":"plain+password"})
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(urlsplit(r["Location"])[2], "/accounts/profile/")
|
|
|
|
# try logging out
|
|
r = self.client.get(urlreverse("account_logout"))
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
r = self.client.get(urlreverse("account_profile"))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(urlsplit(r["Location"])[2], "/accounts/login/")
|
|
|
|
# try logging in with a next
|
|
r = self.client.post(urlreverse("account_login") + "?next=/foobar", {"username":"plain", "password":"plain+password"})
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(urlsplit(r["Location"])[2], "/foobar")
|
|
|
|
def extract_confirm_url(self, confirm_email):
|
|
# dig out confirm_email link
|
|
msg = confirm_email.get_payload(decode=True)
|
|
line_start = "http"
|
|
confirm_url = None
|
|
for line in msg.split("\n"):
|
|
if line.strip().startswith(line_start):
|
|
confirm_url = line.strip()
|
|
self.assertTrue(confirm_url)
|
|
|
|
return confirm_url
|
|
|
|
def username_in_htpasswd_file(self, username):
|
|
with open(settings.HTPASSWD_FILE) as f:
|
|
for l in f:
|
|
if l.startswith(username + ":" + settings.HTDIGEST_REALM):
|
|
return True
|
|
return False
|
|
|
|
def test_create_account(self):
|
|
make_test_data()
|
|
|
|
url = urlreverse('create_account')
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# register email
|
|
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.assertEqual(len(outbox), 1)
|
|
|
|
# go to confirm page
|
|
confirm_url = self.extract_confirm_url(outbox[-1])
|
|
r = self.client.get(confirm_url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# password mismatch
|
|
r = self.client.post(confirm_url, { 'password': 'secret', 'password_confirmation': 'nosecret' })
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(User.objects.filter(username=email).count(), 0)
|
|
|
|
# confirm
|
|
r = self.client.post(confirm_url, { 'password': 'secret', 'password_confirmation': 'secret' })
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(User.objects.filter(username=email).count(), 1)
|
|
self.assertEqual(Person.objects.filter(user__username=email).count(), 1)
|
|
self.assertEqual(Email.objects.filter(person__user__username=email).count(), 1)
|
|
|
|
self.assertTrue(self.username_in_htpasswd_file(email))
|
|
|
|
def test_profile(self):
|
|
make_test_data()
|
|
|
|
username = "plain"
|
|
email_address = Email.objects.filter(person__user__username=username).first().address
|
|
|
|
url = urlreverse('account_profile')
|
|
login_testing_unauthorized(self, username, url)
|
|
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('.form-control-static:contains("%s")' % username)), 1)
|
|
self.assertEqual(len(q('[name="active_emails"][value="%s"][checked]' % email_address)), 1)
|
|
|
|
base_data = {
|
|
"name": u"Test Nãme",
|
|
"ascii": u"Test Name",
|
|
"ascii_short": u"T. Name",
|
|
"address": "Test address",
|
|
"affiliation": "Test Org",
|
|
"active_emails": email_address,
|
|
}
|
|
|
|
# edit details - faulty ASCII
|
|
faulty_ascii = base_data.copy()
|
|
faulty_ascii["ascii"] = u"Test Nãme"
|
|
r = self.client.post(url, faulty_ascii)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q("form .has-error")) > 0)
|
|
|
|
# edit details
|
|
r = self.client.post(url, base_data)
|
|
self.assertEqual(r.status_code, 200)
|
|
person = Person.objects.get(user__username=username)
|
|
self.assertEqual(person.name, u"Test Nãme")
|
|
self.assertEqual(person.ascii, u"Test Name")
|
|
self.assertEqual(Person.objects.filter(alias__name=u"Test Name", user__username=username).count(), 1)
|
|
self.assertEqual(Person.objects.filter(alias__name=u"Test Nãme", user__username=username).count(), 1)
|
|
self.assertEqual(Email.objects.filter(address=email_address, person__user__username=username, active=True).count(), 1)
|
|
|
|
# deactivate address
|
|
without_email_address = { k: v for k, v in base_data.iteritems() if k != "active_emails" }
|
|
|
|
r = self.client.post(url, without_email_address)
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(Email.objects.filter(address=email_address, person__user__username="plain", active=True).count(), 0)
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[name="%s"][checked]' % email_address)), 0)
|
|
|
|
# add email address
|
|
empty_outbox()
|
|
new_email_address = "plain2@example.com"
|
|
with_new_email_address = base_data.copy()
|
|
with_new_email_address["new_email"] = new_email_address
|
|
r = self.client.post(url, with_new_email_address)
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(len(outbox), 1)
|
|
|
|
# confirm new email address
|
|
confirm_url = self.extract_confirm_url(outbox[-1])
|
|
r = self.client.get(confirm_url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[name="action"][value=confirm]')), 1)
|
|
|
|
r = self.client.post(confirm_url, { "action": "confirm" })
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(Email.objects.filter(address=new_email_address, person__user__username=username, active=1).count(), 1)
|
|
|
|
# check that we can't re-add it - that would give a duplicate
|
|
r = self.client.get(confirm_url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[name="action"][value="confirm"]')), 0)
|
|
|
|
# change role email
|
|
role = Role.objects.create(
|
|
person=Person.objects.get(user__username=username),
|
|
email=Email.objects.get(address=email_address),
|
|
name=RoleName.objects.get(slug="chair"),
|
|
group=Group.objects.get(acronym="mars"),
|
|
)
|
|
|
|
role_email_input_name = "role_%s-email" % role.pk
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[name="%s"]' % role_email_input_name)), 1)
|
|
|
|
with_changed_role_email = base_data.copy()
|
|
with_changed_role_email["active_emails"] = new_email_address
|
|
with_changed_role_email[role_email_input_name] = new_email_address
|
|
r = self.client.post(url, with_changed_role_email)
|
|
self.assertEqual(r.status_code, 200)
|
|
updated_roles = Role.objects.filter(person=role.person, name=role.name, group=role.group)
|
|
self.assertEqual(len(updated_roles), 1)
|
|
self.assertEqual(updated_roles[0].email_id, new_email_address)
|
|
|
|
|
|
def test_reset_password(self):
|
|
url = urlreverse('password_reset')
|
|
|
|
user = User.objects.create(username="someone@example.com", email="someone@example.com")
|
|
user.set_password("forgotten")
|
|
user.save()
|
|
p = Person.objects.create(name="Some One", ascii="Some One", user=user)
|
|
Email.objects.create(address=user.username, person=p)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# ask for reset, wrong username
|
|
r = self.client.post(url, { 'email': "nobody@example.com" })
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q("form .has-error")) > 0)
|
|
|
|
# ask for reset
|
|
empty_outbox()
|
|
r = self.client.post(url, { 'email': user.username })
|
|
self.assertEqual(r.status_code, 200)
|
|
self.assertEqual(len(outbox), 1)
|
|
|
|
# go to change password page
|
|
confirm_url = self.extract_confirm_url(outbox[-1])
|
|
r = self.client.get(confirm_url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# password mismatch
|
|
r = self.client.post(confirm_url, { 'password': 'secret', 'password_confirmation': 'nosecret' })
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q("form .has-error")) > 0)
|
|
|
|
# confirm
|
|
r = self.client.post(confirm_url, { 'password': 'secret', 'password_confirmation': 'secret' })
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q("form .has-error")), 0)
|
|
self.assertTrue(self.username_in_htpasswd_file(user.username))
|