diff --git a/packages/athena_postgres/lib/src/athena_postgres_base.dart b/packages/athena_postgres/lib/src/athena_postgres_base.dart index 340a831..be1c439 100644 --- a/packages/athena_postgres/lib/src/athena_postgres_base.dart +++ b/packages/athena_postgres/lib/src/athena_postgres_base.dart @@ -88,7 +88,25 @@ class PostgreSQLDriver extends PostgreTransactionSQLDriver username: endpoint.username, password: endpoint.password, ), - settings: settings); + settings: pg.ConnectionSettings( + applicationName: settings.applicationName, + connectTimeout: settings.connectTimeout, + encoding: settings.encoding, + queryTimeout: settings.queryTimeout, + queryMode: settings.queryMode, + ignoreSuperfluousParameters: settings.ignoreSuperfluousParameters, + securityContext: settings.securityContext, + sslMode: switch (settings.sslMode) { + AthenaSslMode.disable => pg.SslMode.disable, + AthenaSslMode.require => pg.SslMode.require, + AthenaSslMode.verifyFull => pg.SslMode.verifyFull, + null => null, + }, + timeZone: settings.timeZone, + typeRegistry: settings.typeRegistry, + onOpen: (settings.onOpen != null) + ? (conn) => settings.onOpen!(AthenaPostgresql._(conn)) + : null)); return PostgreSQLDriver._(connection); } diff --git a/packages/athena_postgres/lib/src/database_config.dart b/packages/athena_postgres/lib/src/database_config.dart index 2679dda..c9d1b06 100644 --- a/packages/athena_postgres/lib/src/database_config.dart +++ b/packages/athena_postgres/lib/src/database_config.dart @@ -1,5 +1,10 @@ +import 'dart:convert'; +import 'dart:io'; + import 'package:postgres/postgres.dart'; +import '../athena_postgres.dart'; + /// PostgreSQL Endpoint for connecting to a PostgreSQL database. class AthenaPostgresqlEndpoint { /// PostgreSQL Endpoint for connecting to a PostgreSQL database. @@ -27,22 +32,103 @@ class AthenaPostgresqlEndpoint { final String? password; } +/// The mode to use for queries. +class AthenaSessionSettings { + /// The mode to use for queries. + const AthenaSessionSettings({ + this.connectTimeout, + this.queryTimeout, + this.queryMode, + this.ignoreSuperfluousParameters, + }); + + /// The connection timeout. + final Duration? connectTimeout; + + /// The query timeout. + final Duration? queryTimeout; + + /// The Query Execution Mode + /// + /// The default value is [QueryMode.extended] which uses the Extended Query + /// Protocol. In certain cases, the Extended protocol cannot be used + /// (e.g. in replication mode or with proxies such as PGBouncer), hence the + /// the Simple one would be the only viable option. Unless necessary, always + /// prefer using [QueryMode.extended]. + final QueryMode? queryMode; + + /// When set, the default query map will not throw exception when superfluous + /// parameters are found. + final bool? ignoreSuperfluousParameters; +} + +/// The SSL mode to use for a connection. +enum AthenaSslMode { + /// No SSL is used, implies that password may be sent as plaintext. + disable, + + /// Always use SSL (but ignore verification errors). + /// + /// If you're using this option to accept self-signed certificates, consider + /// the security ramifications of accepting _every_ certificate: Despite using + /// TLS, MitM attacks are possible by injecting another certificate. + /// An alternative is using [verifyFull] with a [SecurityContext] passed to + /// [ConnectionSettings.securityContext] that only accepts the known + /// self-signed certificate. + require, + + /// Always use SSL and verify certificates. + verifyFull, + ; + + /// Whether to ignore certificate issues. + bool get ignoreCertificateIssues => this == AthenaSslMode.require; + + /// Whether to allow cleartext passwords. + bool get allowCleartextPassword => this == AthenaSslMode.disable; +} + /// Connection settings for connecting to a PostgreSQL database. -class AthenaConnectionSettings extends ConnectionSettings { +class AthenaConnectionSettings extends AthenaSessionSettings { /// Connection settings for connecting to a PostgreSQL database. const AthenaConnectionSettings({ - super.applicationName, + this.applicationName, super.connectTimeout, - super.encoding, + this.encoding, super.ignoreSuperfluousParameters, - super.onOpen, + this.onOpen, super.queryMode, super.queryTimeout, - super.replicationMode, - super.securityContext, - super.sslMode, - super.timeZone, - super.transformer, - super.typeRegistry, + this.securityContext, + this.sslMode, + this.timeZone, + this.typeRegistry, }); + + /// The name of the application connecting to the database. + final String? applicationName; + + /// The timezone to use for the connection. + final String? timeZone; + + /// The encoding to use for the connection. + final Encoding? encoding; + + /// The SSL mode to use for the connection. + final AthenaSslMode? sslMode; + + /// The [SecurityContext] to use when opening a connection. + /// + /// This can be configured to only allow some certificates. When used, + /// [ConnectionSettings.sslMode] should be set to [SslMode.verifyFull], as + /// this package will allow other certificates or insecure connections + /// otherwise. + final SecurityContext? securityContext; + + /// When set, use the type registry with custom types, instead of the + /// built-in ones provided by the package. + final TypeRegistry? typeRegistry; + + /// This callback function will be called after opening the connection. + final Future Function(AthenaPostgresql connection)? onOpen; }