From 89ec9a5081caa95d5c3bbddd3f09015cc74329b7 Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Thu, 4 Aug 2022 17:24:04 +0100
Subject: [PATCH] Sprinkled in some user language validation

For #3615
---
 .../Controllers/Api/UserApiController.php     |  4 ++--
 app/Http/Controllers/UserController.php       |  4 ++--
 tests/User/UserManagementTest.php             | 24 +++++++++++++++++++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/app/Http/Controllers/Api/UserApiController.php b/app/Http/Controllers/Api/UserApiController.php
index 4f0d30034..03d2a0f06 100644
--- a/app/Http/Controllers/Api/UserApiController.php
+++ b/app/Http/Controllers/Api/UserApiController.php
@@ -41,7 +41,7 @@ class UserApiController extends ApiController
                     'required', 'min:2', 'email', new Unique('users', 'email'),
                 ],
                 'external_auth_id' => ['string'],
-                'language'         => ['string'],
+                'language'         => ['string', 'max:15', 'alpha_dash'],
                 'password'         => [Password::default()],
                 'roles'            => ['array'],
                 'roles.*'          => ['integer'],
@@ -55,7 +55,7 @@ class UserApiController extends ApiController
                     (new Unique('users', 'email'))->ignore($userId ?? null),
                 ],
                 'external_auth_id' => ['string'],
-                'language'         => ['string'],
+                'language'         => ['string', 'max:15', 'alpha_dash'],
                 'password'         => [Password::default()],
                 'roles'            => ['array'],
                 'roles.*'          => ['integer'],
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index 3110f1a98..88d44565c 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -83,7 +83,7 @@ class UserController extends Controller
         $validationRules = [
             'name'             => ['required'],
             'email'            => ['required', 'email', 'unique:users,email'],
-            'language'         => ['string'],
+            'language'         => ['string', 'max:15', 'alpha_dash'],
             'roles'            => ['array'],
             'roles.*'          => ['integer'],
             'password'         => $passwordRequired ? ['required', Password::default()] : null,
@@ -143,7 +143,7 @@ class UserController extends Controller
             'email'            => ['min:2', 'email', 'unique:users,email,' . $id],
             'password'         => ['required_with:password_confirm', Password::default()],
             'password-confirm' => ['same:password', 'required_with:password'],
-            'language'         => ['string'],
+            'language'         => ['string', 'max:15', 'alpha_dash'],
             'roles'            => ['array'],
             'roles.*'          => ['integer'],
             'external_auth_id' => ['string'],
diff --git a/tests/User/UserManagementTest.php b/tests/User/UserManagementTest.php
index c09ce8cb3..f0bc7c2f0 100644
--- a/tests/User/UserManagementTest.php
+++ b/tests/User/UserManagementTest.php
@@ -234,4 +234,28 @@ class UserManagementTest extends TestCase
 
         $this->assertDatabaseMissing('activities', ['type' => 'USER_CREATE']);
     }
+
+    public function test_user_create_update_fails_if_locale_is_invalid()
+    {
+        $user = $this->getEditor();
+
+        // Too long
+        $resp = $this->asAdmin()->put($user->getEditUrl(), ['language' => 'this_is_too_long']);
+        $resp->assertSessionHasErrors(['language' => 'The language may not be greater than 15 characters.']);
+        session()->flush();
+
+        // Invalid characters
+        $resp = $this->put($user->getEditUrl(), ['language' => 'en<GB']);
+        $resp->assertSessionHasErrors(['language' => 'The language may only contain letters, numbers, dashes and underscores.']);
+        session()->flush();
+
+        // Both on create
+        $resp = $this->post('/settings/users/create', [
+            'language' => 'en<GB_and_this_is_longer',
+            'name' => 'My name',
+            'email' => 'jimmy@example.com',
+        ]);
+        $resp->assertSessionHasErrors(['language' => 'The language may not be greater than 15 characters.']);
+        $resp->assertSessionHasErrors(['language' => 'The language may only contain letters, numbers, dashes and underscores.']);
+    }
 }