From 461e53c40615c636ebbdd0b92b72271767799e05 Mon Sep 17 00:00:00 2001 From: Chandra Y Date: Fri, 12 Apr 2024 12:20:24 -0500 Subject: [PATCH] WP-547: case insensitive email in GET tickets (#944) * WP-547: case insensitive email in GET tickets * Do not assume ticket fields are a list. * lint fix * Fix redundancy --- server/portal/apps/tickets/rtUtil.py | 12 ++++- server/portal/apps/tickets/unit_test.py | 59 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/server/portal/apps/tickets/rtUtil.py b/server/portal/apps/tickets/rtUtil.py index bd848e585..13467d466 100644 --- a/server/portal/apps/tickets/rtUtil.py +++ b/server/portal/apps/tickets/rtUtil.py @@ -60,7 +60,7 @@ def replyToTicket(self, ticket_id, reply_text, files=[]): def hasAccess(self, ticket_id, user=None): if user and ticket_id: ticket = self.tracker.get_ticket(ticket_id) - if user in ticket.get('Requestors', '') or user in ticket.get('Cc', ''): + if DjangoRt.contains_user(ticket.get('Requestors', ''), user) or DjangoRt.contains_user(ticket.get('Cc', ''), user): return True return False @@ -68,3 +68,13 @@ def hasAccess(self, ticket_id, user=None): def getAttachment(self, ticket_id, attachment_id): ticketAttachment = self.tracker.get_attachment(ticket_id, attachment_id) return ticketAttachment + + @staticmethod + def contains_user(ticket_field_data, user): + user_lower = user.lower() + + if isinstance(ticket_field_data, str): + return user_lower in ticket_field_data.lower() + elif isinstance(ticket_field_data, list): + return user_lower in map(str.lower, ticket_field_data) + return user_lower in ticket_field_data diff --git a/server/portal/apps/tickets/unit_test.py b/server/portal/apps/tickets/unit_test.py index 58acf82be..e7049d4ec 100644 --- a/server/portal/apps/tickets/unit_test.py +++ b/server/portal/apps/tickets/unit_test.py @@ -2,6 +2,7 @@ from django.http import HttpResponse from django.http import HttpRequest from portal.apps.tickets.utils import get_recaptcha_verification +from portal.apps.tickets import rtUtil @pytest.fixture(autouse=True) @@ -46,3 +47,61 @@ def test_get_recaptcha_verification(mocker, requests_mock, regular_user): request.POST['recaptchaResponse'] = 'string' result = get_recaptcha_verification(request) assert result['success'] == recaptchaSuccess['success'] + + +class RtUtilTestable(rtUtil.DjangoRt): + ''' + Tester for rtUtil.DjangoRt. + ''' + + def __init__(self, tracker): + # Set the attributes directly + self.rtHost = 'mock_host' + self.rtUn = 'mock_rt_user' + self.rtPw = 'mock_pw' + self.rtQueue = '' + self.tracker = tracker + + +@pytest.fixture +def rt_ticket(request): + return request.param + + +@pytest.fixture +def mock_tracker(mocker, rt_ticket): + mock_tracker = mocker.MagicMock() + mock_tracker.get_ticket.return_value = rt_ticket + yield mock_tracker + + +@pytest.mark.parametrize('rt_ticket', [ + {'id': 1, 'Requestors': ["UserName1@Example.COM", "Username2@Example.com"], 'Cc': []}, + {'id': 1, 'Requestors': "UserName1@Example.COM,Username2@Example.com", 'Cc': []}, + {'id': 1, 'Requestors': ["username1@example.com", "username2@example.com"], 'Cc': []}], indirect=True) +def test_rt_hasaccess_requestors_or_cc(mock_tracker): + rtTester = RtUtilTestable(mock_tracker) + assert rtTester.hasAccess(1, 'Username1@Example.com') is True + assert rtTester.hasAccess(1, 'Username2@Example.com') is True + + +@pytest.mark.parametrize('rt_ticket', [ + {'id': 1, 'Requestors': ["Foo@example.com"], 'Cc': ["UserName1@Example.COM", "username2@example.com"]}, + {'id': 1, 'Requestors': ["Foo@example.com"], 'Cc': "UserName1@Example.COM,username2@example.com"}, + {'id': 1, 'Requestors': ["Foo@example.com"], 'Cc': ["username1@example.com", "username2@example.com"]}, + {'id': 1, 'Cc': ["username1@example.com", "username2@example.com"]}, + {'id': 1, 'Requestors': [], 'Cc': ["username1@example.com", "username2@example.com"]}], indirect=True) +def test_rt_hasaccess_cc(mock_tracker): + rtTester = RtUtilTestable(mock_tracker) + assert rtTester.hasAccess(1, 'Username1@Example.com') is True + assert rtTester.hasAccess(1, 'Username2@Example.com') is True + + +@pytest.mark.parametrize('rt_ticket', [ + {'id': 1, 'Requestors': ["foo@example.com"], 'Cc': ["baz@example.com"]}, + {'id': 1, 'Requestors': ["FOO@example.com"], 'Cc': ["BAZ@example.com"]}, + {'id': 1}, + {'id': 1, 'Requestors': [], 'Cc': []}], indirect=True) +def test_rt_hasnoaccess(mock_tracker): + rtTester = RtUtilTestable(mock_tracker) + assert rtTester.hasAccess(1, 'Username1@Example.com') is False