From 49a1b674729a5c6c1da345d8a0785aeb45143bd6 Mon Sep 17 00:00:00 2001 From: Rob Rudin Date: Tue, 24 Jan 2023 09:21:25 -0500 Subject: [PATCH] Added more builder methods Syntatic sugar for when the client knows the desired security context type. --- .../fastfunctest/AbstractFunctionalTest.java | 2 +- .../TestDatabaseAuthentication.java | 2 +- .../fastfunctest/TestRuntimeDBselection.java | 2 +- .../functionaltest/ConnectedRESTQA.java | 14 ------ .../client/DatabaseClientBuilder.java | 46 +++++++++++++++++++ .../impl/DatabaseClientPropertySource.java | 14 +++--- .../test/DatabaseClientBuilderTest.java | 22 +++------ 7 files changed, 63 insertions(+), 39 deletions(-) diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java index f137faa8b..8822634ff 100644 --- a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java +++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/AbstractFunctionalTest.java @@ -57,7 +57,7 @@ public static void initializeClients() throws Exception { isML11OrHigher = version.getMajor() >= 11; client = newDatabaseClientBuilder().build(); - schemasClient = newClientForDatabase("java-functest-schemas"); + schemasClient = newDatabaseClientBuilder().withDatabase("java-functest-schemas").build(); adminModulesClient = newAdminModulesClient(); // Required to ensure that tests using the "/ext/" prefix work reliably. Expand to other directories as needed. diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestDatabaseAuthentication.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestDatabaseAuthentication.java index 161b706af..deccac1ee 100644 --- a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestDatabaseAuthentication.java +++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestDatabaseAuthentication.java @@ -81,7 +81,7 @@ public void testAuthenticationBasic() throws IOException String filename = "text-original.txt"; // connect the client - DatabaseClient client = newBasicAuthClient("rest-writer", "x"); + DatabaseClient client = newDatabaseClientBuilder().withBasicAuth("rest-writer", "x").build(); // write doc writeDocumentUsingStringHandle(client, filename, "/write-text-doc-basic/", "Text"); diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestRuntimeDBselection.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestRuntimeDBselection.java index df2be0826..104ccce52 100644 --- a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestRuntimeDBselection.java +++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/fastfunctest/TestRuntimeDBselection.java @@ -43,7 +43,7 @@ public void testRuntimeDBclientWithDifferentAuthType() { String originalServerAuthentication = getServerAuthentication(getRestServerName()); try { setAuthentication("basic", getRestServerName()); - client = newBasicAuthClient("eval-user", "x"); + client = newDatabaseClientBuilder().withBasicAuth("eval-user", "x").build(); String insertJSON = "xdmp:document-insert(\"test2.json\",object-node {\"test\":\"hello\"})"; client.newServerEval().xquery(insertJSON).eval(); String query1 = "fn:count(fn:doc())"; diff --git a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java index d1d52e56c..5822d6c91 100644 --- a/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java +++ b/marklogic-client-api-functionaltests/src/test/java/com/marklogic/client/functionaltest/ConnectedRESTQA.java @@ -2027,14 +2027,6 @@ public static DatabaseClientBuilder newDatabaseClientBuilder() { return new DatabaseClientBuilder(props); } - public static DatabaseClient newBasicAuthClient(String username, String password) { - return newDatabaseClientBuilder() - .withUsername(username) - .withPassword(password) - .withSecurityContextType("basic") - .build(); - } - public static DatabaseClient newClientAsUser(String username, String password) { return newDatabaseClientBuilder() .withUsername(username) @@ -2042,12 +2034,6 @@ public static DatabaseClient newClientAsUser(String username, String password) { .build(); } - public static DatabaseClient newClientForDatabase(String database) { - return newDatabaseClientBuilder() - .withDatabase(database) - .build(); - } - public static DatabaseClient newAdminModulesClient() { return newDatabaseClientBuilder() .withUsername(getAdminUser()) diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/DatabaseClientBuilder.java b/marklogic-client-api/src/main/java/com/marklogic/client/DatabaseClientBuilder.java index f7f803342..298153f38 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/DatabaseClientBuilder.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/DatabaseClientBuilder.java @@ -38,6 +38,13 @@ public class DatabaseClientBuilder { public final static String PREFIX = "marklogic.client."; + public final static String SECURITY_CONTEXT_TYPE_BASIC = "basic"; + public final static String SECURITY_CONTEXT_TYPE_DIGEST = "digest"; + public final static String SECURITY_CONTEXT_TYPE_MARKLOGIC_CLOUD = "cloud"; + public final static String SECURITY_CONTEXT_TYPE_KERBEROS = "kerberos"; + public final static String SECURITY_CONTEXT_TYPE_CERTIFICATE = "certificate"; + public final static String SECURITY_CONTEXT_TYPE_SAML = "saml"; + private final Map props; public DatabaseClientBuilder() { @@ -113,11 +120,50 @@ public DatabaseClientBuilder withSecurityContext(DatabaseClientFactory.SecurityC return this; } + /** + * + * @param type must be one of "basic", "digest", "cloud", "kerberos", "certificate", or "saml" + * @return + */ public DatabaseClientBuilder withSecurityContextType(String type) { props.put(PREFIX + "securityContextType", type); return this; } + public DatabaseClientBuilder withBasicAuth(String username, String password) { + return withSecurityContextType(SECURITY_CONTEXT_TYPE_BASIC) + .withUsername(username) + .withPassword(password); + } + + public DatabaseClientBuilder withDigestAuth(String username, String password) { + return withSecurityContextType(SECURITY_CONTEXT_TYPE_DIGEST) + .withUsername(username) + .withPassword(password); + } + + public DatabaseClientBuilder withMarkLogicCloudAuth(String apiKey, String basePath) { + return withSecurityContextType(SECURITY_CONTEXT_TYPE_MARKLOGIC_CLOUD) + .withCloudApiKey(apiKey) + .withBasePath(basePath); + } + + public DatabaseClientBuilder withKerberosAuth(String principal) { + return withSecurityContextType(SECURITY_CONTEXT_TYPE_KERBEROS) + .withKerberosPrincipal(principal); + } + + public DatabaseClientBuilder withCertificateAuth(String file, String password) { + return withSecurityContextType(SECURITY_CONTEXT_TYPE_CERTIFICATE) + .withCertificateFile(file) + .withCertificatePassword(password); + } + + public DatabaseClientBuilder withSAMLAuth(String token) { + return withSecurityContextType(SECURITY_CONTEXT_TYPE_SAML) + .withSAMLToken(token); + } + public DatabaseClientBuilder withConnectionType(DatabaseClient.ConnectionType type) { props.put(PREFIX + "connectionType", type); return this; diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/impl/DatabaseClientPropertySource.java b/marklogic-client-api/src/main/java/com/marklogic/client/impl/DatabaseClientPropertySource.java index 710fd2f77..fdf02d54c 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/impl/DatabaseClientPropertySource.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/impl/DatabaseClientPropertySource.java @@ -31,6 +31,8 @@ * Contains the implementation for the {@code DatabaseClientFactory.newClient} method that accepts a function as a * property source. Implementation is here primarily to ease readability and avoid making the factory class any larger * than it already is. + * + * @since 6.1.0 */ public class DatabaseClientPropertySource { @@ -117,17 +119,17 @@ private DatabaseClientFactory.SecurityContext newSecurityContext() { private DatabaseClientFactory.SecurityContext newSecurityContext(String type) { switch (type.toLowerCase()) { - case "basic": + case DatabaseClientBuilder.SECURITY_CONTEXT_TYPE_BASIC: return newBasicAuthContext(); - case "digest": + case DatabaseClientBuilder.SECURITY_CONTEXT_TYPE_DIGEST: return newDigestAuthContext(); - case "cloud": + case DatabaseClientBuilder.SECURITY_CONTEXT_TYPE_MARKLOGIC_CLOUD: return newCloudAuthContext(); - case "kerberos": + case DatabaseClientBuilder.SECURITY_CONTEXT_TYPE_KERBEROS: return newKerberosAuthContext(); - case "certificate": + case DatabaseClientBuilder.SECURITY_CONTEXT_TYPE_CERTIFICATE: return newCertificateAuthContext(); - case "saml": + case DatabaseClientBuilder.SECURITY_CONTEXT_TYPE_SAML: return newSAMLAuthContext(); default: throw new IllegalArgumentException("Unrecognized security context type: " + type); diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/DatabaseClientBuilderTest.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/DatabaseClientBuilderTest.java index 7b79e079c..ae5061615 100644 --- a/marklogic-client-api/src/test/java/com/marklogic/client/test/DatabaseClientBuilderTest.java +++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/DatabaseClientBuilderTest.java @@ -78,9 +78,7 @@ void invalidSecurityContextType() { @Test void digest() { bean = Common.newClientBuilder() - .withUsername("my-user") - .withPassword("my-password") - .withSecurityContextType("digest") + .withDigestAuth("my-user", "my-password") .buildBean(); DatabaseClientFactory.DigestAuthContext context = (DatabaseClientFactory.DigestAuthContext) bean.getSecurityContext(); @@ -91,9 +89,7 @@ void digest() { @Test void basic() { bean = Common.newClientBuilder() - .withUsername("my-user") - .withPassword("my-password") - .withSecurityContextType("basic") + .withBasicAuth("my-user", "my-password") .buildBean(); DatabaseClientFactory.BasicAuthContext context = (DatabaseClientFactory.BasicAuthContext) bean.getSecurityContext(); @@ -104,9 +100,7 @@ void basic() { @Test void cloudWithBasePath() { bean = Common.newClientBuilder() - .withSecurityContextType("cloud") - .withCloudApiKey("my-key") - .withBasePath("/my/path") + .withMarkLogicCloudAuth("my-key", "/my/path") .buildBean(); DatabaseClientFactory.MarkLogicCloudAuthContext context = @@ -127,8 +121,7 @@ void cloudNoApiKey() { @Test void kerberos() { bean = Common.newClientBuilder() - .withSecurityContextType("kerberos") - .withKerberosPrincipal("someone") + .withKerberosAuth("someone") .buildBean(); DatabaseClientFactory.KerberosAuthContext context = (DatabaseClientFactory.KerberosAuthContext) bean.getSecurityContext(); @@ -138,9 +131,7 @@ void kerberos() { @Test void certificate() { DatabaseClientBuilder builder = Common.newClientBuilder() - .withSecurityContextType("CERTificate") - .withCertificateFile("not.found") - .withCertificatePassword("passwd"); + .withCertificateAuth("not.found", "passwd"); Exception ex = assertThrows(Exception.class, () -> builder.buildBean()); assertTrue(ex.getMessage().contains("Unable to create CertificateAuthContext"), @@ -151,8 +142,7 @@ void certificate() { @Test void saml() { bean = Common.newClientBuilder() - .withSecurityContextType("saml") - .withSAMLToken("my-token") + .withSAMLAuth("my-token") .buildBean(); DatabaseClientFactory.SAMLAuthContext context = (DatabaseClientFactory.SAMLAuthContext) bean.getSecurityContext();