diff --git a/ojdbc-provider-hashicorp/README.md b/ojdbc-provider-hashicorp/README.md index 4922d48b..7dc3617a 100644 --- a/ojdbc-provider-hashicorp/README.md +++ b/ojdbc-provider-hashicorp/README.md @@ -13,6 +13,37 @@ and HashiCorp Vault (HCP).
Caching mechanism adopted by Centralized Config Providers
+## Resource Providers +
+
Dedicated Vault Username Provider
+
Provides a username stored in a HashiCorp Vault Dedicated.
+
HCP Vault Secrets Username Provider
+
Provides a username stored in HashiCorp Vault Secrets.
+
Dedicated Vault Password Provider
+
Provides a password stored in a HashiCorp Vault Dedicated.
+
HCP Vault Secrets Password Provider
+
Provides a password stored in HashiCorp Vault Secrets.
+
Dedicated Vault TCPS Wallet Provider
+
Provides TLS wallets from HashiCorp Vault Dedicated for secure connections.
+
HCP Vault Secrets TCPS Wallet Provider
+
Provides TLS wallets from HashiCorp Vault Secrets for secure connections.
+
Dedicated Vault SEPS Wallet Provider
+
Provides SEPS (Secure External Password Store) wallets for secure username and password retrieval from HashiCorp Vault Dedicated.
+
HCP Vault Secrets SEPS Wallet Provider
+
Provides SEPS (Secure External Password Store) wallets for secure username and password retrieval from HashiCorp Vault Secrets.
+
Dedicated Vault Connection String Provider
+
Provides connection strings based on aliases stored in a `tnsnames.ora` file within HashiCorp Vault Dedicated.
+
HCP Vault Secrets Connection String Provider
+
Provides connection strings based on aliases stored in a `tnsnames.ora` file within HashiCorp Vault Secrets.
+
Common Parameters for HCP Vault Dedicated Resource Providers
+
Defines common configuration parameters for providers using HCP Vault Dedicated.
+
Common Parameters for HCP Vault Secrets Resource Providers
+
Defines common parameters for all providers using HCP Vault Secrets.
+
Configuring Authentication for Resource Providers
+
Details supported authentication methods and usage instructions.
+
+ + Visit any of the links above to find information and usage examples for a particular provider. ## Installation @@ -534,7 +565,786 @@ For the JSON type of provider (HCP Vault Dedicated, HCP Vault Secrets, HTTP/HTTP - method - optional parameters (depends on the cloud provider). -## Caching configuration +## Dedicated Vault Username Provider + +The **Dedicated Vault Username Provider** provides Oracle JDBC with a **database username** that is managed by **HashiCorp Vault Dedicated**. +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-dedicated-username`. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-dedicated-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
vaultAddrThe URL of the HashiCorp Vault Dedicated instance. +The URL will typically have the following form: +
https://{vault-name}.hashicorp.cloud:8200/
+
+No default value. A value must be configured for this parameter. +
secretPathThe path to the secret containing the username.Any valid secret path. +No default value. A value must be configured for this parameter. +
fieldName (Optional) +The field inside the JSON secret that contains the required value. +If the secret contains multiple keys, this parameter specifies which key to extract. +If the secret contains only one key, the value is automatically used. +If omitted and multiple keys exist, an error is thrown. +Any valid field name. +No default value. If not specified, the provider selects the only key if a single key exists. +
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-dedicated.properties](example-vault-dedicated.properties). + +## HCP Vault Secrets Username Provider + +The **HCP Vault Secrets Username Provider** provides Oracle JDBC with a **database username** that is managed by **HashiCorp Vault Secrets**. +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-secrets-username`. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-secrets-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
secretNameThe name of the secret in HCP Vault Secrets containing the username.Any valid secret name within the app. No default value. A value must be configured for this parameter.
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-secrets.properties](example-vault-secrets.properties). + +--- + +## Dedicated Vault Password Provider + +The **Dedicated Vault Password Provider** provides Oracle JDBC with a **database password** that is managed by **HashiCorp Vault Dedicated**. +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-dedicated-password`. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-dedicated-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
vaultAddrThe URL of the HashiCorp Vault Dedicated instance. +The URL will typically have the following form: +
https://{vault-name}.hashicorp.cloud:8200/
+
+No default value. A value must be configured for this parameter. +
secretPathThe path to the secret containing the password.Any valid secret path. +No default value. A value must be configured for this parameter. +
fieldName (Optional) +The field inside the JSON secret that contains the required value. +If the secret contains multiple keys, this parameter specifies which key to extract. +If the secret contains only one key, the value is automatically used. +If omitted and multiple keys exist, an error is thrown. +Any valid field name. +No default value. If not specified, the provider selects the only key if a single key exists. +
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-dedicated.properties](example-vault-dedicated.properties). + +## HCP Vault Secrets Password Provider + +The **HCP Vault Secrets Password Provider** provides Oracle JDBC with a **database password** that is managed by **HashiCorp Vault Secrets**. +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-secrets-password`. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-secrets-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
secretNameThe name of the secret in HCP Vault Secrets containing the password.Any valid secret name within the app. No default value. A value must be configured for this parameter.
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-secrets.properties](example-vault-secrets.properties). + +--- + +## Dedicated Vault TCPS Wallet Provider + +The **Dedicated Vault TCPS Wallet Provider** provides Oracle JDBC with **keys and certificates** managed by **HashiCorp Vault Dedicated** to establish secure **TLS connections** with an Autonomous Database. +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-dedicated-tls`. + +For example, when connecting to an Autonomous Database Serverless with **mutual TLS (mTLS)**, +you need to configure the JDBC-thin driver with its client certificate. +If this certificate is stored in a wallet file (`cwallet.sso`, `ewallet.p12`, `ewallet.pem`), +you may store it in **HCP Vault Dedicated** for additional security. +This provider retrieves the wallet content from **HCP Vault Dedicated** and passes it to the JDBC thin driver. + +- The **type** parameter must be specified to indicate the wallet format: **SSO, PKCS12, or PEM**. +- The **walletPassword** must be provided for wallets that require a password (**PKCS12** or password-protected **PEM** files). + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-dedicated-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
vaultAddrThe URL of the HashiCorp Vault Dedicated instance. +
https://{vault-name}.hashicorp.cloud:8200/
+
+No default value. A value must be configured for this parameter. +
secretPathThe path to the wallet file.Any valid secret path. +No default value. A value must be configured for this parameter. +
typeThe wallet format.SSO, PKCS12, PEM +No default value. The file type must be specified. +
walletPassword +Optional password for **PKCS12** or protected **PEM** files. +If omitted, the file is assumed to be **SSO** or an **unprotected PEM** file. +Any valid password. +No default value. PKCS12 and password-protected PEM files require a password. +
fieldName (Optional) +The field inside the JSON secret that contains the required value. +If the secret contains multiple keys, this parameter specifies which key to extract. +If the secret contains only one key, the value is automatically used. +If omitted and multiple keys exist, an error is thrown. +Any valid field name. +No default value. If not specified, the provider selects the only key if a single key exists. +
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-dedicated-wallet.properties](example-vault-dedicated-wallet.properties). + +## HCP Vault Secrets TCPS Wallet Provider + +The **HCP Vault Secrets TCPS Wallet Provide** provides Oracle JDBC with **keys and certificates** managed by **HashiCorp Vault Secrets** to establish secure **TLS connections** with an Autonomous Database. +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-secrets-tls`. + +For example, when connecting to an Autonomous Database Serverless with **mutual TLS (mTLS)**, +you need to configure the JDBC-thin driver with its client certificate. +If this certificate is stored in a wallet file (`cwallet.sso`, `ewallet.p12`, `ewallet.pem`), +you may store it in **HCP Vault Secrets** for additional security. +This provider retrieves the wallet content from **HCP Vault Secrets** and passes it to the JDBC thin driver. + +- The **type** parameter must be specified to indicate the wallet format: **SSO, PKCS12, or PEM**. +- The **walletPassword** must be provided for wallets that require a password (**PKCS12** or password-protected **PEM** files). + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-secrets-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
secretNameThe name of the secret in HCP Vault Secrets containing the wallet.Any valid secret name within the app. No default value. A value must be configured for this parameter.
typeThe wallet format.SSO, PKCS12, PEM No default value. The file type must be specified.
walletPassword Optional password for **PKCS12** or protected **PEM** files. If omitted, the file is assumed to be **SSO** or an **unprotected PEM** file. Any valid password. No default value. Required for password-protected files.
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-secrets-wallet.properties](example-vault-secrets-wallet.properties). + +--- + +## Dedicated Vault SEPS Wallet Provider + +The **Dedicated Vault SEPS Wallet Provider** provides Oracle JDBC with **username and password credentials** stored in a **Secure External Password Store (SEPS) wallet** within **HCP Vault Dedicated**. + +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-dedicated-seps`. + +- The SEPS wallet securely stores **encrypted database credentials**, including the **username, password, and connection strings**. + These credentials can be stored as **default values**, such as: + - `oracle.security.client.default_username` + - `oracle.security.client.default_password` + + or as indexed credentials, for example: + - `oracle.security.client.username1` + - `oracle.security.client.password1` + - `oracle.security.client.connect_string1`. + +- The provider retrieves credentials using the following logic: + 1. If `connectionStringIndex` is **not specified**, the provider attempts to retrieve the **default credentials** (`oracle.security.client.default_username` and `oracle.security.client.default_password`). + 2. If **default credentials are missing**, the provider checks for a single **set of credentials** associated with a **connection string**. + 3. If **exactly one connection string** is found, the associated credentials are used. + 4. If **multiple connection strings** exist, an **error is thrown**, prompting you to specify a `connectionStringIndex`. + 5. If `connectionStringIndex` is specified, the provider attempts to retrieve the credentials associated with the **specified connection string index** (e.g., `oracle.security.client.username{idx}`, `oracle.security.client.password{idx}`, `oracle.security.client.connect_string{idx}`). + 6. If credentials for the **specified index** are not found, an **error is thrown**, indicating that no connection string exists with that index. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-dedicated-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
vaultAddrThe URL of the HashiCorp Vault Dedicated instance. +The URL will typically have the following form: +
https://{vault-name}.hashicorp.cloud:8200/
+
+No default value. A value must be configured for this parameter. +
secretPathThe path to the SEPS wallet file in HashiCorp Vault Dedicated.Any valid secret path. +No default value. A value must be configured for this parameter. +
walletPassword +Optional password for **PKCS12 SEPS wallets**. If omitted, the wallet is assumed to be **SSO**. +Any valid password for the SEPS wallet. +No default value. PKCS12 wallets require a password. +
connectionStringIndex (Optional) +Specifies the **index** of the connection string to use when retrieving credentials from the wallet. +A positive integer representing the index of the desired credential set (e.g., 1, 2, 3, etc.). +No default value. If not specified, the provider follows the default behavior as described above. +
fieldName (Optional) +The field inside the JSON secret that contains the required value. +If the secret contains multiple keys, this parameter specifies which key to extract. +If the secret contains only one key, the value is automatically used. +If omitted and multiple keys exist, an error is thrown. +Any valid field name. +No default value. If not specified, the provider selects the only key if a single key exists. +
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-dedicated-wallet.properties](example-vault-dedicated-wallet.properties). + +## HCP Vault Secrets SEPS Wallet Provider + +The **HCP Vault Secrets SEPS Wallet Provider** provides Oracle JDBC with **username and password credentials** stored in a **Secure External Password Store (SEPS) wallet** within **HCP Vault Secrets**. + +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-secrets-seps`. + +- The SEPS wallet securely stores **encrypted database credentials**, including the **username, password, and connection strings**. + These credentials can be stored as **default values**, such as: + - `oracle.security.client.default_username` + - `oracle.security.client.default_password` + + or as indexed credentials, for example: + - `oracle.security.client.username1` + - `oracle.security.client.password1` + - `oracle.security.client.connect_string1`. + +- The provider retrieves credentials using the following logic: + 1. If `connectionStringIndex` is **not specified**, the provider attempts to retrieve the **default credentials** (`oracle.security.client.default_username` and `oracle.security.client.default_password`). + 2. If **default credentials are missing**, the provider checks for a single **set of credentials** associated with a **connection string**. + 3. If **exactly one connection string** is found, the associated credentials are used. + 4. If **multiple connection strings** exist, an **error is thrown**, prompting you to specify a `connectionStringIndex`. + 5. If `connectionStringIndex` is specified, the provider attempts to retrieve the credentials associated with the **specified connection string index** (e.g., `oracle.security.client.username{idx}`, `oracle.security.client.password{idx}`, `oracle.security.client.connect_string{idx}`). + 6. If credentials for the **specified index** are not found, an **error is thrown**, indicating that no connection string exists with that index. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-secrets-resource-providers), this provider also supports the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
secretNameThe name of the SEPS wallet secret in HCP Vault Secrets.Any valid secret name within the app.No default value. A value must be configured for this parameter.
walletPassword Optional password for **PKCS12 SEPS wallets**. If omitted, the wallet is assumed to be **SSO**. Any valid password for the SEPS wallet.No default value. PKCS12 wallets require a password.
connectionStringIndex (Optional) Specifies the **index** of the connection string to use when retrieving credentials from the wallet. A positive integer representing the index of the desired credential set (e.g., 1, 2, 3, etc.).No default value. If not specified, the provider follows the default behavior as described above.
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-secrets-wallet.properties](example-vault-secrets-wallet.properties). + +--- + +## Dedicated Vault Connection String Provider + +The **Dedicated Vault Connection String Provider** provides Oracle JDBC with a **connection string** +retrieved from a `tnsnames.ora` file stored in **HCP Vault Dedicated**. + +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-dedicated-tnsnames`. + +This provider retrieves and decodes a `tnsnames.ora` file stored as a **base64-encoded secret** or **plain text** in **HCP Vault Dedicated**, allowing selection of connection strings based on specified aliases. + +This enables flexible configuration for **secure database connections** using the alias names defined in your `tnsnames.ora` file. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-dedicated-resource-providers), this provider also requires the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
vaultAddrThe URL of the HashiCorp Vault Dedicated instance. +
https://{vault-name}.hashicorp.cloud:8200/
+
+No default value. A value must be configured for this parameter. +
secretPathThe path to the `tnsnames.ora` file.Any valid secret path. +No default value. A value must be configured for this parameter. +
tnsAliasThe alias to retrieve the connection string.Any valid alias present in the `tnsnames.ora` file. +No default value. A value must be configured for this parameter. +
fieldName (Optional) +The field inside the JSON secret that contains the required value. +If the secret contains multiple keys, this parameter specifies which key to extract. +If the secret contains only one key, the value is automatically used. +If omitted and multiple keys exist, an error is thrown. +Any valid field name. +No default value. If not specified, the provider selects the only key if a single key exists. +
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-dedicated.properties](example-vault-dedicated.properties). + +## HCP Vault Secrets Connection String Provider + +The **HCP Vault Secrets Connection String Provider** provides Oracle JDBC with a **connection string** +retrieved from a `tnsnames.ora` file stored in **HCP Vault Secrets**. + +This is a **Resource Provider** identified by the name `ojdbc-provider-hcpvault-secrets-tnsnames`. + +This provider retrieves and decodes a `tnsnames.ora` file stored as a **base64-encoded secret** or **plain text** in **HCP Vault Secrets**, allowing selection of connection strings based on specified aliases. + +This enables flexible configuration for **secure database connections** using the alias names defined in your `tnsnames.ora` file. + +In addition to the set of [common parameters](#common-parameters-for-hcp-vault-secrets-resource-providers), this provider also requires the parameters listed below. + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesDefault Value
secretNameThe name of the secret in HCP Vault Secrets containing the tnsnames.ora file.Any valid secret name within the app. No default value. A value must be configured for this parameter.
tnsAliasThe alias to retrieve the connection string.Any valid alias present in the `tnsnames.ora` file. No default value. A value must be configured for this parameter.
+ +An example of a [connection properties file](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE) that configures this provider can be found in [example-vault-secrets.properties](example-vault-secrets.properties). + +## Common Parameters for HCP Vault Dedicated Resource Providers + +Providers classified as Resource Providers in this module all support a common set of parameters. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesSystem Property / Environment VariableDefault Value
authenticationMethodConfigures a method of authentication for HCP Vault Dedicated.Accepted values are defined in: Configuring Authentication for HCP Vault Dedicated.Not supportedauto-detect
vaultAddrThe URL of the HashiCorp Vault Dedicated instance.A valid Vault endpoint, typically in the form:
https://vault.example.com:8200
VAULT_ADDRNo default value.
vaultNamespaceThe namespace in the Vault (only required if using namespaces).Any valid Vault namespace.VAULT_NAMESPACEadmin (if not explicitly set)
vaultTokenConfigures authentication using a Vault token.A valid Vault authentication token.VAULT_TOKENNo default value.
vaultUsernameConfigures authentication using the Userpass method.A valid Vault username. VAULT_USERNAMENo default value.
vaultPasswordThe password for Userpass authentication.A valid Vault password.VAULT_PASSWORDNo default value.
roleIdConfigures authentication using the AppRole method.A valid Role ID for the AppRole authentication method.ROLE_IDNo default value.
secretIdThe secret ID for AppRole authentication.A valid Secret ID for the AppRole authentication method.SECRET_IDNo default value.
githubTokenConfigures authentication using a GitHub token.A valid GitHub personal access token.GITHUB_TOKENNo default value.
userPassAuthPathThe authentication path in the Vault for Userpass authentication.Any valid Vault authentication path.USERPASS_AUTH_PATHuserpass (if not explicitly set)
appRoleAuthPathThe authentication path in the Vault for AppRole authentication.Any valid Vault authentication path.APPROLE_AUTH_PATHapprole (if not explicitly set)
githubAuthPathThe authentication path in the Vault for GitHub authentication.Any valid Vault authentication path. GITHUB_AUTH_PATHgithub (if not explicitly set)
+ +--- + +## Common Parameters for HCP Vault Secrets Resource Providers + +Providers classified as Resource Providers for HCP Vault Secrets support a common set of parameters used for authenticating with the HCP Vault Secrets API. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter NameDescriptionAccepted ValuesSystem Property / Environment VariableDefault Value
authenticationMethodConfigures a method of authentication for HCP Vault Secrets.client_credentials, cli_credentials_file, auto-detectNot supportedauto-detect
orgIdThe organization ID associated with the HCP Vault Secrets project.A valid HCP organization ID.HCP_ORG_IDNo default value.
projectIdThe project ID associated with the HCP Vault Secrets app.A valid HCP project ID.HCP_PROJECT_IDNo default value.
appNameThe name of the application registered in HCP Vault Secrets.A valid HCP application name.HCP_APP_NAMENo default value.
clientIdThe client ID used for client credentials OAuth 2.0 authentication.A valid HCP Client ID.HCP_CLIENT_IDNo default value.
clientSecretThe client secret associated with the client ID.A valid HCP Client Secret.HCP_CLIENT_SECRETNo default value.
credentialsFileThe path to the local HCP CLI credentials file.A valid file path (e.g., ~/.config/hcp/creds-cache.json)HCP_CREDENTIALS_FILE~/.config/hcp/creds-cache.json
+ +## Configuring Authentication for Resource Providers + +### HCP Vault Dedicated + +Resource Providers in this module must authenticate with **HashiCorp Vault Dedicated**. +By default, the provider will automatically detect any available credentials. +A specific authentication method may be configured using the "authenticationMethod" parameter. + +Supported values for `authenticationMethod`: + +- **`vault-token`** + Authenticate using a pre-existing Vault token. + +- **`userpass`** + Authenticate using a username and password. + +- **`approle`** + Authenticate using AppRole credentials (requires `roleId` and `secretId`). + +- **`github`** + Authenticate using a GitHub personal access token. + +- **`auto-detect`** (default) + Automatically selects the method based on the following priority: + 1. `vault-token` + 2. `userpass` + 3. `approle` + 4. `github` + +### HCP Vault Secrets + +Resource Providers that access **HCP Vault Secrets** also require authentication. +By default, the provider will **auto-detect** the method to use. +You may override this using the `authenticationMethod` parameter. + +Supported values for `authenticationMethod`: + +- **`client-credentials`** + Uses OAuth 2.0 Client Credentials Flow. Requires `clientId` and `clientSecret`. + +- **`cli-credentials-file`** + Uses the local HCP CLI credentials file (`~/.config/hcp/creds-cache.json`), which contains `access_token` and `refresh_token`. + +- **`auto-detect`** (default) + Automatically selects based on: + 1. `cli-credentials-file` (if file exists or is configured) + 2. `client-credentials` (if both `clientId` and `clientSecret` are available) + +## caching-configuration Config providers in this module store the configuration in caches to minimize the number of RPC requests to remote location. See diff --git a/ojdbc-provider-hashicorp/example-test.properties b/ojdbc-provider-hashicorp/example-test.properties index 31b862fe..23f03302 100644 --- a/ojdbc-provider-hashicorp/example-test.properties +++ b/ojdbc-provider-hashicorp/example-test.properties @@ -124,6 +124,36 @@ GITHUB_TOKEN=your-github-personal-access-token # Optional path for GitHub authentication in Vault (default: github) GITHUB_AUTH_PATH=github +# The secret path for the username provider in HCP Vault Dedicated. +USERNAME_SECRET_PATH=/v1/namespace/secret/data/username + +# The secret path for the password provider in HCP Vault Dedicated. +PASSWORD_SECRET_PATH=/v1/namespace/secret/data/password + +# The secret path for the connection string provider in HCP Vault Dedicated. +TNSNAMES_SECRET_PATH=/v1/namespace/secret/data/tnsnames + +# The alias in the tnsnames.ora file to use for the connection string. +TNS_ALIAS=your_tns_alias + +# The secret path for the TCPS (TLS) wallet in HCP Vault Dedicated. +TLS_WALLET_SECRET_PATH=/v1/namespace/secret/data/tcps-wallet + +# The type of the file stored in HCP Vault Dedicated (SSO, PKCS12, PEM). +TLS_FILE_TYPE=PKCS12 + +# Optional password for the TLS file stored in HCP Vault Dedicated. +TLS_FILE_PASSWORD=****** + +# The secret path for the SEPS wallet in HCP Vault Dedicated. +SEPS_WALLET_SECRET_PATH=/v1/namespace/secret/data/seps-wallet + +# Optional password for the SEPS wallet stored in HCP Vault Dedicated. +SEPS_WALLET_PASSWORD=***** + +# Optional index to select specific credentials from the SEPS wallet. +SEPS_CONNECTION_STRING_INDEX=1 + ################################################################################ # HCP VAULT SECRETS CONFIGURATION ################################################################################ diff --git a/ojdbc-provider-hashicorp/example-vault-dedicated-wallet.properties b/ojdbc-provider-hashicorp/example-vault-dedicated-wallet.properties new file mode 100644 index 00000000..b32c0bae --- /dev/null +++ b/ojdbc-provider-hashicorp/example-vault-dedicated-wallet.properties @@ -0,0 +1,82 @@ +################################################################################ +# Copyright (c) 2025 Oracle and/or its affiliates. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or data +# (collectively the "Software"), free of charge and under any and all copyright +# rights in the Software, and any and all patent rights owned or freely +# licensable by each licensor hereunder covering either (i) the unmodified +# Software as contributed to or provided by such licensor, or (ii) the Larger +# Works (as defined below), to deal in both +# +# (a) the Software, and +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software (each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# The above copyright notice and either this complete permission notice or at +# a minimum a reference to the UPL must be included in all copies or +# substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +################################################################################ + +# An example of a connection properties file that configures Oracle JDBC to +# obtain a TLS wallet and SEPS credentials from HashiCorp Vault Dedicated. +# +# This file can be located by Oracle JDBC using the "oracle.jdbc.config.file" +# connection property. For details, see: +# https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE + +# Configures the HCP Vault Dedicated TCPS (TLS) Wallet Provider. The vault URL and +# secret path are configured as environment variables or JVM system properties named +# "VAULT_ADDR" and "TLS_WALLET_SECRET_PATH". +oracle.jdbc.provider.tlsConfiguration=ojdbc-provider-hcpvault-dedicated-tls +oracle.jdbc.provider.tlsConfiguration.vaultAddr=${VAULT_ADDR} +oracle.jdbc.provider.tlsConfiguration.secretPath=${TLS_WALLET_SECRET_PATH} + +# Configures the HCP Vault Dedicated TLS Wallet Password. The password for the +# file is optional and can be configured as an environment variable or JVM +# system property named "TLS_FILE_PASSWORD". +oracle.jdbc.provider.tlsConfiguration.walletPassword=${TLS_FILE_PASSWORD} + +# Specifies the file type (SSO, PKCS12, or PEM) for the TCPS wallet. +# This can be configured as an environment variable or JVM system property named "TLS_FILE_TYPE". +oracle.jdbc.provider.tlsConfiguration.type=${TLS_FILE_TYPE} + +# Configures the HCP Vault Dedicated SEPS (Secure External Password Store) Provider. +# The vault URL and secret path are configured as environment variables or JVM system properties +# named "VAULT_ADDR" and "SEPS_WALLET_SECRET_PATH". +oracle.jdbc.provider.username=ojdbc-provider-hcpvault-dedicated-seps +oracle.jdbc.provider.password=ojdbc-provider-hcpvault-dedicated-seps + +# Configures the vault URL and secret path for SEPS. +oracle.jdbc.provider.username.vaultAddr=${VAULT_ADDR} +oracle.jdbc.provider.username.secretPath=${SEPS_WALLET_SECRET_PATH} +oracle.jdbc.provider.password.vaultAddr=${VAULT_ADDR} +oracle.jdbc.provider.password.secretPath=${SEPS_WALLET_SECRET_PATH} + +# Optional password for SEPS Wallet stored in HCP Vault Dedicated. +oracle.jdbc.provider.username.walletPassword=${SEPS_WALLET_PASSWORD} +oracle.jdbc.provider.password.walletPassword=${SEPS_WALLET_PASSWORD} + +# Optional connection string index for SEPS Wallet. +# This determines which set of credentials (username/password) to use from the SEPS Wallet. +oracle.jdbc.provider.username.connectionStringIndex=${SEPS_CONNECTION_STRING_INDEX} +oracle.jdbc.provider.password.connectionStringIndex=${SEPS_CONNECTION_STRING_INDEX} + diff --git a/ojdbc-provider-hashicorp/example-vault-dedicated.properties b/ojdbc-provider-hashicorp/example-vault-dedicated.properties new file mode 100644 index 00000000..5fad700e --- /dev/null +++ b/ojdbc-provider-hashicorp/example-vault-dedicated.properties @@ -0,0 +1,67 @@ +################################################################################ +# Copyright (c) 2025 Oracle and/or its affiliates. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or data +# (collectively the "Software"), free of charge and under any and all copyright +# rights in the Software, and any and all patent rights owned or freely +# licensable by each licensor hereunder covering either (i) the unmodified +# Software as contributed to or provided by such licensor, or (ii) the Larger +# Works (as defined below), to deal in both +# +# (a) the Software, and +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software (each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# The above copyright notice and either this complete permission notice or at +# a minimum a reference to the UPL must be included in all copies or +# substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +################################################################################ + +# An example of a connection properties file that configures Oracle JDBC to +# login using a username and password managed by HashiCorp Vault Dedicated service. +# This file can be located by Oracle JDBC using the "oracle.jdbc.config.file" +# connection property. For details, see: +# https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE + +# Configures the HCP Vault Dedicated Username Provider. The vault Address and secret path +# are configured as environment variables or JVM system properties +# named "VAULT_ADDR" and "USERNAME_SECRET_PATH". +oracle.jdbc.provider.username=ojdbc-provider-hcpvault-dedicated-username +oracle.jdbc.provider.username.vaultAddr=${VAULT_ADDR} +oracle.jdbc.provider.username.secretPath=${USERNAME_SECRET_PATH} + +# Configures the HCP Vault Dedicated Password Provider. The vault Address and secret path +# are configured as environment variables or JVM system properties +# named "VAULT_ADDR" and "PASSWORD_SECRET_PATH". +oracle.jdbc.provider.password=ojdbc-provider-hcpvault-dedicated-password +oracle.jdbc.provider.password.vaultAddr=${VAULT_ADDR} +oracle.jdbc.provider.password.secretPath=${PASSWORD_SECRET_PATH} + +# Configures the HCP Vault Dedicated Connection String Provider. The vault Address, secret path, +# and tns alias are configured as environment variables or JVM system properties +# named "VAULT_ADDR", "TNSNAMES_SECRET_PATH", and "TNS_ALIAS". +oracle.jdbc.provider.connectionString=ojdbc-provider-hcpvault-dedicated-tnsnames +oracle.jdbc.provider.connectionString.vaultAddr=${VAULT_ADDR} +oracle.jdbc.provider.connectionString.secretPath=${TNSNAMES_SECRET_PATH} +oracle.jdbc.provider.connectionString.tnsAlias=${TNS_ALIAS} + + diff --git a/ojdbc-provider-hashicorp/example-vault-secrets-wallet.properties b/ojdbc-provider-hashicorp/example-vault-secrets-wallet.properties new file mode 100644 index 00000000..fb463555 --- /dev/null +++ b/ojdbc-provider-hashicorp/example-vault-secrets-wallet.properties @@ -0,0 +1,78 @@ +################################################################################ +# Copyright (c) 2025 Oracle and/or its affiliates. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or data +# (collectively the "Software"), free of charge and under any and all copyright +# rights in the Software, and any and all patent rights owned or freely +# licensable by each licensor hereunder covering either (i) the unmodified +# Software as contributed to or provided by such licensor, or (ii) the Larger +# Works (as defined below), to deal in both +# +# (a) the Software, and +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software (each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# The above copyright notice and either this complete permission notice or at +# a minimum a reference to the UPL must be included in all copies or +# substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +################################################################################ + +# An example of a connection properties file that configures Oracle JDBC to +# obtain a TLS wallet and SEPS credentials from HCP Vault Secrets Service. +# +# This file can be located by Oracle JDBC using the "oracle.jdbc.config.file" +# connection property. For details, see: +# https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE + +# Configures the HCP Vault Secrets TCPS (TLS) Wallet Provider. The secret name is +# configured as an environment variable or JVM system property named "TLS_WALLET_SECRET_NAME". +oracle.jdbc.provider.tlsConfiguration=ojdbc-provider-hcpvault-secrets-tls +oracle.jdbc.provider.tlsConfiguration.secretName=${TLS_WALLET_SECRET_NAME} + +# Configures the HCP Vault Secrets TLS Wallet Password. The password for the +# file is optional and can be configured as an environment variable or JVM +# system property named "TLS_FILE_PASSWORD". +oracle.jdbc.provider.tlsConfiguration.walletPassword=${TLS_FILE_PASSWORD} + +# Specifies the file type (SSO, PKCS12, or PEM) for the TCPS wallet. +# This can be configured as an environment variable or JVM system property named "TLS_FILE_TYPE". +oracle.jdbc.provider.tlsConfiguration.type=${TLS_FILE_TYPE} + +# Configures the HCP Vault Secrets SEPS (Secure External Password Store) Provider. +# Secret Name is configured as environment variables or JVM system properties +# named "SEPS_WALLET_SECRET_NAME". +oracle.jdbc.provider.username=ojdbc-provider-hcpvault-secrets-seps +oracle.jdbc.provider.password=ojdbc-provider-hcpvault-secrets-seps + +# Configures the Secret Name for SEPS. +oracle.jdbc.provider.username.secretPath=${SEPS_WALLET_SECRET_NAME} +oracle.jdbc.provider.password.secretPath=${SEPS_WALLET_SECRET_NAME} + +# Optional password for SEPS Wallet stored in HCP Vault Secret. +oracle.jdbc.provider.username.walletPassword=${SEPS_WALLET_PASSWORD} +oracle.jdbc.provider.password.walletPassword=${SEPS_WALLET_PASSWORD} + +# Optional connection string index for SEPS Wallet. +# This determines which set of credentials (username/password) to use from the SEPS Wallet. +oracle.jdbc.provider.username.connectionStringIndex=${SEPS_CONNECTION_STRING_INDEX} +oracle.jdbc.provider.password.connectionStringIndex=${SEPS_CONNECTION_STRING_INDEX} + diff --git a/ojdbc-provider-hashicorp/example-vault-secrets.properties b/ojdbc-provider-hashicorp/example-vault-secrets.properties new file mode 100644 index 00000000..19e3f957 --- /dev/null +++ b/ojdbc-provider-hashicorp/example-vault-secrets.properties @@ -0,0 +1,61 @@ +################################################################################ +# Copyright (c) 2025 Oracle and/or its affiliates. +# +# The Universal Permissive License (UPL), Version 1.0 +# +# Subject to the condition set forth below, permission is hereby granted to any +# person obtaining a copy of this software, associated documentation and/or data +# (collectively the "Software"), free of charge and under any and all copyright +# rights in the Software, and any and all patent rights owned or freely +# licensable by each licensor hereunder covering either (i) the unmodified +# Software as contributed to or provided by such licensor, or (ii) the Larger +# Works (as defined below), to deal in both +# +# (a) the Software, and +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +# one is included with the Software (each a "Larger Work" to which the Software +# is contributed by such licensors), +# +# without restriction, including without limitation the rights to copy, create +# derivative works of, display, perform, and distribute the Software and make, +# use, sell, offer for sale, import, export, have made, and have sold the +# Software and the Larger Work(s), and to sublicense the foregoing rights on +# either these or other terms. +# +# This license is subject to the following condition: +# The above copyright notice and either this complete permission notice or at +# a minimum a reference to the UPL must be included in all copies or +# substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +################################################################################ + +# An example of a connection properties file that configures Oracle JDBC to +# login using a username and password managed by HashiCorp Vault Secrets service. +# This file can be located by Oracle JDBC using the "oracle.jdbc.config.file" +# connection property. For details, see: +# https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html#CONNECTION_PROPERTY_CONFIG_FILE + +# Configures the HCP Vault Secrets Username Provider.The secret name is +# configured as an environment variable or JVM system property named "USERNAME_SECRET_NAME". +oracle.jdbc.provider.username=ojdbc-provider-hcpvault-secrets-username +oracle.jdbc.provider.username.secretName=${USERNAME_SECRET_NAME} + +# Configures the HCP Vault Secrets Password Provider.The secret name is +# configured as an environment variable or JVM system property named "PASSWORD_SECRET_NAME". +oracle.jdbc.provider.password=ojdbc-provider-hcpvault-secrets-password +oracle.jdbc.provider.password.secretName=${PASSWORD_SECRET_NAME} + +# Configures the HCP Vault Secrets Connection String Provider. The secret name and alias +# are configured as environment variables or JVM system properties named "TNSNAMES_SECRET_NAME" and "TNS_ALIAS". +oracle.jdbc.provider.connectionString=ojdbc-provider-hcpvault-secrets-tnsnames +oracle.jdbc.provider.connectionString.secretName=${TNSNAMES_SECRET_NAME} +oracle.jdbc.provider.connectionString.tnsAlias=${TNS_ALIAS} + + diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/authentication/DedicatedVaultParameters.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/authentication/DedicatedVaultParameters.java index 8610e0c6..5216984b 100644 --- a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/authentication/DedicatedVaultParameters.java +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/authentication/DedicatedVaultParameters.java @@ -81,10 +81,10 @@ public class DedicatedVaultParameters { // Default values - static final String DEFAULT_NAMESPACE = "admin"; - static final String DEFAULT_USERPASS_PATH = "userpass"; - static final String DEFAULT_APPROLE_PATH = "approle"; - static final String DEFAULT_GITHUB_PATH = "github"; + public static final String DEFAULT_NAMESPACE = "admin"; + public static final String DEFAULT_USERPASS_PATH = "userpass"; + public static final String DEFAULT_APPROLE_PATH = "approle"; + public static final String DEFAULT_GITHUB_PATH = "github"; /** *

@@ -93,7 +93,7 @@ public class DedicatedVaultParameters { *

*/ public static final Parameter AUTHENTICATION_METHOD = - Parameter.create(REQUIRED); + Parameter.create(); /** The path of the secret in Vault. Required. */ public static final Parameter SECRET_PATH = Parameter.create(REQUIRED); @@ -107,12 +107,12 @@ public class DedicatedVaultParameters { /** * The Vault address. If not specified, fallback to system property or environment var. */ - public static final Parameter VAULT_ADDR = Parameter.create(REQUIRED); + public static final Parameter VAULT_ADDR = Parameter.create(); /** * The Vault token. If not specified, fallback to system property or environment var. */ - public static final Parameter VAULT_TOKEN = Parameter.create(REQUIRED); + public static final Parameter VAULT_TOKEN = Parameter.create(); /** * The field name for extracting a specific value from the JSON. @@ -122,12 +122,12 @@ public class DedicatedVaultParameters { /** * The username for Userpass authentication. Required for Userpass method. */ - public static final Parameter USERNAME = Parameter.create(REQUIRED); + public static final Parameter USERNAME = Parameter.create(); /** * The password for Userpass authentication. Required for Userpass method. */ - public static final Parameter PASSWORD = Parameter.create(REQUIRED); + public static final Parameter PASSWORD = Parameter.create(); /** * The path for Userpass authentication. Optional. @@ -146,7 +146,7 @@ public class DedicatedVaultParameters { * configured in Vault as part of the AppRole authentication setup. *

*/ - public static final Parameter ROLE_ID = Parameter.create(REQUIRED); + public static final Parameter ROLE_ID = Parameter.create(); /** * The Secret ID for AppRole authentication. Required for AppRole method. @@ -155,7 +155,7 @@ public class DedicatedVaultParameters { * conjunction with the Role ID for AppRole authentication. *

*/ - public static final Parameter SECRET_ID = Parameter.create(REQUIRED); + public static final Parameter SECRET_ID = Parameter.create(); /** * The path for AppRole authentication. Optional. @@ -176,7 +176,7 @@ public class DedicatedVaultParameters { * the Vault policy. *

*/ - public static final Parameter GITHUB_TOKEN = Parameter.create(REQUIRED); + public static final Parameter GITHUB_TOKEN = Parameter.create(); /** * The path for GitHub authentication. Optional. @@ -259,7 +259,7 @@ public static ParameterSet buildResolvedParameterSet(Map inputOp * @return the parsed {@link DedicatedVaultAuthenticationMethod}. * @throws IllegalArgumentException if the value is unrecognized. */ - private static DedicatedVaultAuthenticationMethod parseAuthentication(String value) { + public static DedicatedVaultAuthenticationMethod parseAuthentication(String value) { try { return DedicatedVaultAuthenticationMethod.valueOf(value.toUpperCase()); } catch (IllegalArgumentException e) { diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultJsonSecretProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultJsonSecretProvider.java index e719e021..731d54ff 100644 --- a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultJsonSecretProvider.java +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultJsonSecretProvider.java @@ -49,6 +49,7 @@ import static oracle.jdbc.provider.hashicorp.hcpvaultdedicated.authentication.DedicatedVaultParameters.FIELD_NAME; import static oracle.jdbc.provider.hashicorp.hcpvaultdedicated.authentication.DedicatedVaultParameters.PARAMETER_SET_PARSER; +import static oracle.jdbc.provider.hashicorp.util.JsonUtil.extractSecret; /** *

@@ -95,20 +96,11 @@ public char[] getSecret(Map map) { OracleJsonObject secretJsonObj = JsonUtil.convertJsonToOracleJsonObject(secretString); String fieldName = parameterSet.getOptional(FIELD_NAME); - String extractedPassword; - if (fieldName != null && secretJsonObj.containsKey(fieldName)) { - extractedPassword = secretJsonObj.getString(fieldName); - } else if (secretJsonObj.size() == 1) { - extractedPassword = secretJsonObj.values().iterator().next().toString(); - } else { - throw new IllegalStateException( - "FIELD_NAME is required when multiple keys exist in the secret." - ); - } + String extractedSecret = extractSecret(secretJsonObj, fieldName); return Base64.getEncoder() - .encodeToString(extractedPassword.getBytes()) - .toCharArray(); + .encodeToString(extractedSecret.getBytes()) + .toCharArray(); } @Override diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedConnectionStringProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedConnectionStringProvider.java new file mode 100644 index 00000000..9d535007 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedConnectionStringProvider.java @@ -0,0 +1,129 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.FileUtils; +import oracle.jdbc.provider.util.TNSNames; +import oracle.jdbc.spi.ConnectionStringProvider; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; +import java.util.Map; + +import static oracle.jdbc.provider.util.CommonParameters.TNS_ALIAS; + +/** + *

+ * A provider for securely retrieving the connection string from a tnsnames.ora + * file stored in HashiCorp Vault Dedicated for use with an Oracle Autonomous Database. + * The tnsnames.ora file can be stored as a base64-encoded secret or as plain + * text. The provider automatically detects the format and processes the + * content accordingly to extract connection strings by alias. + *

+ *

+ * This class implements the {@link ConnectionStringProvider} SPI defined by + * Oracle JDBC. + * It is designed to be instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultDedicatedConnectionStringProvider + extends HcpVaultDedicatedSecretProvider + implements ConnectionStringProvider { + + private static final ResourceParameter[] TNS_NAMES_PARAMETERS = { + new ResourceParameter("tnsAlias", TNS_ALIAS) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultDedicatedConnectionStringProvider() { + super("tnsnames", TNS_NAMES_PARAMETERS); + } + + + /** + * Retrieves a database connection string from the tnsnames.ora file stored + * in HashiCorp Vault Dedicated. + *

+ * This method accesses the file in Vault, decodes it, and parses + * the tnsnames.ora content. It returns the connection string associated + * with the specified alias from the tnsnames.ora file. + *

+ * + * @param parameterValues The parameters required to access the tnsnames.ora + * file in HashiCorp Vault Dedicated. + * @return The connection string associated with the specified alias + * in the tnsnames.ora file. + * @throws IllegalStateException If there is an error reading the tnsnames.ora + * file or accessing HashiCorp Vault Dedicated. + * @throws IllegalArgumentException If the specified alias is invalid or + * does not exist in the tnsnames.ora file. + */ + @Override + public String getConnectionString(Map parameterValues) { + String alias = parseParameterValues(parameterValues).getRequired(TNS_ALIAS); + + byte[] secretBytes = getSecret(parameterValues).getBytes(); + + byte[] fileBytes; + if (FileUtils.isBase64Encoded(secretBytes)) { + fileBytes = Base64.getDecoder().decode(secretBytes); + } else { + fileBytes = secretBytes; + } + + TNSNames tnsNames; + try (InputStream inputStream = new ByteArrayInputStream(fileBytes)) { + tnsNames = TNSNames.read(inputStream); + } catch (IOException e) { + throw new IllegalStateException("Failed to read tnsnames.ora content", e); + } + + String connectionString = tnsNames.getConnectionStringByAlias(alias); + if (connectionString == null) { + throw new IllegalArgumentException( + "Alias specified does not exist in tnsnames.ora: " + alias); + } + return connectionString; + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedPasswordProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedPasswordProvider.java new file mode 100644 index 00000000..6e8c03df --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedPasswordProvider.java @@ -0,0 +1,71 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.spi.PasswordProvider; + +import java.util.Map; + +/** + *

+ * A provider for retrieving passwords securely stored in HashiCorp Vault Dedicated. + * This provider fetches the password from the Vault and returns it as a character array. + *

+ *

+ * This class implements the {@link PasswordProvider} SPI defined by Oracle JDBC + * and is designed to be instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultDedicatedPasswordProvider + extends HcpVaultDedicatedSecretProvider + implements PasswordProvider { + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultDedicatedPasswordProvider() { + super("password"); + } + + @Override + public char[] getPassword(Map parameterValues) { + return getSecret(parameterValues).toCharArray(); + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedResourceProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedResourceProvider.java new file mode 100644 index 00000000..4eaefaef --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedResourceProvider.java @@ -0,0 +1,149 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.authentication.DedicatedVaultAuthenticationMethod; +import oracle.jdbc.provider.hashicorp.util.AbstractVaultResourceProvider; +import oracle.jdbc.provider.resource.ResourceParameter; + +import java.util.stream.Stream; + +import static oracle.jdbc.provider.hashicorp.hcpvaultdedicated.authentication.DedicatedVaultParameters.*; +import static oracle.jdbc.provider.hashicorp.hcpvaultdedicated.authentication.DedicatedVaultParameters.PASSWORD; + +/** + * Super class of all {@code OracleResourceProvider} implementations + * that request a resource from Hcp Vault Dedicated. This super class defines + * parameters for authentication with Hcp Vault Dedicated. + */ +public class HcpVaultDedicatedResourceProvider extends AbstractVaultResourceProvider { + + static final ResourceParameter[] PARAMETERS = { + new ResourceParameter("authenticationMethod", AUTHENTICATION_METHOD, + "auto-detect", + HcpVaultDedicatedResourceProvider::parseAuthenticationMethod), + new ResourceParameter("vaultAddr", VAULT_ADDR), + new ResourceParameter("vaultNamespace", NAMESPACE, DEFAULT_NAMESPACE), + new ResourceParameter("vaultUsername", USERNAME), + new ResourceParameter("vaultPassword", PASSWORD), + new ResourceParameter("vaultToken", VAULT_TOKEN), + new ResourceParameter("roleId", ROLE_ID), + new ResourceParameter("secretId", SECRET_ID), + new ResourceParameter("userPassAuthPath", USERPASS_AUTH_PATH, DEFAULT_USERPASS_PATH), + new ResourceParameter("appRoleAuthPath", APPROLE_AUTH_PATH, DEFAULT_APPROLE_PATH), + new ResourceParameter("githubToken", GITHUB_TOKEN), + new ResourceParameter("githubAuthPath", GITHUB_AUTH_PATH, DEFAULT_GITHUB_PATH), + }; + + /** + *

+ * Constructs a provider identified by the name: + *

+ *
{@code
+   *   ojdbc-provider-hcpvault-dedicated-{resourceType}
+   * }
+ *

+ * This constructor defines all parameters related to authentication with + * HashiCorp Vault Dedicated. + * Subclasses must call this constructor with any additional parameters for + * the specific resource they provide. + *

+ * + * @param resourceType The resource type identifier that appears in the name of + * the provider. Not null. + * @param parameters Additional parameters specific to the subclass provider. + */ + protected HcpVaultDedicatedResourceProvider( + String resourceType, ResourceParameter... parameters) { + super("hcpvault-dedicated", resourceType, + Stream.concat( + Stream.of(PARAMETERS), + Stream.of(parameters)) + .toArray(ResourceParameter[]::new)); + } + + /** + * Parses the "authentication-method" parameter into a recognized + * {@link DedicatedVaultAuthenticationMethod}. + * + * @param authenticationMethod The authentication method as a string. + * @return The corresponding {@link DedicatedVaultAuthenticationMethod}. + * @throws IllegalArgumentException if the authentication method is unrecognized. + */ + private static DedicatedVaultAuthenticationMethod parseAuthenticationMethod(String authenticationMethod) { + switch (authenticationMethod) { + case "vault-token": + return DedicatedVaultAuthenticationMethod.VAULT_TOKEN; + case "userpass": + return DedicatedVaultAuthenticationMethod.USERPASS; + case "approle": + return DedicatedVaultAuthenticationMethod.APPROLE; + case "github": + return DedicatedVaultAuthenticationMethod.GITHUB; + case "auto-detect": + return DedicatedVaultAuthenticationMethod.AUTO_DETECT; + default: + throw new IllegalArgumentException("Unrecognized authentication method: " + authenticationMethod); + } + } + + /** + * Maps ResourceParameter names to their corresponding environment variable keys. + * + * @param paramName The ResourceParameter name (e.g., "vaultAddr"). + * @return The corresponding environment variable key (e.g., "VAULT_ADDR"). + */ + @Override + protected String getEnvVariableForParameter(String paramName) { + switch (paramName) { + case "vaultAddr": return PARAM_VAULT_ADDR; + case "vaultNamespace": return PARAM_VAULT_NAMESPACE; + case "vaultUsername": return PARAM_VAULT_USERNAME; + case "vaultPassword": return PARAM_VAULT_PASSWORD; + case "vaultToken": return PARAM_VAULT_TOKEN; + case "roleId": return PARAM_VAULT_ROLE_ID; + case "secretId": return PARAM_VAULT_SECRET_ID; + case "userPassAuthPath": return PARAM_USERPASS_AUTH_PATH; + case "appRoleAuthPath": return PARAM_APPROLE_AUTH_PATH; + case "githubAuthPath": return PARAM_GITHUB_AUTH_PATH; + default: return paramName; + } + } + +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSEPSProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSEPSProvider.java new file mode 100644 index 00000000..048e1a5b --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSEPSProvider.java @@ -0,0 +1,123 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.parameter.ParameterSet; +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.FileUtils; +import oracle.jdbc.provider.util.WalletUtils; +import oracle.jdbc.spi.OracleResourceProvider; +import oracle.jdbc.spi.PasswordProvider; +import oracle.jdbc.spi.UsernameProvider; + +import java.util.Base64; +import java.util.Map; + +import static oracle.jdbc.provider.util.CommonParameters.CONNECTION_STRING_INDEX; +import static oracle.jdbc.provider.util.CommonParameters.PASSWORD; + +/** + *

+ * A provider for Secure External Password Store (SEPS) credentials used + * to establish secure authentication with an Oracle database. The wallet is + * retrieved from HashiCorp Vault Dedicated, where it is stored as a + * base64-encoded string. + *

+ *

+ * This provider supports retrieving both **username** and **password** from + * the wallet. It can handle both **SSO** and **PKCS12**-based wallets. + *

+ *

+ * This class implements the {@link UsernameProvider} and + * {@link PasswordProvider} SPIs defined by Oracle JDBC and is designed to be + * instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultDedicatedSEPSProvider + extends HcpVaultDedicatedSecretProvider + implements UsernameProvider, PasswordProvider { + + private static final ResourceParameter[] SEPS_PARAMETERS = { + new ResourceParameter("walletPassword", PASSWORD), + new ResourceParameter("connectionStringIndex", CONNECTION_STRING_INDEX) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultDedicatedSEPSProvider() { + super("seps", SEPS_PARAMETERS); + } + + @Override + public String getUsername(Map parameterValues) { + return getWalletCredentials(parameterValues).username(); + } + + @Override + public char[] getPassword(Map parameterValues) { + return getWalletCredentials(parameterValues).password(); + } + + /** + * Retrieves the Oracle Wallet credentials by decoding the base64-encoded + * wallet stored in HashiCorp Vault Dedicated and opening it as either SSO + * or PKCS12, based on whether a password is provided. + * + * @param parameterValues The parameters required to access the wallet file. + * @return The extracted credentials containing username and password. + */ + private WalletUtils.Credentials getWalletCredentials( + Map parameterValues) { + ParameterSet parameterSet = parseParameterValues(parameterValues); + + String secretValue = getSecret(parameterValues); + + byte[] walletBytes = FileUtils.isBase64Encoded(secretValue.getBytes()) ? + Base64.getDecoder().decode(secretValue) : secretValue.getBytes(); + + char[] walletPassword = parameterSet.getOptional(PASSWORD) != null + ? parameterSet.getOptional(PASSWORD).toCharArray() : null; + + String connectionStringIndex = parameterSet.getOptional(CONNECTION_STRING_INDEX); + return WalletUtils.getCredentials(walletBytes, walletPassword, connectionStringIndex); + } + +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSecretProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSecretProvider.java new file mode 100644 index 00000000..870284b0 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSecretProvider.java @@ -0,0 +1,110 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.secrets.DedicatedVaultSecretsManagerFactory; +import oracle.jdbc.provider.hashicorp.util.JsonUtil; +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.ResourceParameterUtils; +import oracle.sql.json.OracleJsonObject; + +import java.util.Map; +import java.util.stream.Stream; + +import static oracle.jdbc.provider.hashicorp.hcpvaultdedicated.authentication.DedicatedVaultParameters.*; + +/** + *

+ * A provider of secrets from HashiCorp Vault Dedicated. This class is designed + * for inheritance by subclasses that implement an + * {@link oracle.jdbc.spi.OracleResourceProvider} SPI defined by the Oracle JDBC + * driver. This class defines parameters that configure the Secret path, + * and optional field selection for extracting values from JSON-based secrets. + *

+ */ +public class HcpVaultDedicatedSecretProvider extends HcpVaultDedicatedResourceProvider { + + private static final ResourceParameter[] PARAMETERS = { + new ResourceParameter("secretPath", SECRET_PATH), + new ResourceParameter("fieldName", FIELD_NAME), + }; + + protected HcpVaultDedicatedSecretProvider(String valueType) { + super(valueType, PARAMETERS); + } + + protected HcpVaultDedicatedSecretProvider(String valueType, ResourceParameter[] additionalParameters) { + super(valueType, ResourceParameterUtils.combineParameters(PARAMETERS, additionalParameters)); + } + + /** + *

+ * Retrieves a secret from HashiCorp Vault Dedicated based on parameters + * provided in {@code parameterValues}. This method centralizes secret + * retrieval logic and is used by subclasses implementing + * the {@link oracle.jdbc.spi.OracleResourceProvider} SPI. + *

+ *

+ * If the secret is stored in JSON format with multiple fields, a specific field + * can be extracted using the "fieldName" parameter. If no field name is provided + * and the JSON contains a single key, that key’s value is returned. If + * multiple keys exist and no field name is specified, an exception is thrown. + *

+ * + * @param parameterValues A map of parameter names and their corresponding + * -values required for secret retrieval. Must not be null. + * @return The extracted secret value as a {@code String}. + */ + protected final String getSecret(Map parameterValues) { + Map resolvedValues = + resolveMissingParameters(parameterValues, HcpVaultDedicatedResourceProvider.PARAMETERS); + String secretJson = getResource( + DedicatedVaultSecretsManagerFactory.getInstance(), resolvedValues); + OracleJsonObject secretJsonObj = JsonUtil.convertJsonToOracleJsonObject(secretJson); + ResourceParameter fieldNameParam = Stream.of(PARAMETERS) + .filter(param -> param.name().equals("fieldName")) + .findFirst() + .orElse(null); + + String fieldName = parameterValues.containsKey(fieldNameParam) ? + parameterValues.get(fieldNameParam).toString() : null; + return JsonUtil.extractSecret(secretJsonObj, fieldName); + } + +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedTCPSProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedTCPSProvider.java new file mode 100644 index 00000000..01ef96fb --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedTCPSProvider.java @@ -0,0 +1,126 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.parameter.ParameterSet; +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.FileUtils; +import oracle.jdbc.provider.util.TlsUtils; +import oracle.jdbc.spi.TlsConfigurationProvider; + +import javax.net.ssl.SSLContext; +import java.util.Base64; +import java.util.Map; + +import static oracle.jdbc.provider.util.CommonParameters.PASSWORD; +import static oracle.jdbc.provider.util.CommonParameters.TYPE; + +/** + *

+ * A provider for TCPS/TLS files used to establish secure TLS communication + * with an Autonomous Database. The file is retrieved from HashiCorp Vault Dedicated, + * where it is stored as a base64-encoded string. This provider supports + * different file types including SSO, PKCS12, and PEM formats. + *

+ *

+ * The type of the file must be explicitly specified using the {@code type} + * parameter. Based on the type, the file may contain private keys and + * certificates for establishing secure communication. A password is only + * required for PKCS12 or encrypted PEM files. + *

+ *

+ * This class implements the {@link TlsConfigurationProvider} SPI defined by + * Oracle JDBC and is designed to be instantiated via + * {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultDedicatedTCPSProvider + extends HcpVaultDedicatedSecretProvider + implements TlsConfigurationProvider { + + private static final ResourceParameter[] TCPS_PARAMETERS = { + new ResourceParameter("walletPassword", PASSWORD), + new ResourceParameter("type", TYPE) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultDedicatedTCPSProvider() { + super("tls", TCPS_PARAMETERS); + } + + /** + * Retrieves an SSLContext by loading a file from HashiCorp Vault Dedicated and + * configuring it for secure TLS communication with Autonomous Database. + *

+ * The file is stored in HashiCorp Vault Dedicated as a base64-encoded string. + * The type of the file (SSO, PKCS12, or PEM) must be explicitly provided, + * and the method processes the file data accordingly, extracting keys and + * certificates, and creating an SSLContext. + *

+ * + * @param parameterValues The parameters required to access the file, + * including the vault URL, the secret name, password (if applicable), and + * file type (SSO, PKCS12, PEM). + * @return An initialized SSLContext for establishing secure communications. + * @throws IllegalStateException If the SSLContext cannot be created due to + * errors during processing. + */ + @Override + public SSLContext getSSLContext(Map parameterValues) { + try { + ParameterSet parameterSet = parseParameterValues(parameterValues); + String secretValue = getSecret(parameterValues); + byte[] fileBytes = FileUtils.isBase64Encoded(secretValue.getBytes()) ? + Base64.getDecoder().decode(secretValue) : secretValue.getBytes(); + + char[] password = parameterSet.getOptional(PASSWORD) != null + ? parameterSet.getOptional(PASSWORD).toCharArray() : null; + + String type = parameterSet.getRequired(TYPE); + return TlsUtils.createSSLContext(fileBytes, password, type); + } catch (Exception e) { + throw new IllegalStateException + ("Failed to create SSLContext from the file", e); + } + } + +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedUsernameProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedUsernameProvider.java new file mode 100644 index 00000000..84f15830 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedUsernameProvider.java @@ -0,0 +1,71 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.spi.UsernameProvider; + +import java.util.Map; + +/** + *

+ * A provider for securely retrieving a username stored as a secret + * in HashiCorp Vault Dedicated. + *

+ *

+ * This class implements the {@link UsernameProvider} SPI defined by + * Oracle JDBC and is designed to be instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultDedicatedUsernameProvider + extends HcpVaultDedicatedSecretProvider + implements UsernameProvider { + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultDedicatedUsernameProvider() { + super("username"); + } + + @Override + public String getUsername(Map parameterValues) { + return getSecret(parameterValues); + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/authentication/HcpVaultSecretParameters.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/authentication/HcpVaultSecretParameters.java index 80da8158..99109ce9 100644 --- a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/authentication/HcpVaultSecretParameters.java +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/authentication/HcpVaultSecretParameters.java @@ -72,7 +72,7 @@ public class HcpVaultSecretParameters { public static final String PARAM_HCP_CLIENT_SECRET = "HCP_CLIENT_SECRET"; public static final String PARAM_HCP_CREDENTIALS_FILE = "HCP_CREDENTIALS_FILE"; - private static final String DEFAULT_CREDENTIALS_FILE_PATH = + public static final String DEFAULT_CREDENTIALS_FILE_PATH = System.getProperty("user.home") + "/.config/hcp/creds-cache.json"; private static final String PARAM_AUTHENTICATION = "AUTHENTICATION"; diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretConnectionStringProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretConnectionStringProvider.java new file mode 100644 index 00000000..60f2b8ea --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretConnectionStringProvider.java @@ -0,0 +1,109 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.TNSNames; +import oracle.jdbc.spi.ConnectionStringProvider; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; +import java.util.Map; + +import static oracle.jdbc.provider.util.CommonParameters.TNS_ALIAS; +import static oracle.jdbc.provider.util.FileUtils.isBase64Encoded; + +/** + *

+ * A provider for securely retrieving the connection string from a tnsnames.ora + * file stored in HCP Vault Secrets for use with an Oracle Autonomous Database. + * The tnsnames.ora file can be stored as a base64-encoded secret or as plain + * text. The provider automatically detects the format and processes the + * content accordingly to extract connection strings by alias. + *

+ *

+ * This class implements the {@link ConnectionStringProvider} SPI defined by + * Oracle JDBC and is designed to be instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultSecretConnectionStringProvider + extends HcpVaultSecretProvider + implements ConnectionStringProvider { + + private static final ResourceParameter[] TNS_NAMES_PARAMETERS = { + new ResourceParameter("tnsAlias", TNS_ALIAS) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultSecretConnectionStringProvider() { + super("tnsnames", TNS_NAMES_PARAMETERS); + } + + @Override + public String getConnectionString(Map parameterValues) { + String alias = parseParameterValues(parameterValues).getRequired(TNS_ALIAS); + byte[] secretBytes = getSecret(parameterValues).getBytes(); + + byte[] fileBytes; + if (isBase64Encoded(secretBytes)) { + fileBytes = Base64.getDecoder().decode(secretBytes); + } else { + fileBytes = secretBytes; + } + + TNSNames tnsNames; + try (InputStream inputStream = new ByteArrayInputStream(fileBytes)) { + tnsNames = TNSNames.read(inputStream); + } catch (IOException e) { + throw new IllegalStateException("Failed to read tnsnames.ora content", e); + } + + String connectionString = tnsNames.getConnectionStringByAlias(alias); + if (connectionString == null) { + throw new IllegalArgumentException( + "Alias specified does not exist in tnsnames.ora: " + alias); + } + return connectionString; + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretPasswordProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretPasswordProvider.java new file mode 100644 index 00000000..de4f3142 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretPasswordProvider.java @@ -0,0 +1,71 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.spi.PasswordProvider; + +import java.util.Map; + +/** + *

+ * A provider for retrieving password securely stored in HCP Vault Secrets. + * This provider fetches the password from the Vault and returns it as a character array. + *

+ *

+ * This class implements the {@link PasswordProvider} SPI defined by Oracle JDBC + * and is designed to be instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultSecretPasswordProvider + extends HcpVaultSecretProvider + implements PasswordProvider { + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultSecretPasswordProvider() { + super("password"); + } + + @Override + public char[] getPassword(Map parameterValues) { + return getSecret(parameterValues).toCharArray(); + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretProvider.java new file mode 100644 index 00000000..160ddeb0 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretProvider.java @@ -0,0 +1,88 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.secrets.HcpVaultSecretsManagerFactory; +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.ResourceParameterUtils; + +import java.util.Map; + +import static oracle.jdbc.provider.hashicorp.hcpvaultsecret.authentication.HcpVaultSecretParameters.*; + +/** + *

+ * A provider of secrets from HashiCorp HCP Vault Secrets. This class is designed + * for inheritance by subclasses that implement an + * {@link oracle.jdbc.spi.OracleResourceProvider} SPI defined by the Oracle JDBC + * driver. + *

+ */ +public class HcpVaultSecretProvider extends HcpVaultSecretResourceProvider { + + private static final ResourceParameter[] PARAMETERS = { + new ResourceParameter("secretName", SECRET_NAME), + }; + + protected HcpVaultSecretProvider(String valueType) { + super(valueType, PARAMETERS); + } + + protected HcpVaultSecretProvider(String valueType, ResourceParameter[] additionalParameters) { + super(valueType, ResourceParameterUtils.combineParameters(PARAMETERS, additionalParameters)); + } + + /** + *

+ * Retrieves a secret from HashiCorp HCP Vault Secrets based on parameters + * provided in {@code parameterValues}. This method centralizes secret + * retrieval logic and is used by subclasses implementing + * the {@link oracle.jdbc.spi.OracleResourceProvider} SPI. + *

+ * + * @param parameterValues A map of parameter names and their corresponding + * -values required for secret retrieval. Must not be null. + * @return The raw secret value as a {@code String}. + */ + protected final String getSecret(Map parameterValues) { + Map resolvedValues = + resolveMissingParameters(parameterValues, HcpVaultSecretResourceProvider.PARAMETERS); + return getResource(HcpVaultSecretsManagerFactory.getInstance(), resolvedValues); + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretResourceProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretResourceProvider.java new file mode 100644 index 00000000..8e1d20b7 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretResourceProvider.java @@ -0,0 +1,101 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.authentication.HcpVaultAuthenticationMethod; +import oracle.jdbc.provider.hashicorp.util.AbstractVaultResourceProvider; +import oracle.jdbc.provider.resource.ResourceParameter; + +import java.util.stream.Stream; + +import static oracle.jdbc.provider.hashicorp.hcpvaultsecret.authentication.HcpVaultSecretParameters.*; + +/** + * Super class of all {@code OracleResourceProvider} implementations + * that request a resource from HCP Vault Secrets. This class defines + * parameters for authentication with HCP Vault Secrets. + */ +public class HcpVaultSecretResourceProvider extends AbstractVaultResourceProvider { + + static final ResourceParameter[] PARAMETERS = { + new ResourceParameter("authenticationMethod", AUTHENTICATION_METHOD, + "auto-detect", + HcpVaultSecretResourceProvider::parseAuthenticationMethod), + new ResourceParameter("orgId", HCP_ORG_ID), + new ResourceParameter("projectId", HCP_PROJECT_ID), + new ResourceParameter("appName", HCP_APP_NAME), + new ResourceParameter("clientId", HCP_CLIENT_ID), + new ResourceParameter("clientSecret", HCP_CLIENT_SECRET), + new ResourceParameter("credentialsFile", HCP_CREDENTIALS_FILE, DEFAULT_CREDENTIALS_FILE_PATH), + }; + + protected HcpVaultSecretResourceProvider(String resourceType, ResourceParameter... additionalParameters) { + super("hcpvault-secrets", resourceType, + Stream.concat( + Stream.of(PARAMETERS), + Stream.of(additionalParameters)) + .toArray(ResourceParameter[]::new)); + } + + private static HcpVaultAuthenticationMethod parseAuthenticationMethod(String method) { + switch (method) { + case "client-credentials": + return HcpVaultAuthenticationMethod.CLIENT_CREDENTIALS; + case "cli-credentials-file": + return HcpVaultAuthenticationMethod.CLI_CREDENTIALS_FILE; + case "auto-detect": + return HcpVaultAuthenticationMethod.AUTO_DETECT; + default: + throw new IllegalArgumentException("Unrecognized authentication method: " + method); + } + } + + @Override + protected String getEnvVariableForParameter(String paramName) { + switch (paramName) { + case "orgId": return PARAM_HCP_ORG_ID; + case "projectId": return PARAM_HCP_PROJECT_ID; + case "appName": return PARAM_HCP_APP_NAME; + case "clientId": return PARAM_HCP_CLIENT_ID; + case "clientSecret": return PARAM_HCP_CLIENT_SECRET; + case "credentialsFile": return PARAM_HCP_CREDENTIALS_FILE; + default: return paramName; + } + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretSEPSProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretSEPSProvider.java new file mode 100644 index 00000000..50afe27f --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretSEPSProvider.java @@ -0,0 +1,115 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.parameter.ParameterSet; +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.FileUtils; +import oracle.jdbc.provider.util.WalletUtils; +import oracle.jdbc.spi.OracleResourceProvider; +import oracle.jdbc.spi.PasswordProvider; +import oracle.jdbc.spi.UsernameProvider; + +import java.util.Base64; +import java.util.Map; + +import static oracle.jdbc.provider.util.CommonParameters.CONNECTION_STRING_INDEX; +import static oracle.jdbc.provider.util.CommonParameters.PASSWORD; + +/** + *

+ * A provider for Secure External Password Store (SEPS) credentials used + * to establish secure authentication with an Oracle database. The wallet is + * retrieved from HCP Vault Secrets, where it is stored as a base64-encoded string. + *

+ *

+ * This provider supports retrieving both **username** and **password** from + * the wallet. It can handle both **SSO** and **PKCS12**-based wallets. + *

+ *

+ * This class implements the {@link UsernameProvider} and + * {@link PasswordProvider} SPIs defined by Oracle JDBC and is designed to be + * instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultSecretSEPSProvider + extends HcpVaultSecretProvider + implements UsernameProvider, PasswordProvider { + + private static final ResourceParameter[] SEPS_PARAMETERS = { + new ResourceParameter("walletPassword", PASSWORD), + new ResourceParameter("connectionStringIndex", CONNECTION_STRING_INDEX) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultSecretSEPSProvider() { + super("seps", SEPS_PARAMETERS); + } + + @Override + public String getUsername(Map parameterValues) { + return getWalletCredentials(parameterValues).username(); + } + + @Override + public char[] getPassword(Map parameterValues) { + return getWalletCredentials(parameterValues).password(); + } + + private WalletUtils.Credentials getWalletCredentials( + Map parameterValues) { + ParameterSet parameterSet = parseParameterValues(parameterValues); + + String secretValue = getSecret(parameterValues); + + byte[] walletBytes = FileUtils.isBase64Encoded(secretValue.getBytes()) + ? Base64.getDecoder().decode(secretValue) + : secretValue.getBytes(); + + char[] walletPassword = parameterSet.getOptional(PASSWORD) != null + ? parameterSet.getOptional(PASSWORD).toCharArray() + : null; + + String connectionStringIndex = parameterSet.getOptional(CONNECTION_STRING_INDEX); + return WalletUtils.getCredentials(walletBytes, walletPassword, connectionStringIndex); + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretTCPSProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretTCPSProvider.java new file mode 100644 index 00000000..13db83fd --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretTCPSProvider.java @@ -0,0 +1,110 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.parameter.ParameterSet; +import oracle.jdbc.provider.resource.ResourceParameter; +import oracle.jdbc.provider.util.FileUtils; +import oracle.jdbc.provider.util.TlsUtils; +import oracle.jdbc.spi.TlsConfigurationProvider; + +import javax.net.ssl.SSLContext; +import java.util.Base64; +import java.util.Map; + +import static oracle.jdbc.provider.util.CommonParameters.PASSWORD; +import static oracle.jdbc.provider.util.CommonParameters.TYPE; + +/** + *

+ * A provider for TCPS/TLS files used to establish secure TLS communication + * with an Autonomous Database. The file is retrieved from HCP Vault Secrets, + * where it is stored as a base64-encoded string. This provider supports + * different file types including SSO, PKCS12, and PEM formats. + *

+ *

+ * The type of the file must be explicitly specified using the {@code type} + * parameter. Based on the type, the file may contain private keys and + * certificates for establishing secure communication. A password is only + * required for PKCS12 or encrypted PEM files. + *

+ *

+ * This class implements the {@link TlsConfigurationProvider} SPI defined by + * Oracle JDBC and is designed to be instantiated via + * {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultSecretTCPSProvider + extends HcpVaultSecretProvider + implements TlsConfigurationProvider { + + private static final ResourceParameter[] TCPS_PARAMETERS = { + new ResourceParameter("walletPassword", PASSWORD), + new ResourceParameter("type", TYPE) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultSecretTCPSProvider() { + super("tls", TCPS_PARAMETERS); + } + + @Override + public SSLContext getSSLContext(Map parameterValues) { + try { + ParameterSet parameterSet = parseParameterValues(parameterValues); + String secretValue = getSecret(parameterValues); + + byte[] fileBytes = FileUtils.isBase64Encoded(secretValue.getBytes()) + ? Base64.getDecoder().decode(secretValue) + : secretValue.getBytes(); + + char[] password = parameterSet.getOptional(PASSWORD) != null + ? parameterSet.getOptional(PASSWORD).toCharArray() + : null; + + String type = parameterSet.getRequired(TYPE); + return TlsUtils.createSSLContext(fileBytes, password, type); + } catch (Exception e) { + throw new IllegalStateException("Failed to create SSLContext from the file", e); + } + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretUsernameProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretUsernameProvider.java new file mode 100644 index 00000000..c0d24dbf --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSecretUsernameProvider.java @@ -0,0 +1,71 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.spi.UsernameProvider; + +import java.util.Map; + +/** + *

+ * A provider for securely retrieving a username stored as a secret + * in HashiCorp HCP Vault Secrets. + *

+ *

+ * This class implements the {@link UsernameProvider} SPI defined by + * Oracle JDBC and is designed to be instantiated via {@link java.util.ServiceLoader}. + *

+ */ +public class HcpVaultSecretUsernameProvider + extends HcpVaultSecretProvider + implements UsernameProvider { + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public HcpVaultSecretUsernameProvider() { + super("username"); + } + + @Override + public String getUsername(Map parameterValues) { + return getSecret(parameterValues); + } +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/AbstractVaultResourceProvider.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/AbstractVaultResourceProvider.java new file mode 100644 index 00000000..ea3ae8eb --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/AbstractVaultResourceProvider.java @@ -0,0 +1,91 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.util; + +import oracle.jdbc.provider.resource.AbstractResourceProvider; +import oracle.jdbc.provider.resource.ResourceParameter; + +import java.util.HashMap; +import java.util.Map; + +/** + * Abstract class that encapsulates common behavior for resolving parameters + * from system properties or environment variables. + */ +public abstract class AbstractVaultResourceProvider extends AbstractResourceProvider { + + protected AbstractVaultResourceProvider(String providerType, String resourceType, ResourceParameter[] parameters) { + super(providerType, resourceType, parameters); + } + + /** + * Resolves missing parameters using system properties or environment variables. + * + * @param parameterValues The original parameter map. + * @param parameters The parameters to check. + * @return A map with resolved parameters. + */ + protected Map resolveMissingParameters( + Map parameterValues, ResourceParameter[] parameters) { + + Map resolved = new HashMap<>(parameterValues); + for (ResourceParameter param : parameters) { + resolveParameter(resolved, param); + } + return resolved; + } + + private void resolveParameter(Map parameterValues, ResourceParameter parameter) { + if (!parameterValues.containsKey(parameter)) { + String envKey = getEnvVariableForParameter(parameter.name()); + String value = System.getProperty(envKey, System.getenv(envKey)); + if (value != null) { + parameterValues.put(parameter, value); + } + } + } + + /** + * Subclasses must define how parameter names map to env vars or sys props. + * + * @param paramName The parameter name + * @return Corresponding environment variable or system property key + */ + protected abstract String getEnvVariableForParameter(String paramName); +} diff --git a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/JsonUtil.java b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/JsonUtil.java index 8c12dd5d..5735187a 100644 --- a/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/JsonUtil.java +++ b/ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/util/JsonUtil.java @@ -80,4 +80,32 @@ public static String extractField(OracleJsonObject jsonObject, String fieldName) } throw new IllegalStateException("Missing field '" + fieldName + "' in the response JSON."); } + + /** + * Extracts the secret value from the given JSON object based on the field name. + * + *

Logic:

+ *
    + *
  • If {@code fieldName} is provided and exists in the JSON, return its value.
  • + *
  • If the JSON contains only one key-value pair, return that value automatically.
  • + *
  • If multiple keys exist and no {@code fieldName} is provided, throw an error.
  • + *
+ * + * @param secretJsonObj The JSON object containing the secret. + * @param fieldName The field name to extract (optional). + * @return The extracted secret value as a string. + * @throws IllegalStateException If multiple keys exist but no `fieldName` is specified. + */ + public static String extractSecret(OracleJsonObject secretJsonObj, String fieldName) { + if (fieldName != null && secretJsonObj.containsKey(fieldName)) { + return secretJsonObj.getString(fieldName); + } else if (secretJsonObj.size() == 1) { + String firstKey = secretJsonObj.keySet().iterator().next(); + return secretJsonObj.getString(firstKey); + } else { + throw new IllegalStateException( + "FIELD_NAME is required when multiple keys exist in the secret." + ); + } + } } \ No newline at end of file diff --git a/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.ConnectionStringProvider b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.ConnectionStringProvider new file mode 100644 index 00000000..4d20243a --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.ConnectionStringProvider @@ -0,0 +1,2 @@ +oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource.HcpVaultDedicatedConnectionStringProvider +oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource.HcpVaultSecretConnectionStringProvider \ No newline at end of file diff --git a/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.PasswordProvider b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.PasswordProvider new file mode 100644 index 00000000..a57a51ad --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.PasswordProvider @@ -0,0 +1,4 @@ +oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource.HcpVaultDedicatedPasswordProvider +oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource.HcpVaultDedicatedSEPSProvider +oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource.HcpVaultSecretPasswordProvider +oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource.HcpVaultSecretSEPSProvider diff --git a/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.TlsConfigurationProvider b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.TlsConfigurationProvider new file mode 100644 index 00000000..b60fb543 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.TlsConfigurationProvider @@ -0,0 +1,2 @@ +oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource.HcpVaultDedicatedTCPSProvider +oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource.HcpVaultSecretTCPSProvider \ No newline at end of file diff --git a/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.UsernameProvider b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.UsernameProvider new file mode 100644 index 00000000..7709bdb2 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/main/resources/META-INF/services/oracle.jdbc.spi.UsernameProvider @@ -0,0 +1,4 @@ +oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource.HcpVaultDedicatedUsernameProvider +oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource.HcpVaultDedicatedSEPSProvider +oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource.HcpVaultSecretUsernameProvider +oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource.HcpVaultSecretSEPSProvider \ No newline at end of file diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultTestProperty.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/DedicatedVaultTestProperty.java similarity index 92% rename from ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultTestProperty.java rename to ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/DedicatedVaultTestProperty.java index 97212117..ef162011 100644 --- a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultTestProperty.java +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/DedicatedVaultTestProperty.java @@ -36,7 +36,7 @@ ** SOFTWARE. */ -package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.configuration; +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated; /** * Enumeration of test properties for Dedicated Vault. @@ -62,5 +62,15 @@ public enum DedicatedVaultTestProperty { SECRET_ID, - GITHUB_TOKEN + PASSWORD_SECRET_PATH, + + TNSNAMES_SECRET_PATH, + + TNSNAMES_ALIAS, + + GITHUB_TOKEN, + + WALLET_SECRET_PATH, + + WALLET_PASSWORD } diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/HcpVaultDedicatedTestUtil.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/HcpVaultDedicatedTestUtil.java new file mode 100644 index 00000000..5d912219 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/HcpVaultDedicatedTestUtil.java @@ -0,0 +1,126 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated; + +import oracle.jdbc.provider.TestProperties; +import org.junit.jupiter.api.Assumptions; + +import java.util.Map; + +import static oracle.jdbc.provider.TestProperties.getOptional; +import static oracle.jdbc.provider.TestProperties.getOrAbort; + +/** + * Utility class for configuring authentication parameters in tests that verify + * implementations of {@link oracle.jdbc.spi.OracleResourceProvider} in the + * ojdbc-provider-hcpvault-dedicated provider. + */ +public final class HcpVaultDedicatedTestUtil { + + private HcpVaultDedicatedTestUtil() { } + + /** + * Configures authentication parameters for HashiCorp Vault Dedicated based on + * values from a test.properties file. If the "authenticationMethod" is already set, + * it verifies required parameters. If "auto-detect" is used, it selects the first + * available method from the test properties. + * + * @param testParameters The parameter map used for authentication. + */ + public static void configureAuthentication(Map testParameters) { + testParameters.putIfAbsent("authenticationMethod", "auto-detect"); + String authMethod = testParameters.get("authenticationMethod"); + + switch (authMethod) { + case "vault-token": + testParameters.put("vaultToken", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_TOKEN)); + break; + case "approle": + testParameters.put("roleId", getOrAbort(DedicatedVaultTestProperty.ROLE_ID)); + testParameters.put("secretId", getOrAbort(DedicatedVaultTestProperty.SECRET_ID)); + break; + case "userpass": + testParameters.put("vaultUsername", getOrAbort(DedicatedVaultTestProperty.VAULT_USERNAME)); + testParameters.put("vaultPassword", getOrAbort(DedicatedVaultTestProperty.VAULT_PASSWORD)); + break; + case "github": + testParameters.put("githubToken", getOrAbort(DedicatedVaultTestProperty.GITHUB_TOKEN)); + break; + case "auto-detect": + if (!configureAutoDetect(testParameters)) + Assumptions.abort("No valid authentication method found for auto-detect."); + break; + default: + throw new IllegalArgumentException("Unsupported authentication method: " + authMethod); + } + } + + /** + * Auto-detects the first available authentication method and configures the necessary parameters. + * If no valid method is found, it returns {@code false}. + * + * @param testParameters The parameter map to populate. + * @return {@code true} if a valid authentication method was found, otherwise {@code false}. + */ + private static boolean configureAutoDetect(Map testParameters) { + return setIfAvailable(testParameters, "vaultToken", DedicatedVaultTestProperty.VAULT_TOKEN) || + (setIfAvailable(testParameters, "roleId", DedicatedVaultTestProperty.ROLE_ID) && + setIfAvailable(testParameters, "secretId", DedicatedVaultTestProperty.SECRET_ID)) || + (setIfAvailable(testParameters, "vaultUsername", DedicatedVaultTestProperty.VAULT_USERNAME) && + setIfAvailable(testParameters, "vaultPassword", DedicatedVaultTestProperty.VAULT_PASSWORD)) || + setIfAvailable(testParameters, "githubToken", DedicatedVaultTestProperty.GITHUB_TOKEN); + } + + /** + * Retrieves an optional test property and adds it to the parameters if available. + * + * @param testParameters The parameter map to populate. + * @param key The parameter key. + * @param property The test property to retrieve. + * @return {@code true} if the value was added, otherwise {@code false}. + */ + private static boolean setIfAvailable(Map testParameters, String key, DedicatedVaultTestProperty property) { + String value = getOptional(property); + if (value != null) { + testParameters.put(key, value); + return true; + } + return false; + } +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultConfigurationProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultConfigurationProviderTest.java index b321543c..d3de44ad 100644 --- a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultConfigurationProviderTest.java +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/configuration/DedicatedVaultConfigurationProviderTest.java @@ -39,6 +39,7 @@ package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.configuration; import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.DedicatedVaultTestProperty; import oracle.jdbc.spi.OracleConfigurationProvider; import org.junit.jupiter.api.Test; diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedConnectionStringProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedConnectionStringProviderTest.java new file mode 100644 index 00000000..08f9e297 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedConnectionStringProviderTest.java @@ -0,0 +1,148 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.DedicatedVaultTestProperty; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.HcpVaultDedicatedTestUtil; +import oracle.jdbc.spi.ConnectionStringProvider; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultDedicatedConnectionStringProviderTest { + + private static final ConnectionStringProvider PROVIDER = + findProvider(ConnectionStringProvider.class, "ojdbc-provider-hcpvault-dedicated-tnsnames"); + + /** + * Verifies that {@link ConnectionStringProvider#getParameters()} includes parameters + * to configure a vault URL and secret name. + */ + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter vaultAddrParameter = + parameters.stream() + .filter(parameter -> "vaultAddr".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(vaultAddrParameter.isSensitive()); + assertNull(vaultAddrParameter.defaultValue()); + + Parameter secretPathParameter = + parameters.stream() + .filter(parameter -> "secretPath".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(secretPathParameter.isSensitive()); + assertTrue(secretPathParameter.isRequired()); + assertNull(secretPathParameter.defaultValue()); + + Parameter aliasParameter = + parameters.stream() + .filter(parameter -> "tnsAlias".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(aliasParameter.isSensitive()); + assertTrue(aliasParameter.isRequired()); + assertNull(aliasParameter.defaultValue()); + } + + /** + * Retrieves a connection string using a valid alias from a plain + * text tnsnames.ora. + */ + @Test + public void testRetrieveConnectionStringFromPlainText() { + Map testParameters = new HashMap<>(); + + testParameters.put("vaultAddr", + TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", + TestProperties.getOrAbort(DedicatedVaultTestProperty.TNSNAMES_SECRET_PATH)); + testParameters.put("tnsAlias", + TestProperties.getOrAbort(DedicatedVaultTestProperty.TNSNAMES_ALIAS)); + testParameters.put("fieldName", "tnsnames_plain_text"); + + // Automatically configure authentication + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + + String connectionString = PROVIDER.getConnectionString(parameterValues); + + assertNotNull(connectionString, "Connection string should not be null"); + } + + /** + * Retrieves a connection string using a valid alias from a base64-encoded tnsnames.ora. + */ + @Test + public void testRetrieveConnectionStringFromBase64Encoded() { + Map testParameters = new HashMap<>(); + + testParameters.put("vaultAddr", + TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", + TestProperties.getOrAbort(DedicatedVaultTestProperty.TNSNAMES_SECRET_PATH)); + testParameters.put("tnsAlias", + TestProperties.getOrAbort(DedicatedVaultTestProperty.TNSNAMES_ALIAS)); + testParameters.put("fieldName", "tnsnames_base64"); + + // Automatically configure authentication + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + + String connectionString = PROVIDER.getConnectionString(parameterValues); + + assertNotNull(connectionString, "Connection string should not be null"); + } + +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedPasswordProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedPasswordProviderTest.java new file mode 100644 index 00000000..8749f0c1 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedPasswordProviderTest.java @@ -0,0 +1,113 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.DedicatedVaultTestProperty; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.HcpVaultDedicatedTestUtil; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.PasswordProvider; +import oracle.jdbc.spi.UsernameProvider; +import org.junit.jupiter.api.Test; + + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultDedicatedPasswordProviderTest { + + private static final PasswordProvider PROVIDER = + findProvider(PasswordProvider.class, "ojdbc-provider-hcpvault-dedicated-password"); + + /** + * Verifies that {@link UsernameProvider#getParameters()} includes parameters + * to configure authentication and secret retrieval. + */ + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter vaultAddrParameter = + parameters.stream() + .filter(parameter -> "vaultAddr".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertNull(vaultAddrParameter.defaultValue()); + + Parameter secretPathParameter = + parameters.stream() + .filter(parameter -> "secretPath".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretPathParameter.isRequired()); + assertNull(secretPathParameter.defaultValue()); + + Parameter fieldNameParameter = + parameters.stream() + .filter(parameter -> "fieldName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(fieldNameParameter.isRequired()); + assertNull(fieldNameParameter.defaultValue()); + } + + @Test + public void testRetrievePassword() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.PASSWORD_SECRET_PATH)); + testParameters.put("fieldName", "password"); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = + createParameterValues(PROVIDER, testParameters); + + char[] password = PROVIDER.getPassword(parameterValues); + + assertNotNull(password, "Password should not be null"); + } + +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSEPSProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSEPSProviderTest.java new file mode 100644 index 00000000..22a72be0 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedSEPSProviderTest.java @@ -0,0 +1,182 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.DedicatedVaultTestProperty; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.HcpVaultDedicatedTestUtil; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.PasswordProvider; +import oracle.jdbc.spi.UsernameProvider; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultDedicatedSEPSProviderTest { + + private static final UsernameProvider USERNAME_PROVIDER = findProvider( + UsernameProvider.class, "ojdbc-provider-hcpvault-dedicated-seps"); + + private static final PasswordProvider PASSWORD_PROVIDER = findProvider( + PasswordProvider.class, "ojdbc-provider-hcpvault-dedicated-seps"); + + @Test + public void testProviderParameters() { + Collection usernameParameters = + USERNAME_PROVIDER.getParameters(); + Collection passwordParameters = + PASSWORD_PROVIDER.getParameters(); + + // Verify both providers have the same parameters + assertEquals(usernameParameters, passwordParameters, + "Username and Password providers should have identical parameters"); + + assertNotNull(usernameParameters); + assertNotNull(passwordParameters); + + Parameter vaultAddrParameter = + usernameParameters.stream() + .filter(parameter -> "vaultAddr".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(vaultAddrParameter.isSensitive()); + assertNull(vaultAddrParameter.defaultValue()); + + Parameter secretPathParameter = + usernameParameters.stream() + .filter(parameter -> "secretPath".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(secretPathParameter.isSensitive()); + assertTrue(secretPathParameter.isRequired()); + assertNull(secretPathParameter.defaultValue()); + + Parameter walletPasswordParameter = + usernameParameters.stream() + .filter(parameter -> "walletPassword".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(walletPasswordParameter.isSensitive()); + assertNull(walletPasswordParameter.defaultValue()); + + Parameter connStringParameter = + usernameParameters.stream() + .filter(parameter -> "connectionStringIndex".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(connStringParameter.isSensitive()); + assertNull(connStringParameter.defaultValue()); + } + + @Test + public void testRetrieveUsernameFromPKCS12() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("fieldName", "base64-seps-p12"); + testParameters.put("walletPassword", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_PASSWORD)); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(USERNAME_PROVIDER, testParameters); + String username = USERNAME_PROVIDER.getUsername(parameterValues); + + assertNotNull(username); + } + + @Test + public void testRetrievePasswordFromPKCS12() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("fieldName", "base64-seps-p12"); + testParameters.put("walletPassword", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_PASSWORD)); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PASSWORD_PROVIDER, testParameters); + char[] password = PASSWORD_PROVIDER.getPassword(parameterValues); + + assertNotNull(password); + } + + /** + * Test retrieving a password from an SSO SEPS wallet with a connection + * string index. + */ + @Test + public void testRetrievePasswordFromSSO() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("fieldName", "base64-seps-sso"); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PASSWORD_PROVIDER, testParameters); + char[] password = PASSWORD_PROVIDER.getPassword(parameterValues); + assertNotNull(password); + } + + /** + * Test retrieving a username from an SSO SEPS wallet without specifying a connection string index. + */ + @Test + public void testRetrieveUsernameFromSSO() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("fieldName", "base64-seps-sso"); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(USERNAME_PROVIDER, testParameters); + String username = USERNAME_PROVIDER.getUsername(parameterValues); + assertNotNull(username); + } + + + +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedTCPSProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedTCPSProviderTest.java new file mode 100644 index 00000000..be2eb131 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedTCPSProviderTest.java @@ -0,0 +1,198 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.DedicatedVaultTestProperty; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.HcpVaultDedicatedTestUtil; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.TlsConfigurationProvider; +import org.junit.jupiter.api.Test; + +import javax.net.ssl.SSLContext; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultDedicatedTCPSProviderTest { + + private static final TlsConfigurationProvider PROVIDER = findProvider( + TlsConfigurationProvider.class, "ojdbc-provider-hcpvault-dedicated-tls"); + + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter vaultAddrParameter = + parameters.stream() + .filter(parameter -> "vaultAddr".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(vaultAddrParameter.isSensitive()); + assertNull(vaultAddrParameter.defaultValue()); + + Parameter secretPathParameter = + parameters.stream() + .filter(parameter -> "secretPath".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(secretPathParameter.isSensitive()); + assertTrue(secretPathParameter.isRequired()); + assertNull(secretPathParameter.defaultValue()); + + Parameter typeParameter = + parameters.stream() + .filter(parameter -> "type".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(typeParameter.isSensitive()); + assertTrue(typeParameter.isRequired()); + assertNull(typeParameter.defaultValue()); + + Parameter walletPasswordParameter = + parameters.stream() + .filter(parameter -> "walletPassword".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(walletPasswordParameter.isSensitive()); + assertFalse(walletPasswordParameter.isRequired()); + assertNull(walletPasswordParameter.defaultValue()); + } + + /** + * Test retrieving an SSLContext from a PKCS12 TCPS wallet. + */ + @Test + public void testRetrieveSSLContextFromPKCS12() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("type", "PKCS12"); + testParameters.put("fieldName", "base64-wallet-p12"); + testParameters.put("walletPassword", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_PASSWORD)); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + SSLContext sslContext = PROVIDER.getSSLContext(parameterValues); + + assertNotNull(sslContext); + } + + /** + * Test retrieving an SSLContext from an SSO TCPS wallet. + */ + @Test + public void testRetrieveSSLContextFromSSO() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("type", "SSO"); + testParameters.put("fieldName", "base64-wallet-sso"); + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + SSLContext sslContext = PROVIDER.getSSLContext(parameterValues); + + assertNotNull(sslContext); + } + + /** + * Test retrieving an SSLContext from a PEM TCPS wallet. + */ + @Test + public void testRetrieveSSLContextFromPEM() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("type", "PEM"); + testParameters.put("fieldName", "base64-wallet-pem"); + testParameters.put("walletPassword", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_PASSWORD)); + + + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + SSLContext sslContext = PROVIDER.getSSLContext(parameterValues); + + assertNotNull(sslContext); + } + + /** + * Test missing password for a PKCS12 TCPS wallet. + */ + @Test + public void testPKCS12MissingPassword() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("type", "PKCS12"); + testParameters.put("fieldName", "base64-wallet-p12"); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + + assertThrows(IllegalStateException.class, () -> { + PROVIDER.getSSLContext(parameterValues); + }); + } + + /** + * Test missing password for a PEM TCPS wallet. + */ + @Test + public void testPemMissingPassword() { + Map testParameters = new HashMap<>(); + testParameters.put("vaultAddr", TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", TestProperties.getOrAbort(DedicatedVaultTestProperty.WALLET_SECRET_PATH)); + testParameters.put("type", "PEM"); + testParameters.put("fieldName", "base64-wallet-pem"); + + Map parameterValues = createParameterValues(PROVIDER, testParameters); + + assertThrows(IllegalStateException.class, () -> { + PROVIDER.getSSLContext(parameterValues); + }); + } +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedUsernameProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedUsernameProviderTest.java new file mode 100644 index 00000000..f8e4e817 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultdedicated/resource/HcpVaultDedicatedUsernameProviderTest.java @@ -0,0 +1,115 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultdedicated.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.DedicatedVaultTestProperty; +import oracle.jdbc.provider.hashicorp.hcpvaultdedicated.HcpVaultDedicatedTestUtil; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.UsernameProvider; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + + +public class HcpVaultDedicatedUsernameProviderTest { + + private static final UsernameProvider PROVIDER = + findProvider(UsernameProvider.class, "ojdbc-provider-hcpvault-dedicated-username"); + + /** + * Verifies that {@link UsernameProvider#getParameters()} includes parameters + * to configure authentication and secret retrieval. + */ + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter vaultAddrParameter = + parameters.stream() + .filter(parameter -> "vaultAddr".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertNull(vaultAddrParameter.defaultValue()); + + Parameter secretPathParameter = + parameters.stream() + .filter(parameter -> "secretPath".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretPathParameter.isRequired()); + assertNull(secretPathParameter.defaultValue()); + + Parameter fieldNameParameter = + parameters.stream() + .filter(parameter -> "fieldName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertFalse(fieldNameParameter.isRequired()); + assertNull(fieldNameParameter.defaultValue()); + } + + @Test + public void testRetrieveUsername() { + Map testParameters = new HashMap<>(); + + testParameters.put("vaultAddr", + TestProperties.getOrAbort(DedicatedVaultTestProperty.VAULT_ADDR)); + testParameters.put("secretPath", + TestProperties.getOrAbort(DedicatedVaultTestProperty.PASSWORD_SECRET_PATH)); + testParameters.put("fieldName", "username"); + + // Automatically configure authentication + HcpVaultDedicatedTestUtil.configureAuthentication(testParameters); + + Map parameterValues = + createParameterValues(PROVIDER, testParameters); + + String username = PROVIDER.getUsername(parameterValues); + + assertNotNull(username, "Username should not be null"); + } +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultTestProperty.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/HcpVaultTestProperty.java similarity index 87% rename from ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultTestProperty.java rename to ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/HcpVaultTestProperty.java index c69eb5de..52f0c770 100644 --- a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultTestProperty.java +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/HcpVaultTestProperty.java @@ -36,7 +36,7 @@ ** SOFTWARE. */ -package oracle.jdbc.provider.hashicorp.hcpvaultsecret.configuration; +package oracle.jdbc.provider.hashicorp.hcpvaultsecret; /** * Enumeration of test properties for HCP Vault. @@ -58,5 +58,25 @@ public enum HcpVaultTestProperty { KEY, + CONNECTION_STRING_BASE64, + + CONNECTION_STRING_PLAIN_TEXT, + + TNSNAMES_ALIAS, + + USERNAME_SECRET_NAME, + + WALLET_P12_SECRET_NAME, + + WALLET_PASSWORD, + + WALLET_SSO_SECRET_NAME, + + WALLET_PEM_SECRET_NAME, + + WALLET_SECRET_PKCS12_NAME, + + WALLET_SECRET_SSO_NAME, + HCP_CREDENTIALS_FILE } diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/HcpVaultTestUtil.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/HcpVaultTestUtil.java new file mode 100644 index 00000000..54fd0190 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/HcpVaultTestUtil.java @@ -0,0 +1,97 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret; + +import oracle.jdbc.provider.TestProperties; +import org.junit.jupiter.api.Assumptions; + +import java.util.Map; + +/** + * Utility class for configuring authentication parameters in tests that verify + * implementations of {@link oracle.jdbc.spi.OracleResourceProvider} in the + * ojdbc-provider-hcpvault-secrets provider. + */ +public final class HcpVaultTestUtil { + + private HcpVaultTestUtil() { } + + public static void configureAuthentication(Map testParameters) { + testParameters.putIfAbsent("authenticationMethod", "auto-detect"); + String authMethod = testParameters.get("authenticationMethod"); + + switch (authMethod) { + case "client-credentials": + testParameters.put("clientId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_CLIENT_ID)); + testParameters.put("clientSecret", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_CLIENT_SECRET)); + break; + case "cli-credentials-file": + testParameters.put("credentialsFile", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_CREDENTIALS_FILE)); + break; + case "auto-detect": + if (!configureAutoDetect(testParameters)) + Assumptions.abort("No valid authentication method found for auto-detect."); + break; + default: + throw new IllegalArgumentException("Unsupported authentication method: " + authMethod); + } + + testParameters.put("orgId", + TestProperties.getOrAbort(HcpVaultTestProperty.HCP_ORG_ID)); + testParameters.put("projectId", + TestProperties.getOrAbort(HcpVaultTestProperty.HCP_PROJECT_ID)); + testParameters.put("appName", + TestProperties.getOrAbort(HcpVaultTestProperty.HCP_APP_NAME)); + } + + private static boolean configureAutoDetect(Map testParameters) { + return setIfAvailable(testParameters, "clientId", HcpVaultTestProperty.HCP_CLIENT_ID) && + setIfAvailable(testParameters, "clientSecret", HcpVaultTestProperty.HCP_CLIENT_SECRET) || + setIfAvailable(testParameters, "credentialsFile", HcpVaultTestProperty.HCP_CREDENTIALS_FILE); + } + + private static boolean setIfAvailable(Map testParameters, String key, HcpVaultTestProperty property) { + String value = TestProperties.getOptional(property); + if (value != null) { + testParameters.put(key, value); + return true; + } + return false; + } +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultConfigurationProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultConfigurationProviderTest.java index dcee9b56..afc05f9b 100644 --- a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultConfigurationProviderTest.java +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/configuration/HcpVaultConfigurationProviderTest.java @@ -39,6 +39,7 @@ package oracle.jdbc.provider.hashicorp.hcpvaultsecret.configuration; import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestProperty; import oracle.jdbc.spi.OracleConfigurationProvider; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultConnectionStringProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultConnectionStringProviderTest.java new file mode 100644 index 00000000..3ca32be2 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultConnectionStringProviderTest.java @@ -0,0 +1,143 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestUtil; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestProperty; +import oracle.jdbc.spi.ConnectionStringProvider; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultConnectionStringProviderTest { + + private static final ConnectionStringProvider PROVIDER = + findProvider(ConnectionStringProvider.class, "ojdbc-provider-hcpvault-secrets-tnsnames"); + + + /** + * Verifies that {@link ConnectionStringProvider#getParameters()} includes parameters + * to configure authentication and secret retrieval. + */ + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter secretNameParameter = + parameters.stream() + .filter(parameter -> "secretName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretNameParameter.isRequired()); + assertNull(secretNameParameter.defaultValue()); + + Parameter tnsAliasParameter = + parameters.stream() + .filter(parameter -> "tnsAlias".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(tnsAliasParameter.isRequired()); + assertNull(tnsAliasParameter.defaultValue()); + + Parameter orgIdParameter = + parameters.stream() + .filter(parameter -> "orgId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(orgIdParameter.isRequired()); + assertNull(orgIdParameter.defaultValue()); + + Parameter appNameParameter = + parameters.stream() + .filter(parameter -> "appName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(appNameParameter.isRequired()); + assertNull(appNameParameter.defaultValue()); + + Parameter projectIdParameter = + parameters.stream() + .filter(parameter -> "projectId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(projectIdParameter.isRequired()); + assertNull(projectIdParameter.defaultValue()); + } + + @Test + public void testRetrieveConnectionStringFromBase64Encoded() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.CONNECTION_STRING_BASE64)); + testParams.put("tnsAlias", TestProperties.getOrAbort(HcpVaultTestProperty.TNSNAMES_ALIAS)); + testParams.put("orgId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_ORG_ID)); + testParams.put("projectId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_PROJECT_ID)); + testParams.put("appName", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_APP_NAME)); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + String connectionString = PROVIDER.getConnectionString(values); + + assertNotNull(connectionString); + } + + @Test + public void testRetrieveConnectionStringFromPlainText() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.CONNECTION_STRING_PLAIN_TEXT)); + testParams.put("tnsAlias", TestProperties.getOrAbort(HcpVaultTestProperty.TNSNAMES_ALIAS)); + testParams.put("orgId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_ORG_ID)); + testParams.put("projectId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_PROJECT_ID)); + testParams.put("appName", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_APP_NAME)); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + String connectionString = PROVIDER.getConnectionString(values); + + assertNotNull(connectionString); + } +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultPasswordProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultPasswordProviderTest.java new file mode 100644 index 00000000..5ff5de4d --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultPasswordProviderTest.java @@ -0,0 +1,119 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestUtil; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestProperty; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.PasswordProvider; +import oracle.jdbc.spi.UsernameProvider; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultPasswordProviderTest { + + private static final PasswordProvider PROVIDER = + findProvider(PasswordProvider.class, "ojdbc-provider-hcpvault-secrets-password"); + + + /** + * Verifies that {@link UsernameProvider#getParameters()} includes parameters + * to configure authentication and secret retrieval. + */ + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter secretNameParameter = + parameters.stream() + .filter(parameter -> "secretName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretNameParameter.isRequired()); + assertNull(secretNameParameter.defaultValue()); + + Parameter orgIdParameter = + parameters.stream() + .filter(parameter -> "orgId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(orgIdParameter.isRequired()); + assertNull(orgIdParameter.defaultValue()); + + Parameter appNameParameter = + parameters.stream() + .filter(parameter -> "appName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(appNameParameter.isRequired()); + assertNull(appNameParameter.defaultValue()); + + Parameter projectIdParameter = + parameters.stream() + .filter(parameter -> "projectId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(projectIdParameter.isRequired()); + assertNull(projectIdParameter.defaultValue()); + } + + @Test + public void testRetrievePassword() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.USERNAME_SECRET_NAME)); + testParams.put("orgId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_ORG_ID)); + testParams.put("projectId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_PROJECT_ID)); + testParams.put("appName", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_APP_NAME)); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + char[] password = PROVIDER.getPassword(values); + + assertNotNull(password); + } +} diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSEPSProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSEPSProviderTest.java new file mode 100644 index 00000000..97955310 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultSEPSProviderTest.java @@ -0,0 +1,164 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestUtil; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestProperty; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.PasswordProvider; +import oracle.jdbc.spi.UsernameProvider; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultSEPSProviderTest { + + private static final UsernameProvider USERNAME_PROVIDER = findProvider( + UsernameProvider.class, "ojdbc-provider-hcpvault-secrets-seps"); + + private static final PasswordProvider PASSWORD_PROVIDER = findProvider( + PasswordProvider.class, "ojdbc-provider-hcpvault-secrets-seps"); + + @Test + public void testGetusernameParams() { + Collection usernameParams = USERNAME_PROVIDER.getParameters(); + Collection passwordParams = PASSWORD_PROVIDER.getParameters(); + + assertEquals(usernameParams, passwordParams); + + Parameter secretNameParameter = + usernameParams.stream() + .filter(parameter -> "secretName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretNameParameter.isRequired()); + assertNull(secretNameParameter.defaultValue()); + + Parameter orgIdParameter = + usernameParams.stream() + .filter(parameter -> "orgId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(orgIdParameter.isRequired()); + assertNull(orgIdParameter.defaultValue()); + + Parameter appNameParameter = + usernameParams.stream() + .filter(parameter -> "appName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(appNameParameter.isRequired()); + assertNull(appNameParameter.defaultValue()); + + Parameter projectIdParameter = + usernameParams.stream() + .filter(parameter -> "projectId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(projectIdParameter.isRequired()); + assertNull(projectIdParameter.defaultValue()); + + + Parameter walletPasswordParameter = + usernameParams.stream() + .filter(parameter -> "walletPassword".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(walletPasswordParameter.isSensitive()); + assertFalse(walletPasswordParameter.isRequired()); + assertNull(walletPasswordParameter.defaultValue()); + } + + @Test + public void testRetrieveUsernameFromPKCS12() { + Map params = new HashMap<>(); + params.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_SECRET_PKCS12_NAME)); + params.put("walletPassword", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_PASSWORD)); + HcpVaultTestUtil.configureAuthentication(params); + + Map values = createParameterValues(USERNAME_PROVIDER, params); + String username = USERNAME_PROVIDER.getUsername(values); + + assertNotNull(username); + } + + @Test + public void testRetrievePasswordFromPKCS12() { + Map params = new HashMap<>(); + params.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_SECRET_PKCS12_NAME)); + params.put("walletPassword", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_PASSWORD)); + HcpVaultTestUtil.configureAuthentication(params); + + Map values = createParameterValues(PASSWORD_PROVIDER, params); + char[] password = PASSWORD_PROVIDER.getPassword(values); + assertNotNull(password); + } + + @Test + public void testRetrieveUsernameFromSSO() { + Map params = new HashMap<>(); + params.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_SECRET_SSO_NAME)); + HcpVaultTestUtil.configureAuthentication(params); + + Map values = createParameterValues(USERNAME_PROVIDER, params); + String username = USERNAME_PROVIDER.getUsername(values); + + assertNotNull(username); + } + + @Test + public void testRetrievePasswordFromSSO() { + Map params = new HashMap<>(); + params.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_SECRET_SSO_NAME)); + HcpVaultTestUtil.configureAuthentication(params); + + Map values = createParameterValues(PASSWORD_PROVIDER, params); + char[] password = PASSWORD_PROVIDER.getPassword(values); + + assertNotNull(password); + } + +} \ No newline at end of file diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultTCPSProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultTCPSProviderTest.java new file mode 100644 index 00000000..6367384c --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultTCPSProviderTest.java @@ -0,0 +1,176 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestUtil; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestProperty; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.TlsConfigurationProvider; +import org.junit.jupiter.api.Test; + +import javax.net.ssl.SSLContext; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultTCPSProviderTest { + + private static final TlsConfigurationProvider PROVIDER = findProvider( + TlsConfigurationProvider.class, "ojdbc-provider-hcpvault-secrets-tls"); + + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter secretNameParameter = + parameters.stream() + .filter(parameter -> "secretName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretNameParameter.isRequired()); + assertNull(secretNameParameter.defaultValue()); + + Parameter orgIdParameter = + parameters.stream() + .filter(parameter -> "orgId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(orgIdParameter.isRequired()); + assertNull(orgIdParameter.defaultValue()); + + Parameter appNameParameter = + parameters.stream() + .filter(parameter -> "appName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(appNameParameter.isRequired()); + assertNull(appNameParameter.defaultValue()); + + Parameter projectIdParameter = + parameters.stream() + .filter(parameter -> "projectId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(projectIdParameter.isRequired()); + assertNull(projectIdParameter.defaultValue()); + + Parameter typeParameter = + parameters.stream() + .filter(parameter -> "type".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(typeParameter.isRequired()); + assertNull(typeParameter.defaultValue()); + + Parameter walletPasswordParameter = + parameters.stream() + .filter(parameter -> "walletPassword".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(walletPasswordParameter.isSensitive()); + assertFalse(walletPasswordParameter.isRequired()); + assertNull(walletPasswordParameter.defaultValue()); + } + + @Test + public void testRetrieveSSLContextFromPKCS12() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_P12_SECRET_NAME)); + testParams.put("type", "PKCS12"); + testParams.put("walletPassword", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_PASSWORD)); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + SSLContext context = PROVIDER.getSSLContext(values); + assertNotNull(context); + } + + @Test + public void testRetrieveSSLContextFromSSO() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_SSO_SECRET_NAME)); + testParams.put("type", "SSO"); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + SSLContext context = PROVIDER.getSSLContext(values); + assertNotNull(context); + } + + @Test + public void testRetrieveSSLContextFromPEM() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_PEM_SECRET_NAME)); + testParams.put("type", "PEM"); + testParams.put("walletPassword", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_PASSWORD)); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + SSLContext context = PROVIDER.getSSLContext(values); + assertNotNull(context); + } + + @Test + public void testMissingPasswordForPKCS12() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_P12_SECRET_NAME)); + testParams.put("type", "PKCS12"); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + assertThrows(IllegalStateException.class, () -> PROVIDER.getSSLContext(values)); + } + + @Test + public void testMissingPasswordForPEM() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.WALLET_PEM_SECRET_NAME)); + testParams.put("type", "PEM"); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + assertThrows(IllegalStateException.class, () -> PROVIDER.getSSLContext(values)); + } +} \ No newline at end of file diff --git a/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultUsernameProviderTest.java b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultUsernameProviderTest.java new file mode 100644 index 00000000..cca26f15 --- /dev/null +++ b/ojdbc-provider-hashicorp/src/test/java/oracle/jdbc/provider/hashicorp/hcpvaultsecret/resource/HcpVaultUsernameProviderTest.java @@ -0,0 +1,118 @@ +/* + ** Copyright (c) 2025 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.hashicorp.hcpvaultsecret.resource; + +import oracle.jdbc.provider.TestProperties; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestUtil; +import oracle.jdbc.provider.hashicorp.hcpvaultsecret.HcpVaultTestProperty; +import oracle.jdbc.spi.OracleResourceProvider.Parameter; +import oracle.jdbc.spi.UsernameProvider; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.createParameterValues; +import static oracle.jdbc.provider.resource.ResourceProviderTestUtil.findProvider; +import static org.junit.jupiter.api.Assertions.*; + +public class HcpVaultUsernameProviderTest { + + private static final UsernameProvider PROVIDER = + findProvider(UsernameProvider.class, "ojdbc-provider-hcpvault-secrets-username"); + + + /** + * Verifies that {@link UsernameProvider#getParameters()} includes parameters + * to configure authentication and secret retrieval. + */ + @Test + public void testGetParameters() { + Collection parameters = PROVIDER.getParameters(); + assertNotNull(parameters); + + Parameter secretNameParameter = + parameters.stream() + .filter(parameter -> "secretName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(secretNameParameter.isRequired()); + assertNull(secretNameParameter.defaultValue()); + + Parameter orgIdParameter = + parameters.stream() + .filter(parameter -> "orgId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(orgIdParameter.isRequired()); + assertNull(orgIdParameter.defaultValue()); + + Parameter appNameParameter = + parameters.stream() + .filter(parameter -> "appName".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(appNameParameter.isRequired()); + assertNull(appNameParameter.defaultValue()); + + Parameter projectIdParameter = + parameters.stream() + .filter(parameter -> "projectId".equals(parameter.name())) + .findFirst() + .orElseThrow(AssertionError::new); + assertTrue(projectIdParameter.isRequired()); + assertNull(projectIdParameter.defaultValue()); + } + + @Test + public void testRetrieveUsername() { + Map testParams = new HashMap<>(); + testParams.put("secretName", TestProperties.getOrAbort(HcpVaultTestProperty.USERNAME_SECRET_NAME)); + testParams.put("orgId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_ORG_ID)); + testParams.put("projectId", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_PROJECT_ID)); + testParams.put("appName", TestProperties.getOrAbort(HcpVaultTestProperty.HCP_APP_NAME)); + HcpVaultTestUtil.configureAuthentication(testParams); + + Map values = createParameterValues(PROVIDER, testParams); + String username = PROVIDER.getUsername(values); + + assertNotNull(username); + } +}