Skip to content

Commit 4e8ef49

Browse files
committed
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
1 parent d192281 commit 4e8ef49

5 files changed

Lines changed: 82 additions & 8 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.18 on 2019-01-18 07:25
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('person', '0008_auto_20181014_1448'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='email',
17+
name='origin',
18+
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),
19+
),
20+
migrations.AlterField(
21+
model_name='historicalemail',
22+
name='origin',
23+
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),
24+
),
25+
]

ietf/person/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ class Email(models.Model):
258258
person = ForeignKey(Person, null=True)
259259
time = models.DateTimeField(auto_now_add=True)
260260
primary = models.BooleanField(default=False)
261-
origin = models.CharField(max_length=150, default='', editable=False) # User.username or Document.name
261+
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
262262
active = models.BooleanField(default=True) # Old email addresses are *not* purged, as history
263263
# information points to persons through these
264264

ietf/secr/rolodex/forms.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1+
# Copyright The IETF Trust 2016, All Rights Reserved
2+
# -*- coding: utf-8 -*-
3+
from __future__ import unicode_literals, print_function
4+
5+
import re
6+
17
from django import forms
28
from django.conf import settings
39
from django.contrib.auth.models import User
410
from django.core.exceptions import ObjectDoesNotExist, ValidationError
5-
from django.core.validators import validate_email
11+
from django.core.validators import validate_email, EmailValidator
12+
13+
import debug # pyflakes:ignore
614

15+
from ietf.doc.models import Document
16+
from ietf.group.models import Group
17+
from ietf.name.models import RoleName
718
from ietf.person.models import Email, Person
819

9-
import re
1020

1121
class SearchForm(forms.Form):
1222
name = forms.CharField(max_length=50,required=False)
@@ -27,7 +37,37 @@ class EmailForm(forms.ModelForm):
2737
class Meta:
2838
model = Email
2939
fields = '__all__'
30-
widgets = {'address': forms.TextInput(attrs={'readonly':True})}
40+
widgets = {
41+
'address': forms.TextInput(attrs={'readonly':True}),
42+
'origin': forms.TextInput(attrs={'blank':False}),
43+
}
44+
45+
def clean_origin(self):
46+
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'.")
47+
if 'origin' in self.changed_data and self.instance.origin:
48+
raise forms.ValidationError("You may not change existing origin fields, only set the value when empty")
49+
origin = self.cleaned_data['origin']
50+
if ':' in origin:
51+
valid_tags = ['author', 'role', 'registration', ]
52+
tag, value = [ v.strip() for v in origin.split(':', 1) ]
53+
if not tag in valid_tags:
54+
raise forms.ValidationError("Invalid tag. Valid tags are: %s" % ','.join(valid_tags))
55+
if tag == 'author':
56+
if not Document.objects.filter(name=value).exists():
57+
raise forms.ValidationError("Invalid document: %s. A valid document is required with 'author:'" % value)
58+
elif tag == 'role':
59+
if not ' ' in value:
60+
raise forms.ValidationError("Invalid role spec: %s. Please indicate 'group role'." % value)
61+
acronym, slug = value.split(None, 1)
62+
if not Group.objects.filter(acronym=acronym).exists():
63+
raise forms.ValidationError("Invalid group: %s. A valid 'group role' string is required with 'role:'" % acronym)
64+
if not RoleName.objects.filter(slug=slug).exists():
65+
roles = RoleName.objects.values_list('slug', flat=True)
66+
raise forms.ValidationError("Invalid role: %s. A valid 'group role' string is required with 'role:'.\n Valid roles are: %s" % (slug, ', '.join(roles)))
67+
else:
68+
validate_email(origin)
69+
return origin
70+
3171

3272
class EditPersonForm(forms.ModelForm):
3373
class Meta:

ietf/secr/rolodex/tests.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import debug # pyflakes:ignore
44

55
from ietf.utils.test_utils import TestCase
6+
from ietf.group.factories import GroupFactory, RoleFactory
67
from ietf.person.factories import PersonFactory, UserFactory
78
from ietf.person.models import Person, User
89

@@ -47,20 +48,28 @@ def test_add(self):
4748

4849
def test_edit_replace_user(self):
4950
person = PersonFactory()
51+
email = person.email()
5052
user = UserFactory()
53+
group = GroupFactory(type_id='wg')
54+
role = RoleFactory(group=group,name_id='chair',person=person)
5155
url = reverse('ietf.secr.rolodex.views.edit', kwargs={'id':person.id})
5256
redirect_url = reverse('ietf.secr.rolodex.views.view', kwargs={'id':person.id})
5357
self.client.login(username="secretary", password="secretary+password")
5458
response = self.client.get(url)
59+
#debug.show('unicontent(response)')
5560
self.assertEqual(response.status_code, 200)
5661
post_data = {
5762
'name': person.name,
5863
'ascii': person.ascii,
5964
'ascii_short': person.ascii_short,
6065
'user': user.username,
6166
'email-0-person':person.pk,
62-
'email-0-address': person.email_address(),
63-
'email-TOTAL_FORMS':1,
67+
'email-0-address': email.address,
68+
'email-0-origin': email.origin,
69+
'email-1-person':person.pk,
70+
'email-1-address': 'name@example.com',
71+
'email-1-origin': 'role: %s %s' % (group.acronym, role.name.slug),
72+
'email-TOTAL_FORMS':2,
6473
'email-INITIAL_FORMS':1,
6574
'email-MIN_NUM_FORMS':0,
6675
'email-MAX_NUM_FORMS':1000,

ietf/secr/static/secr/css/custom.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,11 @@ td.document-name {
612612
========================================================================== */
613613

614614
form[id^="rolodex-"] input[type=text] {
615-
width: 30em;
615+
width: 25em;
616616
}
617617

618618
form[id^="rolodex-"] #id_address {
619-
width: 30em;
619+
width: 25em;
620620
height: 7em;
621621
}
622622

0 commit comments

Comments
 (0)