@@ -24,16 +24,11 @@ public function update(DatabaseUser $databaseUser, array $input): DatabaseUser
2424 $ oldHost = $ databaseUser ->host ;
2525 $ oldPermission = $ databaseUser ->permission ;
2626 $ newPassword = $ input ['password ' ] ?? null ;
27- $ newHost = null ;
27+ $ newHost = $ this -> changedHost ( $ databaseUser , $ input ) ;
2828 $ permissionChanged = false ;
2929
30- if (isset ($ input ['remote ' ])) {
31- $ newHost = $ input ['remote ' ] ? ($ input ['host ' ] ?? '% ' ) : 'localhost ' ;
32- if ($ newHost !== $ oldHost ) {
33- $ databaseUser ->host = $ newHost ;
34- } else {
35- $ newHost = null ;
36- }
30+ if ($ newHost !== null ) {
31+ $ databaseUser ->host = $ newHost ;
3732 }
3833
3934 if ($ newPassword ) {
@@ -79,8 +74,14 @@ private function validate(DatabaseUser $databaseUser, array $input): void
7974 ];
8075 }
8176
82- if (isset ($ input ['remote ' ]) && $ input ['remote ' ]) {
83- $ rules ['host ' ] = 'required ' ;
77+ /** @var Database $handler */
78+ $ handler = $ databaseUser ->server ->database ()->handler ();
79+
80+ if ($ handler ->usesHost ()) {
81+ $ rules ['host ' ] = [
82+ isset ($ input ['remote ' ]) && $ input ['remote ' ] ? 'required ' : 'nullable ' ,
83+ 'regex:/^[A-Za-z0-9%._:\-]*$/ ' ,
84+ ];
8485 }
8586
8687 $ rules ['permission ' ] = [
@@ -89,6 +90,35 @@ private function validate(DatabaseUser $databaseUser, array $input): void
8990 ];
9091
9192 Validator::make ($ input , $ rules )->validate ();
93+
94+ $ newHost = $ this ->changedHost ($ databaseUser , $ input );
95+ if ($ newHost !== null && $ handler ->databaseUserExists ($ databaseUser ->server , $ databaseUser ->username , $ newHost , $ databaseUser )) {
96+ throw ValidationException::withMessages ([
97+ 'host ' => __ ('A database user with this username and host already exists. ' ),
98+ ]);
99+ }
100+ }
101+
102+ /**
103+ * Resolves the new host when it is being changed, or null when unchanged or
104+ * the database engine does not use hosts (e.g. PostgreSQL).
105+ *
106+ * @param array<string, mixed> $input
107+ */
108+ private function changedHost (DatabaseUser $ databaseUser , array $ input ): ?string
109+ {
110+ if (! isset ($ input ['remote ' ])) {
111+ return null ;
112+ }
113+
114+ $ handler = $ databaseUser ->server ->database ()?->handler();
115+ if (! $ handler instanceof Database || ! $ handler ->usesHost ()) {
116+ return null ;
117+ }
118+
119+ $ resolved = $ input ['remote ' ] ? (! empty ($ input ['host ' ]) ? $ input ['host ' ] : '% ' ) : 'localhost ' ;
120+
121+ return $ resolved !== $ databaseUser ->host ? $ resolved : null ;
92122 }
93123
94124 private function updatePermissions (DatabaseUser $ databaseUser , string $ oldHost , ?string $ newHost ): void
0 commit comments