Added a function to allow creation of database with owner#37
Added a function to allow creation of database with owner#37aashikgowda wants to merge 9 commits intoDbUp:mainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for specifying a database owner when creating PostgreSQL databases and includes code formatting improvements. The key changes include:
- Adding an optional
ownerparameter to thePostgresqlDatabasemethod for database creation with ownership assignment - Implementing role validation before database creation
- Removing obsolete method overloads from the public API
- Applying consistent code formatting (spacing, indentation)
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/dbup-postgresql/PostgresqlExtensions.cs | Added new method overload with owner parameter, implemented role existence validation, updated CREATE DATABASE SQL to include owner clause, and applied formatting fixes |
| src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs | Updated approved public API surface to reflect removal of deprecated methods and addition of new owner parameter overload |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| sqlCommandText = $"select 1 from pg_roles where rolname = \'{owner}\' limit 1;"; | ||
| // check to see if the owner exists.. | ||
| using (var command = new NpgsqlCommand(sqlCommandText, connection) | ||
| { | ||
| CommandType = CommandType.Text | ||
| }) | ||
| { |
There was a problem hiding this comment.
SQL injection vulnerability: the owner parameter is interpolated directly into the SQL query using single quotes. Use parameterized queries with NpgsqlParameter to prevent SQL injection attacks.
| sqlCommandText = $"select 1 from pg_roles where rolname = \'{owner}\' limit 1;"; | |
| // check to see if the owner exists.. | |
| using (var command = new NpgsqlCommand(sqlCommandText, connection) | |
| { | |
| CommandType = CommandType.Text | |
| }) | |
| { | |
| sqlCommandText = "select 1 from pg_roles where rolname = @owner limit 1;"; | |
| // check to see if the owner exists.. | |
| using (var command = new NpgsqlCommand(sqlCommandText, connection) | |
| { | |
| CommandType = CommandType.Text | |
| }) | |
| { | |
| command.Parameters.AddWithValue("@owner", owner); |
There was a problem hiding this comment.
Well... it's unlikely SQLi would happen this way, but I don't think it hurts to do it this way.
There was a problem hiding this comment.
Updated the SQL command to take in parameters instead.
| var results = Convert.ToInt32(command.ExecuteScalar()); | ||
|
|
||
| // if the owner role does not exist, we throw an exception. | ||
| if (results == 0) |
There was a problem hiding this comment.
Potential null reference exception: ExecuteScalar() can return null when no rows are found. The code should handle the null case explicitly before converting to Int32, e.g., var results = command.ExecuteScalar() as int? ?? 0;
There was a problem hiding this comment.
This sounds right based on my SQL Server knowledge. If owner does not exist, no rows are returned (since it doesn't use Count(*).
There was a problem hiding this comment.
Convert.ToInt32 can take in a null object and return a zero for null objects.
However, to keep it cleaner, I updated the SQL to return a boolean instead which makes it more readable.
| } | ||
| } | ||
|
|
||
| sqlCommandText = $"create database \"{databaseName}\" with owner = \"{owner}\";"; |
There was a problem hiding this comment.
SQL injection vulnerability: both databaseName and owner are directly interpolated into the CREATE DATABASE statement. While PostgreSQL doesn't support parameterized DDL, consider validating these identifiers (e.g., checking they only contain alphanumeric characters and underscores) or using identifier quoting functions to prevent injection.
There was a problem hiding this comment.
Addressed it by formatting using helper functions.
Co-authored-by: Copilot <[email protected]>
droyad
left a comment
There was a problem hiding this comment.
On change that is breaking that I'd like to avoid. Also some Co-pilot suggestions. The SQLi ones are a stretch though.
| owner = string.IsNullOrWhiteSpace(owner) ? masterConnectionStringBuilder.Username : owner; | ||
|
|
There was a problem hiding this comment.
According to CoPilot
The default owner of the new database is the user executing the CREATE DATABASE command
✅
However
The [user[:password]@] part is optional. If omitted, most PostgreSQL clients will default to using the operating system's current username (the user running the client) for authentication
Confirmed via the docs.
So I think the best approach would be to not do this line and keep the existing statement if owner is null. If it's not null the new check for existance and with owner should be used.
There was a problem hiding this comment.
The [user[:password]@] part is optional. If omitted, most PostgreSQL clients will default to using the operating system's current username (the user running the client) for authentication
I missed out on this part. Updated as per your suggestion.
…tabase with or without owner
Checklist
Description