From 5d861ef124397922017e65f341d924db74c4dbe1 Mon Sep 17 00:00:00 2001 From: Henrich Neumann <henrich.neumann@usit.uio.no> Date: Fri, 14 Jul 2023 11:42:54 +0200 Subject: [PATCH] Further restrict the set of valid characters Improve the tests. --- .../src/routes/guest/register/index.test.tsx | 2 +- .../guest/register/steps/register.test.tsx | 12 +++---- frontend/src/utils/index.test.ts | 32 +++++++++++++++---- frontend/src/utils/index.ts | 20 ++++++++++-- greg/tests/test_utils.py | 4 ++- greg/utils.py | 20 ++++++++++-- gregui/tests/api/views/test_invitation.py | 4 +-- 7 files changed, 73 insertions(+), 21 deletions(-) diff --git a/frontend/src/routes/guest/register/index.test.tsx b/frontend/src/routes/guest/register/index.test.tsx index a1240c16..624a3841 100644 --- a/frontend/src/routes/guest/register/index.test.tsx +++ b/frontend/src/routes/guest/register/index.test.tsx @@ -12,7 +12,7 @@ enableFetchMocks() const testData = { person: { - first_name: 'Test20', + first_name: 'TestTwenty', last_name: 'Tester', private_mobile: '+4797543910', private_email: 'test@example.org', diff --git a/frontend/src/routes/guest/register/steps/register.test.tsx b/frontend/src/routes/guest/register/steps/register.test.tsx index ad034c11..f6669fe5 100644 --- a/frontend/src/routes/guest/register/steps/register.test.tsx +++ b/frontend/src/routes/guest/register/steps/register.test.tsx @@ -194,7 +194,7 @@ test('Gender required to be set if gender field is showing', async () => { const formData: GuestRegisterData = { firstName: 'Test', - lastName: 'Test2', + lastName: 'TestTwo', mobilePhoneCountry: 'NO', mobilePhone: '97543980', nationalIdNumber: '', @@ -249,7 +249,7 @@ test('Gender not required to be set if gender field is not showing', async () => const formData: GuestRegisterData = { firstName: 'Test', - lastName: 'Test2', + lastName: 'TestTwo', mobilePhoneCountry: 'NO', mobilePhone: '97543980', nationalIdNumber: '', @@ -297,7 +297,7 @@ test('Guest not allowed to proceed in wizard if phone number is not valid', asyn const formData: GuestRegisterData = { firstName: 'Test', - lastName: 'Test2', + lastName: 'TestTwo', mobilePhoneCountry: 'NO', mobilePhone: '50', nationalIdNumber: '', @@ -341,7 +341,7 @@ test('Guest allowed to proceed in wizard if data is valid', async () => { const formData: GuestRegisterData = { firstName: 'Test', - lastName: 'Test2', + lastName: 'TestTwo', mobilePhoneCountry: 'NO', mobilePhone: '97543992', nationalIdNumber: '', @@ -391,7 +391,7 @@ test('Default country code gets set in form values', async () => { // be populated with a default value const formData: GuestRegisterData = { firstName: 'Test', - lastName: 'Test2', + lastName: 'TestTwo', mobilePhoneCountry: '', mobilePhone: '97543992', nationalIdNumber: '', @@ -441,7 +441,7 @@ test('Foreign country code gets set in form values', async () => { const formData: GuestRegisterData = { firstName: 'Test', - lastName: 'Test2', + lastName: 'TestTwo', mobilePhoneCountry: '', mobilePhone: '3892778472', nationalIdNumber: '', diff --git a/frontend/src/utils/index.test.ts b/frontend/src/utils/index.test.ts index 3acfa0d2..bdc3108c 100644 --- a/frontend/src/utils/index.test.ts +++ b/frontend/src/utils/index.test.ts @@ -57,23 +57,43 @@ test('Invalid e-mail', async () => { }) test('Valid first name', async () => { - expect(isValidFirstName('Ååæž')).toEqual(true) + expect(isValidFirstName('AZ az ÀÖ ØÞßö øÿ Āſ')).toEqual(true) }) test('Invalid first name', async () => { expect(isValidFirstName('')).toEqual('common:validation.firstNameRequired') - expect(isValidFirstName('aaƂåå')).toEqual('common:validation.firstNameContainsInvalidChars') - expect(isValidFirstName('汉å—')).toEqual('common:validation.firstNameContainsInvalidChars') + expect(isValidFirstName('aaƂåå')).toEqual( + 'common:validation.firstNameContainsInvalidChars' + ) + expect(isValidFirstName('!')).toEqual( + 'common:validation.firstNameContainsInvalidChars' + ) + expect(isValidFirstName('÷')).toEqual( + 'common:validation.firstNameContainsInvalidChars' + ) + expect(isValidFirstName('汉å—')).toEqual( + 'common:validation.firstNameContainsInvalidChars' + ) }) test('Valid last name', async () => { - expect(isValidLastName('Ååæž')).toEqual(true) + expect(isValidLastName('AZ az ÀÖ ØÞßö øÿ Āſ')).toEqual(true) }) test('Invalid last name', async () => { expect(isValidLastName('')).toEqual('common:validation.lastNameRequired') - expect(isValidLastName('aaƂåå')).toEqual('common:validation.lastNameContainsInvalidChars') - expect(isValidLastName('汉å—')).toEqual('common:validation.lastNameContainsInvalidChars') + expect(isValidLastName('aaƂåå')).toEqual( + 'common:validation.lastNameContainsInvalidChars' + ) + expect(isValidLastName('!')).toEqual( + 'common:validation.lastNameContainsInvalidChars' + ) + expect(isValidLastName('÷')).toEqual( + 'common:validation.lastNameContainsInvalidChars' + ) + expect(isValidLastName('汉å—')).toEqual( + 'common:validation.lastNameContainsInvalidChars' + ) }) test('Body has values', async () => { diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index d482cd40..d85c7f3f 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -122,9 +122,23 @@ export async function isValidEmail(data: string | undefined) { } function stringContainsIllegalChars(string: string): boolean { - // Only allow ISO-8859-1 and Latin Extended-A + // Only allow the following characters: + // ----- Basic Latin ----- + // U+0020 (Space) + // U+0041 - U+005A (Latin Alphabet: Uppercase) + // U+0061 - U+007A (Latin Alphabet: Lowercase) + // ----- Latin-1 Supplement ----- + // U+00C0 - U+00D6 (Letters: Uppercase) + // U+00D8 - U+00DE (Letters: Uppercase) + // U+00DF - U+00F6 (Letters: Lowercase) + // U+00F8 - U+00FF (Letters: Lowercase) + // ----- Latin Extended-A ----- + // U+0100 - U+017F (European Latin) + // eslint-disable-next-line no-control-regex - return /[^\u0000-\u017F]/g.test(string) + return /[^\u0020\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u017F]/g.test( + string + ) } export function isValidFirstName(data: string | undefined): string | true { @@ -341,7 +355,7 @@ function extractBirthdateFromFnr(nationalId: string): Date { function extractBirthdateFromDnumber(nationalId: string): Date { return suggestBirthDate( (parseInt(nationalId.charAt(0), 10) - 4).toString(10) + - nationalId.substring(1, 6) + nationalId.substring(1, 6) ) } diff --git a/greg/tests/test_utils.py b/greg/tests/test_utils.py index 696a742b..75b5687e 100644 --- a/greg/tests/test_utils.py +++ b/greg/tests/test_utils.py @@ -32,8 +32,10 @@ def test_not_valid_so_number(): @pytest.mark.parametrize( "string, expected_output", [ - ("Ååæž", False), + ("AZ az ÀÖ ØÞßö øÿ Āſ", False), ("aaƂåå", True), + ("!", True), + ("÷", True), ("汉å—", True), ], ) diff --git a/greg/utils.py b/greg/utils.py index 8efa0b4b..b60d9b94 100644 --- a/greg/utils.py +++ b/greg/utils.py @@ -223,5 +223,21 @@ def role_invitation_date_validator( def string_contains_illegal_chars(string: str) -> bool: - # Only allow ISO-8859-1 and Latin Extended-A - return bool(re.search(r"[^\u0000-\u017F]", string)) + # Only allow the following characters: + # ----- Basic Latin ----- + # U+0020 (Space) + # U+0041 - U+005A (Latin Alphabet: Uppercase) + # U+0061 - U+007A (Latin Alphabet: Lowercase) + # ----- Latin-1 Supplement ----- + # U+00C0 - U+00D6 (Letters: Uppercase) + # U+00D8 - U+00DE (Letters: Uppercase) + # U+00DF - U+00F6 (Letters: Lowercase) + # U+00F8 - U+00FF (Letters: Lowercase) + # ----- Latin Extended-A ----- + # U+0100 - U+017F (European Latin) + return bool( + re.search( + r"[^\u0020\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u017F]", + string, + ) + ) diff --git a/gregui/tests/api/views/test_invitation.py b/gregui/tests/api/views/test_invitation.py index 54370a36..8c8cb866 100644 --- a/gregui/tests/api/views/test_invitation.py +++ b/gregui/tests/api/views/test_invitation.py @@ -747,7 +747,7 @@ def test_session_type_id_porten( data = { "person": { "first_name": "Updated", - "last_name": "Updated2", + "last_name": "UpdatedTwo", "private_mobile": "+4797543992", } } @@ -763,7 +763,7 @@ def test_session_type_id_porten( person.refresh_from_db() assert person.first_name == "Updated" - assert person.last_name == "Updated2" + assert person.last_name == "UpdatedTwo" @pytest.mark.django_db -- GitLab