From ce6b7cf03d930a2975f1a9b3dabd71b02ae257e0 Mon Sep 17 00:00:00 2001 From: Rodrigo Pastrana Date: Fri, 14 Jun 2024 17:09:38 -0400 Subject: [PATCH] HPCC4J-614 WsStore IPT invalid character tests - Adds new WsStore tests based on values which include IPT attribute delimiters - Fixes issue noticed in wsstoreclient - Adds ability to test encod-able username - Adds fetch encoded key test - Adds fetch invalid key test Signed-off-by: Rodrigo Pastrana --- .../ws/client/HPCCWsStoreClient.java | 2 +- .../ws/client/WSStoreClientTest.java | 318 ++++++++++++++++++ 2 files changed, 319 insertions(+), 1 deletion(-) diff --git a/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCWsStoreClient.java b/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCWsStoreClient.java index a88cb9685..c110c99e2 100644 --- a/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCWsStoreClient.java +++ b/wsclient/src/main/java/org/hpccsystems/ws/client/HPCCWsStoreClient.java @@ -254,7 +254,7 @@ public String[] listNamespaces(String storename, boolean global) throws Exceptio String namespaces[] = null; ListNamespacesRequest request = new ListNamespacesRequest(); request.setStoreName(storename); - request.setUserSpecific(global); + request.setUserSpecific(!global); try { ListNamespacesResponse response = ((WsstoreStub) stub).listNamespaces(request); diff --git a/wsclient/src/test/java/org/hpccsystems/ws/client/WSStoreClientTest.java b/wsclient/src/test/java/org/hpccsystems/ws/client/WSStoreClientTest.java index d6aeba052..334033488 100644 --- a/wsclient/src/test/java/org/hpccsystems/ws/client/WSStoreClientTest.java +++ b/wsclient/src/test/java/org/hpccsystems/ws/client/WSStoreClientTest.java @@ -19,6 +19,7 @@ HPCC SYSTEMS software Copyright (C) 2019 HPCC Systems®. import static org.junit.Assert.assertNotNull; +import java.net.MalformedURLException; import java.nio.charset.Charset; import java.util.Properties; import java.util.Random; @@ -29,8 +30,10 @@ HPCC SYSTEMS software Copyright (C) 2019 HPCC Systems®. import org.apache.axis2.AxisFault; import org.hpccsystems.commons.utils.CryptoHelper; import org.hpccsystems.commons.utils.DigestAlgorithmType; +import org.hpccsystems.ws.client.utils.Connection; import org.hpccsystems.ws.client.wrappers.ArrayOfEspExceptionWrapper; import org.junit.Assert; +import org.junit.Assume; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; @@ -42,6 +45,12 @@ public class WSStoreClientTest extends BaseRemoteTest public final static String defaultStoreName = "WsClientTestStore"; public final static String defaultNS = "Junittests"; + public final static String defaultEncodedUserName = "Juni@tUser"; + public final static String defaultEncodedStoreName = "WsCli@ntT_estStore"; + public final static String defaultEncodedNS = "Junit_t@ests"; + private static Connection encodedUserConn = null; + private static HPCCWsStoreClient encodedUserClient; + private final static String storename = System.getProperty("storename", defaultStoreName); private final static String namespace = System.getProperty("storenamespace", defaultNS); @@ -55,6 +64,29 @@ public class WSStoreClientTest extends BaseRemoteTest client = HPCCWsStoreClient.get(connection); Assert.assertNotNull(client); + + try + { + encodedUserConn = new Connection(connString); + } + catch (MalformedURLException e) + { + System.out.println("Could not acquire connection object based on: '" + connString + "' - " + e.getLocalizedMessage()); + } + + if (encodedUserConn != null) + { + encodedUserConn.setCredentials(defaultEncodedUserName, hpccPass); + + if (connTO != null) + encodedUserConn.setConnectTimeoutMilli(connTO); + + if (sockTO != null) + encodedUserConn.setSocketTimeoutMilli(Integer.valueOf(sockTO)); + + encodedUserClient = HPCCWsStoreClient.get(encodedUserConn); + } + Assert.assertNotNull(encodedUserClient); } public void printMetaData(int tabs, Properties props) @@ -355,6 +387,292 @@ public void z91deleteNSTest() throws Exception, ArrayOfEspExceptionWrapper } } + @Test + public void b1createEncodedStoreTest() throws Exception, ArrayOfEspExceptionWrapper + { + Assume.assumeNotNull(encodedUserClient); + try + { + System.out.println("Creating Store: '" + defaultEncodedStoreName + "' ..."); + boolean success = encodedUserClient.createStore(defaultEncodedStoreName, "Store strictly for WsClient tests", "TEST"); + if (!success) + System.out.println("No exceptions, but failure reported. Does this store already exist? Store: '" + defaultEncodedStoreName + "'"); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void zz91deleteEncodedNSTest() throws Exception, ArrayOfEspExceptionWrapper + { + Assume.assumeNotNull(encodedUserClient); + try + { + System.out.println("Deleting ns: '" + defaultEncodedNS + "' ..."); + Assert.assertTrue(encodedUserClient.deleteNamespace(defaultEncodedStoreName, defaultEncodedNS, true, "")); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void a3fetchInvalidKeyTest() + { + try + { + System.out.println("Fetching invalid key " + defaultEncodedStoreName + "." + defaultEncodedNS + "keys..."); + String invalidKeyResponse = client.fetchValue(storename, namespace, "invalid.global.test", true); + + Assert.assertNull(invalidKeyResponse); + } + catch (ArrayOfEspExceptionWrapper e) + { + Assert.fail(e.toString()); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void b4fetchAllEncodedNSKeysTest() + { + Assume.assumeNotNull(encodedUserClient); + try + { + System.out.println("Fetching all " + defaultEncodedStoreName + "." + defaultEncodedNS + "keys..."); + Properties fetchAllNSKeys = encodedUserClient.fetchAllNSKeys(defaultEncodedStoreName, defaultEncodedNS, true); + Assert.assertNotNull(fetchAllNSKeys); + System.out.println("All Keys: " + fetchAllNSKeys.toString()); + } + catch (ArrayOfEspExceptionWrapper e) + { + Assert.fail(e.toString()); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void b4fetchEncodedNSKeysAttributesTest() + { + Assume.assumeNotNull(encodedUserClient); + try + { + System.out.println("Fetching key attribute: " + defaultEncodedStoreName + "." + defaultEncodedNS + "global.test"); + Properties fetchKeyMetadata = encodedUserClient.fetchKeyMetaData(defaultEncodedStoreName, defaultEncodedNS, "global.test", true); + Assert.assertNotNull(fetchKeyMetadata); + System.out.println("Key Metadata: " + fetchKeyMetadata.toString()); + } + catch (ArrayOfEspExceptionWrapper e) + { + Assert.fail(e.toString()); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void b4fetchEncodedKeyTest() + { + Assume.assumeNotNull(encodedUserClient); + try + { + System.out.println("Fetching encoded key attributes: " + defaultEncodedStoreName + "." + defaultEncodedNS + ".encod@ble"); + Properties fetchKeyMetadata = encodedUserClient.fetchKeyMetaData(defaultEncodedStoreName, defaultEncodedNS, "encod@ble", true); + Assert.assertNotNull(fetchKeyMetadata); + System.out.println("Key Metadata: " + fetchKeyMetadata.toString()); + + System.out.println("Fetching encoded key: " + defaultEncodedStoreName + "." + defaultEncodedNS + ".encod@ble"); + String fetchedValue = encodedUserClient.fetchValue(defaultEncodedStoreName, defaultEncodedNS, "encod@ble", true); + Assert.assertNotNull(fetchedValue); + Assert.assertTrue(fetchedValue.equals("whatever")); + System.out.println("Key/value: " + fetchedValue.toString()); + } + catch (ArrayOfEspExceptionWrapper e) + { + Assert.fail(e.toString()); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void b3setEncodedTest() throws Exception, ArrayOfEspExceptionWrapper + { + Assume.assumeNotNull(encodedUserClient); + try + { + System.out.println("Setting " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "WsClient.global.test=\"success\"..."); + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "global.test", "success", true)); + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "a", "ddfa", true)); + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "encod@ble", "whatever", true)); + + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "global.test", "success", true)); + System.out.println("Setting " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "WsClient.user.test=\"success\"..."); + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "user.test", "success", false)); + + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "files.rowperpage.default", "50", true)); + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "dp-thor_160-jim::tutorialperson-wuid", "W20190710-114239", false)); + Assert.assertTrue(encodedUserClient.setValue(defaultEncodedStoreName, defaultEncodedNS, "ecl.playground.sample.default", "Java Simple", true)); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void b4setEncryptedTest() throws Exception, ArrayOfEspExceptionWrapper + { + try + { + //Generating random data as key content, client must keep track of this key in order to decrypt + byte[] array = new byte[12]; + new Random().nextBytes(array); + String mysecretkeycontent = new String(array, Charset.forName("UTF-8")); + + Cipher aesEncryptCipher = CryptoHelper.createDefaultCipher(mysecretkeycontent, true); //Encrypt cipher, caller can create their own, and is responsible for safe keeping + Cipher aesDecryptCipher = CryptoHelper.createDefaultCipher(mysecretkeycontent, false); //decrypt cipher, caller can create their own, should match the encryp counterpart and is responsible for safe keeping + + Assert.assertNotNull(aesEncryptCipher); + + System.out.println("Setting (encrypted based on provided cipher) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "global.encrypted.test=\"mysensitivedata\"..."); + Assert.assertTrue(client.setValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.test", "mysensitivedata", true, aesEncryptCipher)); + + String encryptedvalue = client.fetchValue(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.test", true); + Assert.assertNotNull(encryptedvalue); + System.out.println("Fetching (encrypted based on provided cipher) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "global.encrypted.test=\"" + encryptedvalue + "\""); + + String decryptedvalue = CryptoHelper.decrypt(encryptedvalue, aesDecryptCipher); + Assert.assertNotNull(decryptedvalue); + + System.out.println("Decrypted localy: global.encrypted.test=\"" + decryptedvalue + "\""); + + String decryptedvalue2 = client.fetchValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.test", true, aesDecryptCipher); + Assert.assertNotNull(decryptedvalue2); + + Assert.assertTrue("Decrypted locally not equal decrypted by wsstore client", decryptedvalue.equals(decryptedvalue2)); + + System.out.println("Setting (encrypted based on provided cipher) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "WsClient.user.encrypted.test=\"moresensitivedata\"..."); + Assert.assertTrue(client.setValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "WsClient.user.encrypted.test", "moresensitivedata", false, aesEncryptCipher)); + + System.out.println("Setting (encrypted based on private key) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "global.encrypted.secretkey.test=\"privateinfo\"..."); + Assert.assertTrue(client.setValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.secretkey.test", "privateinfo", true, mysecretkeycontent)); + + System.out.println("Setting (encrypted based on private key) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "WsClient.user.encrypted.secretkey.test=\"moreprivateinfo\"..."); + Assert.assertTrue(client.setValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "WsClient.user.encrypted.secretkey.test", "moreprivateinfo", false, mysecretkeycontent)); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + + @Test + public void b4setEncryptedCustomTest() + { + //Generating random data as key content, client must keep track of this key in order to decrypt + byte[] array = new byte[12]; + new Random().nextBytes(array); + String mysecretkeycontent = new String(array, Charset.forName("UTF-8")); + + + final String secretKeyAlgo = "AES"; + final DigestAlgorithmType digestAlgo = DigestAlgorithmType.SHA1; + final String cipherAlgo = "AES"; + + SecretKeySpec secretKeySpec = CryptoHelper.createSecretKey(mysecretkeycontent, digestAlgo, secretKeyAlgo); //Caller can create their own secret key spec + Assert.assertNotNull("Could not create custom secretKeySpec '"+ digestAlgo +"' '" + secretKeyAlgo + "'!", secretKeySpec); + + Cipher someencryptcipher = null; + try + { + someencryptcipher = CryptoHelper.createCipher(secretKeySpec, cipherAlgo, true); + } + catch (Exception e) + { + Assert.fail("Could create encrypt cipher: " + e.getLocalizedMessage()); + } + Assert.assertNotNull("Could not create custom encrypt cipher '"+ digestAlgo +"' '" + secretKeyAlgo + "'!", someencryptcipher); + + Cipher somedecryptcipher = null; + try + { + somedecryptcipher = CryptoHelper.createCipher(secretKeySpec, cipherAlgo, false); + } + catch (Exception e) + { + Assert.fail("Could create decrypt cipher: " + e.getLocalizedMessage()); + } + Assert.assertNotNull("Could not create custom encrypt cipher '"+ digestAlgo +"' '" + secretKeyAlgo + "'!", somedecryptcipher); + + System.out.println("Setting (encrypted based on provided custom '"+ digestAlgo +"' '" + secretKeyAlgo + "' cipher) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "global.encrypted.custom.test=\"myhiddensecret\"..."); + try + { + Assert.assertTrue(client.setValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.custom.test", "myhiddensecret", true, someencryptcipher)); + } + catch (Exception e) + { + Assert.fail("Could not set and encrypted value: " + e.getLocalizedMessage()); + } + + String encryptedvalue = null; + try + { + encryptedvalue = client.fetchValue(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.custom.test", true); + } + catch (Exception e) + { + Assert.fail("Could not fetch encrypted value value: " + e.getLocalizedMessage()); + } + Assert.assertNotNull("failed to fetch valid encrypted value", encryptedvalue); + + System.out.println("Fetching (encrypted based on provided custom '"+ digestAlgo +"' '" + secretKeyAlgo + "' cipher) " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "global.encrypted.custom.test=\"" + encryptedvalue + "\""); + String decryptedvalue = null; + try + { + decryptedvalue = client.fetchValueEncrypted(defaultEncodedStoreName, defaultEncodedNS, "global.encrypted.custom.test", true, somedecryptcipher); + } + catch (Exception e) + { + Assert.fail("Could not fetch and decrypt value: " + e.getLocalizedMessage()); + } + Assert.assertNotNull(decryptedvalue); + + String ldecryptedvalue2 = CryptoHelper.decrypt(encryptedvalue, somedecryptcipher); + Assert.assertNotNull(ldecryptedvalue2); + + Assert.assertTrue("Decrypted locally not equal decrypted by wsstore client", decryptedvalue.equals(ldecryptedvalue2)); + } + + @Test + public void b5deleteTest() throws Exception, ArrayOfEspExceptionWrapper + { + try + { + System.out.println("Deleting " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "WsClient.global.test=\"success\"..."); + Assert.assertTrue(client.setValue(defaultEncodedStoreName, defaultEncodedNS, "WsClient.global.test", "success", true)); + System.out.println("Deleting " + defaultEncodedStoreName + "." + defaultEncodedNS + "." + "WsClient.user.test=\"success\"..."); + Assert.assertTrue(client.setValue(defaultEncodedStoreName, defaultEncodedNS, "WsClient.user.test", "success", false)); + } + catch (Exception e) + { + Assert.fail(e.getLocalizedMessage()); + } + } + @Test public void ping() throws Exception {