Skip to content

Commit e797c5f

Browse files
authored
Refactor note fetching logic to improve permission checks and reduce code duplication (#14081)
1 parent 5057b4b commit e797c5f

1 file changed

Lines changed: 35 additions & 54 deletions

File tree

dojo/notes/views.py

Lines changed: 35 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,67 @@
11
# Standard library imports
22
import logging
3+
from typing import Literal, get_args
34

45
# Third party imports
56
from django.contrib import messages
67
from django.core.exceptions import PermissionDenied
7-
from django.http import HttpResponseRedirect
8+
from django.http import Http404, HttpRequest, HttpResponseRedirect
89
from django.shortcuts import get_object_or_404, render
910
from django.urls import reverse
1011
from django.utils import timezone
1112
from django.utils.translation import gettext as _
1213

1314
from dojo.authorization.authorization import user_has_permission_or_403
1415
from dojo.authorization.roles_permissions import Permissions
16+
from dojo.cred.queries import get_authorized_cred_mappings
17+
from dojo.engagement.queries import get_authorized_engagements
18+
from dojo.finding.queries import get_authorized_findings
1519

1620
# Local application/library imports
1721
from dojo.forms import DeleteNoteForm, NoteForm, TypedNoteForm
1822
from dojo.models import Cred_User, Engagement, Finding, Note_Type, NoteHistory, Notes, Test
23+
from dojo.test.queries import get_authorized_tests
1924

2025
logger = logging.getLogger(__name__)
2126

27+
SUPPORTED_PAGES = Literal["engagement", "test", "finding", "cred"]
2228

23-
def delete_note(request, note_id, page, objid):
24-
note = get_object_or_404(Notes, id=note_id)
25-
reverse_url = None
26-
object_id = None
2729

30+
def _get_page_details(request: HttpRequest, note_id: int, page: SUPPORTED_PAGES | None, objid: int) -> tuple[Notes, Engagement | Test | Finding | Cred_User, int, str]:
31+
note = get_object_or_404(Notes, id=note_id)
32+
# Quick check to make sure we have a valid page
33+
if page is None or page not in get_args(SUPPORTED_PAGES):
34+
raise PermissionDenied
35+
# Get the real object based on page type
2836
if page == "engagement":
29-
obj = get_object_or_404(Engagement, id=objid)
30-
object_id = obj.id
37+
obj = get_authorized_engagements(Permissions.Engagement_View).filter(id=objid).first()
3138
reverse_url = "view_engagement"
3239
elif page == "test":
33-
obj = get_object_or_404(Test, id=objid)
34-
object_id = obj.id
40+
obj = get_authorized_tests(Permissions.Test_View).filter(id=objid).first()
3541
reverse_url = "view_test"
3642
elif page == "finding":
37-
obj = get_object_or_404(Finding, id=objid)
38-
object_id = obj.id
43+
obj = get_authorized_findings(Permissions.Finding_View).filter(id=objid).first()
3944
reverse_url = "view_finding"
4045
elif page == "cred":
41-
obj = get_object_or_404(Cred_User, id=objid)
42-
object_id = obj.id
46+
obj = get_authorized_cred_mappings(Permissions.Cred_View).filter(id=objid).first()
4347
reverse_url = "view_cred_details"
48+
else:
49+
# If we get here, something is wrong, so let's just raise PermissionDenied
50+
raise PermissionDenied
51+
# Ensure we have an object back, and if not, raise the 404 like before
52+
if obj is None:
53+
raise Http404
54+
# Next check if the note supplied is even attached to the object
55+
if obj.notes.filter(id=note.id).exists() is False:
56+
raise PermissionDenied
57+
58+
return note, obj, obj.id, reverse_url
4459

60+
61+
def delete_note(request: HttpRequest, note_id: int, page: SUPPORTED_PAGES, objid: int) -> HttpResponseRedirect:
62+
note, obj, object_id, reverse_url = _get_page_details(request, note_id, page, objid)
4563
form = DeleteNoteForm(request.POST, instance=note)
4664

47-
if page is None:
48-
raise PermissionDenied
4965
if str(request.user) != note.author.username:
5066
user_has_permission_or_403(request.user, obj, Permissions.Note_Delete)
5167

@@ -64,26 +80,8 @@ def delete_note(request, note_id, page, objid):
6480
return HttpResponseRedirect(reverse(reverse_url, args=(object_id, )))
6581

6682

67-
def edit_note(request, note_id, page, objid):
68-
note = get_object_or_404(Notes, id=note_id)
69-
reverse_url = None
70-
object_id = None
71-
72-
if page is None:
73-
raise PermissionDenied
74-
75-
if page == "engagement":
76-
obj = get_object_or_404(Engagement, id=objid)
77-
object_id = obj.id
78-
reverse_url = "view_engagement"
79-
elif page == "test":
80-
obj = get_object_or_404(Test, id=objid)
81-
object_id = obj.id
82-
reverse_url = "view_test"
83-
elif page == "finding":
84-
obj = get_object_or_404(Finding, id=objid)
85-
object_id = obj.id
86-
reverse_url = "view_finding"
83+
def edit_note(request: HttpRequest, note_id: int, page: SUPPORTED_PAGES, objid: int) -> HttpResponseRedirect:
84+
note, obj, object_id, reverse_url = _get_page_details(request, note_id, page, objid)
8785

8886
if str(request.user) != note.author.username:
8987
user_has_permission_or_403(request.user, obj, Permissions.Note_Edit)
@@ -141,26 +139,9 @@ def edit_note(request, note_id, page, objid):
141139
})
142140

143141

144-
def note_history(request, note_id, page, objid):
145-
note = get_object_or_404(Notes, id=note_id)
146-
reverse_url = None
147-
object_id = None
148-
149-
if page == "engagement":
150-
obj = get_object_or_404(Engagement, id=objid)
151-
object_id = obj.id
152-
reverse_url = "view_engagement"
153-
elif page == "test":
154-
obj = get_object_or_404(Test, id=objid)
155-
object_id = obj.id
156-
reverse_url = "view_test"
157-
elif page == "finding":
158-
obj = get_object_or_404(Finding, id=objid)
159-
object_id = obj.id
160-
reverse_url = "view_finding"
142+
def note_history(request: HttpRequest, note_id: int, page: SUPPORTED_PAGES, objid: int) -> HttpResponseRedirect:
143+
note, obj, object_id, reverse_url = _get_page_details(request, note_id, page, objid)
161144

162-
if page is None:
163-
raise PermissionDenied
164145
if str(request.user) != note.author.username:
165146
user_has_permission_or_403(request.user, obj, Permissions.Note_View_History)
166147

0 commit comments

Comments
 (0)