@@ -246,6 +246,81 @@ func Test_ReadOnlyUser_MultipleSchemas_AllAccessible(t *testing.T) {
246246 assert .NoError (t , err )
247247}
248248
249+ func Test_CreateReadOnlyUser_DatabaseNameWithDash_Success (t * testing.T ) {
250+ env := config .GetEnv ()
251+ container := connectToPostgresContainer (t , env .TestPostgres16Port )
252+ defer container .DB .Close ()
253+
254+ dashDbName := "test-db-with-dash"
255+
256+ _ , err := container .DB .Exec (fmt .Sprintf (`DROP DATABASE IF EXISTS "%s"` , dashDbName ))
257+ assert .NoError (t , err )
258+
259+ _ , err = container .DB .Exec (fmt .Sprintf (`CREATE DATABASE "%s"` , dashDbName ))
260+ assert .NoError (t , err )
261+
262+ defer func () {
263+ _ , _ = container .DB .Exec (fmt .Sprintf (`DROP DATABASE IF EXISTS "%s"` , dashDbName ))
264+ }()
265+
266+ dashDSN := fmt .Sprintf ("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable" ,
267+ container .Host , container .Port , container .Username , container .Password , dashDbName )
268+ dashDB , err := sqlx .Connect ("postgres" , dashDSN )
269+ assert .NoError (t , err )
270+ defer dashDB .Close ()
271+
272+ _ , err = dashDB .Exec (`
273+ CREATE TABLE dash_test (
274+ id SERIAL PRIMARY KEY,
275+ data TEXT NOT NULL
276+ );
277+ INSERT INTO dash_test (data) VALUES ('test1'), ('test2');
278+ ` )
279+ assert .NoError (t , err )
280+
281+ pgModel := & PostgresqlDatabase {
282+ Version : tools .GetPostgresqlVersionEnum ("16" ),
283+ Host : container .Host ,
284+ Port : container .Port ,
285+ Username : container .Username ,
286+ Password : container .Password ,
287+ Database : & dashDbName ,
288+ IsHttps : false ,
289+ }
290+
291+ logger := slog .New (slog .NewTextHandler (os .Stdout , nil ))
292+ ctx := context .Background ()
293+
294+ username , password , err := pgModel .CreateReadOnlyUser (ctx , logger , nil , uuid .New ())
295+ assert .NoError (t , err )
296+ assert .NotEmpty (t , username )
297+ assert .NotEmpty (t , password )
298+ assert .True (t , strings .HasPrefix (username , "postgresus-" ))
299+
300+ readOnlyDSN := fmt .Sprintf ("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable" ,
301+ container .Host , container .Port , username , password , dashDbName )
302+ readOnlyConn , err := sqlx .Connect ("postgres" , readOnlyDSN )
303+ assert .NoError (t , err )
304+ defer readOnlyConn .Close ()
305+
306+ var count int
307+ err = readOnlyConn .Get (& count , "SELECT COUNT(*) FROM dash_test" )
308+ assert .NoError (t , err )
309+ assert .Equal (t , 2 , count )
310+
311+ _ , err = readOnlyConn .Exec ("INSERT INTO dash_test (data) VALUES ('should-fail')" )
312+ assert .Error (t , err )
313+ assert .Contains (t , err .Error (), "permission denied" )
314+
315+ _ , err = dashDB .Exec (fmt .Sprintf (`DROP OWNED BY "%s" CASCADE` , username ))
316+ if err != nil {
317+ t .Logf ("Warning: Failed to drop owned objects: %v" , err )
318+ }
319+
320+ _ , err = dashDB .Exec (fmt .Sprintf (`DROP USER IF EXISTS "%s"` , username ))
321+ assert .NoError (t , err )
322+ }
323+
249324func Test_CreateReadOnlyUser_Supabase_UserCanReadButNotWrite (t * testing.T ) {
250325 env := config .GetEnv ()
251326
0 commit comments