fix: optimize and debug has_role and can_manage_some_groups (#7949)
* fix: optimize can_manage_some_groups * fix: improve cache key * refactor: extra_role_qs to kwargs and bugfix to cache key * fix: restrict groupman_role matches to active states * chore: styling, decommenting, black
This commit is contained in:
parent
86148a2a3c
commit
8362b45c8e
|
@ -2,6 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
from itertools import chain
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
@ -153,17 +154,23 @@ def can_manage_materials(user, group):
|
||||||
def can_manage_session_materials(user, group, session):
|
def can_manage_session_materials(user, group, session):
|
||||||
return has_role(user, 'Secretariat') or (group.has_role(user, group.features.matman_roles) and not session.is_material_submission_cutoff())
|
return has_role(user, 'Secretariat') or (group.has_role(user, group.features.matman_roles) and not session.is_material_submission_cutoff())
|
||||||
|
|
||||||
# Maybe this should be cached...
|
|
||||||
def can_manage_some_groups(user):
|
def can_manage_some_groups(user):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
authroles = set(
|
||||||
|
chain.from_iterable(
|
||||||
|
GroupFeatures.objects.values_list("groupman_authroles", flat=True)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
extra_role_qs = dict()
|
||||||
for gf in GroupFeatures.objects.all():
|
for gf in GroupFeatures.objects.all():
|
||||||
for authrole in gf.groupman_authroles:
|
extra_role_qs[f"{gf.type_id} groupman roles"] = Q(
|
||||||
if has_role(user, authrole):
|
name__in=gf.groupman_roles,
|
||||||
return True
|
group__type_id=gf.type_id,
|
||||||
if Role.objects.filter(name__in=gf.groupman_roles, group__type_id=gf.type_id, person__user=user).exists():
|
group__state__in=["active", "bof", "proposed"],
|
||||||
return True
|
)
|
||||||
return False
|
return has_role(user, authroles, extra_role_qs=extra_role_qs)
|
||||||
|
|
||||||
|
|
||||||
def can_provide_status_update(user, group):
|
def can_provide_status_update(user, group):
|
||||||
if not group.features.acts_like_wg:
|
if not group.features.acts_like_wg:
|
||||||
|
|
|
@ -38,9 +38,10 @@ def has_role(user, role_names, *args, **kwargs):
|
||||||
"""Determines whether user has any of the given standard roles
|
"""Determines whether user has any of the given standard roles
|
||||||
given. Role names must be a list or, in case of a single value, a
|
given. Role names must be a list or, in case of a single value, a
|
||||||
string."""
|
string."""
|
||||||
if not isinstance(role_names, (list, tuple)):
|
extra_role_qs = kwargs.get("extra_role_qs", None)
|
||||||
role_names = [ role_names ]
|
if not isinstance(role_names, (list, tuple, set)):
|
||||||
|
role_names = [role_names]
|
||||||
|
|
||||||
if not user or not user.is_authenticated:
|
if not user or not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -48,7 +49,13 @@ def has_role(user, role_names, *args, **kwargs):
|
||||||
if not hasattr(user, "roles_check_cache"):
|
if not hasattr(user, "roles_check_cache"):
|
||||||
user.roles_check_cache = {}
|
user.roles_check_cache = {}
|
||||||
|
|
||||||
key = frozenset(role_names)
|
keynames = set(role_names)
|
||||||
|
if extra_role_qs:
|
||||||
|
keynames.update(set(extra_role_qs.keys()))
|
||||||
|
year = kwargs.get("year", None)
|
||||||
|
if year is not None:
|
||||||
|
keynames.add(f"nomcomyear{year}")
|
||||||
|
key = frozenset(keynames)
|
||||||
if key not in user.roles_check_cache:
|
if key not in user.roles_check_cache:
|
||||||
try:
|
try:
|
||||||
person = user.person
|
person = user.person
|
||||||
|
@ -56,54 +63,119 @@ def has_role(user, role_names, *args, **kwargs):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
role_qs = {
|
role_qs = {
|
||||||
"Area Director": Q(person=person, name__in=("pre-ad", "ad"), group__type="area", group__state="active"),
|
"Area Director": Q(
|
||||||
"Secretariat": Q(person=person, name="secr", group__acronym="secretariat"),
|
name__in=("pre-ad", "ad"), group__type="area", group__state="active"
|
||||||
"IAB" : Q(person=person, name="member", group__acronym="iab"),
|
),
|
||||||
"IANA": Q(person=person, name="auth", group__acronym="iana"),
|
"Secretariat": Q(name="secr", group__acronym="secretariat"),
|
||||||
"RFC Editor": Q(person=person, name="auth", group__acronym="rpc"),
|
"IAB": Q(name="member", group__acronym="iab"),
|
||||||
"ISE" : Q(person=person, name="chair", group__acronym="ise"),
|
"IANA": Q(name="auth", group__acronym="iana"),
|
||||||
"IAD": Q(person=person, name="admdir", group__acronym="ietf"),
|
"RFC Editor": Q(name="auth", group__acronym="rpc"),
|
||||||
"IETF Chair": Q(person=person, name="chair", group__acronym="ietf"),
|
"ISE": Q(name="chair", group__acronym="ise"),
|
||||||
"IETF Trust Chair": Q(person=person, name="chair", group__acronym="ietf-trust"),
|
"IAD": Q(name="admdir", group__acronym="ietf"),
|
||||||
"IRTF Chair": Q(person=person, name="chair", group__acronym="irtf"),
|
"IETF Chair": Q(name="chair", group__acronym="ietf"),
|
||||||
"RSAB Chair": Q(person=person, name="chair", group__acronym="rsab"),
|
"IETF Trust Chair": Q(name="chair", group__acronym="ietf-trust"),
|
||||||
"IAB Chair": Q(person=person, name="chair", group__acronym="iab"),
|
"IRTF Chair": Q(name="chair", group__acronym="irtf"),
|
||||||
"IAB Executive Director": Q(person=person, name="execdir", group__acronym="iab"),
|
"RSAB Chair": Q(name="chair", group__acronym="rsab"),
|
||||||
"IAB Group Chair": Q(person=person, name="chair", group__type="iab", group__state="active"),
|
"IAB Chair": Q(name="chair", group__acronym="iab"),
|
||||||
"IAOC Chair": Q(person=person, name="chair", group__acronym="iaoc"),
|
"IAB Executive Director": Q(name="execdir", group__acronym="iab"),
|
||||||
"WG Chair": Q(person=person,name="chair", group__type="wg", group__state__in=["active","bof", "proposed"]),
|
"IAB Group Chair": Q(
|
||||||
"WG Secretary": Q(person=person,name="secr", group__type="wg", group__state__in=["active","bof", "proposed"]),
|
name="chair", group__type="iab", group__state="active"
|
||||||
"RG Chair": Q(person=person,name="chair", group__type="rg", group__state__in=["active","proposed"]),
|
),
|
||||||
"RG Secretary": Q(person=person,name="secr", group__type="rg", group__state__in=["active","proposed"]),
|
"IAOC Chair": Q(name="chair", group__acronym="iaoc"),
|
||||||
"AG Secretary": Q(person=person,name="secr", group__type="ag", group__state__in=["active"]),
|
"WG Chair": Q(
|
||||||
"RAG Secretary": Q(person=person,name="secr", group__type="rag", group__state__in=["active"]),
|
name="chair",
|
||||||
"Team Chair": Q(person=person,name="chair", group__type="team", group__state="active"),
|
group__type="wg",
|
||||||
"Program Lead": Q(person=person,name="lead", group__type="program", group__state="active"),
|
group__state__in=["active", "bof", "proposed"],
|
||||||
"Program Secretary": Q(person=person,name="secr", group__type="program", group__state="active"),
|
),
|
||||||
"Program Chair": Q(person=person,name="chair", group__type="program", group__state="active"),
|
"WG Secretary": Q(
|
||||||
"EDWG Chair": Q(person=person, name="chair", group__type="edwg", group__state="active"),
|
name="secr",
|
||||||
"Nomcom Chair": Q(person=person, name="chair", group__type="nomcom", group__acronym__icontains=kwargs.get('year', '0000')),
|
group__type="wg",
|
||||||
"Nomcom Advisor": Q(person=person, name="advisor", group__type="nomcom", group__acronym__icontains=kwargs.get('year', '0000')),
|
group__state__in=["active", "bof", "proposed"],
|
||||||
"Nomcom": Q(person=person, group__type="nomcom", group__acronym__icontains=kwargs.get('year', '0000')),
|
),
|
||||||
"Liaison Manager": Q(person=person,name="liaiman",group__type="sdo",group__state="active", ),
|
"RG Chair": Q(
|
||||||
"Authorized Individual": Q(person=person,name="auth",group__type="sdo",group__state="active", ),
|
name="chair", group__type="rg", group__state__in=["active", "proposed"]
|
||||||
"Recording Manager": Q(person=person,name="recman",group__type="ietf",group__state="active", ),
|
),
|
||||||
"Reviewer": Q(person=person, name="reviewer", group__state="active"),
|
"RG Secretary": Q(
|
||||||
"Review Team Secretary": Q(person=person, name="secr", group__reviewteamsettings__isnull=False,group__state="active", ),
|
name="secr", group__type="rg", group__state__in=["active", "proposed"]
|
||||||
"IRSG Member": (Q(person=person, name="member", group__acronym="irsg") | Q(person=person, name="chair", group__acronym="irtf") | Q(person=person, name="atlarge", group__acronym="irsg")),
|
),
|
||||||
"RSAB Member": Q(person=person, name="member", group__acronym="rsab"),
|
"AG Secretary": Q(
|
||||||
"Robot": Q(person=person, name="robot", group__acronym="secretariat"),
|
name="secr", group__type="ag", group__state__in=["active"]
|
||||||
}
|
),
|
||||||
|
"RAG Secretary": Q(
|
||||||
|
name="secr", group__type="rag", group__state__in=["active"]
|
||||||
|
),
|
||||||
|
"Team Chair": Q(name="chair", group__type="team", group__state="active"),
|
||||||
|
"Program Lead": Q(
|
||||||
|
name="lead", group__type="program", group__state="active"
|
||||||
|
),
|
||||||
|
"Program Secretary": Q(
|
||||||
|
name="secr", group__type="program", group__state="active"
|
||||||
|
),
|
||||||
|
"Program Chair": Q(
|
||||||
|
name="chair", group__type="program", group__state="active"
|
||||||
|
),
|
||||||
|
"EDWG Chair": Q(name="chair", group__type="edwg", group__state="active"),
|
||||||
|
"Nomcom Chair": Q(
|
||||||
|
name="chair",
|
||||||
|
group__type="nomcom",
|
||||||
|
group__acronym__icontains=kwargs.get("year", "0000"),
|
||||||
|
),
|
||||||
|
"Nomcom Advisor": Q(
|
||||||
|
name="advisor",
|
||||||
|
group__type="nomcom",
|
||||||
|
group__acronym__icontains=kwargs.get("year", "0000"),
|
||||||
|
),
|
||||||
|
"Nomcom": Q(
|
||||||
|
group__type="nomcom",
|
||||||
|
group__acronym__icontains=kwargs.get("year", "0000"),
|
||||||
|
),
|
||||||
|
"Liaison Manager": Q(
|
||||||
|
name="liaiman",
|
||||||
|
group__type="sdo",
|
||||||
|
group__state="active",
|
||||||
|
),
|
||||||
|
"Authorized Individual": Q(
|
||||||
|
name="auth",
|
||||||
|
group__type="sdo",
|
||||||
|
group__state="active",
|
||||||
|
),
|
||||||
|
"Recording Manager": Q(
|
||||||
|
name="recman",
|
||||||
|
group__type="ietf",
|
||||||
|
group__state="active",
|
||||||
|
),
|
||||||
|
"Reviewer": Q(name="reviewer", group__state="active"),
|
||||||
|
"Review Team Secretary": Q(
|
||||||
|
name="secr",
|
||||||
|
group__reviewteamsettings__isnull=False,
|
||||||
|
group__state="active",
|
||||||
|
),
|
||||||
|
"IRSG Member": (
|
||||||
|
Q(name="member", group__acronym="irsg")
|
||||||
|
| Q(name="chair", group__acronym="irtf")
|
||||||
|
| Q(name="atlarge", group__acronym="irsg")
|
||||||
|
),
|
||||||
|
"RSAB Member": Q(name="member", group__acronym="rsab"),
|
||||||
|
"Robot": Q(name="robot", group__acronym="secretariat"),
|
||||||
|
}
|
||||||
|
|
||||||
filter_expr = Q(pk__in=[]) # ensure empty set is returned if no other terms are added
|
filter_expr = Q(
|
||||||
|
pk__in=[]
|
||||||
|
) # ensure empty set is returned if no other terms are added
|
||||||
for r in role_names:
|
for r in role_names:
|
||||||
filter_expr |= role_qs[r]
|
filter_expr |= role_qs[r]
|
||||||
|
if extra_role_qs:
|
||||||
|
for r in extra_role_qs:
|
||||||
|
filter_expr |= extra_role_qs[r]
|
||||||
|
|
||||||
user.roles_check_cache[key] = bool(Role.objects.filter(filter_expr).exists())
|
user.roles_check_cache[key] = bool(
|
||||||
|
Role.objects.filter(person=person).filter(filter_expr).exists()
|
||||||
|
)
|
||||||
|
|
||||||
return user.roles_check_cache[key]
|
return user.roles_check_cache[key]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# convenient decorator
|
# convenient decorator
|
||||||
|
|
||||||
def passes_test_decorator(test_func, message):
|
def passes_test_decorator(test_func, message):
|
||||||
|
|
Loading…
Reference in a new issue