use of org.apache.druid.server.security.AuthenticationResult in project druid by druid-io.
the class NativeQueryMaker method execute.
private <T> Sequence<Object[]> execute(Query<T> query, final List<String> newFields, final List<SqlTypeName> newTypes) {
Hook.QUERY_PLAN.run(query);
if (query.getId() == null) {
final String queryId = UUID.randomUUID().toString();
plannerContext.addNativeQueryId(queryId);
query = query.withId(queryId);
}
query = query.withSqlQueryId(plannerContext.getSqlQueryId());
final AuthenticationResult authenticationResult = plannerContext.getAuthenticationResult();
final Access authorizationResult = plannerContext.getAuthorizationResult();
final QueryLifecycle queryLifecycle = queryLifecycleFactory.factorize();
// After calling "runSimple" the query will start running. We need to do this before reading the toolChest, since
// otherwise it won't yet be initialized. (A bummer, since ideally, we'd verify the toolChest exists and can do
// array-based results before starting the query; but in practice we don't expect this to happen since we keep
// tight control over which query types we generate in the SQL layer. They all support array-based results.)
final Sequence<T> results = queryLifecycle.runSimple(query, authenticationResult, authorizationResult);
// noinspection unchecked
final QueryToolChest<T, Query<T>> toolChest = queryLifecycle.getToolChest();
final List<String> resultArrayFields = toolChest.resultArraySignature(query).getColumnNames();
final Sequence<Object[]> resultArrays = toolChest.resultsAsArrays(query, results);
return mapResultSequence(resultArrays, resultArrayFields, newFields, newTypes);
}
use of org.apache.druid.server.security.AuthenticationResult in project druid by druid-io.
the class QueryResourceTest method testSecuredCancelQuery.
@Test(timeout = 60_000L)
public void testSecuredCancelQuery() throws Exception {
final CountDownLatch waitForCancellationLatch = new CountDownLatch(1);
final CountDownLatch waitFinishLatch = new CountDownLatch(2);
final CountDownLatch startAwaitLatch = new CountDownLatch(1);
final CountDownLatch cancelledCountDownLatch = new CountDownLatch(1);
EasyMock.expect(testServletRequest.getAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED)).andReturn(null).anyTimes();
EasyMock.expect(testServletRequest.getAttribute(AuthConfig.DRUID_ALLOW_UNSECURED_PATH)).andReturn(null).anyTimes();
EasyMock.expect(testServletRequest.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT)).andReturn(AUTHENTICATION_RESULT).anyTimes();
testServletRequest.setAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED, true);
EasyMock.expectLastCall().times(1);
EasyMock.replay(testServletRequest);
AuthorizerMapper authMapper = new AuthorizerMapper(null) {
@Override
public Authorizer getAuthorizer(String name) {
return new Authorizer() {
@Override
public Access authorize(AuthenticationResult authenticationResult, Resource resource, Action action) {
// WRITE corresponds to cancellation of query
if (action.equals(Action.READ)) {
try {
// Countdown startAwaitLatch as we want query cancellation to happen
// after we enter isAuthorized method so that we can handle the
// InterruptedException here because of query cancellation
startAwaitLatch.countDown();
waitForCancellationLatch.await();
} catch (InterruptedException e) {
// When the query is cancelled the control will reach here,
// countdown the latch and rethrow the exception so that error response is returned for the query
cancelledCountDownLatch.countDown();
throw new RuntimeException(e);
}
return new Access(true);
} else {
return new Access(true);
}
}
};
}
};
queryResource = new QueryResource(new QueryLifecycleFactory(WAREHOUSE, TEST_SEGMENT_WALKER, new DefaultGenericQueryMetricsFactory(), new NoopServiceEmitter(), testRequestLogger, new AuthConfig(), authMapper, Suppliers.ofInstance(new DefaultQueryConfig(ImmutableMap.of()))), jsonMapper, smileMapper, queryScheduler, new AuthConfig(), authMapper, ResponseContextConfig.newConfig(true), DRUID_NODE);
final String queryString = "{\"queryType\":\"timeBoundary\", \"dataSource\":\"allow\"," + "\"context\":{\"queryId\":\"id_1\"}}";
ObjectMapper mapper = new DefaultObjectMapper();
Query<?> query = mapper.readValue(queryString, Query.class);
ListenableFuture<?> future = MoreExecutors.listeningDecorator(Execs.singleThreaded("test_query_resource_%s")).submit(new Runnable() {
@Override
public void run() {
try {
Response response = queryResource.doPost(new ByteArrayInputStream(queryString.getBytes(StandardCharsets.UTF_8)), null, testServletRequest);
Assert.assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
} catch (IOException e) {
throw new RuntimeException(e);
}
waitFinishLatch.countDown();
}
});
queryScheduler.registerQueryFuture(query, future);
startAwaitLatch.await();
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
Response response = queryResource.cancelQuery("id_1", testServletRequest);
Assert.assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus());
waitForCancellationLatch.countDown();
waitFinishLatch.countDown();
}
});
waitFinishLatch.await();
cancelledCountDownLatch.await();
}
use of org.apache.druid.server.security.AuthenticationResult in project druid by druid-io.
the class QueryResourceTest method testDenySecuredCancelQuery.
@Test(timeout = 60_000L)
public void testDenySecuredCancelQuery() throws Exception {
final CountDownLatch waitForCancellationLatch = new CountDownLatch(1);
final CountDownLatch waitFinishLatch = new CountDownLatch(2);
final CountDownLatch startAwaitLatch = new CountDownLatch(1);
EasyMock.expect(testServletRequest.getAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED)).andReturn(null).anyTimes();
EasyMock.expect(testServletRequest.getAttribute(AuthConfig.DRUID_ALLOW_UNSECURED_PATH)).andReturn(null).anyTimes();
EasyMock.expect(testServletRequest.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT)).andReturn(AUTHENTICATION_RESULT).anyTimes();
testServletRequest.setAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED, true);
EasyMock.expectLastCall().times(1);
testServletRequest.setAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED, false);
EasyMock.expectLastCall().times(1);
EasyMock.replay(testServletRequest);
AuthorizerMapper authMapper = new AuthorizerMapper(null) {
@Override
public Authorizer getAuthorizer(String name) {
return new Authorizer() {
@Override
public Access authorize(AuthenticationResult authenticationResult, Resource resource, Action action) {
// WRITE corresponds to cancellation of query
if (action.equals(Action.READ)) {
try {
waitForCancellationLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return new Access(true);
} else {
// Deny access to cancel the query
return new Access(false);
}
}
};
}
};
queryResource = new QueryResource(new QueryLifecycleFactory(WAREHOUSE, TEST_SEGMENT_WALKER, new DefaultGenericQueryMetricsFactory(), new NoopServiceEmitter(), testRequestLogger, new AuthConfig(), authMapper, Suppliers.ofInstance(new DefaultQueryConfig(ImmutableMap.of()))), jsonMapper, smileMapper, queryScheduler, new AuthConfig(), authMapper, ResponseContextConfig.newConfig(true), DRUID_NODE);
final String queryString = "{\"queryType\":\"timeBoundary\", \"dataSource\":\"allow\"," + "\"context\":{\"queryId\":\"id_1\"}}";
ObjectMapper mapper = new DefaultObjectMapper();
Query<?> query = mapper.readValue(queryString, Query.class);
ListenableFuture<?> future = MoreExecutors.listeningDecorator(Execs.singleThreaded("test_query_resource_%s")).submit(new Runnable() {
@Override
public void run() {
try {
startAwaitLatch.countDown();
Response response = queryResource.doPost(new ByteArrayInputStream(queryString.getBytes(StandardCharsets.UTF_8)), null, testServletRequest);
Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
} catch (IOException e) {
throw new RuntimeException(e);
}
waitFinishLatch.countDown();
}
});
queryScheduler.registerQueryFuture(query, future);
startAwaitLatch.await();
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
try {
queryResource.cancelQuery("id_1", testServletRequest);
} catch (ForbiddenException e) {
waitForCancellationLatch.countDown();
waitFinishLatch.countDown();
}
}
});
waitFinishLatch.await();
}
use of org.apache.druid.server.security.AuthenticationResult in project druid by druid-io.
the class DruidMeta method prepare.
@Override
public StatementHandle prepare(final ConnectionHandle ch, final String sql, final long maxRowCount) {
try {
final StatementHandle statement = createStatement(ch);
final DruidStatement druidStatement;
try {
druidStatement = getDruidStatement(statement);
} catch (NoSuchStatementException e) {
throw logFailure(new ISE(e, e.getMessage()));
}
final DruidConnection druidConnection = getDruidConnection(statement.connectionId);
AuthenticationResult authenticationResult = authenticateConnection(druidConnection);
if (authenticationResult == null) {
throw logFailure(new ForbiddenException("Authentication failed."), "Authentication failed for statement[%s]", druidStatement.getStatementId());
}
statement.signature = druidStatement.prepare(sql, maxRowCount, authenticationResult).getSignature();
LOG.debug("Successfully prepared statement[%s] for execution", druidStatement.getStatementId());
return statement;
} catch (NoSuchConnectionException e) {
throw e;
} catch (Throwable t) {
throw errorHandler.sanitize(t);
}
}
use of org.apache.druid.server.security.AuthenticationResult in project druid by druid-io.
the class ParallelIndexSupervisorTaskResourceTest method newRequest.
private static HttpServletRequest newRequest() {
final HttpServletRequest request = EasyMock.niceMock(HttpServletRequest.class);
EasyMock.expect(request.getAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED)).andReturn(null);
EasyMock.expect(request.getAttribute(AuthConfig.DRUID_AUTHENTICATION_RESULT)).andReturn(new AuthenticationResult("test", "test", "test", Collections.emptyMap()));
EasyMock.replay(request);
return request;
}
Aggregations