Skip to content

Commit

Permalink
Oci secret retrieval refactor username test (#115)
Browse files Browse the repository at this point in the history
* Refactor secret retrieval to centralize logic in OciResourceProvider

* Rename retrieveSecret to getSecret

* Add Username provider Test

* Add Username provider Test

* Refactor wallet retrieval in OciResourceProvider

* Refactor wallet retrieval in OciResourceProvider

* Refactor resource retrieval logic in AbstractResourceProvider && Rename getSecret to getVaultSecret and getWallet to getAutonomousDatabaseWallet
  • Loading branch information
MouhsinElmajdouby authored Nov 15, 2024
1 parent 84bcc79 commit aa76cc1
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

package oracle.jdbc.provider.resource;

import oracle.jdbc.provider.factory.ResourceFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.parameter.ParameterSetParser;
import oracle.jdbc.spi.OracleResourceProvider;
Expand Down Expand Up @@ -129,4 +130,37 @@ protected final ParameterSet parseParameterValues(
entry -> entry.getValue().toString())));
}

/**
* Requests a resource from a factory using the given parameterValues. This
* method implements the common operations of parsing parameterValues,
* requesting a resource from a factory, and then extracting the content from
* the resource object. Concrete implementations of AbstractResourceProvider
* should use this method whenever possible to avoid duplications of the same
* code pattern.
*
* @param factory Factory to request resources from. Not null.
*
* @param parameterValues Parameters for the request. Not null.
*
* @return The content of the requested resource.
*
* @param <T> The type of resource content.
*
* @throws IllegalArgumentException If {@code parameterValues} includes an
* unrecognized parameter or a value that can not be parsed. Or if the
* {@code parameterValues} does not include a required parameter, or does
* not represent a valid configuration.
*
* @throws IllegalStateException If the request fails to return a resource.
*/
protected <T> T getResource(
ResourceFactory<T> factory, Map<Parameter, CharSequence> parameterValues) {

ParameterSet parameterSet = parseParameterValues(parameterValues);

return factory
.request(parameterSet)
.getContent();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ public String getConnectionString(

ParameterSet parameterSet = parseParameterValues(parameterValues);

Wallet wallet = WalletFactory.getInstance()
.request(parameterSet)
.getContent();
Wallet wallet = getAutonomousDatabaseWallet(parameterValues);

String consumerGroup =
parameterSet.getRequired(CONSUMER_GROUP)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
package oracle.jdbc.provider.oci.resource;

import oracle.jdbc.provider.oci.database.WalletFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.resource.ResourceParameter;
import oracle.jdbc.spi.TlsConfigurationProvider;

Expand Down Expand Up @@ -83,13 +82,8 @@ public DatabaseTlsProvider() {
@Override
public SSLContext getSSLContext(
Map<Parameter, CharSequence> parameterValues) {

ParameterSet parameterSet = parseParameterValues(parameterValues);

return WalletFactory.getInstance()
.request(parameterSet)
.getContent()
.getSSLContext();
return getAutonomousDatabaseWallet(parameterValues)
.getSSLContext();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@
import com.oracle.bmc.Region;
import oracle.jdbc.provider.oci.authentication.AuthenticationDetailsFactory;
import oracle.jdbc.provider.oci.authentication.AuthenticationMethod;
import oracle.jdbc.provider.oci.database.WalletFactory;
import oracle.jdbc.provider.oci.vault.Secret;
import oracle.jdbc.provider.oci.vault.SecretFactory;
import oracle.jdbc.provider.resource.AbstractResourceProvider;
import oracle.jdbc.provider.resource.ResourceParameter;
import oracle.jdbc.provider.util.Wallet;

import java.util.Map;
import java.util.stream.Stream;

import static oracle.jdbc.provider.oci.authentication.AuthenticationMethod.*;
Expand Down Expand Up @@ -127,4 +132,50 @@ private static AuthenticationMethod parseAuthenticationMethod(
}
}

/**
* <p>
* Retrieves a secret from OCI Vault identified by a set of parameters
* provided in {@code parameterValues}. This method is intended to centralize
* secret retrieval logic and can be called by subclasses implementing
* {@link oracle.jdbc.spi.OracleResourceProvider} SPI.
* </p><p>
* This method uses the {@code getResource} method to parse parameters
* from {@code parameterValues} and retrieve the secret from OCI Vault
* through the {@link SecretFactory} instance.
* </p>
*
* @param parameterValues The map of parameter names and their corresponding
* text values required for secret retrieval. Must not be null.
* @return The {@link Secret} object containing the retrieved secret data.
* Not null.
*/
protected Secret getVaultSecret(
Map<Parameter, CharSequence> parameterValues) {
return getResource(SecretFactory.getInstance(),parameterValues);
}

/**
* <p>
* Retrieves a wallet from the Autonomous Database (ADB) service using
* a set of parameters provided in {@code parameterValues}. This method
* centralizes wallet retrieval logic for use by subclasses implementing the
* {@link oracle.jdbc.spi.OracleResourceProvider} SPI.
* </p><p>
* This method uses the {@code getResource} method to parse parameters
* from {@code parameterValues} and retrieve the wallet from the ADB
* service through the {@link WalletFactory} instance. Wallets contain
* connection strings and TLS key and trust material for establishing secure
* connections with the database.
* </p>
*
* @param parameterValues The map of parameter names and their corresponding
* text values required for wallet retrieval. Must not be null.
* @return The {@link Wallet} object containing connection strings and
* TLS material. Not null.
*/
protected Wallet getAutonomousDatabaseWallet(
Map<Parameter, CharSequence> parameterValues) {
return getResource(WalletFactory.getInstance(), parameterValues);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@

package oracle.jdbc.provider.oci.resource;

import oracle.jdbc.provider.oci.vault.SecretFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.resource.ResourceParameter;
import oracle.jdbc.spi.PasswordProvider;

Expand Down Expand Up @@ -74,13 +72,8 @@ public VaultPasswordProvider() {

@Override
public char[] getPassword(Map<Parameter, CharSequence> parameterValues) {

ParameterSet parameterSet = parseParameterValues(parameterValues);

return SecretFactory.getInstance()
.request(parameterSet)
.getContent()
.toCharArray();
return getVaultSecret(parameterValues)
.toCharArray();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
package oracle.jdbc.provider.oci.resource;

import oracle.jdbc.provider.oci.vault.Secret;
import oracle.jdbc.provider.oci.vault.SecretFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.resource.ResourceParameter;
import oracle.jdbc.provider.util.WalletUtils;
Expand Down Expand Up @@ -112,9 +111,7 @@ private WalletUtils.Credentials getWalletCredentials(
Map<OracleResourceProvider.Parameter, CharSequence> parameterValues) {

ParameterSet parameterSet = parseParameterValues(parameterValues);
Secret secret = SecretFactory.getInstance()
.request(parameterSet)
.getContent();
Secret secret = getVaultSecret(parameterValues);

char[] walletPassword = parameterSet.getOptional(PASSWORD) != null
? parameterSet.getOptional(PASSWORD).toCharArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
package oracle.jdbc.provider.oci.resource;

import oracle.jdbc.provider.oci.vault.Secret;
import oracle.jdbc.provider.oci.vault.SecretFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.resource.ResourceParameter;
import oracle.jdbc.provider.util.TlsUtils;
Expand Down Expand Up @@ -114,10 +113,8 @@ public VaultTCPSProvider() {
public SSLContext getSSLContext(Map<Parameter, CharSequence> parameterValues) {
try {
ParameterSet parameterSet = parseParameterValues(parameterValues);
Secret secret = SecretFactory
.getInstance()
.request(parameterSet)
.getContent();

Secret secret = getVaultSecret(parameterValues);

byte[] fileBytes = Base64
.getDecoder()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** Copyright (c) 2023 Oracle and/or its affiliates.
** Copyright (c) 2024 Oracle and/or its affiliates.
**
** The Universal Permissive License (UPL), Version 1.0
**
Expand Down Expand Up @@ -37,8 +37,7 @@
*/
package oracle.jdbc.provider.oci.resource;

import oracle.jdbc.provider.oci.vault.SecretFactory;
import oracle.jdbc.provider.parameter.ParameterSet;
import oracle.jdbc.provider.oci.vault.Secret;
import oracle.jdbc.provider.resource.ResourceParameter;
import oracle.jdbc.spi.UsernameProvider;

Expand Down Expand Up @@ -75,14 +74,9 @@ public VaultUsernameProvider() {
@Override
public String getUsername(Map<Parameter, CharSequence> parameterValues) {

ParameterSet parameterSet = parseParameterValues(parameterValues);
Secret secret = getVaultSecret(parameterValues);

char[] username = SecretFactory.getInstance()
.request(parameterSet)
.getContent()
.toCharArray();

return new String(username);
return new String(secret.toCharArray());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public enum OciTestProperty {

OCI_PASSWORD_OCID,

OCI_USERNAME_OCID,

OCI_DATABASE_OCID,

OCI_OBJECT_STORAGE_URL,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
** Copyright (c) 2023 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.oci.resource;

import oracle.jdbc.provider.TestProperties;
import oracle.jdbc.provider.oci.OciTestProperty;
import oracle.jdbc.spi.OracleResourceProvider.Parameter;
import oracle.jdbc.spi.UsernameProvider;
import org.junit.jupiter.api.Test;

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.assertNotNull;

public class VaultUsernameProviderTest {

private static final UsernameProvider PROVIDER =
findProvider(UsernameProvider.class, "ojdbc-provider-oci-vault-username");

@Test
public void test() {
Map<String, CharSequence> testParameters = new HashMap<>();
testParameters.put("authenticationMethod", "config-file");
testParameters.put("configFile", TestProperties.getOrAbort(
OciTestProperty.OCI_CONFIG_FILE));
testParameters.put("profile", TestProperties.getOrAbort(
OciTestProperty.OCI_CONFIG_PROFILE));
testParameters.put("ocid", TestProperties.getOrAbort(
OciTestProperty.OCI_USERNAME_OCID));

Map<Parameter, CharSequence> parameterValues =
createParameterValues(PROVIDER, testParameters);

String username = PROVIDER.getUsername(parameterValues);
assertNotNull(username);
}
}

0 comments on commit aa76cc1

Please sign in to comment.