From 399c2a97b69971d352527dd3f888c0150063de3b Mon Sep 17 00:00:00 2001 From: James Antill Date: May 06 2024 17:44:46 +0000 Subject: [PATCH 1/8] Add some regexp validation to fix #213 Signed-off-by: James Antill --- diff --git a/fedocal/forms.py b/fedocal/forms.py index f070c83..517f088 100644 --- a/fedocal/forms.py +++ b/fedocal/forms.py @@ -52,12 +52,23 @@ def validate_time(form, field): def validate_meeting_location(form, field): - """ Validate if location doesn't contain #irc-chan format - More info: https://fedorahosted.org/fedocal/ticket/118 + """ Validate if location for compatibility to IRC and Matrix. + More info: https://fedorahosted.org/fedocal/ticket/213 """ - if '#' in field.data.strip(): - raise wtforms.ValidationError( - _('Please use channel@server format!') + # As always, try: https://regex101.com/ + # These aren't "perfect" but close enough: [-\w] allows alphanum '_' and '-' + loc = field.data.strip() + # - ircroom@irc.server + if re.match(r'^[-\w]+@[-\w]+([.][-\w]+)*$', loc): + return + # - #room:host.name.tld + if re.match(r'^#[-\w]+:[-\w]+([.][-\w]+)*$', loc): + return + # - https://matrix.to/#/#room:host.name.tld + if re.match(r'^https?://matrix.to/#/#[-\w]+:[-\w]+([.][-\w]+)*$', loc): + return + raise wtforms.ValidationError( + _('Please use channel@server or #room:server formats!') ) diff --git a/tests/test_flask.py b/tests/test_flask.py index 02105a7..2db5523 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -1579,7 +1579,7 @@ class Flasktests(Modeltests): self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( - 'Please use channel@server format!', output_text) + 'Please use channel@server or #room:server formats!', output_text) self.assertIn( 'Add meeting - Fedocal', output_text) From cfed440e1d985cdad28c75fbf28e29a3d4dc132a Mon Sep 17 00:00:00 2001 From: Dominik Wombacher Date: May 07 2024 16:09:18 +0000 Subject: [PATCH 2/8] tests: Validate meeting location. Relates to PR #214 and Issue #213 --- diff --git a/tests/test_flask.py b/tests/test_flask.py index 2db5523..a171050 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -1562,7 +1562,9 @@ class Flasktests(Modeltests): self.assertIn( 'Add meeting - Fedocal', output_text) - # Invalid location + # Invalid meeting location: IRC Channel name without server + # Allowed: channel@irc.server.tld + # https://pagure.io/fedocal/issue/118 data = { 'meeting_name': 'guess what?', 'meeting_date': TODAY, @@ -1787,6 +1789,70 @@ class Flasktests(Modeltests): self.assertNotIn( 'href="/meeting/20/?from_date=', output_text) + # Valid meeting location: IRC Channel with server + # https://pagure.io/fedocal/issue/118 + data = { + 'meeting_name': 'guess what?', + 'meeting_date': TODAY, + 'meeting_time_start': time(13, 0), + 'meeting_time_stop': time(14, 0), + 'meeting_timezone': 'Europe/Paris', + 'meeting_location': 'meeting-1@fedoraproject.org', + 'frequency': '', + 'csrf_token': csrf_token, + } + + with testing.mock_sends(schema.MeetingNewV1): + output = self.app.post('/test_calendar/add/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Meeting added
  • ', output_text) + + # Valid meeting location: Matrix Room + # https://pagure.io/fedocal/issue/213 + data = { + 'meeting_name': 'guess what?', + 'meeting_date': TODAY, + 'meeting_time_start': time(13, 0), + 'meeting_time_stop': time(14, 0), + 'meeting_timezone': 'Europe/Paris', + 'meeting_location': '#meeting-1:fedoraproject.org', + 'frequency': '', + 'csrf_token': csrf_token, + } + + with testing.mock_sends(schema.MeetingNewV1): + output = self.app.post('/test_calendar/add/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Meeting added
  • ', output_text) + + # Valid meeting location: Matrix Room URL + # https://pagure.io/fedocal/issue/213 + data = { + 'meeting_name': 'guess what?', + 'meeting_date': TODAY, + 'meeting_time_start': time(13, 0), + 'meeting_time_stop': time(14, 0), + 'meeting_timezone': 'Europe/Paris', + 'meeting_location': 'https://matrix.to/#/#meeting-1:fedoraproject.org', + 'frequency': '', + 'csrf_token': csrf_token, + } + + with testing.mock_sends(schema.MeetingNewV1): + output = self.app.post('/test_calendar/add/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Meeting added
  • ', output_text) + + def test_edit_meeting(self): """ Test the edit_meeting function. """ self.__setup_db() From 188adce474d0ecafa59ede3cf2cc2e0647c93500 Mon Sep 17 00:00:00 2001 From: James Antill Date: May 07 2024 16:18:41 +0000 Subject: [PATCH 3/8] Add more validation for #213, meet/zoom/hangouts/etc. Signed-off-by: James Antill --- diff --git a/fedocal/forms.py b/fedocal/forms.py index 517f088..59bd900 100644 --- a/fedocal/forms.py +++ b/fedocal/forms.py @@ -58,17 +58,63 @@ def validate_meeting_location(form, field): # As always, try: https://regex101.com/ # These aren't "perfect" but close enough: [-\w] allows alphanum '_' and '-' loc = field.data.strip() + # Allow a "blank" entry... + if loc == '': + return + # - ircroom@irc.server if re.match(r'^[-\w]+@[-\w]+([.][-\w]+)*$', loc): return + # - #room:host.name.tld if re.match(r'^#[-\w]+:[-\w]+([.][-\w]+)*$', loc): return + # - https://matrix.to/#/#room:host.name.tld if re.match(r'^https?://matrix.to/#/#[-\w]+:[-\w]+([.][-\w]+)*$', loc): return + + # - irc://irc.server/ircroom + # Eg. + # irc://irc.libera.chat/fedora-zh + if re.match(r'^irc://[-\w]+([.][-\w]+)*/[-\w]+$', loc): + return + + # - https://meet./ + # Eg. + # https://meet.google.com/acq-pwxk-fhv + # https://meet.jit.si/fedora-websites-apps-meeting + if re.match(r'^https?://meet([.][-\w]+)+/[-\w]+$', loc): + return + + # - https://meet./b/ + # Eg. + # https://meet.kde.org/b/ale-swq-39j + if re.match(r'^https?://meet([.][-\w]+)+/b/[-\w]+$', loc): + return + + # - https://.zoom.us/j/?pwd= + # Eg. + # https://umich.zoom.us/j/96648123924?pwd=RitQVVQvMFVSaXJhNkFBS08vWTk0Zz09 + if re.match(r'^https?://[-\w]+.zoom.us/j/\d+([?]pwd=\w+)?$', loc): + return + + # - https://hangouts.google.com/hangouts/_/ + # Eg. + # https://hangouts.google.com/hangouts/_/67zc3kvkovelxctlilphwodlp4e + if re.match(r'^https?://hangouts.google.com/hangouts/_/[-\w]+$', loc): + return + + # podcast.fedoraproject.org + if loc == 'podcast.fedoraproject.org': + return + if loc == 'http://podcast.fedoraproject.org/': + return + if loc == 'https://podcast.fedoraproject.org/': + return + raise wtforms.ValidationError( - _('Please use channel@server or #room:server formats!') + _('Please use IRC, Matrix, meet, zoom or hangouts formats!') ) From 601e8cc5c625bfc9c627c8ebeff690243ec91af7 Mon Sep 17 00:00:00 2001 From: James Antill Date: May 07 2024 16:35:20 +0000 Subject: [PATCH 4/8] tests: Validate meeting location using current values from calendar. Relates to PR #214 and Issue #213 Signed-off-by: James Antill --- diff --git a/tests/test_flask.py b/tests/test_flask.py index a171050..b01b66d 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -1852,6 +1852,44 @@ class Flasktests(Modeltests): self.assertIn( '
  • Meeting added
  • ', output_text) + # Valid meeting location: List of current meeting locations: + meet_locations = ['', + 'https://unomaha.zoom.us/j/609939109', + 'https://hangouts.google.com/hangouts/_/67zc3kvkovelxctlilphwodlp4e', + 'https://meet.opensuse.org/epel', + 'irc://irc.libera.chat/fedora-zh', + 'https://meet.google.com/acq-pwxk-fhv', + 'https://meet.google.com/mic-otnv-kse', + 'https://meet.jit.si/fedora-websites-apps-meeting', + 'https://meet.kde.org/b/ale-swq-39j', + 'https://umich.zoom.us/j/96648123924?pwd=RitQVVQvMFVSaXJhNkFBS08vWTk0Zz09', + 'https://umich.zoom.us/j/99842244394?pwd=YVdkQjJTdnpBMUkySGVzK1kyTGoyZz09', + 'https://meet.google.com/xuj-jswy-hat', + 'podcast.fedoraproject.org', + 'https://podcast.fedoraproject.org/', + 'https://meet.google.com/jod-dkmw-ibd'] + # https://pagure.io/fedocal/issue/213 + data = { + 'meeting_name': 'guess what?', + 'meeting_date': TODAY, + 'meeting_time_start': time(13, 0), + 'meeting_time_stop': time(14, 0), + 'meeting_timezone': 'Europe/Paris', + 'meeting_location': None, + 'frequency': '', + 'csrf_token': csrf_token, + } + + for meet_location in meet_locations: + with testing.mock_sends(schema.MeetingNewV1): + data['meeting_location'] = meet_location + output = self.app.post('/test_calendar/add/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Meeting added
  • ', output_text) + def test_edit_meeting(self): """ Test the edit_meeting function. """ From cfee527e9276dc0115cd39bd58bc8a0d3d668217 Mon Sep 17 00:00:00 2001 From: James Antill Date: May 20 2024 21:34:28 +0000 Subject: [PATCH 5/8] tests: Fix message we check for, in test error output. Signed-off-by: James Antill --- diff --git a/tests/test_flask.py b/tests/test_flask.py index b01b66d..9119924 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -1581,7 +1581,7 @@ class Flasktests(Modeltests): self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( - 'Please use channel@server or #room:server formats!', output_text) + 'Please use IRC, Matrix, meet, zoom or hangouts formats!', output_text) self.assertIn( 'Add meeting - Fedocal', output_text) From cf38cb23601a2d33cd365f35be98ad57ba1ece95 Mon Sep 17 00:00:00 2001 From: James Antill Date: May 20 2024 21:35:29 +0000 Subject: [PATCH 6/8] tests: Stupid hack workaround for mock/strftime failures. Signed-off-by: James Antill --- diff --git a/tests/test_flask.py b/tests/test_flask.py index 9119924..c7ec38c 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -1880,8 +1880,12 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - for meet_location in meet_locations: - with testing.mock_sends(schema.MeetingNewV1): + # Copy and paste works, but using: + # for meet_location in meet_locations + # ...always fails on the second attempt. + import random + meet_location = random.choice(meet_locations) + with testing.mock_sends(schema.MeetingNewV1): data['meeting_location'] = meet_location output = self.app.post('/test_calendar/add/', data=data, follow_redirects=True) From b75c4dd61267a1ada56734fb5a3b1e92cb659c9b Mon Sep 17 00:00:00 2001 From: James Antill Date: May 20 2024 21:36:11 +0000 Subject: [PATCH 7/8] Allow all URLs for a meeting location. Issue #213 Signed-off-by: James Antill --- diff --git a/fedocal/forms.py b/fedocal/forms.py index 59bd900..75b24a9 100644 --- a/fedocal/forms.py +++ b/fedocal/forms.py @@ -108,9 +108,13 @@ def validate_meeting_location(form, field): # podcast.fedoraproject.org if loc == 'podcast.fedoraproject.org': return - if loc == 'http://podcast.fedoraproject.org/': + + # Just let in all URLs ... + if loc.startswith('irc://'): + return + if loc.startswith('http://'): return - if loc == 'https://podcast.fedoraproject.org/': + if loc.startswith('https://'): return raise wtforms.ValidationError( From fff15b096d149bfb9a57c10595e1eb320ae08f86 Mon Sep 17 00:00:00 2001 From: James Antill Date: Jun 05 2024 00:01:36 +0000 Subject: [PATCH 8/8] test: Change the meeting time to not get the testing error, and test all urls. Signed-off-by: James Antill --- diff --git a/tests/test_flask.py b/tests/test_flask.py index c7ec38c..628cb58 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -1789,20 +1789,21 @@ class Flasktests(Modeltests): self.assertNotIn( 'href="/meeting/20/?from_date=', output_text) - # Valid meeting location: IRC Channel with server - # https://pagure.io/fedocal/issue/118 - data = { + _mnum = 0 + def _tst_add_meeting_loc(loc): + nonlocal _mnum + data = { 'meeting_name': 'guess what?', 'meeting_date': TODAY, - 'meeting_time_start': time(13, 0), - 'meeting_time_stop': time(14, 0), + 'meeting_time_start': time(_mnum, 0), + 'meeting_time_stop': time(_mnum+1, 0), 'meeting_timezone': 'Europe/Paris', - 'meeting_location': 'meeting-1@fedoraproject.org', + 'meeting_location': loc, 'frequency': '', 'csrf_token': csrf_token, - } - - with testing.mock_sends(schema.MeetingNewV1): + } + _mnum += 1 + with testing.mock_sends(schema.MeetingNewV1): output = self.app.post('/test_calendar/add/', data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) @@ -1810,89 +1811,37 @@ class Flasktests(Modeltests): self.assertIn( '
  • Meeting added
  • ', output_text) + meeting_locs = set() + # Valid meeting location: IRC Channel with server + # https://pagure.io/fedocal/issue/118 + meeting_locs.add('meeting-1@fedoraproject.org') + # Valid meeting location: Matrix Room # https://pagure.io/fedocal/issue/213 - data = { - 'meeting_name': 'guess what?', - 'meeting_date': TODAY, - 'meeting_time_start': time(13, 0), - 'meeting_time_stop': time(14, 0), - 'meeting_timezone': 'Europe/Paris', - 'meeting_location': '#meeting-1:fedoraproject.org', - 'frequency': '', - 'csrf_token': csrf_token, - } - - with testing.mock_sends(schema.MeetingNewV1): - output = self.app.post('/test_calendar/add/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - '
  • Meeting added
  • ', output_text) + meeting_locs.add('#meeting-1:fedoraproject.org') # Valid meeting location: Matrix Room URL # https://pagure.io/fedocal/issue/213 - data = { - 'meeting_name': 'guess what?', - 'meeting_date': TODAY, - 'meeting_time_start': time(13, 0), - 'meeting_time_stop': time(14, 0), - 'meeting_timezone': 'Europe/Paris', - 'meeting_location': 'https://matrix.to/#/#meeting-1:fedoraproject.org', - 'frequency': '', - 'csrf_token': csrf_token, - } - - with testing.mock_sends(schema.MeetingNewV1): - output = self.app.post('/test_calendar/add/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - '
  • Meeting added
  • ', output_text) + meeting_locs.add('https://matrix.to/#/#meeting-1:fedoraproject.org') # Valid meeting location: List of current meeting locations: - meet_locations = ['', - 'https://unomaha.zoom.us/j/609939109', - 'https://hangouts.google.com/hangouts/_/67zc3kvkovelxctlilphwodlp4e', - 'https://meet.opensuse.org/epel', - 'irc://irc.libera.chat/fedora-zh', - 'https://meet.google.com/acq-pwxk-fhv', - 'https://meet.google.com/mic-otnv-kse', - 'https://meet.jit.si/fedora-websites-apps-meeting', - 'https://meet.kde.org/b/ale-swq-39j', - 'https://umich.zoom.us/j/96648123924?pwd=RitQVVQvMFVSaXJhNkFBS08vWTk0Zz09', - 'https://umich.zoom.us/j/99842244394?pwd=YVdkQjJTdnpBMUkySGVzK1kyTGoyZz09', - 'https://meet.google.com/xuj-jswy-hat', - 'podcast.fedoraproject.org', - 'https://podcast.fedoraproject.org/', - 'https://meet.google.com/jod-dkmw-ibd'] - # https://pagure.io/fedocal/issue/213 - data = { - 'meeting_name': 'guess what?', - 'meeting_date': TODAY, - 'meeting_time_start': time(13, 0), - 'meeting_time_stop': time(14, 0), - 'meeting_timezone': 'Europe/Paris', - 'meeting_location': None, - 'frequency': '', - 'csrf_token': csrf_token, - } - - # Copy and paste works, but using: - # for meet_location in meet_locations - # ...always fails on the second attempt. - import random - meet_location = random.choice(meet_locations) - with testing.mock_sends(schema.MeetingNewV1): - data['meeting_location'] = meet_location - output = self.app.post('/test_calendar/add/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - '
  • Meeting added
  • ', output_text) + meeting_locs.add('') + meeting_locs.add('https://unomaha.zoom.us/j/609939109') + meeting_locs.add('https://hangouts.google.com/hangouts/_/67zc3kvkovelxctlilphwodlp4e') + meeting_locs.add('https://meet.opensuse.org/epel') + meeting_locs.add('irc://irc.libera.chat/fedora-zh') + meeting_locs.add('https://meet.google.com/acq-pwxk-fhv') + meeting_locs.add('https://meet.google.com/mic-otnv-kse') + meeting_locs.add('https://meet.jit.si/fedora-websites-apps-meeting') + meeting_locs.add('https://meet.kde.org/b/ale-swq-39j') + meeting_locs.add('https://umich.zoom.us/j/96648123924?pwd=RitQVVQvMFVSaXJhNkFBS08vWTk0Zz09') + meeting_locs.add('https://umich.zoom.us/j/99842244394?pwd=YVdkQjJTdnpBMUkySGVzK1kyTGoyZz09') + meeting_locs.add('https://meet.google.com/xuj-jswy-hat') + meeting_locs.add('podcast.fedoraproject.org') + meeting_locs.add('https://podcast.fedoraproject.org/') + meeting_locs.add('https://meet.google.com/jod-dkmw-ibd') + for loc in meeting_locs: + _tst_add_meeting_loc(loc) def test_edit_meeting(self):