Converted many cases of plain-text 403 messages to use a properly styled page instead, with a login link when appropriate. Also changed some API endpoint 400 responses to a more correct 403.

- Legacy-Id: 18339
This commit is contained in:
Henrik Levkowetz 2020-08-06 10:59:52 +00:00
parent ab7abb5975
commit 57938b039d
27 changed files with 183 additions and 158 deletions

View file

@ -83,7 +83,7 @@ class CustomApiTests(TestCase):
badrole.person.user.last_login = timezone.now()
badrole.person.user.save()
r = self.client.post(url, {'apikey': badapikey.hash()} )
self.assertContains(r, "Restricted to role Recording Manager", status_code=403)
self.assertContains(r, "Restricted to role: Recording Manager", status_code=403)
r = self.client.post(url, {'apikey': apikey.hash()} )
self.assertContains(r, "Too long since last regular login", status_code=400)
@ -173,7 +173,7 @@ class CustomApiTests(TestCase):
badrole.person.user.last_login = timezone.now()
badrole.person.user.save()
r = self.client.post(url, {'apikey': badapikey.hash()} )
self.assertContains(r, "Restricted to roles Recording Manager, Secretariat", status_code=403)
self.assertContains(r, "Restricted to roles: Recording Manager, Secretariat", status_code=403)
r = self.client.post(url, {'apikey': apikey.hash()} )
self.assertContains(r, "Too long since last regular login", status_code=400)
@ -257,7 +257,7 @@ class CustomApiTests(TestCase):
badrole.person.user.last_login = timezone.now()
badrole.person.user.save()
r = self.client.post(url, {'apikey': badapikey.hash()})
self.assertContains(r, "Restricted to role Secretariat", status_code=403)
self.assertContains(r, "Restricted to role: Secretariat", status_code=403)
r = self.client.post(url, {'apikey': apikey.hash()})
self.assertContains(r, "Too long since last regular login", status_code=400)
@ -292,7 +292,7 @@ class CustomApiTests(TestCase):
}
url = urlreverse('ietf.api.views.api_new_meeting_registration')
r = self.client.post(url, reg)
self.assertContains(r, 'Invalid apikey', status_code=400)
self.assertContains(r, 'Invalid apikey', status_code=403)
oidcp = PersonFactory(user__is_staff=True)
# Make sure 'oidcp' has an acceptable role
RoleFactory(name_id='robot', person=oidcp, email=oidcp.email(), group__acronym='secretariat')

View file

@ -7,7 +7,7 @@ import datetime
import json
import uuid
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect, Http404
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404, render
from django.contrib.auth.decorators import login_required
from django.utils.html import strip_tags
@ -21,6 +21,7 @@ from ietf.community.utils import docs_tracked_by_community_list, docs_matching_c
from ietf.community.utils import states_of_significant_change, reset_name_contains_index_for_rule
from ietf.doc.models import DocEvent, Document
from ietf.doc.utils_search import prepare_document_table
from ietf.utils.response import permission_denied
def view_list(request, username=None):
clist = lookup_community_list(username)
@ -45,7 +46,7 @@ def manage_list(request, username=None, acronym=None, group_type=None):
clist = lookup_community_list(username, acronym)
if not can_manage_community_list(request.user, clist):
return HttpResponseForbidden("You do not have permission to access this view")
permission_denied(request, "You do not have permission to access this view")
action = request.POST.get('action')
@ -129,7 +130,7 @@ def track_document(request, name, username=None, acronym=None):
if request.method == "POST":
clist = lookup_community_list(username, acronym)
if not can_manage_community_list(request.user, clist):
return HttpResponseForbidden("You do not have permission to access this view")
permission_denied(request, "You do not have permission to access this view")
if clist.pk is None:
clist.save()
@ -151,7 +152,7 @@ def untrack_document(request, name, username=None, acronym=None):
doc = get_object_or_404(Document, docalias__name=name)
clist = lookup_community_list(username, acronym)
if not can_manage_community_list(request.user, clist):
return HttpResponseForbidden("You do not have permission to access this view")
permission_denied(request, "You do not have permission to access this view")
if request.method == "POST":
if clist.pk is not None:

View file

@ -1,4 +1,6 @@
from django.http import HttpResponseForbidden, HttpResponseRedirect
# Copyright The IETF Trust 2012-2020, All Rights Reserved
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
import debug # pyflakes:ignore
@ -7,13 +9,14 @@ from ietf.dbtemplate.models import DBTemplate
from ietf.dbtemplate.forms import DBTemplateForm
from ietf.group.models import Group
from ietf.ietfauth.utils import has_role
from ietf.utils.response import permission_denied
def group_template_list(request, acronym):
group = get_object_or_404(Group, acronym=acronym)
chairs = group.role_set.filter(name__slug='chair')
if not has_role(request.user, "Secretariat") and not (request.user.id and chairs.filter(person__user=request.user).count()):
return HttpResponseForbidden("You are not authorized to access this view")
permission_denied(request, "You are not authorized to access this view.")
template_list = DBTemplate.objects.filter(group=group)
return render(request, 'dbtemplate/template_list.html',
@ -28,7 +31,7 @@ def group_template_edit(request, acronym, template_id, base_template='dbtemplate
extra_context = extra_context or {}
if not has_role(request.user, "Secretariat") and not (request.user.id and chairs.filter(person__user=request.user).count()):
return HttpResponseForbidden("You are not authorized to access this view")
permission_denied(request, "You are not authorized to access this view.")
template = get_object_or_404(DBTemplate, id=template_id, group=group)
if request.method == 'POST':
@ -52,7 +55,7 @@ def group_template_show(request, acronym, template_id, base_template='dbtemplate
extra_context = extra_context or {}
if not has_role(request.user, "Secretariat") and not (request.user.id and chairs.filter(person__user=request.user).count()):
return HttpResponseForbidden("You are not authorized to access this view")
permission_denied(request, "You are not authorized to access this view.")
template = get_object_or_404(DBTemplate, id=template_id, group=group)

View file

@ -739,7 +739,7 @@ class ApproveBallotTests(TestCase):
# Only Secretariat can use this URL
login_testing_unauthorized(self, "ad", url)
r = self.client.get(url)
self.assertContains(r, "Restricted to role Secretariat", status_code=403)
self.assertContains(r, "Restricted to role: Secretariat", status_code=403)
# There are no downrefs, the page should say so
login_testing_unauthorized(self, "secretary", url)

View file

@ -8,7 +8,7 @@ import datetime, json
from django import forms
from django.conf import settings
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect, Http404
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.template.defaultfilters import striptags
from django.template.loader import render_to_string
@ -28,6 +28,7 @@ from ietf.doc.mails import ( email_ballot_deferred, email_ballot_undeferred,
generate_issue_ballot_mail, generate_ballot_writeup, generate_ballot_rfceditornote,
generate_approval_mail, email_irsg_ballot_closed, email_irsg_ballot_issued )
from ietf.doc.lastcall import request_last_call
from ietf.doc.templatetags.ietf_filters import can_ballot
from ietf.iesg.models import TelechatDate
from ietf.ietfauth.utils import has_role, role_required, is_authorized_in_doc_stream
from ietf.mailtrigger.utils import gather_address_lists
@ -38,7 +39,7 @@ from ietf.person.models import Person
from ietf.utils import log
from ietf.utils.mail import send_mail_text, send_mail_preformatted
from ietf.utils.decorators import require_api_key
from ietf.doc.templatetags.ietf_filters import can_ballot
from ietf.utils.response import permission_denied
BALLOT_CHOICES = (("yes", "Yes"),
("noobj", "No Objection"),
@ -213,7 +214,7 @@ def edit_position(request, name, ballot_id):
old_pos = None
if not has_role(request.user, "Secretariat") and not can_ballot(request.user, doc):
# prevent pre-ADs from voting
return HttpResponseForbidden("Must be a proper Area Director in an active area or IRSG Member to cast ballot")
permission_denied(request, "Must be a proper Area Director in an active area or IRSG Member to cast ballot")
form = EditPositionForm(request.POST, ballot_type=ballot.ballot_type)
if form.is_valid():
@ -682,7 +683,7 @@ def ballot_rfceditornote(request, name):
doc = get_object_or_404(Document, docalias__name=name)
if not is_authorized_in_doc_stream(request.user, doc):
return HttpResponseForbidden("You do not have the necessary permissions to change the RFC Editor Note for this document")
permission_denied(request, "You do not have the necessary permissions to change the RFC Editor Note for this document")
login = request.user.person

View file

@ -8,7 +8,7 @@ import json
import os
import textwrap
from django.http import HttpResponseRedirect, HttpResponseNotFound, HttpResponseForbidden, Http404
from django.http import HttpResponseRedirect, HttpResponseNotFound, Http404
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse as urlreverse
from django import forms
@ -32,16 +32,17 @@ from ietf.doc.utils_charter import ( historic_milestones_for_charter,
change_group_state_after_charter_approval, fix_charter_revision_after_approval,
split_charter_name)
from ietf.doc.mails import email_state_changed, email_charter_internal_review
from ietf.group.mails import email_admin_re_charter
from ietf.group.models import Group, ChangeStateGroupEvent, MilestoneGroupEvent
from ietf.group.utils import save_group_in_history, save_milestone_in_history, can_manage_group_type
from ietf.group.views import fill_in_charter_info
from ietf.ietfauth.utils import has_role, role_required
from ietf.name.models import GroupStateName
from ietf.person.models import Person
from ietf.utils.history import find_history_active_at
from ietf.utils.mail import send_mail_preformatted
from ietf.utils.textupload import get_cleaned_text_file_content
from ietf.group.mails import email_admin_re_charter
from ietf.group.views import fill_in_charter_info
from ietf.utils.response import permission_denied
class ChangeStateForm(forms.Form):
charter_state = forms.ModelChoiceField(State.objects.filter(used=True, type="charter"), label="Charter state", empty_label=None, required=False)
@ -70,7 +71,7 @@ def change_state(request, name, option=None):
group = charter.group
if not can_manage_group_type(request.user, group):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view.")
chartering_type = get_chartering_type(charter)
@ -261,7 +262,7 @@ def change_title(request, name, option=None):
charter = get_object_or_404(Document, type="charter", name=name)
group = charter.group
if not can_manage_group_type(request.user, group):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view.")
by = request.user.person
if request.method == 'POST':
form = ChangeTitleForm(request.POST, charter=charter)
@ -374,7 +375,7 @@ def submit(request, name, option=None):
charter_rev = "00-00"
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")
permission_denied(request, "You don't have permission to access this view.")
path = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (charter_canonical_name, charter_rev))

View file

@ -43,7 +43,7 @@ import re
from urllib.parse import quote
from django.http import HttpResponse, Http404 , HttpResponseForbidden
from django.http import HttpResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.template.loader import render_to_string
from django.urls import reverse as urlreverse
@ -76,6 +76,7 @@ from ietf.review.models import ReviewAssignment
from ietf.review.utils import can_request_review_of_doc, review_assignments_to_list_for_docs
from ietf.review.utils import no_review_from_teams_on_doc
from ietf.utils import markup_txt
from ietf.utils.response import permission_denied
from ietf.utils.text import maybe_split
@ -1199,7 +1200,7 @@ def add_comment(request, name):
can_add_comment = has_role(request.user, ("Area Director", "Secretariat", "IRTF Chair"))
if not can_add_comment:
# The user is a chair or secretary, but not for this WG or RG
return HttpResponseForbidden("You need to be a chair or secretary of this group to add a comment.")
permission_denied(request, "You need to be a chair or secretary of this group to add a comment.")
if request.method == 'POST':
form = AddCommentForm(request.POST)
@ -1272,7 +1273,7 @@ def edit_notify(request, name):
doc = get_object_or_404(Document, name=name)
if not ( is_authorized_in_doc_stream(request.user, doc) or user_is_person(request.user, doc.shepherd and doc.shepherd.person) or has_role(request.user, ["Area Director"]) ):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
init = { "notify" : doc.notify }

View file

@ -15,7 +15,7 @@ from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponseForbidden, Http404
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.template.loader import render_to_string
from django.forms.utils import ErrorList
@ -41,6 +41,7 @@ from ietf.group.models import Group, Role, GroupFeatures
from ietf.iesg.models import TelechatDate
from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person, is_individual_draft_author
from ietf.ietfauth.utils import role_required
from ietf.mailtrigger.utils import gather_address_lists
from ietf.message.models import Message
from ietf.name.models import IntendedStdLevelName, DocTagName, StreamName, ExtResourceName
from ietf.person.fields import SearchableEmailField
@ -49,7 +50,7 @@ from ietf.utils.mail import send_mail, send_mail_message, on_behalf_of
from ietf.utils.textupload import get_cleaned_text_file_content
from ietf.utils.validators import validate_external_resource_value
from ietf.utils import log
from ietf.mailtrigger.utils import gather_address_lists
from ietf.utils.response import permission_denied
class ChangeStateForm(forms.Form):
state = forms.ModelChoiceField(State.objects.filter(used=True, type="draft-iesg"), empty_label=None, required=True)
@ -267,7 +268,7 @@ def change_stream(request, name):
Role.objects.filter(name="chair",
group__acronym__in=StreamName.objects.values_list("slug", flat=True),
person__user=request.user))):
return HttpResponseForbidden("You do not have permission to view this page")
permission_denied(request, "You do not have permission to view this page")
login = request.user.person
@ -344,7 +345,7 @@ def replaces(request, name):
raise Http404
if not (has_role(request.user, ("Secretariat", "Area Director", "WG Chair", "RG Chair", "WG Secretary", "RG Secretary"))
or is_authorized_in_doc_stream(request.user, doc)):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
if request.method == 'POST':
form = ReplacesForm(request.POST, doc=doc)
@ -388,7 +389,7 @@ def review_possibly_replaces(request, name):
raise Http404
if not (has_role(request.user, ("Secretariat", "Area Director"))
or is_authorized_in_doc_stream(request.user, doc)):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page")
suggested = list(doc.related_that_doc("possibly-replaces"))
if not suggested:
@ -444,7 +445,7 @@ def change_intention(request, name):
if not (has_role(request.user, ("Secretariat", "Area Director"))
or is_authorized_in_doc_stream(request.user, doc)):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
login = request.user.person
@ -928,7 +929,7 @@ def edit_shepherd_writeup(request, name):
or has_role(request.user, ["Area Director"]))
if not can_edit_shepherd_writeup:
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page")
login = request.user.person
@ -996,7 +997,7 @@ def edit_shepherd(request, name):
can_edit_stream_info = is_authorized_in_doc_stream(request.user, doc)
if not can_edit_stream_info:
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
if request.method == 'POST':
form = ShepherdForm(request.POST)
@ -1055,7 +1056,7 @@ def change_shepherd_email(request, name):
can_edit_stream_info = is_authorized_in_doc_stream(request.user, doc)
is_shepherd = user_is_person(request.user, doc.shepherd and doc.shepherd.person)
if not can_edit_stream_info and not is_shepherd:
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page")
initial = { "shepherd": doc.shepherd_id }
if request.method == 'POST':
@ -1147,7 +1148,7 @@ def edit_consensus(request, name):
if not (has_role(request.user, ("Secretariat", "Area Director"))
or is_authorized_in_doc_stream(request.user, doc)):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
prev_consensus = e.consensus if e else default_consensus(doc)
@ -1159,7 +1160,7 @@ def edit_consensus(request, name):
e = ConsensusDocEvent(doc=doc, rev=doc.rev, type="changed_consensus", by=request.user.person)
e.consensus = {"Unknown":None,"Yes":True,"No":False}[form.cleaned_data["consensus"]]
if not e.consensus and doc.intended_std_level_id in ("std", "ds", "ps", "bcp"):
return HttpResponseForbidden("BCPs and Standards Track documents must include the consensus boilerplate")
permission_denied(request, "BCPs and Standards Track documents must include the consensus boilerplate.")
e.desc = "Changed consensus to <b>%s</b> from %s" % (nice_consensus(e.consensus),
nice_consensus(prev_consensus))
@ -1224,7 +1225,7 @@ def edit_doc_extresources(request, name):
if not (has_role(request.user, ("Secretariat", "Area Director"))
or is_authorized_in_doc_stream(request.user, doc)
or is_individual_draft_author(request.user, doc)):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
old_resources = format_resources(doc.docextresource_set.all())
@ -1270,7 +1271,7 @@ def request_publication(request, name):
doc = get_object_or_404(Document, type="draft", name=name, stream__in=("iab", "ise", "irtf"))
if not is_authorized_in_doc_stream(request.user, doc):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
consensus_event = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
@ -1410,7 +1411,7 @@ def adopt_draft(request, name):
doc = get_object_or_404(Document, type="draft", name=name)
if not can_adopt_draft(request.user, doc):
return HttpResponseForbidden("You don't have permission to access this page")
permission_denied(request, "You don't have permission to access this page.")
if request.method == 'POST':
form = AdoptDraftForm(request.POST, user=request.user)
@ -1501,7 +1502,7 @@ def release_draft(request, name):
raise Http404
if not can_unadopt_draft(request.user, doc):
return HttpResponseForbidden("You don't have permission to access this page")
permission_denied(request, "You don't have permission to access this page.")
if request.method == 'POST':
form = ReleaseDraftForm(request.POST)
@ -1632,7 +1633,7 @@ def change_stream_state(request, name, state_type):
state_type = get_object_or_404(StateType, slug=state_type)
if not is_authorized_in_doc_stream(request.user, doc):
return HttpResponseForbidden("You don't have permission to access this page")
permission_denied(request, "You don't have permission to access this page.")
prev_state = doc.get_state(state_type.slug)
next_states = next_states_for_stream_state(doc, state_type, prev_state)

View file

@ -8,10 +8,10 @@ import os
import re
from django import forms
from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponseForbidden, Http404
from django.utils.html import mark_safe # type:ignore
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.utils.html import mark_safe # type:ignore
from django.urls import reverse as urlreverse
import debug # pyflakes:ignore
@ -21,6 +21,7 @@ from ietf.doc.models import NewRevisionDocEvent
from ietf.doc.utils import add_state_change_event, check_common_doc_name_rules
from ietf.group.models import Group
from ietf.group.utils import can_manage_materials
from ietf.utils.response import permission_denied
@login_required
def choose_material_type(request, acronym):
@ -106,7 +107,7 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
if not can_manage_materials(request.user, group):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view")
if request.method == 'POST':
form = UploadMaterialForm(document_type, action, group, doc, request.POST, request.FILES)

View file

@ -15,7 +15,7 @@ from simple_history.utils import update_change_reason
import debug # pyflakes:ignore
from django.http import HttpResponseForbidden, JsonResponse, Http404, HttpResponse, HttpResponseRedirect
from django.http import JsonResponse, Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, redirect
from django import forms
from django.conf import settings
@ -49,6 +49,7 @@ from ietf.utils.textupload import get_cleaned_text_file_content
from ietf.utils.mail import send_mail_message
from ietf.mailtrigger.utils import gather_address_lists
from ietf.utils.fields import MultiEmailField
from ietf.utils.response import permission_denied
def clean_doc_revision(doc, rev):
if rev:
@ -112,7 +113,7 @@ def request_review(request, name):
doc = get_object_or_404(Document, name=name)
if not can_request_review_of_doc(request.user, doc):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
now = datetime.datetime.now()
@ -280,7 +281,7 @@ def close_request(request, name, request_id):
can_manage_request = can_manage_review_requests_for_team(request.user, review_req.team)
if not (can_request or can_manage_request):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST":
form = CloseReviewRequestForm(can_manage_request, request.POST)
@ -315,7 +316,7 @@ def assign_reviewer(request, name, request_id):
review_req = get_object_or_404(ReviewRequest, pk=request_id, state__in=["requested", "assigned"])
if not can_manage_review_requests_for_team(request.user, review_req.team):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST" and request.POST.get("action") == "assign":
form = AssignReviewerForm(review_req, request.POST)
@ -351,7 +352,7 @@ def reject_reviewer_assignment(request, name, assignment_id):
can_manage_request = can_manage_review_requests_for_team(request.user, review_assignment.review_request.team)
if not (is_reviewer or can_manage_request):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST" and request.POST.get("action") == "reject" and not review_request_past_deadline:
form = RejectReviewerAssignmentForm(request.POST)
@ -406,7 +407,7 @@ def withdraw_reviewer_assignment(request, name, assignment_id):
can_manage_request = can_manage_review_requests_for_team(request.user, review_assignment.review_request.team)
if not can_manage_request:
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST" and request.POST.get("action") == "withdraw":
review_assignment.state_id = 'withdrawn'
@ -447,7 +448,7 @@ def mark_reviewer_assignment_no_response(request, name, assignment_id):
can_manage_request = can_manage_review_requests_for_team(request.user, review_assignment.review_request.team)
if not can_manage_request:
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST" and request.POST.get("action") == "noresponse":
review_assignment.state_id = 'no-response'
@ -649,7 +650,7 @@ def complete_review(request, name, assignment_id=None, acronym=None):
can_manage_request = can_manage_review_requests_for_team(request.user, assignment.review_request.team)
if not (is_reviewer or can_manage_request):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
team = assignment.review_request.team
team_acronym = assignment.review_request.team.acronym.lower()
@ -666,7 +667,7 @@ def complete_review(request, name, assignment_id=None, acronym=None):
else:
team = get_object_or_404(Group, acronym=acronym)
if not can_manage_review_requests_for_team(request.user, team):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
assignment = None
is_reviewer = False
revising_review = False
@ -918,7 +919,7 @@ def search_mail_archive(request, name, acronym=None, assignment_id=None):
can_manage_request = can_manage_review_requests_for_team(request.user, team)
if not (is_reviewer or can_manage_request):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
res = mailarch.construct_query_urls(doc, team, query=request.GET.get("query"))
if not res:
@ -951,7 +952,7 @@ class EditReviewRequestCommentForm(forms.ModelForm):
def edit_comment(request, name, request_id):
review_req = get_object_or_404(ReviewRequest, pk=request_id)
if not can_request_review_of_doc(request.user, review_req.doc):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST":
form = EditReviewRequestCommentForm(request.POST, instance=review_req)
@ -982,7 +983,7 @@ class EditReviewRequestDeadlineForm(forms.ModelForm):
def edit_deadline(request, name, request_id):
review_req = get_object_or_404(ReviewRequest, pk=request_id)
if not can_request_review_of_doc(request.user, review_req.doc):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
old_deadline = review_req.deadline

View file

@ -9,7 +9,6 @@ from django import forms
from django.contrib import admin
from django.contrib.admin.utils import unquote
from django.core.exceptions import PermissionDenied
from django.core.management import load_command_class
from django.http import Http404
from django.shortcuts import render
@ -22,6 +21,7 @@ from ietf.group.models import (Group, GroupFeatures, GroupHistory, GroupEvent, G
MilestoneGroupEvent, GroupExtResource, )
from ietf.utils.validators import validate_external_resource_value
from ietf.utils.response import permission_denied
class RoleInline(admin.TabularInline):
model = Role
@ -121,7 +121,7 @@ class GroupAdmin(admin.ModelAdmin):
obj = None
if not self.has_change_permission(request, obj):
raise PermissionDenied
permission_denied(request, "You don't have edit permissions for this change.")
if obj is None:
raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})

View file

@ -6,8 +6,7 @@ import calendar
from django import forms
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.http import HttpResponseForbidden, HttpResponseBadRequest, HttpResponseRedirect, Http404
from django.http import HttpResponseRedirect, HttpResponseBadRequest, Http404
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
@ -22,6 +21,7 @@ from ietf.group.utils import (save_milestone_in_history, can_manage_group_type,
from ietf.name.models import GroupMilestoneStateName
from ietf.group.mails import email_milestones_changed
from ietf.utils.fields import DatepickerDateField
from ietf.utils.response import permission_denied
class MilestoneForm(forms.Form):
id = forms.IntegerField(required=True, widget=forms.HiddenInput)
@ -118,7 +118,7 @@ def edit_milestones(request, acronym, group_type=None, milestone_set="current"):
if milestone_set == "current":
needs_review = True
else:
return HttpResponseForbidden("You are not authorized to edit the milestones of this group.")
permission_denied(request, "You are not authorized to edit the milestones of this group.")
desc_editable = has_role(request.user,["Secretariat","Area Director","IRTF Chair"])
@ -320,7 +320,7 @@ def edit_milestones(request, acronym, group_type=None, milestone_set="current"):
for m in milestones:
forms.append(MilestoneForm(needs_review, reviewer, desc_editable, instance=m, uses_dates=group.uses_milestone_dates))
else:
raise PermissionDenied
permission_denied(request, "You don't have the required permissions to change the 'uses milestone dates' setting")
else:
# parse out individual milestone forms
for prefix in request.POST.getlist("prefix"):
@ -405,7 +405,7 @@ def reset_charter_milestones(request, group_type, acronym):
raise Http404
if not can_manage_group(request.user, group):
return HttpResponseForbidden("You are not authorized to change the milestones for this group.")
permission_denied(request, "You are not authorized to change the milestones for this group.")
current_milestones = group.groupmilestone_set.filter(state="active")
charter_milestones = group.groupmilestone_set.filter(state="charter")

View file

@ -51,7 +51,7 @@ from django import forms
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.db.models import Q, Count
from django.http import HttpResponse, HttpResponseForbidden, Http404, HttpResponseRedirect, JsonResponse
from django.http import HttpResponse, HttpResponseRedirect, Http404, JsonResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.template.loader import render_to_string
from django.urls import reverse as urlreverse
@ -119,6 +119,7 @@ from ietf.mailtrigger.utils import gather_address_lists
from ietf.mailtrigger.models import Recipient
from ietf.settings import MAILING_LIST_INFO_URL
from ietf.utils.pipe import pipe
from ietf.utils.response import permission_denied
from ietf.utils.text import strip_suffix
@ -853,7 +854,7 @@ def group_photos(request, group_type=None, acronym=None):
# group_type = group.type_id
#
# if not can_manage_group(request.user, group):
# return HttpResponseForbidden("You don't have permission to access this view")
# permission_denied(request, "You don't have permission to access this view")
#
# if not group.charter:
# group.charter = get_or_create_initial_charter(group, group_type)
@ -905,7 +906,7 @@ def edit(request, group_type=None, acronym=None, action="edit", field=None):
group_type = group.type_id
if not (can_manage_group(request.user, group)
or group.has_role(request.user, group.features.groupman_roles)):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view")
if request.method == 'POST':
form = GroupForm(request.POST, group=group, group_type=group_type, field=field)
@ -1089,7 +1090,7 @@ def conclude(request, acronym, group_type=None):
group = get_group_or_404(acronym, group_type)
if not can_manage_group_type(request.user, group):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view")
if request.method == 'POST':
form = ConcludeGroupForm(request.POST)
@ -1136,7 +1137,7 @@ def customize_workflow(request, group_type=None, acronym=None):
if not (can_manage_group(request.user, group)
or group.has_role(request.user, group.features.groupman_roles)):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view")
if group_type == "rg":
stream_id = "irtf"
@ -1246,7 +1247,7 @@ def stream_edit(request, acronym):
group = get_object_or_404(Group, acronym=acronym)
if not (has_role(request.user, "Secretariat") or group.has_role(request.user, "chair")):
return HttpResponseForbidden("You don't have permission to access this page.")
permission_denied(request, "You don't have permission to access this page.")
chairs = Email.objects.filter(role__group=group, role__name="chair").select_related("person")
@ -1487,7 +1488,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
raise Http404
if not can_manage_review_requests_for_team(request.user, group):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
review_requests = get_open_review_requests_for_team(group, assignment_status=assignment_status)
@ -1622,7 +1623,7 @@ def email_open_review_assignments(request, acronym, group_type=None):
raise Http404
if not can_manage_review_requests_for_team(request.user, group):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
review_assignments = list(ReviewAssignment.objects.filter(
review_request__team=group,
@ -1731,7 +1732,7 @@ def change_reviewer_settings(request, acronym, reviewer_email, group_type=None):
if not (user_is_person(request.user, reviewer)
or can_manage_review_requests_for_team(request.user, group)):
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
exclude_fields = []
if not can_manage_review_requests_for_team(request.user, group):
@ -1918,7 +1919,7 @@ def add_comment(request, acronym, group_type=None):
group = get_group_or_404(acronym, group_type)
if not is_authorized_in_group(request.user,group):
return HttpResponseForbidden("You need to a chair, secretary, or delegate of this group to add a comment.")
permission_denied(request, "You need to a chair, secretary, or delegate of this group to add a comment.")
if request.method == 'POST':
form = AddCommentForm(request.POST)
@ -1949,7 +1950,7 @@ def reset_next_reviewer(request, acronym, group_type=None):
raise Http404
if not Role.objects.filter(name="secr", group=group, person__user=request.user).exists() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("You don't have permission to access this view")
permission_denied(request, "You don't have permission to access this view")
instance = group.nextreviewerinteam_set.first()
if not instance:

View file

@ -613,7 +613,7 @@ class IetfAuthTests(TestCase):
# invalid apikey
r = self.client.post(key.endpoint, {'apikey':BAD_KEY, 'dummy':'dummy',})
self.assertContains(r, 'Invalid apikey', status_code=400)
self.assertContains(r, 'Invalid apikey', status_code=403)
# too long since regular login
person.user.last_login = datetime.datetime.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS+1)

View file

@ -14,8 +14,9 @@ from functools import wraps
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.decorators import available_attrs
from django.utils.http import urlquote
@ -117,7 +118,7 @@ def passes_test_decorator(test_func, message):
elif test_func(request.user, *args, **kwargs):
return view_func(request, *args, **kwargs)
else:
return HttpResponseForbidden(message)
raise PermissionDenied(message)
return inner
return decorate
@ -126,7 +127,7 @@ def role_required(*role_names):
"""View decorator for checking that the user is logged in and
has one of the listed roles."""
return passes_test_decorator(lambda u, *args, **kwargs: has_role(u, role_names, *args, **kwargs),
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ", ".join(role_names)))
"Restricted to role%s: %s" % ("s" if len(role_names) != 1 else "", ", ".join(role_names)))
# specific permissions

View file

@ -9,7 +9,7 @@ from django.contrib import messages
from django.urls import reverse as urlreverse
from django.core.validators import validate_email, ValidationError
from django.db.models import Q, Prefetch
from django.http import HttpResponse, HttpResponseForbidden
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404, redirect
import debug # pyflakes:ignore
@ -26,6 +26,7 @@ from ietf.liaisons.forms import liaison_form_factory, SearchLiaisonForm, EditAtt
from ietf.liaisons.mails import notify_pending_by_email, send_liaison_by_email
from ietf.liaisons.fields import select2_id_liaison_json
from ietf.name.models import LiaisonStatementTagName
from ietf.utils.response import permission_denied
EMAIL_ALIASES = {
'IETFCHAIR':'The IETF Chair <chair@ietf.org>',
@ -322,9 +323,9 @@ def add_comment(request, object_id):
@can_submit_liaison_required
def liaison_add(request, type=None, **kwargs):
if type == 'incoming' and not can_add_incoming_liaison(request.user):
return HttpResponseForbidden("Restricted to users who are authorized to submit incoming liaison statements")
permission_denied(request, "Restricted to users who are authorized to submit incoming liaison statements.")
if type == 'outgoing' and not can_add_outgoing_liaison(request.user):
return HttpResponseForbidden("Restricted to users who are authorized to submit outgoing liaison statements")
permission_denied(request, "Restricted to users who are authorized to submit outgoing liaison statements.")
if request.method == 'POST':
form = liaison_form_factory(request, data=request.POST.copy(),
@ -372,7 +373,7 @@ def liaison_delete_attachment(request, object_id, attach_id):
liaison = get_object_or_404(LiaisonStatement, pk=object_id)
attach = get_object_or_404(LiaisonStatementAttachment, pk=attach_id)
if not can_edit_liaison(request.user, liaison):
return HttpResponseForbidden("You are not authorized for this action")
permission_denied(request, "You are not authorized for this action.")
# FIXME: this view should use POST instead of GET when deleting
attach.removed = True
@ -430,7 +431,7 @@ def liaison_detail(request, object_id):
def liaison_edit(request, object_id):
liaison = get_object_or_404(LiaisonStatement, pk=object_id)
if not can_edit_liaison(request.user, liaison):
return HttpResponseForbidden('You do not have permission to edit this liaison statement')
permission_denied(request, 'You do not have permission to edit this liaison statement.')
return liaison_add(request, instance=liaison)
def liaison_edit_attachment(request, object_id, doc_id):
@ -438,7 +439,7 @@ def liaison_edit_attachment(request, object_id, doc_id):
liaison = get_object_or_404(LiaisonStatement, pk=object_id)
doc = get_object_or_404(Document, pk=doc_id)
if not can_edit_liaison(request.user, liaison):
return HttpResponseForbidden("You are not authorized for this action")
permission_denied(request, "You are not authorized for this action.")
if request.method == 'POST':
form = EditAttachmentForm(request.POST)
@ -480,8 +481,8 @@ def liaison_list(request, state='posted'):
# check authorization for pending and dead tabs
if state in ('pending','dead') and not can_add_liaison(request.user):
msg = "Restricted to participants who are authorized to submit liaison statements on behalf of the various IETF entities"
return HttpResponseForbidden(msg)
msg = "Restricted to participants who are authorized to submit liaison statements on behalf of the various IETF entities."
permission_denied(request, msg)
if 'tags' in request.GET:
value = request.GET.get('tags')

View file

@ -27,7 +27,7 @@ import debug # pyflakes:ignore
from django import forms
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
@ -86,10 +86,11 @@ from ietf.utils.decorators import require_api_key
from ietf.utils.history import find_history_replacements_active_at
from ietf.utils.log import assertion
from ietf.utils.mail import send_mail_message, send_mail_text
from ietf.utils.mime import get_mime_type
from ietf.utils.pipe import pipe
from ietf.utils.pdf import pdf_pages
from ietf.utils.response import permission_denied
from ietf.utils.text import xslugify
from ietf.utils.mime import get_mime_type
from .forms import (InterimMeetingModelForm, InterimAnnounceForm, InterimSessionModelForm,
InterimCancelForm, InterimSessionInlineFormSet, FileUploadForm, RequestMinutesForm,)
@ -462,7 +463,7 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None):
if not can_see:
if request.method == 'POST':
return HttpResponseForbidden("Can't view this schedule")
permission_denied(request, "Can't view this schedule.")
# FIXME: check this
return render(request, "meeting/private_schedule.html",
@ -491,7 +492,7 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None):
if request.method == 'POST':
if not can_edit:
return HttpResponseForbidden("Can't edit this schedule")
permission_denied(request, "Can't edit this schedule.")
action = request.POST.get('action')
@ -859,7 +860,7 @@ def edit_schedule_properties(request, num=None, owner=None, name=None):
cansee, canedit, secretariat = schedule_permissions(meeting, schedule, request.user)
if not (canedit or has_role(request.user,'Secretariat')):
return HttpResponseForbidden("You may not edit this schedule")
permission_denied(request, "You may not edit this schedule.")
else:
if request.method == 'POST':
form = SchedulePropertiesForm(instance=schedule,data=request.POST)
@ -1704,12 +1705,12 @@ def upload_session_bluesheets(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload bluesheets for this session.")
permission_denied(request, "You don't have permission to upload bluesheets for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
if session.meeting.type.slug == 'ietf' and not has_role(request.user, 'Secretariat'):
return HttpResponseForbidden('Restricted to role Secretariat')
permission_denied(request, 'Restricted to role Secretariat')
session_number = None
sessions = get_sessions(session.meeting.number,session.group.acronym)
@ -1801,9 +1802,9 @@ def upload_session_minutes(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload minutes for this session.")
permission_denied(request, "You don't have permission to upload minutes for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
session_number = None
sessions = get_sessions(session.meeting.number,session.group.acronym)
@ -1901,9 +1902,9 @@ def upload_session_agenda(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload an agenda for this session.")
permission_denied(request, "You don't have permission to upload an agenda for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
session_number = None
sessions = get_sessions(session.meeting.number,session.group.acronym)
@ -2015,9 +2016,9 @@ def upload_session_slides(request, session_id, num, name):
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload slides for this session.")
permission_denied(request, "You don't have permission to upload slides for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
session_number = None
sessions = get_sessions(session.meeting.number,session.group.acronym)
@ -2111,7 +2112,7 @@ def upload_session_slides(request, session_id, num, name):
def propose_session_slides(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
session_number = None
sessions = get_sessions(session.meeting.number,session.group.acronym)
@ -2175,9 +2176,9 @@ def remove_sessionpresentation(request, session_id, num, name):
sp = get_object_or_404(SessionPresentation,session_id=session_id,document__name=name)
session = sp.session
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to manage materials for this session.")
permission_denied(request, "You don't have permission to manage materials for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
if request.method == 'POST':
session.sessionpresentation_set.filter(pk=sp.pk).delete()
c = DocEvent(type="added_comment", doc=sp.document, rev=sp.document.rev, by=request.user.person)
@ -2191,9 +2192,9 @@ def ajax_add_slides_to_session(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload slides for this session.")
permission_denied(request, "You don't have permission to upload slides for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
if request.method != 'POST' or not request.POST:
return HttpResponse(json.dumps({ 'success' : False, 'error' : 'No data submitted or not POST' }),content_type='application/json')
@ -2224,9 +2225,9 @@ def ajax_remove_slides_from_session(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload slides for this session.")
permission_denied(request, "You don't have permission to upload slides for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
if request.method != 'POST' or not request.POST:
return HttpResponse(json.dumps({ 'success' : False, 'error' : 'No data submitted or not POST' }),content_type='application/json')
@ -2262,9 +2263,9 @@ def ajax_reorder_slides_in_session(request, session_id, num):
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to upload slides for this session.")
permission_denied(request, "You don't have permission to upload slides for this session.")
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
if request.method != 'POST' or not request.POST:
return HttpResponse(json.dumps({ 'success' : False, 'error' : 'No data submitted or not POST' }),content_type='application/json')
@ -2341,13 +2342,13 @@ def delete_schedule(request, num, owner, name):
schedule = get_schedule_by_name(meeting, person, name)
if schedule.name=='Empty-Schedule':
return HttpResponseForbidden('You may not delete the default empty schedule')
permission_denied(request, 'You may not delete the default empty schedule')
if schedule == meeting.schedule:
return HttpResponseForbidden('You may not delete the official schedule for %s'%meeting)
permission_denied(request, 'You may not delete the official schedule for %s'%meeting)
if not ( has_role(request.user, 'Secretariat') or person.user == request.user ):
return HttpResponseForbidden("You may not delete other user's schedules")
permission_denied(request, "You may not delete other user's schedules")
if request.method == 'POST':
schedule.delete()
@ -2466,7 +2467,7 @@ def interim_skip_announcement(request, number):
def interim_pending(request):
if not can_manage_some_groups(request.user):
return HttpResponseForbidden()
permission_denied(request, "You are not authorized to access this view")
'''View which shows interim meeting requests pending approval'''
meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='apprw')
@ -2489,7 +2490,7 @@ def interim_pending(request):
def interim_request(request):
if not can_manage_some_groups(request.user):
return HttpResponseForbidden("You don't have permission to request any interims")
permission_denied(request, "You don't have permission to request any interims")
'''View for requesting an interim meeting'''
SessionFormset = inlineformset_factory(
@ -2582,7 +2583,7 @@ def interim_request_cancel(request, number):
first_session = meeting.session_set.first()
group = first_session.group
if not can_manage_group(request.user, group):
return HttpResponseForbidden("You do not have permissions to cancel this meeting request")
permission_denied(request, "You do not have permissions to cancel this meeting request")
session_status = current_session_status(first_session)
if request.method == 'POST':
@ -2622,7 +2623,7 @@ def interim_request_details(request, number):
meeting = get_object_or_404(Meeting, number=number)
group = meeting.session_set.first().group
if not can_manage_group(request.user, group):
return HttpResponseForbidden("You do not have permissions to manage this meeting request")
permission_denied(request, "You do not have permissions to manage this meeting request")
sessions = meeting.session_set.all()
can_edit = can_edit_interim_request(meeting, request.user)
can_approve = can_approve_interim_request(meeting, request.user)
@ -2668,7 +2669,7 @@ def interim_request_edit(request, number):
'''Edit details of an interim meeting reqeust'''
meeting = get_object_or_404(Meeting, number=number)
if not can_edit_interim_request(meeting, request.user):
return HttpResponseForbidden("You do not have permissions to edit this meeting request")
permission_denied(request, "You do not have permissions to edit this meeting request")
SessionFormset = inlineformset_factory(
Meeting,
@ -3067,7 +3068,8 @@ def api_upload_bluesheet(request):
# group: acronym or special, i.e., 'quic' or 'plenary'
# item: '1', '2', '3' (the group's first, second, third etc.
# session during the week)
# bluesheet: json blob with [{'name': 'Name', 'affiliation': 'Organization', }, ...]
# bluesheet: json blob with
# [{'name': 'Name', 'affiliation': 'Organization', }, ...]
for item in ['meeting', 'group', 'item', 'bluesheet',]:
value = request.POST.get(item)
if not value:
@ -3214,9 +3216,9 @@ class ApproveSlidesForm(forms.Form):
def approve_proposed_slides(request, slidesubmission_id, num):
submission = get_object_or_404(SlideSubmission,pk=slidesubmission_id)
if not submission.session.can_manage_materials(request.user):
return HttpResponseForbidden("You don't have permission to manage slides for this session.")
permission_denied(request, "You don't have permission to manage slides for this session.")
if submission.session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
return HttpResponseForbidden("The materials cutoff for this session has passed. Contact the secretariat for further action.")
permission_denied(request, "The materials cutoff for this session has passed. Contact the secretariat for further action.")
session_number = None
sessions = get_sessions(submission.session.meeting.number,submission.session.group.acronym)

View file

@ -12,7 +12,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import AnonymousUser
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.forms.models import modelformset_factory, inlineformset_factory
from django.http import Http404, HttpResponseRedirect, HttpResponseForbidden
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, redirect
from django.template.loader import render_to_string
from django.urls import reverse
@ -42,6 +42,7 @@ from ietf.nomcom.utils import (get_nomcom_by_year, store_nomcom_private_key,
from ietf.ietfauth.utils import role_required
from ietf.person.models import Person
from ietf.utils import log
from ietf.utils.response import permission_denied
import debug # pyflakes:ignore
@ -661,20 +662,20 @@ def private_questionnaire(request, year):
def process_nomination_status(request, year, nominee_position_id, state, date, hash):
valid = get_hash_nominee_position(date, nominee_position_id) == hash
if not valid:
return HttpResponseForbidden("Bad hash!")
permission_denied(request, "Bad hash!")
expiration_days = getattr(settings, 'DAYS_TO_EXPIRE_NOMINATION_LINK', None)
if expiration_days:
request_date = datetime.date(int(date[:4]), int(date[4:6]), int(date[6:]))
if datetime.date.today() > (request_date + datetime.timedelta(days=settings.DAYS_TO_EXPIRE_NOMINATION_LINK)):
return HttpResponseForbidden("Link expired")
permission_denied(request, "Link expired.")
need_confirmation = True
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id == 'conclude':
return HttpResponseForbidden("This nomcom is concluded.")
permission_denied(request, "This nomcom is concluded.")
nominee_position = get_object_or_404(NomineePosition, id=nominee_position_id)
if nominee_position.state.slug != "pending":
return HttpResponseForbidden("The nomination already was %s" % nominee_position.state)
permission_denied(request, "The nomination already was %s" % nominee_position.state)
state = get_object_or_404(NomineePositionStateName, slug=state)
messages.info(request, "Click on 'Save' to set the state of your nomination to %s to %s (this is not a final commitment - you can notify us later if you need to change this)." % (nominee_position.position.name, state.name))
@ -791,7 +792,7 @@ def view_feedback(request, year):
def view_feedback_pending(request, year):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id == 'conclude':
return HttpResponseForbidden("This nomcom is concluded.")
permission_denied(request, "This nomcom is concluded.")
extra_ids = None
FeedbackFormSet = modelformset_factory(Feedback,
form=PendingFeedbackForm,
@ -987,7 +988,7 @@ def edit_nomcom(request, year):
if request.method == 'POST':
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
permission_denied(request, 'This nomcom is closed.')
formset = ReminderDateInlineFormSet(request.POST, instance=nomcom)
form = EditNomcomForm(request.POST,
@ -1069,7 +1070,7 @@ def list_positions(request, year):
def remove_position(request, year, position_id):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
permission_denied(request, 'This nomcom is closed.')
try:
position = nomcom.position_set.get(id=position_id)
except Position.DoesNotExist:
@ -1091,7 +1092,7 @@ def edit_position(request, year, position_id=None):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
permission_denied(request, 'This nomcom is closed.')
if position_id:
try:
@ -1136,7 +1137,7 @@ def list_topics(request, year):
def remove_topic(request, year, topic_id):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
permission_denied(request, 'This nomcom is closed.')
try:
topic = nomcom.topic_set.get(id=topic_id)
except Topic.DoesNotExist:
@ -1158,7 +1159,7 @@ def edit_topic(request, year, topic_id=None):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
permission_denied(request, 'This nomcom is closed.')
if topic_id:
try:
@ -1194,7 +1195,7 @@ def edit_members(request, year):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
permission_denied(request, 'This nomcom is closed.')
old_members_email = [r.email for r in nomcom.group.role_set.filter(name='member')]

View file

@ -351,6 +351,7 @@ PERSON_API_KEY_VALUES = [
("/api/v2/person/person", "/api/v2/person/person", "Secretariat"),
("/api/meeting/session/video/url", "/api/meeting/session/video/url", "Recording Manager"),
("/api/notify/meeting/registration", "/api/notify/meeting/registration", "Robot"),
("/api/notify/meeting/bluesheet", "/api/notify/meeting/bluesheet", "Recording Manager"),
]
PERSON_API_KEY_ENDPOINTS = [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES ]

View file

@ -1,6 +1,8 @@
# Copyright The IETF Trust 2013-2020, All Rights Reserved
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseForbidden
from django.shortcuts import render, redirect
from ietf.group.models import Role
@ -9,6 +11,8 @@ from ietf.ietfauth.utils import has_role
from ietf.secr.announcement.forms import AnnounceForm
from ietf.secr.utils.decorators import check_for_cancel
from ietf.utils.mail import send_mail_text
from ietf.utils.response import permission_denied
# -------------------------------------------------
# Helper Functions
@ -49,7 +53,7 @@ def main(request):
and send.
'''
if not check_access(request.user):
return HttpResponseForbidden('Restricted to: Secretariat, IAD, or chair of IETF, IAB, RSOC, RSE, IAOC, ISOC, NomCom.')
permission_denied(request, 'Restricted to: Secretariat, IAD, or chair of IETF, IAB, RSOC, RSE, IAOC, ISOC, NomCom.')
form = AnnounceForm(request.POST or None,user=request.user)
@ -74,7 +78,7 @@ def main(request):
def confirm(request):
if not check_access(request.user):
return HttpResponseForbidden('Restricted to: Secretariat, IAD, or chair of IETF, IAB, RSOC, RSE, IAOC, ISOC, NomCom.')
permission_denied(request, 'Restricted to: Secretariat, IAD, or chair of IETF, IAB, RSOC, RSE, IAOC, ISOC, NomCom.')
if request.method == 'POST':
form = AnnounceForm(request.POST, user=request.user)

View file

@ -1,9 +1,10 @@
# Copyright The IETF Trust 2013-2020, All Rights Reserved
from functools import wraps
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.utils.http import urlquote
@ -12,6 +13,7 @@ from ietf.doc.models import Document
from ietf.group.models import Group, Role
from ietf.meeting.models import Session
from ietf.secr.utils.meeting import get_timeslot
from ietf.utils.response import permission_denied
def check_for_cancel(redirect_url):
@ -61,7 +63,7 @@ def check_permissions(func):
try:
login = request.user.person
except ObjectDoesNotExist:
return HttpResponseForbidden("User not authorized to access group: %s" % group.acronym)
permission_denied(request, "User not authorized to access group: %s" % group.acronym)
groups = [group]
if group.parent:
@ -78,7 +80,7 @@ def check_permissions(func):
return func(request, *args, **kwargs)
# if we get here access is denied
return HttpResponseForbidden("User not authorized to access group: %s" % group.acronym)
permission_denied(request, "User not authorized to access group: %s" % group.acronym)
return wraps(func)(wrapper)

View file

@ -15,7 +15,7 @@ from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.cache import cache
from django.db.models import Count, Q
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse as urlreverse
from django.utils.safestring import mark_safe
@ -39,6 +39,7 @@ from ietf.stats.models import MeetingRegistration, CountryAlias
from ietf.stats.utils import get_aliased_affiliations, get_aliased_countries, compute_hirsch_index
from ietf.ietfauth.utils import has_role
from ietf.utils.log import log
from ietf.utils.response import permission_denied
def stats_index(request):
return render(request, "stats/index.html")
@ -1080,7 +1081,7 @@ def review_stats(request, stats_type=None, acronym=None):
reviewer_only_access.add(r.group_id)
if not secr_access and not reviewer_only_access:
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page")
teams = [t for t in teams if t.pk in secr_access or t.pk in reviewer_only_access]

View file

@ -43,6 +43,7 @@ from ietf.stats.utils import clean_country_name
from ietf.utils.accesstoken import generate_access_token
from ietf.utils.log import log
from ietf.utils.mail import parseaddr, send_mail_message
from ietf.utils.response import permission_denied
def upload_submission(request):
if request.method == 'POST':
@ -298,7 +299,7 @@ def submission_status(request, submission_id, access_token=None):
action = request.POST.get('action')
if action == "autopost" and submission.state_id == "uploaded":
if not can_edit:
return HttpResponseForbidden("You do not have permission to perform this action")
permission_denied(request, "You do not have permission to perform this action")
submitter_form = SubmitterForm(request.POST, prefix="submitter")
replaces_form = ReplacesForm(request.POST, name=submission.name)
@ -313,7 +314,7 @@ def submission_status(request, submission_id, access_token=None):
if approvals_received:
if not is_secretariat:
return HttpResponseForbidden('You do not have permission to perform this action')
permission_denied(request, 'You do not have permission to perform this action')
# go directly to posting submission
docevent_from_submission(request, submission, desc="Uploaded new revision")
@ -362,7 +363,7 @@ def submission_status(request, submission_id, access_token=None):
elif action == "cancel" and submission.state.next_states.filter(slug="cancel"):
if not can_cancel:
return HttpResponseForbidden('You do not have permission to perform this action')
permission_denied(request, 'You do not have permission to perform this action.')
cancel_submission(submission)
@ -373,7 +374,7 @@ def submission_status(request, submission_id, access_token=None):
elif action == "approve" and submission.state_id == "grp-appr":
if not can_group_approve:
return HttpResponseForbidden('You do not have permission to perform this action')
permission_denied(request, 'You do not have permission to perform this action.')
post_submission(request, submission, "WG -00 approved", "Approved and posted submission")
@ -382,7 +383,7 @@ def submission_status(request, submission_id, access_token=None):
elif action == "forcepost" and submission.state.next_states.filter(slug="posted"):
if not can_force_post:
return HttpResponseForbidden('You do not have permission to perform this action')
permission_denied(request, 'You do not have permission to perform this action.')
if submission.state_id == "manual":
desc = "Posted submission manually"
@ -424,7 +425,7 @@ def edit_submission(request, submission_id, access_token=None):
submission = get_object_or_404(Submission, pk=submission_id, state="uploaded")
if not can_edit_submission(request.user, submission, access_token):
return HttpResponseForbidden('You do not have permission to access this page')
permission_denied(request, 'You do not have permission to access this page.')
errors = validate_submission(submission)
form_errors = False
@ -638,7 +639,7 @@ def cancel_waiting_for_draft(request):
can_cancel = has_role(request.user, "Secretariat")
if not can_cancel:
return HttpResponseForbidden('You do not have permission to perform this action')
permission_denied(request, 'You do not have permission to perform this action.')
submission_id = request.POST.get('submission_id', '')
access_token = request.POST.get('access_token', '')

View file

@ -7,11 +7,11 @@ import subprocess
import os
import json
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect, Http404
from django.shortcuts import render
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from ietf.doc.models import DeletedEvent, StateDocEvent, DocEvent
@ -19,6 +19,8 @@ from ietf.ietfauth.utils import role_required, has_role
from ietf.sync.discrepancies import find_discrepancies
from ietf.utils.serialize import object_as_shallow_dict
from ietf.utils.log import log
from ietf.utils.response import permission_denied
SYNC_BIN_PATH = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../bin"))
@ -51,7 +53,7 @@ def notify(request, org, notification):
if username != None and password != None:
if settings.SERVER_MODE == "production" and not request.is_secure():
return HttpResponseForbidden("You must use HTTPS when sending username/password")
permission_denied(request, "You must use HTTPS when sending username/password.")
if not user.is_authenticated:
try:
@ -63,7 +65,7 @@ def notify(request, org, notification):
return HttpResponse("Invalid username/password")
if not has_role(user, ("Secretariat", known_orgs[org])):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
permission_denied(request, "You do not have the necessary permissions to view this page.")
known_notifications = {
"protocols": "an added reference to an RFC at <a href=\"%s\">the IANA protocols page</a>" % settings.IANA_SYNC_PROTOCOLS_URL,

View file

@ -9,9 +9,6 @@
<h2>Restricted Access.</h2>
<p>The page you tried to reach is not generally avaiable.</p>
<p>{{ exception }}</p>
<p>If you think this is a server error, please contact <a href="mailto:{{ bugreport_email }}">{{ bugreport_email }}</a>.</p>

View file

@ -55,7 +55,7 @@ def require_api_key(f, request, *args, **kwargs):
# Check hash
key = PersonalApiKey.validate_key(force_bytes(hash))
if not key:
return err(400, "Invalid apikey")
return err(403, "Invalid apikey")
# Check endpoint
urlpath = request.META.get('PATH_INFO')
if not (urlpath and urlpath == key.endpoint):

View file

@ -6,5 +6,6 @@ from django.utils.safestring import mark_safe
def permission_denied(request, msg):
"A wrapper around the PermissionDenied exception"
msg += " <br/>You can <a href='/accounts/login?next=%s'><u>Log in</u></a> if you have that role but aren't logged in." % request.path
if not request.user.is_authenticated:
msg += " <br/>You may want to <a href='/accounts/login?next=%s'><u>Log in</u></a> if you have a datatracker role that lets you access this page." % request.path
raise PermissionDenied(mark_safe(msg))