-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: snowflake key auth server (#34548)
## Description This PR adds new authentication method for snowflake: Use of public and private keys to authorise a snowflake database. Snowflake provides a couple of authentication mechanisms in order to authenticate the DB. Currently appsmith only provides a way to authorise using username and password. This PR adds support for private key authentication, where by user can set a public key on their DB and they can use corresponding private key in appsmith to authorise the datasource. In snowflake DB form, we have added a new field for authentication type which has two options: Basic and Key pair. Basic will allows us to authenticate using username and password. Key pair will provide us a way to upload the private key along with input field for adding passphrase (In case of encrypted private key). More info: https://docs.snowflake.com/en/user-guide/key-pair-auth https://github.com/appsmithorg/appsmith/assets/30018882/99774925-12a3-4cc0-af0a-614c3574cdc3 Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Datasource" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/9743830603> > Commit: cb64fff > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=9743830603&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Datasource` <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced Snowflake integration with improved connection creation and authentication handling (key pair and basic auth types). - **Bug Fixes** - Fixed issues related to handling authentication objects within datasource configuration to ensure more reliable connections. - **Documentation** - Added new error messages for passphrase requirements and incorrect passphrase or private key for encrypted private keys. - **Tests** - Updated tests to verify the correct setting of authentication types in the Snowflake plugin. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Rishabh-Rathod <rishabh.rathod@appsmith.com> Co-authored-by: Aman Agarwal <aman@appsmith.com> Co-authored-by: “sneha122” <“sneha@appsmith.com”>
- Loading branch information
1 parent
dc99eb1
commit eaf1fa4
Showing
5 changed files
with
204 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
.../appsmith-plugins/snowflakePlugin/src/main/java/com/external/utils/SnowflakeKeyUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.external.utils; | ||
|
||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError; | ||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; | ||
import com.external.plugins.exceptions.SnowflakeErrorMessages; | ||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; | ||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | ||
import org.bouncycastle.openssl.PEMParser; | ||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; | ||
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; | ||
import org.bouncycastle.operator.InputDecryptorProvider; | ||
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; | ||
|
||
import java.io.StringReader; | ||
import java.security.PrivateKey; | ||
import java.security.Security; | ||
|
||
import static org.apache.commons.lang.StringUtils.isEmpty; | ||
|
||
public class SnowflakeKeyUtils { | ||
static { | ||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); | ||
} | ||
|
||
public static PrivateKey readEncryptedPrivateKey(byte[] keyBytes, String passphrase) throws Exception { | ||
PrivateKeyInfo privateKeyInfo = null; | ||
String privateKeyPEM = new String(keyBytes); | ||
PEMParser pemParser = new PEMParser(new StringReader(privateKeyPEM)); | ||
Object pemObject = pemParser.readObject(); | ||
if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) { | ||
// Handle the case where the private key is encrypted. | ||
if (isEmpty(passphrase)) { | ||
throw new AppsmithPluginException( | ||
AppsmithPluginError.PLUGIN_DATASOURCE_ARGUMENT_ERROR, | ||
SnowflakeErrorMessages.DS_MISSING_PASSPHRASE_FOR_ENCRYPTED_PRIVATE_KEY); | ||
} | ||
PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemObject; | ||
InputDecryptorProvider pkcs8Prov = | ||
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passphrase.toCharArray()); | ||
privateKeyInfo = encryptedPrivateKeyInfo.decryptPrivateKeyInfo(pkcs8Prov); | ||
} else if (pemObject instanceof PrivateKeyInfo) { | ||
// Handle the case where the private key is unencrypted. | ||
privateKeyInfo = (PrivateKeyInfo) pemObject; | ||
} | ||
pemParser.close(); | ||
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME); | ||
return converter.getPrivateKey(privateKeyInfo); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters