Skip to content

Commit fb8e5c6

Browse files
committed
Allow IAB programs to use normal meeting mechanics. Fixes ietf-tools#2970. Commit ready for merge.
- Legacy-Id: 17764
1 parent caa109c commit fb8e5c6

19 files changed

Lines changed: 14933 additions & 14541 deletions

ietf/group/factories.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ class Meta:
1818
list_email = factory.LazyAttribute(lambda a: '%s@ietf.org'% a.acronym)
1919
uses_milestone_dates = True
2020

21+
@factory.lazy_attribute
22+
def parent(self):
23+
if self.type_id in ['wg','ag']:
24+
return GroupFactory(type_id='area')
25+
elif self.type_id in ['rg']:
26+
return GroupFactory(acronym='irtf', type_id='irtf')
27+
else:
28+
return None
29+
2130
class ReviewTeamFactory(GroupFactory):
2231

2332
type_id = 'review'
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.29 on 2020-05-04 13:10
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations
6+
import jsonfield.fields
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('group', '0023_use_milestone_dates_default_to_true'),
13+
]
14+
15+
operations = [
16+
migrations.AddField(
17+
model_name='groupfeatures',
18+
name='groupman_authroles',
19+
field=jsonfield.fields.JSONField(default=['Secretariat'], max_length=128),
20+
),
21+
migrations.AddField(
22+
model_name='historicalgroupfeatures',
23+
name='groupman_authroles',
24+
field=jsonfield.fields.JSONField(default=['Secretariat'], max_length=128),
25+
),
26+
]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.29 on 2020-05-01 12:54
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations
6+
7+
authroles_map = {
8+
'adhoc': ['Secretariat'],
9+
'admin': ['Secretariat'],
10+
'ag': ['Secretariat', 'Area Director'],
11+
'area': ['Secretariat'],
12+
'dir': ['Secretariat'],
13+
'iab': ['Secretariat'],
14+
'iana': ['Secretariat'],
15+
'iesg': ['Secretariat'],
16+
'ietf': ['Secretariat'],
17+
'individ': [],
18+
'irtf': ['Secretariat'],
19+
'ise': ['Secretariat'],
20+
'isoc': ['Secretariat'],
21+
'nomcom': ['Secretariat'],
22+
'program': ['Secretariat', 'IAB'],
23+
'review': ['Secretariat'],
24+
'rfcedtyp': ['Secretariat'],
25+
'rg': ['Secretariat', 'IRTF Chair'],
26+
'sdo': ['Secretariat'],
27+
'team': ['Secretariat'],
28+
'wg': ['Secretariat', 'Area Director'],
29+
}
30+
31+
def forward(apps, schema_editor):
32+
GroupFeatures = apps.get_model('group', 'GroupFeatures')
33+
for type_id, authroles in authroles_map.items():
34+
GroupFeatures.objects.filter(type_id=type_id).update(groupman_authroles=authroles)
35+
36+
def reverse(apps, schema_editor):
37+
pass
38+
39+
class Migration(migrations.Migration):
40+
41+
dependencies = [
42+
('group', '0024_add_groupman_authroles'),
43+
]
44+
45+
operations = [
46+
migrations.RunPython(forward, reverse),
47+
]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.29 on 2020-05-01 12:54
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations
6+
7+
8+
def forward(apps, schema_editor):
9+
GroupFeatures = apps.get_model('group', 'GroupFeatures')
10+
program = GroupFeatures.objects.get(type_id='program')
11+
program.has_meetings = True
12+
program.matman_roles = ['lead', 'chair', 'secr']
13+
program.docman_roles = ['lead', 'chair', 'secr']
14+
program.groupman_roles = ['lead', 'chair', 'secr']
15+
program.role_order = ['lead', 'chair', 'secr']
16+
program.save()
17+
18+
def reverse(apps, schema_editor):
19+
GroupFeatures = apps.get_model('group', 'GroupFeatures')
20+
program = GroupFeatures.objects.get(type_id='program')
21+
program.has_meetings = False
22+
program.matman_roles = ['lead', 'secr']
23+
program.docman_roles = ['lead', 'secr']
24+
program.groupman_roles = ['lead', 'secr']
25+
program.role_order = ['lead', 'secr']
26+
program.save()
27+
28+
class Migration(migrations.Migration):
29+
30+
dependencies = [
31+
('group', '0025_populate_groupman_authroles'),
32+
]
33+
34+
operations = [
35+
migrations.RunPython(forward, reverse),
36+
]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.29 on 2020-05-08 09:02
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations
6+
7+
def forward(apps, schema_editor):
8+
Group = apps.get_model('group','Group')
9+
iab = Group.objects.get(acronym='iab')
10+
Group.objects.filter(type_id='program').update(parent=iab)
11+
12+
def reverse(apps, schema_editor):
13+
pass # No point in removing the parents
14+
15+
class Migration(migrations.Migration):
16+
17+
dependencies = [
18+
('group', '0026_programs_meet'),
19+
]
20+
21+
operations = [
22+
migrations.RunPython(forward, reverse),
23+
]

ietf/group/models.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@ def about_url(self):
6565
kwargs["group_type"] = self.type_id
6666
return urlreverse(self.features.about_page, kwargs=kwargs)
6767

68-
def interim_approval_roles(self):
69-
return list(set([ role for role in self.parent.role_set.filter(name__in=['ad', 'chair']) ]))
70-
7168
def is_bof(self):
7269
return self.state_id in ["bof", "bof-conc"]
7370

@@ -238,6 +235,7 @@ class GroupFeatures(models.Model):
238235
admin_roles = jsonfield.JSONField(max_length=64, blank=False, default=["chair"]) # Trac Admin
239236
docman_roles = jsonfield.JSONField(max_length=128, blank=False, default=["ad","chair","delegate","secr"])
240237
groupman_roles = jsonfield.JSONField(max_length=128, blank=False, default=["ad","chair",])
238+
groupman_authroles = jsonfield.JSONField(max_length=128, blank=False, default=["Secretariat",])
241239
matman_roles = jsonfield.JSONField(max_length=128, blank=False, default=["ad","chair","delegate","secr"])
242240
role_order = jsonfield.JSONField(max_length=128, blank=False, default=["chair","secr","member"],
243241
help_text="The order in which roles are shown, for instance on photo pages. Enter valid JSON.")

ietf/group/tests_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ def test_group_about(self):
264264
can_edit = {
265265
'wg' : ['secretary','ad'],
266266
'rg' : ['secretary','irtf-chair'],
267-
'ag' : ['secretary', ],
267+
'ag' : ['secretary', 'ad' ],
268268
'team' : ['secretary',], # The code currently doesn't let ads edit teams or directorates. Maybe it should.
269269
'dir' : ['secretary',],
270270
'review' : ['secretary',],

ietf/group/utils.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from ietf.community.models import CommunityList, SearchRule
1616
from ietf.community.utils import reset_name_contains_index_for_rule, can_manage_community_list
1717
from ietf.doc.models import Document, State
18-
from ietf.group.models import Group, RoleHistory, Role
18+
from ietf.group.models import Group, RoleHistory, Role, GroupFeatures
1919
from ietf.ietfauth.utils import has_role
2020
from ietf.name.models import GroupTypeName
2121
from ietf.person.models import Email
@@ -105,6 +105,7 @@ def save_milestone_in_history(milestone):
105105

106106
return h
107107

108+
# TODO: rework this using features.groupman_authroles
108109
def can_manage_group_type(user, group, type_id=None):
109110
if not user.is_authenticated:
110111
return False
@@ -125,8 +126,11 @@ def can_manage_group_type(user, group, type_id=None):
125126
return has_role(user, ('Secretariat'))
126127

127128
def can_manage_group(user, group):
128-
if can_manage_group_type(user, group):
129-
return True
129+
if not user.is_authenticated:
130+
return False
131+
for authrole in group.features.groupman_authroles:
132+
if has_role(user, authrole):
133+
return True
130134
return group.has_role(user, group.features.groupman_roles)
131135

132136
def milestone_reviewer_for_group_type(group_type):
@@ -141,6 +145,18 @@ def can_manage_materials(user, group):
141145
def can_manage_session_materials(user, group, session):
142146
return has_role(user, 'Secretariat') or (group.has_role(user, group.features.matman_roles) and not session.is_material_submission_cutoff())
143147

148+
# Maybe this should be cached...
149+
def can_manage_some_groups(user):
150+
if not user.is_authenticated:
151+
return False
152+
for gf in GroupFeatures.objects.all():
153+
for authrole in gf.groupman_authroles:
154+
if has_role(user, authrole):
155+
return True
156+
if Role.objects.filter(name__in=gf.groupman_roles, group__type_id=gf.type_id, person__user=user).exists():
157+
return True
158+
return False
159+
144160
def can_provide_status_update(user, group):
145161
if not group.features.acts_like_wg:
146162
return False

ietf/ietfauth/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ def has_role(user, role_names, *args, **kwargs):
7070
"RG Secretary": Q(person=person,name="secr", group__type="rg", group__state__in=["active","proposed"]),
7171
"AG Secretary": Q(person=person,name="secr", group__type="ag", group__state__in=["active"]),
7272
"Team Chair": Q(person=person,name="chair", group__type="team", group__state="active"),
73+
"Program Lead": Q(person=person,name="lead", group__type="program", group__state="active"),
74+
"Program Secretary": Q(person=person,name="secr", group__type="program", group__state="active"),
75+
"Program Chair": Q(person=person,name="chair", group__type="program", group__state="active"),
7376
"Nomcom Chair": Q(person=person, name="chair", group__type="nomcom", group__acronym__icontains=kwargs.get('year', '0000')),
7477
"Nomcom Advisor": Q(person=person, name="advisor", group__type="nomcom", group__acronym__icontains=kwargs.get('year', '0000')),
7578
"Nomcom": Q(person=person, group__type="nomcom", group__acronym__icontains=kwargs.get('year', '0000')),

ietf/mailtrigger/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ def gather_group_responsible_directors(self, **kwargs):
166166
addrs.extend(group.role_set.filter(name='ad').values_list('email__address',flat=True))
167167
if group.type_id=='rg':
168168
addrs.extend(Recipient.objects.get(slug='stream_managers').gather(**{'streams':['irtf']}))
169+
elif group.type_id=='program':
170+
addrs.extend(Recipient.objects.get(slug='iab').gather(**{}))
169171
return addrs
170172

171173
def gather_group_secretaries(self, **kwargs):

0 commit comments

Comments
 (0)