From 87f51afae0433151fc5de0652ac0f2181c103ac5 Mon Sep 17 00:00:00 2001 From: shiwang Date: Tue, 11 Apr 2017 15:40:26 -0700 Subject: [PATCH 1/2] CALCITE-1539:Enable proxy access to Avatica server for third party on behalf of end users --- .../avatica/server/AvaticaJsonHandler.java | 3 +- .../server/AvaticaProtobufHandler.java | 3 +- .../server/AvaticaServerConfiguration.java | 7 + ...eryStringParameterRemoteUserExtractor.java | 32 ++++ .../HttpRequestRemoteUserExtractor.java | 33 ++++ .../calcite/avatica/server/HttpServer.java | 25 +++ .../server/RemoteUserExtractionException.java | 38 ++++ .../avatica/server/RemoteUserExtractor.java | 28 +++ .../RemoteUserExtractHttpServerTest.java | 175 ++++++++++++++++++ 9 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java create mode 100644 server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java create mode 100644 server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractionException.java create mode 100644 server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractor.java create mode 100644 server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java diff --git a/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java b/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java index b6391833fa..7afb27fb8f 100644 --- a/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java +++ b/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java @@ -119,7 +119,8 @@ public void handle(String target, Request baseRequest, HandlerResponse jsonResponse; try { if (null != serverConfig && serverConfig.supportsImpersonation()) { - jsonResponse = serverConfig.doAsRemoteUser(request.getRemoteUser(), + String remoteUser = serverConfig.getRemoteUserExtractor().extract(request); + jsonResponse = serverConfig.doAsRemoteUser(remoteUser, request.getRemoteAddr(), new Callable>() { @Override public HandlerResponse call() { return jsonHandler.apply(jsonRequest); diff --git a/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java b/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java index f8723f1b86..8e77018847 100644 --- a/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java +++ b/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java @@ -113,8 +113,9 @@ public void handle(String target, Request baseRequest, HandlerResponse handlerResponse; try { if (null != serverConfig && serverConfig.supportsImpersonation()) { + String remoteUser = serverConfig.getRemoteUserExtractor().extract(request); // Invoke the ProtobufHandler inside as doAs for the remote user. - handlerResponse = serverConfig.doAsRemoteUser(request.getRemoteUser(), + handlerResponse = serverConfig.doAsRemoteUser(remoteUser, request.getRemoteAddr(), new Callable>() { @Override public HandlerResponse call() { return pbHandler.apply(requestBytes); diff --git a/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java b/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java index dd843a4b48..26de3e5dec 100644 --- a/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java +++ b/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java @@ -92,6 +92,13 @@ public interface AvaticaServerConfiguration { */ T doAsRemoteUser(String remoteUserName, String remoteAddress, Callable action) throws Exception; + + /** + * Extract the user this request should execute as. + * + * @return Name of the RemoteUserExtractor + */ + RemoteUserExtractor getRemoteUserExtractor(); } // End AvaticaServerConfiguration.java diff --git a/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java b/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java new file mode 100644 index 0000000000..da4d4859e8 --- /dev/null +++ b/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.avatica.server; + +import javax.servlet.http.HttpServletRequest; +/** + * A RemoteUserExtrator that extracts "doAs" user + */ +public class HttpQueryStringParameterRemoteUserExtractor + implements RemoteUserExtractor { + public String extract(HttpServletRequest request) + throws RemoteUserExtractionException { + return request.getParameter("doAs"); + } + +} + +// End HttpQueryStringParameterRemoteUserExtractor.java diff --git a/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java b/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java new file mode 100644 index 0000000000..03c7e32ac7 --- /dev/null +++ b/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.avatica.server; + +import javax.servlet.http.HttpServletRequest; + +/** + * A RemoteUserExtrator that extracts remote user by getRemoteUser + */ +public class HttpRequestRemoteUserExtractor + implements RemoteUserExtractor { + public String extract(HttpServletRequest request) + throws RemoteUserExtractionException { + return request.getRemoteUser(); + } + +} + +// End HttpRequestRemoteUserExtractor.java diff --git a/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java b/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java index 4c871f009d..ffb67ca055 100644 --- a/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java +++ b/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java @@ -403,6 +403,7 @@ public static class Builder { private File keytab; private DoAsRemoteUserCallback remoteUserCallback; + private RemoteUserExtractor remoteUserExtractor = new HttpRequestRemoteUserExtractor(); private String loginServiceRealm; private String loginServiceProperties; @@ -552,6 +553,20 @@ public Builder withImpersonation(DoAsRemoteUserCallback remoteUserCallback) { return this; } + /** + * Sets a callback implementation to defer the logic on how to use the right remoteUserExtractor + * to extract remote user. + * + * @param remoteUserExtractor User-provided remoteUserExtractor + * @return this + */ + + public Builder withRemoteUserExtractor(RemoteUserExtractor remoteUserExtractor) { + this.remoteUserExtractor = Objects.requireNonNull(remoteUserExtractor); + return this; + } + + /** * Configures the server to use HTTP Basic authentication. The properties must * be in a form consumable by Jetty. Invoking this method overrides any previous call which @@ -686,6 +701,7 @@ private AvaticaServerConfiguration buildSpnegoConfiguration(Builder b) { final String realm = b.kerberosRealm; final String[] additionalAllowedRealms = b.loginServiceAllowedRoles; final DoAsRemoteUserCallback callback = b.remoteUserCallback; + final RemoteUserExtractor remoteUserExtractor = b.remoteUserExtractor; return new AvaticaServerConfiguration() { @Override public AuthenticationType getAuthenticationType() { @@ -709,6 +725,10 @@ private AvaticaServerConfiguration buildSpnegoConfiguration(Builder b) { return callback.doAsRemoteUser(remoteUserName, remoteAddress, action); } + @Override public RemoteUserExtractor getRemoteUserExtractor() { + return remoteUserExtractor; + } + @Override public String[] getAllowedRoles() { return additionalAllowedRealms; } @@ -728,6 +748,7 @@ private AvaticaServerConfiguration buildUserAuthenticationConfiguration(Builder final String[] allowedRoles = b.loginServiceAllowedRoles; final String realm = b.loginServiceRealm; final String properties = b.loginServiceProperties; + final RemoteUserExtractor remoteUserExtractor = b.remoteUserExtractor; return new AvaticaServerConfiguration() { @Override public AuthenticationType getAuthenticationType() { @@ -764,6 +785,10 @@ private AvaticaServerConfiguration buildUserAuthenticationConfiguration(Builder Callable action) throws Exception { return null; } + + @Override public RemoteUserExtractor getRemoteUserExtractor() { + return remoteUserExtractor; + } }; } diff --git a/server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractionException.java b/server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractionException.java new file mode 100644 index 0000000000..07b60fc252 --- /dev/null +++ b/server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractionException.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.avatica.server; + +/** + * The exception of extracting remote user + */ +public class RemoteUserExtractionException extends Exception { + /** + * Creates a RemoteUserExtractionException. + */ + public RemoteUserExtractionException(String message) { + super(message); + } + + /** + * Creates a RemoteUserExtractionException with a cause. + */ + public RemoteUserExtractionException(String message, Throwable cause) { + super(message, cause); + } +} + +// End RemoteUserExtractionException.java diff --git a/server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractor.java b/server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractor.java new file mode 100644 index 0000000000..4506144dcb --- /dev/null +++ b/server/src/main/java/org/apache/calcite/avatica/server/RemoteUserExtractor.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.avatica.server; + +import javax.servlet.http.HttpServletRequest; +/** + * Extracts remote user from request + */ +public interface RemoteUserExtractor { + String extract(HttpServletRequest request) + throws RemoteUserExtractionException; +} + +// End RemoteUserExtractor.java diff --git a/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java b/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java new file mode 100644 index 0000000000..b06aa10b5e --- /dev/null +++ b/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.avatica.server; + +import org.apache.calcite.avatica.ConnectionSpec; +import org.apache.calcite.avatica.jdbc.JdbcMeta; +import org.apache.calcite.avatica.remote.AuthenticationType; +import org.apache.calcite.avatica.remote.Driver; +import org.apache.calcite.avatica.remote.LocalService; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Properties; +import java.util.concurrent.Callable; + +import javax.servlet.http.HttpServletRequest; + +import static org.hamcrest.core.StringContains.containsString; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +/** + * Test class for HTTP Basic authentication. + */ +public class RemoteUserExtractHttpServerTest extends HttpAuthBase { + private static final Logger LOG = LoggerFactory.getLogger(RemoteUserExtractHttpServerTest.class); + + private static final ConnectionSpec CONNECTION_SPEC = ConnectionSpec.HSQLDB; + private static HttpServer server; + private static String url1; + private static String url2; + + @BeforeClass public static void startServer() throws Exception { + + final String userPropertiesFile = BasicAuthHttpServerTest.class + .getResource("/auth-users.properties").getFile(); + assertNotNull("Could not find properties file for basic auth users", userPropertiesFile); + + // Create a LocalService around HSQLDB + final JdbcMeta jdbcMeta = new JdbcMeta(CONNECTION_SPEC.url, + CONNECTION_SPEC.username, CONNECTION_SPEC.password); + LocalService service = new LocalService(jdbcMeta); + + HandlerFactory factory = new HandlerFactory(); + AvaticaHandler avaticaHandler = factory.getHandler(service, Driver.Serialization.PROTOBUF, null, + new AvaticaServerConfiguration() { + @Override public AuthenticationType getAuthenticationType() { + return AuthenticationType.BASIC; + } + + @Override public String getKerberosRealm() { + return null; + } + + @Override public String getKerberosPrincipal() { + return null; + } + + @Override public boolean supportsImpersonation() { + return true; + } + + @Override public T doAsRemoteUser(String remoteUserName, String remoteAddress, + Callable action) throws Exception { + + if (remoteUserName.equals("USER4")) { + throw new RuntimeException("USER4 is a disallowed user"); + } else if (remoteUserName.equals("USER2")) { + return action.call(); + } else { + throw new RuntimeException("Unknown user."); + } + } + + @Override public RemoteUserExtractor getRemoteUserExtractor() { + return new RemoteUserExtractor() { + HttpQueryStringParameterRemoteUserExtractor paramRemoteUserExtractor = + new HttpQueryStringParameterRemoteUserExtractor(); + HttpRequestRemoteUserExtractor requestRemoteUserExtractor = + new HttpRequestRemoteUserExtractor(); + + @Override public String extract(HttpServletRequest request) + throws RemoteUserExtractionException { + if (request.getParameter("doAs") != null) { + String doAsUser = request.getParameter("doAs"); + LOG.info("doAsUser is " + doAsUser); + return paramRemoteUserExtractor.extract(request); + } else { + return "USER2"; + } + + } + }; + } + + @Override public String[] getAllowedRoles() { + return new String[] { "users" }; + } + + @Override public String getHashLoginServiceRealm() { + return "Avatica"; + } + + @Override public String getHashLoginServiceProperties() { + return userPropertiesFile; + } + }); + + server = new HttpServer.Builder() + .withHandler(avaticaHandler) + .withPort(0) + .build(); + server.start(); + + url1 = "jdbc:avatica:remote:url=http://localhost:" + server.getPort() + + ";authentication=BASIC;serialization=PROTOBUF"; + + url2 = "jdbc:avatica:remote:url=http://localhost:" + server.getPort() + + "?doAs=USER4" + ";authentication=BASIC;serialization=PROTOBUF"; + + // Create and grant permissions to our users + createHsqldbUsers(); + } + + @AfterClass public static void stopServer() throws Exception { + if (null != server) { + server.stop(); + } + } + + @Test public void testUserWithAllowedDoAsRole() throws Exception { + // Disallowed by avatica + final Properties props = new Properties(); + props.put("avatica_user", "USER2"); + props.put("avatica_password", "password2"); + + readWriteData(url1, "ALLOWED_doAs_AVATICA_USER", props); + } + + @Test public void testUserWithDisallowedDoAsRole() throws Exception { + // Disallowed by avatica + final Properties props = new Properties(); + props.put("avatica_user", "USER2"); + props.put("avatica_password", "password2"); + + try { + readWriteData(url2, "DISALLOWED_doAs_AVATICA_USER", props); + fail("Expected an exception"); + } catch (RuntimeException e) { + assertThat(e.getMessage(), containsString("USER4 is a disallowed user")); + } + } + +} + +// End RemoteUserExtractHttpServerTest.java From 265c060b66136568b13a145f3586f2e7ecb37297 Mon Sep 17 00:00:00 2001 From: shiwang Date: Fri, 21 Apr 2017 14:31:43 -0700 Subject: [PATCH 2/2] modify test case --- ...eryStringParameterRemoteUserExtractor.java | 9 ++- .../HttpRequestRemoteUserExtractor.java | 6 +- .../RemoteUserExtractHttpServerTest.java | 58 +++++++++++++------ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java b/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java index da4d4859e8..c6cc88ded8 100644 --- a/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java +++ b/server/src/main/java/org/apache/calcite/avatica/server/HttpQueryStringParameterRemoteUserExtractor.java @@ -22,9 +22,12 @@ */ public class HttpQueryStringParameterRemoteUserExtractor implements RemoteUserExtractor { - public String extract(HttpServletRequest request) - throws RemoteUserExtractionException { - return request.getParameter("doAs"); + public String extract(HttpServletRequest request) throws RemoteUserExtractionException { + String remoteUser = request.getParameter("doAs"); + if (remoteUser == null) { + throw new RemoteUserExtractionException("Cannot Extract doAs User!"); + } + return remoteUser; } } diff --git a/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java b/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java index 03c7e32ac7..eeb1a61491 100644 --- a/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java +++ b/server/src/main/java/org/apache/calcite/avatica/server/HttpRequestRemoteUserExtractor.java @@ -25,7 +25,11 @@ public class HttpRequestRemoteUserExtractor implements RemoteUserExtractor { public String extract(HttpServletRequest request) throws RemoteUserExtractionException { - return request.getRemoteUser(); + String remoteUser = request.getRemoteUser(); + if (remoteUser == null) { + throw new RemoteUserExtractionException("Cannot Extract Request User!"); + } + return remoteUser; } } diff --git a/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java b/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java index b06aa10b5e..5e564d3d31 100644 --- a/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java +++ b/server/src/test/java/org/apache/calcite/avatica/server/RemoteUserExtractHttpServerTest.java @@ -48,11 +48,12 @@ public class RemoteUserExtractHttpServerTest extends HttpAuthBase { private static HttpServer server; private static String url1; private static String url2; + private static String url3; @BeforeClass public static void startServer() throws Exception { final String userPropertiesFile = BasicAuthHttpServerTest.class - .getResource("/auth-users.properties").getFile(); + .getResource("/auth-users.properties").getFile().replace("%20", " "); assertNotNull("Could not find properties file for basic auth users", userPropertiesFile); // Create a LocalService around HSQLDB @@ -83,16 +84,15 @@ public class RemoteUserExtractHttpServerTest extends HttpAuthBase { Callable action) throws Exception { if (remoteUserName.equals("USER4")) { - throw new RuntimeException("USER4 is a disallowed user"); - } else if (remoteUserName.equals("USER2")) { - return action.call(); + throw new RuntimeException("USER4 is a disallowed user!"); } else { - throw new RuntimeException("Unknown user."); + return action.call(); } } @Override public RemoteUserExtractor getRemoteUserExtractor() { return new RemoteUserExtractor() { + boolean useDoAs = false; HttpQueryStringParameterRemoteUserExtractor paramRemoteUserExtractor = new HttpQueryStringParameterRemoteUserExtractor(); HttpRequestRemoteUserExtractor requestRemoteUserExtractor = @@ -100,14 +100,16 @@ public class RemoteUserExtractHttpServerTest extends HttpAuthBase { @Override public String extract(HttpServletRequest request) throws RemoteUserExtractionException { - if (request.getParameter("doAs") != null) { - String doAsUser = request.getParameter("doAs"); - LOG.info("doAsUser is " + doAsUser); + LOG.info(request.toString()); + if (request.getParameter("useDoAs") != null + && request.getParameter("useDoAs").equals("true")) { + useDoAs = true; + } + if (useDoAs) { return paramRemoteUserExtractor.extract(request); } else { - return "USER2"; + throw new RemoteUserExtractionException("HTTP/401"); } - } }; } @@ -135,7 +137,10 @@ public class RemoteUserExtractHttpServerTest extends HttpAuthBase { + ";authentication=BASIC;serialization=PROTOBUF"; url2 = "jdbc:avatica:remote:url=http://localhost:" + server.getPort() - + "?doAs=USER4" + ";authentication=BASIC;serialization=PROTOBUF"; + + "?useDoAs=true" + ";authentication=BASIC;serialization=PROTOBUF"; + + url3 = "jdbc:avatica:remote:url=http://localhost:" + server.getPort() + + "?doAs=USER4&useDoAs=true" + ";authentication=BASIC;serialization=PROTOBUF"; // Create and grant permissions to our users createHsqldbUsers(); @@ -147,23 +152,42 @@ public class RemoteUserExtractHttpServerTest extends HttpAuthBase { } } - @Test public void testUserWithAllowedDoAsRole() throws Exception { - // Disallowed by avatica + @Test public void testUserWithDisallowedRole() throws Exception { + final Properties props = new Properties(); props.put("avatica_user", "USER2"); props.put("avatica_password", "password2"); - readWriteData(url1, "ALLOWED_doAs_AVATICA_USER", props); + try { + readWriteData(url1, "DoAs_not_enabled", props); + fail("Expected an exception"); + } catch (RuntimeException e) { + assertThat(e.getMessage(), containsString("HTTP/401")); + } } - @Test public void testUserWithDisallowedDoAsRole() throws Exception { - // Disallowed by avatica + @Test public void testNoDoAsParam() throws Exception { + final Properties props = new Properties(); props.put("avatica_user", "USER2"); props.put("avatica_password", "password2"); try { - readWriteData(url2, "DISALLOWED_doAs_AVATICA_USER", props); + readWriteData(url2, "No_doAs_Param", props); + fail("Expected an exception"); + } catch (RuntimeException e) { + assertThat(e.getMessage(), containsString("Cannot Extract doAs User")); + } + } + + @Test public void testUserWithDisallowedDoAsRole() throws Exception { + + final Properties props = new Properties(); + props.put("avatica_user", "USER4"); + props.put("avatica_password", "password4"); + + try { + readWriteData(url3, "DISALLOWED_doAs_AVATICA_USER", props); fail("Expected an exception"); } catch (RuntimeException e) { assertThat(e.getMessage(), containsString("USER4 is a disallowed user"));