From e2640f358b24f5f3337de2a97c3d4a358a7dedd7 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Mon, 23 Jan 2017 22:54:36 +0000 Subject: [PATCH] Changed semantics for can_manage_group() to include chairs etc, and changed calls with the old semantics to use can_manage_group_type(). Rewrote can_manage_group() in terms of can_manage_group_type() and additional checks. Fixes issue #2155. - Legacy-Id: 12719 --- ietf/doc/views_charter.py | 8 ++++---- ietf/doc/views_doc.py | 4 ++-- ietf/group/milestones.py | 23 ++++++++++++----------- ietf/group/utils.py | 17 +++++++---------- ietf/group/views.py | 9 ++++++--- ietf/group/views_edit.py | 4 ++-- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/ietf/doc/views_charter.py b/ietf/doc/views_charter.py index b9c3b12a5..dc4b66f53 100644 --- a/ietf/doc/views_charter.py +++ b/ietf/doc/views_charter.py @@ -24,7 +24,7 @@ from ietf.doc.utils_charter import ( historic_milestones_for_charter, split_charter_name) from ietf.doc.mails import email_state_changed, email_charter_internal_review from ietf.group.models import Group, ChangeStateGroupEvent, MilestoneGroupEvent -from ietf.group.utils import save_group_in_history, save_milestone_in_history, can_manage_group +from ietf.group.utils import save_group_in_history, save_milestone_in_history, can_manage_group_type from ietf.ietfauth.utils import has_role, role_required from ietf.name.models import GroupStateName from ietf.person.models import Person @@ -60,7 +60,7 @@ def change_state(request, name, option=None): charter = get_object_or_404(Document, type="charter", name=name) group = charter.group - if not can_manage_group(request.user, group): + if not can_manage_group_type(request.user, group): return HttpResponseForbidden("You don't have permission to access this view") chartering_type = get_chartering_type(charter) @@ -247,7 +247,7 @@ def change_title(request, name, option=None): logging the title as a comment.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group - if not can_manage_group(request.user, group): + if not can_manage_group_type(request.user, group): return HttpResponseForbidden("You don't have permission to access this view") by = request.user.person if request.method == 'POST': @@ -360,7 +360,7 @@ def submit(request, name, option=None): charter_canonical_name = name charter_rev = "00-00" - if not can_manage_group(request.user, group) or not group.features.has_chartering_process: + if not can_manage_group_type(request.user, group) or not group.features.has_chartering_process: return HttpResponseForbidden("You don't have permission to access this view") diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index ab950d406..1ef65f12e 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -54,7 +54,7 @@ from ietf.doc.utils import ( add_links_in_new_revision_events, augment_events_wi add_events_message_info, get_unicode_document_content) from ietf.community.utils import augment_docs_with_tracking_info from ietf.group.models import Role -from ietf.group.utils import can_manage_group, can_manage_materials +from ietf.group.utils import can_manage_group_type, can_manage_materials from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person, role_required from ietf.name.models import StreamName, BallotPositionName from ietf.person.models import Email @@ -450,7 +450,7 @@ def document_main(request, name, rev=None): if chartering and not snapshot: milestones = doc.group.groupmilestone_set.filter(state="charter") - can_manage = can_manage_group(request.user, doc.group) + can_manage = can_manage_group_type(request.user, doc.group) return render_to_response("doc/document_charter.html", dict(doc=doc, diff --git a/ietf/group/milestones.py b/ietf/group/milestones.py index 86575b1ca..e88024578 100644 --- a/ietf/group/milestones.py +++ b/ietf/group/milestones.py @@ -8,12 +8,14 @@ from django.http import HttpResponseForbidden, HttpResponseBadRequest, HttpRespo from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required +import debug # pyflakes:ignore + from ietf.doc.models import DocEvent from ietf.doc.utils import get_chartering_type from ietf.doc.fields import SearchableDocumentsField from ietf.group.models import GroupMilestone, MilestoneGroupEvent -from ietf.group.utils import (save_milestone_in_history, can_manage_group, milestone_reviewer_for_group_type, - get_group_or_404) +from ietf.group.utils import (save_milestone_in_history, can_manage_group_type, can_manage_group, + milestone_reviewer_for_group_type, get_group_or_404) from ietf.name.models import GroupMilestoneStateName from ietf.group.mails import email_milestones_changed from ietf.utils.fields import DatepickerDateField @@ -93,12 +95,13 @@ def edit_milestones(request, acronym, group_type=None, milestone_set="current"): raise Http404 needs_review = False - if not can_manage_group(request.user, group): - if group.has_role(request.user, group.features.admin_roles): + if can_manage_group(request.user, group): + if not can_manage_group_type(request.user, group): + # The user is chair or similar, not AD: if milestone_set == "current": needs_review = True - else: - return HttpResponseForbidden("You are not chair of this group.") + else: + return HttpResponseForbidden("You don't have permission to access this view") if milestone_set == "current": title = "Edit milestones for %s %s" % (group.acronym, group.type.name) @@ -328,11 +331,9 @@ def reset_charter_milestones(request, group_type, acronym): group = get_group_or_404(acronym, group_type) if not group.features.has_milestones: raise Http404 - - can_manage = can_manage_group(request.user, group) - is_chair = group.has_role(request.user, "chair") - if (not can_manage) and (not is_chair): - return HttpResponseForbidden("You are not chair of this group.") + + if not can_manage_group(request.user, group): + return HttpResponseForbidden("You don't have permission to access this view") current_milestones = group.groupmilestone_set.filter(state="active") charter_milestones = group.groupmilestone_set.filter(state="charter") diff --git a/ietf/group/utils.py b/ietf/group/utils.py index 98c1943f9..1538e9918 100644 --- a/ietf/group/utils.py +++ b/ietf/group/utils.py @@ -89,15 +89,7 @@ def save_milestone_in_history(milestone): return h -def can_manage_group_type(user, group_type): - if group_type == "rg": - return has_role(user, ('IRTF Chair', 'Secretariat')) - elif group_type == "wg": - return has_role(user, ('Area Director', 'Secretariat')) - - return has_role(user, 'Secretariat') - -def can_manage_group(user, group): +def can_manage_group_type(user, group): if group.type_id == "rg": return has_role(user, ('IRTF Chair', 'Secretariat')) elif group.type_id == "wg": @@ -109,6 +101,11 @@ def can_manage_group(user, group): return has_role(user, ('IRTF Chair', 'Secretariat')) return has_role(user, ('Secretariat')) +def can_manage_group(user, group): + if can_manage_group_type(user, group): + return True + return group.has_role(user, group.features.admin_roles) + def milestone_reviewer_for_group_type(group_type): if group_type == "rg": return "IRTF Chair" @@ -196,7 +193,7 @@ def construct_group_menu_context(request, group, selected, group_type, others): actions = [] is_admin = group.has_role(request.user, group.features.admin_roles) - can_manage = can_manage_group(request.user, group) + can_manage = can_manage_group_type(request.user, group) if group.features.has_milestones: if group.state_id != "proposed" and (is_admin or can_manage): diff --git a/ietf/group/views.py b/ietf/group/views.py index d24aeb24e..776c0ba08 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -57,7 +57,7 @@ from ietf.doc.utils_search import prepare_document_table from ietf.doc.utils_charter import charter_name_for_group from ietf.group.models import Group, Role, ChangeStateGroupEvent from ietf.name.models import GroupTypeName -from ietf.group.utils import (get_charter_text, can_manage_group_type, can_manage_group, +from ietf.group.utils import (get_charter_text, can_manage_group_type, milestone_reviewer_for_group_type, can_provide_status_update, can_manage_materials, get_group_or_404, construct_group_menu_context, get_group_materials) @@ -296,7 +296,10 @@ def chartering_groups(request): for t in group_types: t.chartering_groups = Group.objects.filter(type=t, charter__states__in=charter_states).select_related("state", "charter").order_by("acronym") - t.can_manage = can_manage_group_type(request.user, t.slug) + if t.chartering_groups.exists(): + t.can_manage = can_manage_group_type(request.user, t.chartering_groups.first()) + else: + t.can_manage = False for g in t.chartering_groups: g.chartering_type = get_chartering_type(g.charter) @@ -414,7 +417,7 @@ def group_about(request, acronym, group_type=None): e = group.latest_event(type__in=("changed_state", "requested_close",)) requested_close = group.state_id != "conclude" and e and e.type == "requested_close" - can_manage = can_manage_group(request.user, group) + can_manage = can_manage_group_type(request.user, group) charter_submit_url = "" if group.features.has_chartering_process: charter_submit_url = urlreverse("charter_submit", kwargs={ "name": charter_name_for_group(group) }) diff --git a/ietf/group/views_edit.py b/ietf/group/views_edit.py index 4b96a482f..86184f06a 100644 --- a/ietf/group/views_edit.py +++ b/ietf/group/views_edit.py @@ -16,7 +16,7 @@ from ietf.doc.utils import get_tags_for_stream_id from ietf.doc.utils_charter import charter_name_for_group from ietf.group.models import ( Group, Role, GroupEvent, GroupHistory, GroupStateName, GroupStateTransitions, GroupTypeName, GroupURL, ChangeStateGroupEvent ) -from ietf.group.utils import save_group_in_history, can_manage_group +from ietf.group.utils import save_group_in_history, can_manage_group, can_manage_group_type from ietf.group.utils import get_group_or_404, setup_default_community_list_for_group from ietf.ietfauth.utils import has_role from ietf.person.fields import SearchableEmailsField @@ -401,7 +401,7 @@ def conclude(request, acronym, group_type=None): """Request the closing of group, prompting for instructions.""" group = get_group_or_404(acronym, group_type) - if not can_manage_group(request.user, group): + if not can_manage_group_type(request.user, group): return HttpResponseForbidden("You don't have permission to access this view") if request.method == 'POST':