Modified the rolodex code to make sure we capture information about the origin of email addresses if they are added by the secretariat, to ensure GPR compliance.
- Legacy-Id: 15898
This commit is contained in:
parent
d19228110c
commit
4e8ef492fc
25
ietf/person/migrations/0009_auto_20190118_0725.py
Normal file
25
ietf/person/migrations/0009_auto_20190118_0725.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.18 on 2019-01-18 07:25
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('person', '0008_auto_20181014_1448'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='email',
|
||||
name='origin',
|
||||
field=models.CharField(help_text=b"The origin of the address: the user's email address, or 'author: DRAFTNAME' if a draft, or 'role: GROUP/ROLE' if a role.", max_length=150),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='historicalemail',
|
||||
name='origin',
|
||||
field=models.CharField(help_text=b"The origin of the address: the user's email address, or 'author: DRAFTNAME' if a draft, or 'role: GROUP/ROLE' if a role.", max_length=150),
|
||||
),
|
||||
]
|
|
@ -258,7 +258,7 @@ class Email(models.Model):
|
|||
person = ForeignKey(Person, null=True)
|
||||
time = models.DateTimeField(auto_now_add=True)
|
||||
primary = models.BooleanField(default=False)
|
||||
origin = models.CharField(max_length=150, default='', editable=False) # User.username or Document.name
|
||||
origin = models.CharField(max_length=150, blank=False, help_text="The origin of the address: the user's email address, or 'author: DRAFTNAME' if a draft, or 'role: GROUP/ROLE' if a role.") # User.username or Document.name
|
||||
active = models.BooleanField(default=True) # Old email addresses are *not* purged, as history
|
||||
# information points to persons through these
|
||||
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
# Copyright The IETF Trust 2016, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
|
||||
import re
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||
from django.core.validators import validate_email
|
||||
from django.core.validators import validate_email, EmailValidator
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.models import Document
|
||||
from ietf.group.models import Group
|
||||
from ietf.name.models import RoleName
|
||||
from ietf.person.models import Email, Person
|
||||
|
||||
import re
|
||||
|
||||
class SearchForm(forms.Form):
|
||||
name = forms.CharField(max_length=50,required=False)
|
||||
|
@ -27,7 +37,37 @@ class EmailForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = Email
|
||||
fields = '__all__'
|
||||
widgets = {'address': forms.TextInput(attrs={'readonly':True})}
|
||||
widgets = {
|
||||
'address': forms.TextInput(attrs={'readonly':True}),
|
||||
'origin': forms.TextInput(attrs={'blank':False}),
|
||||
}
|
||||
|
||||
def clean_origin(self):
|
||||
validate_email = EmailValidator("Please provide the origin of the new email: A valid user email if provided by email, or 'author: doc' or 'role: role spec'.")
|
||||
if 'origin' in self.changed_data and self.instance.origin:
|
||||
raise forms.ValidationError("You may not change existing origin fields, only set the value when empty")
|
||||
origin = self.cleaned_data['origin']
|
||||
if ':' in origin:
|
||||
valid_tags = ['author', 'role', 'registration', ]
|
||||
tag, value = [ v.strip() for v in origin.split(':', 1) ]
|
||||
if not tag in valid_tags:
|
||||
raise forms.ValidationError("Invalid tag. Valid tags are: %s" % ','.join(valid_tags))
|
||||
if tag == 'author':
|
||||
if not Document.objects.filter(name=value).exists():
|
||||
raise forms.ValidationError("Invalid document: %s. A valid document is required with 'author:'" % value)
|
||||
elif tag == 'role':
|
||||
if not ' ' in value:
|
||||
raise forms.ValidationError("Invalid role spec: %s. Please indicate 'group role'." % value)
|
||||
acronym, slug = value.split(None, 1)
|
||||
if not Group.objects.filter(acronym=acronym).exists():
|
||||
raise forms.ValidationError("Invalid group: %s. A valid 'group role' string is required with 'role:'" % acronym)
|
||||
if not RoleName.objects.filter(slug=slug).exists():
|
||||
roles = RoleName.objects.values_list('slug', flat=True)
|
||||
raise forms.ValidationError("Invalid role: %s. A valid 'group role' string is required with 'role:'.\n Valid roles are: %s" % (slug, ', '.join(roles)))
|
||||
else:
|
||||
validate_email(origin)
|
||||
return origin
|
||||
|
||||
|
||||
class EditPersonForm(forms.ModelForm):
|
||||
class Meta:
|
||||
|
|
|
@ -3,6 +3,7 @@ from django.urls import reverse
|
|||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.utils.test_utils import TestCase
|
||||
from ietf.group.factories import GroupFactory, RoleFactory
|
||||
from ietf.person.factories import PersonFactory, UserFactory
|
||||
from ietf.person.models import Person, User
|
||||
|
||||
|
@ -47,11 +48,15 @@ class RolodexTestCase(TestCase):
|
|||
|
||||
def test_edit_replace_user(self):
|
||||
person = PersonFactory()
|
||||
email = person.email()
|
||||
user = UserFactory()
|
||||
group = GroupFactory(type_id='wg')
|
||||
role = RoleFactory(group=group,name_id='chair',person=person)
|
||||
url = reverse('ietf.secr.rolodex.views.edit', kwargs={'id':person.id})
|
||||
redirect_url = reverse('ietf.secr.rolodex.views.view', kwargs={'id':person.id})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
#debug.show('unicontent(response)')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
post_data = {
|
||||
'name': person.name,
|
||||
|
@ -59,8 +64,12 @@ class RolodexTestCase(TestCase):
|
|||
'ascii_short': person.ascii_short,
|
||||
'user': user.username,
|
||||
'email-0-person':person.pk,
|
||||
'email-0-address': person.email_address(),
|
||||
'email-TOTAL_FORMS':1,
|
||||
'email-0-address': email.address,
|
||||
'email-0-origin': email.origin,
|
||||
'email-1-person':person.pk,
|
||||
'email-1-address': 'name@example.com',
|
||||
'email-1-origin': 'role: %s %s' % (group.acronym, role.name.slug),
|
||||
'email-TOTAL_FORMS':2,
|
||||
'email-INITIAL_FORMS':1,
|
||||
'email-MIN_NUM_FORMS':0,
|
||||
'email-MAX_NUM_FORMS':1000,
|
||||
|
|
|
@ -612,11 +612,11 @@ td.document-name {
|
|||
========================================================================== */
|
||||
|
||||
form[id^="rolodex-"] input[type=text] {
|
||||
width: 30em;
|
||||
width: 25em;
|
||||
}
|
||||
|
||||
form[id^="rolodex-"] #id_address {
|
||||
width: 30em;
|
||||
width: 25em;
|
||||
height: 7em;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue