Skip to content

Commit 1b2b5b4

Browse files
authored
Added support for supplying a custom CertificateValidationCallback on the connection (#16)
1 parent 9603453 commit 1b2b5b4

File tree

5 files changed

+105
-10
lines changed

5 files changed

+105
-10
lines changed

src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Bui
1111
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(DbUp.Engine.Transactions.IConnectionManager connectionManager, string schema) { }
1212
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { }
1313
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
14+
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, DbUp.Postgresql.PostgresqlConnectionOptions connectionOptions) { }
1415
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString) { }
1516
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
17+
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Postgresql.PostgresqlConnectionOptions connectionOptions) { }
1618
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger) { }
1719
}
1820
namespace DbUp.Postgresql
@@ -21,8 +23,15 @@ public class PostgresqlConnectionManager : DbUp.Engine.Transactions.DatabaseConn
2123
{
2224
public PostgresqlConnectionManager(string connectionString) { }
2325
public PostgresqlConnectionManager(string connectionString, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
26+
public PostgresqlConnectionManager(string connectionString, DbUp.Postgresql.PostgresqlConnectionOptions connectionOptions) { }
2427
public override System.Collections.Generic.IEnumerable<string> SplitScriptIntoCommands(string scriptContents) { }
2528
}
29+
public class PostgresqlConnectionOptions
30+
{
31+
public PostgresqlConnectionOptions() { }
32+
public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { get; set; }
33+
public System.Net.Security.RemoteCertificateValidationCallback UserCertificateValidationCallback { get; set; }
34+
}
2635
public class PostgresqlObjectParser : DbUp.Support.SqlObjectParser, DbUp.Engine.ISqlObjectParser
2736
{
2837
public PostgresqlObjectParser() { }

src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Bui
1111
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(DbUp.Engine.Transactions.IConnectionManager connectionManager, string schema) { }
1212
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { }
1313
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
14+
public static DbUp.Builder.UpgradeEngineBuilder PostgresqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, DbUp.Postgresql.PostgresqlConnectionOptions connectionOptions) { }
1415
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString) { }
1516
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
17+
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Postgresql.PostgresqlConnectionOptions connectionOptions) { }
1618
public static void PostgresqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger) { }
1719
}
1820
namespace DbUp.Postgresql
@@ -21,8 +23,15 @@ public class PostgresqlConnectionManager : DbUp.Engine.Transactions.DatabaseConn
2123
{
2224
public PostgresqlConnectionManager(string connectionString) { }
2325
public PostgresqlConnectionManager(string connectionString, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { }
26+
public PostgresqlConnectionManager(string connectionString, DbUp.Postgresql.PostgresqlConnectionOptions connectionOptions) { }
2427
public override System.Collections.Generic.IEnumerable<string> SplitScriptIntoCommands(string scriptContents) { }
2528
}
29+
public class PostgresqlConnectionOptions
30+
{
31+
public PostgresqlConnectionOptions() { }
32+
public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { get; set; }
33+
public System.Net.Security.RemoteCertificateValidationCallback UserCertificateValidationCallback { get; set; }
34+
}
2635
public class PostgresqlObjectParser : DbUp.Support.SqlObjectParser, DbUp.Engine.ISqlObjectParser
2736
{
2837
public PostgresqlObjectParser() { }

src/dbup-postgresql/PostgresqlConnectionManager.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,23 @@ public PostgresqlConnectionManager(string connectionString)
2727
/// <param name="connectionString">The PostgreSQL connection string.</param>
2828
/// <param name="certificate">Certificate for securing connection.</param>
2929
public PostgresqlConnectionManager(string connectionString, X509Certificate2 certificate)
30+
: this(connectionString, new PostgresqlConnectionOptions
31+
{
32+
ClientCertificate = certificate
33+
})
34+
{
35+
}
36+
37+
/// <summary>
38+
/// Create a new PostgreSQL database connection
39+
/// </summary>
40+
/// <param name="connectionString">The PostgreSQL connection string.</param>
41+
/// <param name="connectionOptions">Custom options to apply on the created connection</param>
42+
public PostgresqlConnectionManager(string connectionString, PostgresqlConnectionOptions connectionOptions)
3043
: base(new DelegateConnectionFactory(l =>
3144
{
3245
NpgsqlConnection databaseConnection = new NpgsqlConnection(connectionString);
33-
databaseConnection.ProvideClientCertificatesCallback +=
34-
certs => certs.Add(certificate);
46+
databaseConnection.ApplyConnectionOptions(connectionOptions);
3547

3648
return databaseConnection;
3749
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Net.Security;
2+
using System.Security.Cryptography.X509Certificates;
3+
4+
namespace DbUp.Postgresql
5+
{
6+
/// <summary>
7+
/// Options that will be applied on the created connection
8+
/// </summary>
9+
public class PostgresqlConnectionOptions
10+
{
11+
/// <summary>
12+
/// Certificate for securing connection.
13+
/// </summary>
14+
public X509Certificate2 ClientCertificate { get; set; }
15+
16+
/// <summary>
17+
// Custom handler to verify the remote SSL certificate.
18+
// Ignored if Npgsql.NpgsqlConnectionStringBuilder.TrustServerCertificate is set.
19+
/// </summary>
20+
public RemoteCertificateValidationCallback UserCertificateValidationCallback { get; set; }
21+
}
22+
}

src/dbup-postgresql/PostgresqlExtensions.cs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ public static UpgradeEngineBuilder PostgresqlDatabase(this SupportedDatabases su
5151
public static UpgradeEngineBuilder PostgresqlDatabase(this SupportedDatabases supported, string connectionString, string schema, X509Certificate2 certificate)
5252
=> PostgresqlDatabase(new PostgresqlConnectionManager(connectionString, certificate), schema);
5353

54+
/// <summary>
55+
/// Creates an upgrader for PostgreSQL databases that use SSL.
56+
/// </summary>
57+
/// <param name="supported">Fluent helper type.</param>
58+
/// <param name="connectionString">PostgreSQL database connection string.</param>
59+
/// <param name="schema">The schema in which to check for changes</param>
60+
/// <param name="connectionOptions">Connection options to set SSL parameters</param>
61+
/// <returns>
62+
/// A builder for a database upgrader designed for PostgreSQL databases.
63+
/// </returns>
64+
public static UpgradeEngineBuilder PostgresqlDatabase(this SupportedDatabases supported, string connectionString, string schema, PostgresqlConnectionOptions connectionOptions)
65+
=> PostgresqlDatabase(new PostgresqlConnectionManager(connectionString, connectionOptions), schema);
66+
5467
/// <summary>
5568
/// Creates an upgrader for PostgreSQL databases.
5669
/// </summary>
@@ -113,6 +126,18 @@ public static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase s
113126
PostgresqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), certificate);
114127
}
115128

129+
/// <summary>
130+
/// Ensures that the database specified in the connection string exists using SSL for the connection.
131+
/// </summary>
132+
/// <param name="supported">Fluent helper type.</param>
133+
/// <param name="connectionString">The connection string.</param>
134+
/// <param name="connectionOptions">Connection SSL to customize SSL behaviour</param>
135+
/// <returns></returns>
136+
public static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, PostgresqlConnectionOptions connectionOptions)
137+
{
138+
PostgresqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), connectionOptions);
139+
}
140+
116141
/// <summary>
117142
/// Ensures that the database specified in the connection string exists.
118143
/// </summary>
@@ -122,10 +147,19 @@ public static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase s
122147
/// <returns></returns>
123148
public static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, IUpgradeLog logger)
124149
{
125-
PostgresqlDatabase(supported, connectionString, logger, null);
150+
PostgresqlDatabase(supported, connectionString, logger, (PostgresqlConnectionOptions)null);
126151
}
127-
152+
128153
private static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, IUpgradeLog logger, X509Certificate2 certificate)
154+
{
155+
var options = new PostgresqlConnectionOptions
156+
{
157+
ClientCertificate = certificate
158+
};
159+
PostgresqlDatabase(supported, connectionString, logger, options);
160+
}
161+
162+
private static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, IUpgradeLog logger, PostgresqlConnectionOptions connectionOptions)
129163
{
130164
if (supported == null) throw new ArgumentNullException("supported");
131165

@@ -137,7 +171,7 @@ private static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase
137171
if (logger == null) throw new ArgumentNullException("logger");
138172

139173
var masterConnectionStringBuilder = new NpgsqlConnectionStringBuilder(connectionString);
140-
174+
141175
var databaseName = masterConnectionStringBuilder.Database;
142176

143177
if (string.IsNullOrEmpty(databaseName) || databaseName.Trim() == string.Empty)
@@ -157,11 +191,7 @@ private static void PostgresqlDatabase(this SupportedDatabasesForEnsureDatabase
157191

158192
using (var connection = new NpgsqlConnection(masterConnectionStringBuilder.ConnectionString))
159193
{
160-
if (certificate != null)
161-
{
162-
connection.ProvideClientCertificatesCallback +=
163-
certs => certs.Add(certificate);
164-
}
194+
connection.ApplyConnectionOptions(connectionOptions);
165195
connection.Open();
166196

167197
var sqlCommandText = string.Format
@@ -216,4 +246,17 @@ public static UpgradeEngineBuilder JournalToPostgresqlTable(this UpgradeEngineBu
216246
builder.Configure(c => c.Journal = new PostgresqlTableJournal(() => c.ConnectionManager, () => c.Log, schema, table));
217247
return builder;
218248
}
249+
250+
internal static void ApplyConnectionOptions(this NpgsqlConnection connection, PostgresqlConnectionOptions connectionOptions)
251+
{
252+
if (connectionOptions?.ClientCertificate != null)
253+
{
254+
connection.ProvideClientCertificatesCallback +=
255+
certs => certs.Add(connectionOptions.ClientCertificate);
256+
}
257+
if (connectionOptions?.UserCertificateValidationCallback != null)
258+
{
259+
connection.UserCertificateValidationCallback = connectionOptions.UserCertificateValidationCallback;
260+
}
261+
}
219262
}

0 commit comments

Comments
 (0)