Skip to content

Commit c59cc77

Browse files
committed
Adding support for Oracle Wallet (Secure External Password Store)
1 parent 2eb3b53 commit c59cc77

4 files changed

Lines changed: 150 additions & 2 deletions

File tree

‎README.md‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Please refer to the following usage example for the parameters descriptions:
7070
<!-- -DdbUser="user" -->
7171
<dbUser>user</dbUser>
7272
<!-- Database connection password. -->
73-
<!-- -DdbPassword="password" -->
73+
<!-- -DdbPass="password" -->
7474
<dbPass>password</dbPass>
7575
</properties>
7676

@@ -253,6 +253,40 @@ directory:
253253
* **type-mapping-project:** Example how to use regex and custom type parameters together.
254254
* **owner-param-project:** Demonstrates how to use sourcesOwner and testsOwner parameters.
255255

256+
### Oracle Wallet (Secure External Password Store)
257+
258+
To keep the database password out of the `pom.xml` and the command line, store the credentials in an Oracle Wallet,
259+
leave `dbUser` and `dbPass` unset and point `dbUrl` to the TNS alias of the stored credential:
260+
261+
```xml
262+
<properties>
263+
<dbUrl>jdbc:oracle:thin:@MYDATABASE</dbUrl>
264+
</properties>
265+
```
266+
267+
Setup example:
268+
269+
```
270+
# create an auto-login wallet with credentials for TNS alias MYDATABASE
271+
orapki wallet create -wallet $HOME/oracle/wallet -auto_login_local
272+
mkstore -wrl $HOME/oracle/wallet -createCredential MYDATABASE someusername
273+
274+
# point the JDBC driver to the wallet
275+
echo "oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=$HOME/oracle/wallet)))" \
276+
> $HOME/oracle/network/admin/ojdbc.properties
277+
278+
# tnsnames.ora with the MYDATABASE entry must be in the same directory
279+
export TNS_ADMIN=$HOME/oracle/network/admin
280+
```
281+
282+
The JDBC driver looks for `tnsnames.ora` and `ojdbc.properties` in the directory given by (in order of precedence):
283+
284+
1. `TNS_ADMIN` parameter in the URL, e.g. `jdbc:oracle:thin:@MYDATABASE?TNS_ADMIN=/path/to/network/admin`
285+
2. Java system property `oracle.net.tns_admin`, e.g. `export MAVEN_OPTS="-Doracle.net.tns_admin=/path/to/network/admin"`
286+
3. `TNS_ADMIN` environment variable
287+
288+
The TNS alias used in `dbUrl` must match the alias of the credential stored in the wallet.
289+
256290
## Comparison with utPLSQL CLI
257291

258292
| CLI short parameter | CLI long parameter | Maven XML path |

‎pom.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1717
<maven.compiler.release>17</maven.compiler.release>
1818

19-
<utplsql-java-api.version>3.2.4</utplsql-java-api.version>
19+
<utplsql-java-api.version>3.2.5-SNAPSHOT</utplsql-java-api.version>
2020

2121
<!-- Minimum Maven API version required to run this plugin -->
2222
<maven.version>3.9.9</maven.version>

‎src/test/java/org/utplsql/maven/plugin/UtPlsqlMojoTest.java‎

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package org.utplsql.maven.plugin;
22

3+
import oracle.security.pki.OracleSecretStore;
4+
import oracle.security.pki.OracleWallet;
35
import org.apache.maven.plugin.MojoExecutionException;
46
import org.apache.maven.plugin.testing.MojoRule;
57
import org.junit.Rule;
68
import org.junit.Test;
9+
import org.junit.rules.TemporaryFolder;
710
import org.utplsql.api.FileMapperOptions;
811
import org.utplsql.maven.plugin.model.ReporterParameter;
912

1013
import java.io.ByteArrayOutputStream;
1114
import java.io.File;
1215
import java.io.PrintStream;
16+
import java.nio.file.Files;
1317
import java.util.List;
1418

1519
import static org.junit.Assert.assertEquals;
@@ -20,9 +24,14 @@
2024

2125
public class UtPlsqlMojoTest {
2226

27+
private static final String WALLET_TNS_ALIAS = "UTPLSQL_MAVEN_WALLET";
28+
2329
@Rule
2430
public final MojoRule rule = new MojoRule();
2531

32+
@Rule
33+
public final TemporaryFolder temporaryFolder = new TemporaryFolder();
34+
2635
/**
2736
* Invalid Sources Directory
2837
* <p>
@@ -322,6 +331,78 @@ public void db_config_using_system_properties() throws Exception {
322331
System.clearProperty("dbPass");
323332
}
324333

334+
/**
335+
* Connection using Oracle Wallet (Secure External Password Store)
336+
* <p>
337+
* Given : a pom.xml without dbUser and dbPass and a dbUrl pointing to a TNS alias stored in an Oracle Wallet
338+
* When : tests are run
339+
* Then : credentials are taken from the wallet
340+
*/
341+
@Test
342+
public void wallet_connection_without_credentials() throws Exception {
343+
System.setProperty("dbUrl", walletDbUrl());
344+
try {
345+
UtPlsqlMojo utPlsqlMojo = createUtPlsqlMojo("wallet_connection");
346+
assertNotNull(utPlsqlMojo);
347+
348+
utPlsqlMojo.execute();
349+
} finally {
350+
System.clearProperty("dbUrl");
351+
}
352+
}
353+
354+
/**
355+
* Connection using Oracle Wallet with empty credentials
356+
* <p>
357+
* Given : a dbUrl pointing to a TNS alias stored in an Oracle Wallet and empty dbUser and dbPass (e.g. -DdbUser= -DdbPass=)
358+
* When : tests are run
359+
* Then : empty credentials are ignored and credentials are taken from the wallet
360+
*/
361+
@Test
362+
public void wallet_connection_with_empty_credentials() throws Exception {
363+
System.setProperty("dbUrl", walletDbUrl());
364+
System.setProperty("dbUser", "");
365+
System.setProperty("dbPass", "");
366+
try {
367+
UtPlsqlMojo utPlsqlMojo = createUtPlsqlMojo("wallet_connection");
368+
assertNotNull(utPlsqlMojo);
369+
370+
utPlsqlMojo.execute();
371+
} finally {
372+
System.clearProperty("dbUrl");
373+
System.clearProperty("dbUser");
374+
System.clearProperty("dbPass");
375+
}
376+
}
377+
378+
/**
379+
* Creates an auto-login Oracle Wallet holding the UT3 credentials for {@link #WALLET_TNS_ALIAS},
380+
* with tnsnames.ora and ojdbc.properties next to it, so no Oracle client tooling (mkstore/orapki) is needed.
381+
*
382+
* @return JDBC URL of the TNS alias, with the generated directory as TNS_ADMIN
383+
*/
384+
private String walletDbUrl() throws Exception {
385+
File tnsAdmin = temporaryFolder.newFolder("tns_admin");
386+
387+
OracleWallet wallet = new OracleWallet();
388+
wallet.create("Wallet_Pwd_123".toCharArray());
389+
OracleSecretStore secretStore = wallet.getSecretStore();
390+
secretStore.createCredential(WALLET_TNS_ALIAS.toCharArray(), "UT3".toCharArray(), "ut3".toCharArray());
391+
wallet.setSecretStore(secretStore);
392+
wallet.saveAs(tnsAdmin.getPath());
393+
wallet.createSSO();
394+
wallet.saveSSO();
395+
396+
Files.writeString(tnsAdmin.toPath().resolve("tnsnames.ora"),
397+
WALLET_TNS_ALIAS + " = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))"
398+
+ "(CONNECT_DATA = (SERVICE_NAME = FREEPDB1)))\n");
399+
// ${TNS_ADMIN} is resolved by the JDBC driver, the same way as in wallets downloaded for Oracle Autonomous Database
400+
Files.writeString(tnsAdmin.toPath().resolve("ojdbc.properties"),
401+
"oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=${TNS_ADMIN})))\n");
402+
403+
return "jdbc:oracle:thin:@" + WALLET_TNS_ALIAS + "?TNS_ADMIN=" + tnsAdmin.getAbsolutePath().replace('\\', '/');
404+
}
405+
325406
/**
326407
* Exclude a list of objects
327408
* <p>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>org.utplsql</groupId>
7+
<artifactId>utplsql-maven-plugin-test</artifactId>
8+
<version>3.1.0-SNAPSHOT</version>
9+
<packaging>pom</packaging>
10+
11+
<!-- dbUrl pointing to a TNS alias stored in an Oracle Wallet is set by the test; dbUser and dbPass are not given -->
12+
13+
<build>
14+
<directory>../../../target</directory>
15+
<plugins>
16+
<plugin>
17+
<groupId>org.utplsql</groupId>
18+
<artifactId>utplsql-maven-plugin</artifactId>
19+
<version>@project.version@</version>
20+
<goals>
21+
<goal>test</goal>
22+
</goals>
23+
<configuration>
24+
<!-- only the connection is verified here, not the test results -->
25+
<ignoreFailure>true</ignoreFailure>
26+
<paths>
27+
<path>app</path>
28+
</paths>
29+
</configuration>
30+
</plugin>
31+
</plugins>
32+
</build>
33+
</project>

0 commit comments

Comments
 (0)