diff --git a/integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java b/integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java index 1e0d0b89bce..e97c35375c3 100644 --- a/integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java +++ b/integration-tests/src/test/java/org/apache/druid/tests/security/AbstractAuthConfigurationTest.java @@ -66,30 +66,30 @@ import java.util.stream.Collectors; public abstract class AbstractAuthConfigurationTest { private static final Logger LOG = new Logger(AbstractAuthConfigurationTest.class); - private static final String INVALID_NAME = "invalid%2Fname"; + protected static final String INVALID_NAME = "invalid%2Fname"; - static final String SYSTEM_SCHEMA_SEGMENTS_RESULTS_RESOURCE = + protected static final String SYSTEM_SCHEMA_SEGMENTS_RESULTS_RESOURCE = "/results/auth_test_sys_schema_segments.json"; - static final String SYSTEM_SCHEMA_SERVER_SEGMENTS_RESULTS_RESOURCE = + protected static final String SYSTEM_SCHEMA_SERVER_SEGMENTS_RESULTS_RESOURCE = "/results/auth_test_sys_schema_server_segments.json"; - static final String SYSTEM_SCHEMA_SERVERS_RESULTS_RESOURCE = + protected static final String SYSTEM_SCHEMA_SERVERS_RESULTS_RESOURCE = "/results/auth_test_sys_schema_servers.json"; - static final String SYSTEM_SCHEMA_TASKS_RESULTS_RESOURCE = + protected static final String SYSTEM_SCHEMA_TASKS_RESULTS_RESOURCE = "/results/auth_test_sys_schema_tasks.json"; - static final String SYS_SCHEMA_SEGMENTS_QUERY = + protected static final String SYS_SCHEMA_SEGMENTS_QUERY = "SELECT * FROM sys.segments WHERE datasource IN ('auth_test')"; - static final String SYS_SCHEMA_SERVERS_QUERY = + protected static final String SYS_SCHEMA_SERVERS_QUERY = "SELECT * FROM sys.servers WHERE tier IS NOT NULL"; - static final String SYS_SCHEMA_SERVER_SEGMENTS_QUERY = + protected static final String SYS_SCHEMA_SERVER_SEGMENTS_QUERY = "SELECT * FROM sys.server_segments WHERE segment_id LIKE 'auth_test%'"; - static final String SYS_SCHEMA_TASKS_QUERY = + protected static final String SYS_SCHEMA_TASKS_QUERY = "SELECT * FROM sys.tasks WHERE datasource IN ('auth_test')"; - static final TypeReference>> SYS_SCHEMA_RESULTS_TYPE_REFERENCE = + protected static final TypeReference>> SYS_SCHEMA_RESULTS_TYPE_REFERENCE = new TypeReference>>() { }; @@ -98,7 +98,7 @@ public abstract class AbstractAuthConfigurationTest * create a ResourceAction set of permissions that can only read a 'auth_test' datasource, for Authorizer * implementations which use ResourceAction pattern matching */ - static final List DATASOURCE_ONLY_PERMISSIONS = Collections.singletonList( + protected static final List DATASOURCE_ONLY_PERMISSIONS = Collections.singletonList( new ResourceAction( new Resource("auth_test", ResourceType.DATASOURCE), Action.READ @@ -109,7 +109,7 @@ public abstract class AbstractAuthConfigurationTest * create a ResourceAction set of permissions that can only read 'auth_test' + partial SYSTEM_TABLE, for Authorizer * implementations which use ResourceAction pattern matching */ - static final List DATASOURCE_SYS_PERMISSIONS = ImmutableList.of( + protected static final List DATASOURCE_SYS_PERMISSIONS = ImmutableList.of( new ResourceAction( new Resource("auth_test", ResourceType.DATASOURCE), Action.READ @@ -138,7 +138,7 @@ public abstract class AbstractAuthConfigurationTest * create a ResourceAction set of permissions that can only read 'auth_test' + STATE + SYSTEM_TABLE read access, for * Authorizer implementations which use ResourceAction pattern matching */ - static final List DATASOURCE_SYS_STATE_PERMISSIONS = ImmutableList.of( + protected static final List DATASOURCE_SYS_STATE_PERMISSIONS = ImmutableList.of( new ResourceAction( new Resource("auth_test", ResourceType.DATASOURCE), Action.READ @@ -157,7 +157,7 @@ public abstract class AbstractAuthConfigurationTest * create a ResourceAction set of permissions with only STATE and SYSTEM_TABLE read access, for Authorizer * implementations which use ResourceAction pattern matching */ - static final List STATE_ONLY_PERMISSIONS = ImmutableList.of( + protected static final List STATE_ONLY_PERMISSIONS = ImmutableList.of( new ResourceAction( new Resource(".*", ResourceType.STATE), Action.READ @@ -168,44 +168,42 @@ public abstract class AbstractAuthConfigurationTest ) ); - List> adminSegments; - List> adminTasks; - List> adminServers; - List> adminServerSegments; + protected List> adminSegments; + protected List> adminTasks; + protected List> adminServers; + protected List> adminServerSegments; @Inject - IntegrationTestingConfig config; + protected IntegrationTestingConfig config; @Inject - ObjectMapper jsonMapper; + protected ObjectMapper jsonMapper; @Inject @Client - HttpClient httpClient; + protected HttpClient httpClient; @Inject - CoordinatorResourceTestClient coordinatorClient; + protected CoordinatorResourceTestClient coordinatorClient; - HttpClient adminClient; - HttpClient datasourceOnlyUserClient; - HttpClient datasourceAndSysUserClient; - HttpClient datasourceWithStateUserClient; - HttpClient stateOnlyUserClient; - HttpClient internalSystemClient; + protected HttpClient adminClient; + protected HttpClient datasourceOnlyUserClient; + protected HttpClient datasourceAndSysUserClient; + protected HttpClient datasourceWithStateUserClient; + protected HttpClient stateOnlyUserClient; + protected HttpClient internalSystemClient; - abstract void setupDatasourceOnlyUser() throws Exception; - abstract void setupDatasourceAndSysTableUser() throws Exception; - abstract void setupDatasourceAndSysAndStateUser() throws Exception; - abstract void setupSysTableAndStateOnlyUser() throws Exception; - - abstract void setupTestSpecificHttpClients() throws Exception; - - abstract String getAuthenticatorName(); - - abstract String getAuthorizerName(); - - abstract String getExpectedAvaticaAuthError(); + protected abstract void setupDatasourceOnlyUser() throws Exception; + protected abstract void setupDatasourceAndSysTableUser() throws Exception; + protected abstract void setupDatasourceAndSysAndStateUser() throws Exception; + protected abstract void setupSysTableAndStateOnlyUser() throws Exception; + protected abstract void setupTestSpecificHttpClients() throws Exception; + protected abstract String getAuthenticatorName(); + protected abstract String getAuthorizerName(); + protected abstract String getExpectedAvaticaAuthError(); + protected abstract Properties getAvaticaConnectionProperties(); + protected abstract Properties getAvaticaConnectionPropertiesFailure(); @Test public void test_systemSchemaAccess_admin() throws Exception @@ -417,6 +415,7 @@ public abstract class AbstractAuthConfigurationTest Collections.emptyList() ); } + @Test public void test_unsecuredPathWithoutCredentials_allowed() { @@ -496,7 +495,7 @@ public abstract class AbstractAuthConfigurationTest verifyMaliciousUser(); } - void setupHttpClientsAndUsers() throws Exception + protected void setupHttpClientsAndUsers() throws Exception { setupHttpClients(); setupDatasourceOnlyUser(); @@ -505,7 +504,7 @@ public abstract class AbstractAuthConfigurationTest setupSysTableAndStateOnlyUser(); } - void checkNodeAccess(HttpClient httpClient) + protected void checkNodeAccess(HttpClient httpClient) { HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getCoordinatorUrl() + "/status", null); HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getOverlordUrl() + "/status", null); @@ -514,7 +513,7 @@ public abstract class AbstractAuthConfigurationTest HttpUtil.makeRequest(httpClient, HttpMethod.GET, config.getRouterUrl() + "/status", null); } - void checkLoadStatus(HttpClient httpClient) throws Exception + protected void checkLoadStatus(HttpClient httpClient) throws Exception { checkLoadStatusSingle(httpClient, config.getCoordinatorUrl()); checkLoadStatusSingle(httpClient, config.getOverlordUrl()); @@ -523,7 +522,7 @@ public abstract class AbstractAuthConfigurationTest checkLoadStatusSingle(httpClient, config.getRouterUrl()); } - void testOptionsRequests(HttpClient httpClient) + protected void testOptionsRequests(HttpClient httpClient) { HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, config.getCoordinatorUrl() + "/status", null); HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, config.getOverlordUrl() + "/status", null); @@ -532,18 +531,16 @@ public abstract class AbstractAuthConfigurationTest HttpUtil.makeRequest(httpClient, HttpMethod.OPTIONS, config.getRouterUrl() + "/status", null); } - void checkUnsecuredCoordinatorLoadQueuePath(HttpClient client) + protected void checkUnsecuredCoordinatorLoadQueuePath(HttpClient client) { HttpUtil.makeRequest(client, HttpMethod.GET, config.getCoordinatorUrl() + "/druid/coordinator/v1/loadqueue", null); } - void testAvaticaQuery(String url) + protected void testAvaticaQuery(String url) { LOG.info("URL: " + url); try { - Properties connectionProperties = new Properties(); - connectionProperties.setProperty("user", "admin"); - connectionProperties.setProperty("password", "priest"); + Properties connectionProperties = getAvaticaConnectionProperties(); Connection connection = DriverManager.getConnection(url, connectionProperties); Statement statement = connection.createStatement(); statement.setMaxRows(450); @@ -558,13 +555,11 @@ public abstract class AbstractAuthConfigurationTest } } - void testAvaticaAuthFailure(String url) throws Exception + protected void testAvaticaAuthFailure(String url) throws Exception { LOG.info("URL: " + url); try { - Properties connectionProperties = new Properties(); - connectionProperties.setProperty("user", "admin"); - connectionProperties.setProperty("password", "wrongpassword"); + Properties connectionProperties = getAvaticaConnectionPropertiesFailure(); Connection connection = DriverManager.getConnection(url, connectionProperties); Statement statement = connection.createStatement(); statement.setMaxRows(450); @@ -581,9 +576,7 @@ public abstract class AbstractAuthConfigurationTest Assert.fail("Test failed, did not get AvaticaSqlException."); } - private void checkLoadStatusSingle( - HttpClient httpClient, - String baseUrl) throws Exception + protected void checkLoadStatusSingle(HttpClient httpClient, String baseUrl) throws Exception { StatusResponseHolder holder = HttpUtil.makeRequest( httpClient, @@ -595,7 +588,7 @@ public abstract class AbstractAuthConfigurationTest Map loadStatus = jsonMapper.readValue(content, JacksonUtils.TYPE_REFERENCE_MAP_STRING_BOOLEAN); String authenticatorName = getAuthenticatorName(); - Assert.assertNotNull(loadStatus.get(getAuthenticatorName())); + Assert.assertNotNull(loadStatus.get(authenticatorName)); Assert.assertTrue(loadStatus.get(authenticatorName)); holder = HttpUtil.makeRequest( @@ -612,7 +605,7 @@ public abstract class AbstractAuthConfigurationTest Assert.assertTrue(loadStatus.get(authorizerName)); } - StatusResponseHolder makeSQLQueryRequest( + protected StatusResponseHolder makeSQLQueryRequest( HttpClient httpClient, String query, HttpResponseStatus expectedStatus @@ -630,7 +623,7 @@ public abstract class AbstractAuthConfigurationTest ); } - void verifySystemSchemaQueryBase( + protected void verifySystemSchemaQueryBase( HttpClient client, String query, List> expectedResults, @@ -646,7 +639,7 @@ public abstract class AbstractAuthConfigurationTest Assert.assertEquals(responseMap, expectedResults); } - void verifySystemSchemaQuery( + protected void verifySystemSchemaQuery( HttpClient client, String query, List> expectedResults @@ -655,7 +648,7 @@ public abstract class AbstractAuthConfigurationTest verifySystemSchemaQueryBase(client, query, expectedResults, false); } - void verifySystemSchemaServerQuery( + protected void verifySystemSchemaServerQuery( HttpClient client, String query, List> expectedResults @@ -664,7 +657,7 @@ public abstract class AbstractAuthConfigurationTest verifySystemSchemaQueryBase(client, query, expectedResults, true); } - void verifySystemSchemaQueryFailure( + protected void verifySystemSchemaQueryFailure( HttpClient client, String query, HttpResponseStatus expectedErrorStatus, @@ -676,17 +669,17 @@ public abstract class AbstractAuthConfigurationTest Assert.assertEquals(responseHolder.getContent(), expectedErrorMessage); } - String getBrokerAvacticaUrl() + protected String getBrokerAvacticaUrl() { return "jdbc:avatica:remote:url=" + config.getBrokerUrl() + DruidAvaticaJsonHandler.AVATICA_PATH; } - String getRouterAvacticaUrl() + protected String getRouterAvacticaUrl() { return "jdbc:avatica:remote:url=" + config.getRouterUrl() + DruidAvaticaJsonHandler.AVATICA_PATH; } - void verifyAdminOptionsRequest() + protected void verifyAdminOptionsRequest() { HttpClient adminClient = new CredentialedHttpClient( new BasicCredentials("admin", "priest"), @@ -695,7 +688,7 @@ public abstract class AbstractAuthConfigurationTest testOptionsRequests(adminClient); } - void verifyAuthenticationInvalidAuthNameFails() + protected void verifyAuthenticationInvalidAuthNameFails() { verifyInvalidAuthNameFails(StringUtils.format( "%s/druid-ext/basic-security/authentication/listen/%s", @@ -704,7 +697,7 @@ public abstract class AbstractAuthConfigurationTest )); } - void verifyAuthorizationInvalidAuthNameFails() + protected void verifyAuthorizationInvalidAuthNameFails() { verifyInvalidAuthNameFails(StringUtils.format( "%s/druid-ext/basic-security/authorization/listen/users/%s", @@ -713,7 +706,7 @@ public abstract class AbstractAuthConfigurationTest )); } - void verifyGroupMappingsInvalidAuthNameFails() + protected void verifyGroupMappingsInvalidAuthNameFails() { verifyInvalidAuthNameFails(StringUtils.format( "%s/druid-ext/basic-security/authorization/listen/groupMappings/%s", @@ -722,7 +715,7 @@ public abstract class AbstractAuthConfigurationTest )); } - void verifyInvalidAuthNameFails(String endpoint) + protected void verifyInvalidAuthNameFails(String endpoint) { HttpClient adminClient = new CredentialedHttpClient( new BasicCredentials("admin", "priest"), @@ -738,7 +731,7 @@ public abstract class AbstractAuthConfigurationTest ); } - void verifyMaliciousUser() + protected void verifyMaliciousUser() { String maliciousUsername = ""; HttpClient maliciousClient = new CredentialedHttpClient( @@ -757,14 +750,14 @@ public abstract class AbstractAuthConfigurationTest Assert.assertFalse(responseContent.contains(maliciousUsername)); } - void setupHttpClients() throws Exception + protected void setupHttpClients() throws Exception { setupCommonHttpClients(); setupTestSpecificHttpClients(); } - void setupCommonHttpClients() + protected void setupCommonHttpClients() { adminClient = new CredentialedHttpClient( new BasicCredentials("admin", "priest"), @@ -797,7 +790,7 @@ public abstract class AbstractAuthConfigurationTest ); } - void setExpectedSystemSchemaObjects() throws IOException + protected void setExpectedSystemSchemaObjects() throws IOException { // initial setup is done now, run the system schema response content tests adminSegments = jsonMapper.readValue( @@ -833,7 +826,7 @@ public abstract class AbstractAuthConfigurationTest * curr_size on historicals changes because cluster state is not isolated across different * integration tests, zero it out for consistent test results */ - static List> getServersWithoutCurrentSize(List> servers) + protected static List> getServersWithoutCurrentSize(List> servers) { return Lists.transform( servers, @@ -845,12 +838,12 @@ public abstract class AbstractAuthConfigurationTest ); } - static String fillSegementServersTemplate(IntegrationTestingConfig config, String template) + protected static String fillSegementServersTemplate(IntegrationTestingConfig config, String template) { return StringUtils.replace(template, "%%HISTORICAL%%", config.getHistoricalInternalHost()); } - static String fillServersTemplate(IntegrationTestingConfig config, String template) + protected static String fillServersTemplate(IntegrationTestingConfig config, String template) { String json = StringUtils.replace(template, "%%HISTORICAL%%", config.getHistoricalInternalHost()); json = StringUtils.replace(json, "%%BROKER%%", config.getBrokerInternalHost()); diff --git a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java b/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java index 8b82d3b323f..690757f7e31 100644 --- a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java +++ b/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthConfigurationTest.java @@ -36,6 +36,7 @@ import org.testng.annotations.Guice; import org.testng.annotations.Test; import java.util.List; +import java.util.Properties; @Test(groups = TestNGGroup.SECURITY) @Guice(moduleFactory = DruidTestModuleFactory.class) @@ -69,7 +70,7 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest } @Override - void setupDatasourceOnlyUser() throws Exception + protected void setupDatasourceOnlyUser() throws Exception { createUserAndRoleWithPermissions( adminClient, @@ -81,7 +82,7 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest } @Override - void setupDatasourceAndSysTableUser() throws Exception + protected void setupDatasourceAndSysTableUser() throws Exception { createUserAndRoleWithPermissions( adminClient, @@ -93,7 +94,7 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest } @Override - void setupDatasourceAndSysAndStateUser() throws Exception + protected void setupDatasourceAndSysAndStateUser() throws Exception { createUserAndRoleWithPermissions( adminClient, @@ -105,7 +106,7 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest } @Override - void setupSysTableAndStateOnlyUser() throws Exception + protected void setupSysTableAndStateOnlyUser() throws Exception { createUserAndRoleWithPermissions( adminClient, @@ -117,7 +118,7 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest } @Override - void setupTestSpecificHttpClients() throws Exception + protected void setupTestSpecificHttpClients() throws Exception { // create a new user+role that can read /status createUserAndRoleWithPermissions( @@ -168,6 +169,42 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest ); } + @Override + protected String getAuthenticatorName() + { + return BASIC_AUTHENTICATOR; + } + + @Override + protected String getAuthorizerName() + { + return BASIC_AUTHORIZER; + } + + @Override + protected String getExpectedAvaticaAuthError() + { + return EXPECTED_AVATICA_AUTH_ERROR; + } + + @Override + protected Properties getAvaticaConnectionProperties() + { + Properties connectionProperties = new Properties(); + connectionProperties.setProperty("user", "admin"); + connectionProperties.setProperty("password", "priest"); + return connectionProperties; + } + + @Override + protected Properties getAvaticaConnectionPropertiesFailure() + { + Properties connectionProperties = new Properties(); + connectionProperties.setProperty("user", "admin"); + connectionProperties.setProperty("password", "wrongpassword"); + return connectionProperties; + } + private void createUserAndRoleWithPermissions( HttpClient adminClient, String user, @@ -239,22 +276,4 @@ public class ITBasicAuthConfigurationTest extends AbstractAuthConfigurationTest permissionsBytes ); } - - @Override - String getAuthenticatorName() - { - return BASIC_AUTHENTICATOR; - } - - @Override - String getAuthorizerName() - { - return BASIC_AUTHORIZER; - } - - @Override - String getExpectedAvaticaAuthError() - { - return EXPECTED_AVATICA_AUTH_ERROR; - } } diff --git a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java b/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java index edfec4e3866..97a7c531756 100644 --- a/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java +++ b/integration-tests/src/test/java/org/apache/druid/tests/security/ITBasicAuthLdapConfigurationTest.java @@ -42,6 +42,7 @@ import org.testng.annotations.Test; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Properties; @Test(groups = TestNGGroup.LDAP_SECURITY) @Guice(moduleFactory = DruidTestModuleFactory.class) @@ -119,7 +120,7 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT @Override - void setupDatasourceOnlyUser() throws Exception + protected void setupDatasourceOnlyUser() throws Exception { createRoleWithPermissionsAndGroupMapping( "datasourceOnlyGroup", @@ -128,7 +129,7 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT } @Override - void setupDatasourceAndSysTableUser() throws Exception + protected void setupDatasourceAndSysTableUser() throws Exception { createRoleWithPermissionsAndGroupMapping( "datasourceWithSysGroup", @@ -137,7 +138,7 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT } @Override - void setupDatasourceAndSysAndStateUser() throws Exception + protected void setupDatasourceAndSysAndStateUser() throws Exception { createRoleWithPermissionsAndGroupMapping( "datasourceWithStateGroup", @@ -146,7 +147,7 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT } @Override - void setupSysTableAndStateOnlyUser() throws Exception + protected void setupSysTableAndStateOnlyUser() throws Exception { createRoleWithPermissionsAndGroupMapping( "stateOnlyGroup", @@ -163,7 +164,7 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT } @Override - void setupTestSpecificHttpClients() + protected void setupTestSpecificHttpClients() { druidUserClient = new CredentialedHttpClient( new BasicCredentials("druid", "helloworld"), @@ -176,6 +177,42 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT ); } + @Override + protected String getAuthenticatorName() + { + return LDAP_AUTHENTICATOR; + } + + @Override + protected String getAuthorizerName() + { + return LDAP_AUTHORIZER; + } + + @Override + protected String getExpectedAvaticaAuthError() + { + return EXPECTED_AVATICA_AUTH_ERROR; + } + + @Override + protected Properties getAvaticaConnectionProperties() + { + Properties connectionProperties = new Properties(); + connectionProperties.setProperty("user", "admin"); + connectionProperties.setProperty("password", "priest"); + return connectionProperties; + } + + @Override + protected Properties getAvaticaConnectionPropertiesFailure() + { + Properties connectionProperties = new Properties(); + connectionProperties.setProperty("user", "admin"); + connectionProperties.setProperty("password", "wrongpassword"); + return connectionProperties; + } + private void createRoleWithPermissionsAndGroupMapping( String group, Map> roleTopermissions @@ -255,22 +292,4 @@ public class ITBasicAuthLdapConfigurationTest extends AbstractAuthConfigurationT null ); } - - @Override - String getAuthenticatorName() - { - return LDAP_AUTHENTICATOR; - } - - @Override - String getAuthorizerName() - { - return LDAP_AUTHORIZER; - } - - @Override - String getExpectedAvaticaAuthError() - { - return EXPECTED_AVATICA_AUTH_ERROR; - } }