feat: add form config for reading certs for PG (#31895)

## Description
Form config changes for the PG datasource to support reading certs from
user

Fixes #31400 

## Automation

/ok-to-test tags="tag.Datasource"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!IMPORTANT]  
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/8538007537>
> Commit: `0fb57fe78e973db8a3df5f2e407b85eef4adb4e2`
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8538007537&attempt=1"
target="_blank">Click here!</a>
> All cypress tests have passed 🎉🎉🎉

<!-- end of auto-generated comment: Cypress test results  -->





<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced SSL configuration options for database connections, including
support for client and server CA certificate files.
- **Refactor**
- Improved handling and encoding of SSL certificate content for database
connections, ensuring compatibility and security.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Aman Agarwal <aman@appsmith.com>
Co-authored-by: Rishabh-Rathod <rishabh.rathod@appsmith.com>
This commit is contained in:
Anagh Hegde 2024-04-03 20:04:49 +05:30 committed by GitHub
parent 223e4c8088
commit 9b14d13af8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 187 additions and 45 deletions

View File

@ -68,6 +68,12 @@ public class SSLDetails implements AppsmithDomain {
UploadedFile caCertificateFile;
UploadedFile clientCACertificateFile;
UploadedFile clientKeyCertificateFile;
UploadedFile serverCACertificateFile;
Boolean usePemCertificate;
PEMCertificate pemCertificate;

View File

@ -51,6 +51,7 @@ import reactor.core.scheduler.Schedulers;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.sql.Array;
import java.sql.Connection;
import java.sql.Date;
@ -1199,25 +1200,31 @@ public class PostgresPlugin extends BasePlugin {
config.addDataSourceProperty("sslfactory", MutualTLSCertValidatingFactory.class.getName());
config.addDataSourceProperty(
"clientCertString",
datasourceConfiguration
.getConnection()
.getSsl()
.getCertificateFile()
.getBase64Content());
new String(
datasourceConfiguration
.getConnection()
.getSsl()
.getClientCACertificateFile()
.getDecodedContent(),
StandardCharsets.UTF_8));
config.addDataSourceProperty(
"clientKeyString",
datasourceConfiguration
.getConnection()
.getSsl()
.getKeyFile()
.getBase64Content());
new String(
datasourceConfiguration
.getConnection()
.getSsl()
.getClientKeyCertificateFile()
.getDecodedContent(),
StandardCharsets.UTF_8));
config.addDataSourceProperty(
"serverCACertString",
datasourceConfiguration
.getConnection()
.getSsl()
.getCaCertificateFile()
.getBase64Content());
new String(
datasourceConfiguration
.getConnection()
.getSsl()
.getServerCACertificateFile()
.getDecodedContent(),
StandardCharsets.UTF_8));
break;

View File

@ -7,6 +7,7 @@ import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.SecureRandom;
@ -23,7 +24,7 @@ public class MutualTLSCertValidatingFactory extends WrappedFactory {
// Client certificate
ByteArrayInputStream clientCertIS =
new ByteArrayInputStream(Base64.getDecoder().decode(info.getProperty("clientCertString")));
new ByteArrayInputStream(info.getProperty("clientCertString").getBytes(StandardCharsets.UTF_8));
X509Certificate clientCertificate = (X509Certificate) cf.generateCertificate(clientCertIS);
// Client key and this assumes we are using RSA keys
@ -39,7 +40,7 @@ public class MutualTLSCertValidatingFactory extends WrappedFactory {
// CA certificate for verifying the server
ByteArrayInputStream caCertIS =
new ByteArrayInputStream(Base64.getDecoder().decode(info.getProperty("serverCACertString")));
new ByteArrayInputStream(info.getProperty("serverCACertString").getBytes(StandardCharsets.UTF_8));
X509Certificate caCertificate = (X509Certificate) cf.generateCertificate(caCertIS);
// Client keystore

View File

@ -10,14 +10,8 @@
"controlType": "SEGMENTED_CONTROL",
"initialValue": "READ_WRITE",
"options": [
{
"label": "Read / Write",
"value": "READ_WRITE"
},
{
"label": "Read only",
"value": "READ_ONLY"
}
{ "label": "Read / Write", "value": "READ_WRITE" },
{ "label": "Read only", "value": "READ_ONLY" }
]
},
{
@ -84,27 +78,155 @@
"controlType": "DROP_DOWN",
"initialValue": "DEFAULT",
"options": [
{
"label": "Default",
"value": "DEFAULT"
},
{
"label": "Allow",
"value": "ALLOW"
},
{
"label": "Prefer",
"value": "PREFER"
},
{
"label": "Require",
"value": "REQUIRE"
},
{
"label": "Disable",
"value": "DISABLE"
}
{ "label": "Default", "value": "DEFAULT" },
{ "label": "Allow", "value": "ALLOW" },
{ "label": "Prefer", "value": "PREFER" },
{ "label": "Require", "value": "REQUIRE" },
{ "label": "Disable", "value": "DISABLE" },
{ "label": "Verify CA", "value": "VERIFY_CA" },
{ "label": "Verify Full", "value": "VERIFY_FULL" }
]
},
{
"label": "Certificate Type",
"configProperty": "datasourceConfiguration.connection.ssl.certificateType",
"controlType": "DROP_DOWN",
"initialValue": "-Select-",
"options": [
{ "label": "Upload File", "value": "FILE" },
{ "label": "Base64 String", "value": "BASE64_STRING" }
],
"hidden": {
"conditionType": "AND",
"conditions": [
{
"path": "datasourceConfiguration.connection.ssl.authType",
"comparison": "NOT_EQUALS",
"value": "VERIFY_CA"
},
{
"path": "datasourceConfiguration.connection.ssl.authType",
"comparison": "NOT_EQUALS",
"value": "VERIFY_FULL"
}
]
}
},
{
"sectionStyles": { "display": "flex", "flex-wrap": "wrap" },
"children": [
{
"sectionStyles": { "marginRight": "10px" },
"children": [
{
"label": "Client CA Certificate File",
"configProperty": "datasourceConfiguration.connection.ssl.clientCACertificateFile",
"controlType": "FILE_PICKER",
"encrypted": true,
"hidden": {
"path": "datasourceConfiguration.connection.ssl.certificateType",
"comparison": "NOT_EQUALS",
"value": "FILE"
}
},
{
"label": "Client CA Certificate String",
"configProperty": "datasourceConfiguration.connection.ssl.clientCACertificateFile.base64Content",
"controlType": "INPUT_TEXT",
"dataType": "PASSWORD",
"encrypted": true,
"hidden": {
"path": "datasourceConfiguration.connection.ssl.certificateType",
"comparison": "NOT_EQUALS",
"value": "BASE64_STRING"
}
}
]
},
{
"sectionStyles": { "marginRight": "10px" },
"children": [
{
"label": "Server CA Certificate File",
"configProperty": "datasourceConfiguration.connection.ssl.serverCACertificateFile",
"controlType": "FILE_PICKER",
"encrypted": true,
"hidden": {
"path": "datasourceConfiguration.connection.ssl.certificateType",
"comparison": "NOT_EQUALS",
"value": "FILE"
}
},
{
"label": "Server CA Certificate String",
"configProperty": "datasourceConfiguration.connection.ssl.serverCACertificateFile.Base64Content",
"controlType": "INPUT_TEXT",
"dataType": "PASSWORD",
"encrypted": true,
"hidden": {
"path": "datasourceConfiguration.connection.ssl.certificateType",
"comparison": "NOT_EQUALS",
"value": "BASE64_STRING"
}
}
]
},
{
"sectionStyles": { "marginRight": "10px" },
"children": [
{
"label": "Client Key Certificate File",
"configProperty": "datasourceConfiguration.connection.ssl.clientKeyCertificateFile",
"controlType": "FILE_PICKER",
"encrypted": true,
"hidden": {
"path": "datasourceConfiguration.connection.ssl.certificateType",
"comparison": "NOT_EQUALS",
"value": "FILE"
}
},
{
"label": "Client Key Certificate String",
"configProperty": "datasourceConfiguration.connection.ssl.clientKeyCertificateFile.Base64Content",
"controlType": "INPUT_TEXT",
"dataType": "PASSWORD",
"encrypted": true,
"hidden": {
"path": "datasourceConfiguration.connection.ssl.certificateType",
"comparison": "NOT_EQUALS",
"value": "BASE64_STRING"
}
}
]
},
{
"sectionStyles": { "flex": 1 },
"children": []
},
{
"sectionStyles": { "flex": 1 },
"children": []
},
{
"sectionStyles": { "flex": 1 },
"children": []
}
],
"hidden": {
"conditionType": "AND",
"conditions": [
{
"path": "datasourceConfiguration.connection.ssl.authType",
"comparison": "NOT_EQUALS",
"value": "VERIFY_CA"
},
{
"path": "datasourceConfiguration.connection.ssl.authType",
"comparison": "NOT_EQUALS",
"value": "VERIFY_FULL"
}
]
}
}
]
}

View File

@ -1455,6 +1455,9 @@ public class ApplicationForkingServiceTests {
new UploadedFile("keyFile", "key file content"),
new UploadedFile("certFile", "cert file content"),
new UploadedFile("caCertFile", "caCert file content"),
new UploadedFile("keyFile", "key file content"),
new UploadedFile("certFile", "cert file content"),
new UploadedFile("caCertFile", "caCert file content"),
true,
new PEMCertificate(
new UploadedFile("pemCertFile", "pem cert file content"),
@ -1684,6 +1687,9 @@ public class ApplicationForkingServiceTests {
new UploadedFile("keyFile", "key file content"),
new UploadedFile("certFile", "cert file content"),
new UploadedFile("caCertFile", "caCert file content"),
new UploadedFile("keyFile", "key file content"),
new UploadedFile("certFile", "cert file content"),
new UploadedFile("caCertFile", "caCert file content"),
true,
new PEMCertificate(
new UploadedFile("pemCertFile", "pem cert file content"),