use of io.druid.server.security.Action in project druid by druid-io.
the class QueryResourceTest method testSecuredGetServer.
@Test(timeout = 60_000L)
public void testSecuredGetServer() 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(EasyMock.anyString())).andReturn(new AuthorizationInfo() {
@Override
public Access isAuthorized(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();
Throwables.propagate(e);
}
return new Access(true);
} else {
return new Access(true);
}
}
}).times(2);
EasyMock.replay(testServletRequest);
queryResource = new QueryResource(warehouse, serverConfig, jsonMapper, jsonMapper, testSegmentWalker, new NoopServiceEmitter(), new NoopRequestLogger(), queryManager, new AuthConfig(true));
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("UTF-8")), null, testServletRequest);
Assert.assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
} catch (IOException e) {
Throwables.propagate(e);
}
waitFinishLatch.countDown();
}
});
queryManager.registerQuery(query, future);
startAwaitLatch.await();
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
Response response = queryResource.getServer("id_1", testServletRequest);
Assert.assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatus());
waitForCancellationLatch.countDown();
waitFinishLatch.countDown();
}
});
waitFinishLatch.await();
cancelledCountDownLatch.await();
}
use of io.druid.server.security.Action in project druid by druid-io.
the class OverlordResourceTest method setUp.
@Before
public void setUp() throws Exception {
taskRunner = EasyMock.createMock(TaskRunner.class);
taskMaster = EasyMock.createStrictMock(TaskMaster.class);
tsqa = EasyMock.createStrictMock(TaskStorageQueryAdapter.class);
req = EasyMock.createStrictMock(HttpServletRequest.class);
EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes();
overlordResource = new OverlordResource(taskMaster, tsqa, null, null, null, new AuthConfig(true));
EasyMock.expect(req.getAttribute(AuthConfig.DRUID_AUTH_TOKEN)).andReturn(new AuthorizationInfo() {
@Override
public Access isAuthorized(Resource resource, Action action) {
if (resource.getName().equals("allow")) {
return new Access(true);
} else {
return new Access(false);
}
}
});
}
use of io.druid.server.security.Action in project druid by druid-io.
the class MetadataResource method getDatabaseDataSources.
@GET
@Path("/datasources")
@Produces(MediaType.APPLICATION_JSON)
public Response getDatabaseDataSources(@QueryParam("full") final String full, @QueryParam("includeDisabled") final String includeDisabled, @Context final HttpServletRequest req) {
final Set<String> dataSourceNamesPreAuth;
if (includeDisabled != null) {
dataSourceNamesPreAuth = Sets.newTreeSet(metadataSegmentManager.getAllDatasourceNames());
} else {
dataSourceNamesPreAuth = Sets.newTreeSet(Iterables.transform(metadataSegmentManager.getInventory(), new Function<DruidDataSource, String>() {
@Override
public String apply(DruidDataSource input) {
return input.getName();
}
}));
}
final Set<String> dataSourceNamesPostAuth;
if (authConfig.isEnabled()) {
// This is an experimental feature, see - https://github.com/druid-io/druid/pull/2424
final Map<Pair<Resource, Action>, Access> resourceAccessMap = new HashMap<>();
final AuthorizationInfo authorizationInfo = (AuthorizationInfo) req.getAttribute(AuthConfig.DRUID_AUTH_TOKEN);
dataSourceNamesPostAuth = ImmutableSet.copyOf(Sets.filter(dataSourceNamesPreAuth, new Predicate<String>() {
@Override
public boolean apply(String input) {
Resource resource = new Resource(input, ResourceType.DATASOURCE);
Action action = Action.READ;
Pair<Resource, Action> key = new Pair<>(resource, action);
if (resourceAccessMap.containsKey(key)) {
return resourceAccessMap.get(key).isAllowed();
} else {
Access access = authorizationInfo.isAuthorized(key.lhs, key.rhs);
resourceAccessMap.put(key, access);
return access.isAllowed();
}
}
}));
} else {
dataSourceNamesPostAuth = dataSourceNamesPreAuth;
}
// Always use dataSourceNamesPostAuth to determine the set of returned dataSources
if (full != null && includeDisabled == null) {
return Response.ok().entity(Collections2.filter(metadataSegmentManager.getInventory(), new Predicate<DruidDataSource>() {
@Override
public boolean apply(DruidDataSource input) {
return dataSourceNamesPostAuth.contains(input.getName());
}
})).build();
} else {
return Response.ok().entity(dataSourceNamesPostAuth).build();
}
}
use of io.druid.server.security.Action in project druid by druid-io.
the class OverlordResource method getCompleteTasks.
@GET
@Path("/completeTasks")
@Produces(MediaType.APPLICATION_JSON)
public Response getCompleteTasks(@Context final HttpServletRequest req) {
final List<TaskStatus> recentlyFinishedTasks;
if (authConfig.isEnabled()) {
// This is an experimental feature, see - https://github.com/druid-io/druid/pull/2424
final Map<Pair<Resource, Action>, Access> resourceAccessMap = new HashMap<>();
final AuthorizationInfo authorizationInfo = (AuthorizationInfo) req.getAttribute(AuthConfig.DRUID_AUTH_TOKEN);
recentlyFinishedTasks = ImmutableList.copyOf(Iterables.filter(taskStorageQueryAdapter.getRecentlyFinishedTaskStatuses(), new Predicate<TaskStatus>() {
@Override
public boolean apply(TaskStatus input) {
final String taskId = input.getId();
final Optional<Task> optionalTask = taskStorageQueryAdapter.getTask(taskId);
if (!optionalTask.isPresent()) {
throw new WebApplicationException(Response.serverError().entity(String.format("No task information found for task with id: [%s]", taskId)).build());
}
Resource resource = new Resource(optionalTask.get().getDataSource(), ResourceType.DATASOURCE);
Action action = Action.READ;
Pair<Resource, Action> key = new Pair<>(resource, action);
if (resourceAccessMap.containsKey(key)) {
return resourceAccessMap.get(key).isAllowed();
} else {
Access access = authorizationInfo.isAuthorized(key.lhs, key.rhs);
resourceAccessMap.put(key, access);
return access.isAllowed();
}
}
}));
} else {
recentlyFinishedTasks = taskStorageQueryAdapter.getRecentlyFinishedTaskStatuses();
}
final List<TaskResponseObject> completeTasks = Lists.transform(recentlyFinishedTasks, new Function<TaskStatus, TaskResponseObject>() {
@Override
public TaskResponseObject apply(TaskStatus taskStatus) {
// Would be nice to include the real created date, but the TaskStorage API doesn't yet allow it.
return new TaskResponseObject(taskStatus.getId(), new DateTime(0), new DateTime(0), Optional.of(taskStatus), TaskLocation.unknown());
}
});
return Response.ok(completeTasks).build();
}
use of io.druid.server.security.Action in project druid by druid-io.
the class OverlordResource method getWaitingTasks.
@GET
@Path("/waitingTasks")
@Produces(MediaType.APPLICATION_JSON)
public Response getWaitingTasks(@Context final HttpServletRequest req) {
return workItemsResponse(new Function<TaskRunner, Collection<? extends TaskRunnerWorkItem>>() {
@Override
public Collection<? extends TaskRunnerWorkItem> apply(TaskRunner taskRunner) {
// A bit roundabout, but works as a way of figuring out what tasks haven't been handed
// off to the runner yet:
final List<Task> allActiveTasks = taskStorageQueryAdapter.getActiveTasks();
final List<Task> activeTasks;
if (authConfig.isEnabled()) {
// This is an experimental feature, see - https://github.com/druid-io/druid/pull/2424
final Map<Pair<Resource, Action>, Access> resourceAccessMap = new HashMap<>();
final AuthorizationInfo authorizationInfo = (AuthorizationInfo) req.getAttribute(AuthConfig.DRUID_AUTH_TOKEN);
activeTasks = ImmutableList.copyOf(Iterables.filter(allActiveTasks, new Predicate<Task>() {
@Override
public boolean apply(Task input) {
Resource resource = new Resource(input.getDataSource(), ResourceType.DATASOURCE);
Action action = Action.READ;
Pair<Resource, Action> key = new Pair<>(resource, action);
if (resourceAccessMap.containsKey(key)) {
return resourceAccessMap.get(key).isAllowed();
} else {
Access access = authorizationInfo.isAuthorized(key.lhs, key.rhs);
resourceAccessMap.put(key, access);
return access.isAllowed();
}
}
}));
} else {
activeTasks = allActiveTasks;
}
final Set<String> runnersKnownTasks = Sets.newHashSet(Iterables.transform(taskRunner.getKnownTasks(), new Function<TaskRunnerWorkItem, String>() {
@Override
public String apply(final TaskRunnerWorkItem workItem) {
return workItem.getTaskId();
}
}));
final List<TaskRunnerWorkItem> waitingTasks = Lists.newArrayList();
for (final Task task : activeTasks) {
if (!runnersKnownTasks.contains(task.getId())) {
waitingTasks.add(// Would be nice to include the real created date, but the TaskStorage API doesn't yet allow it.
new TaskRunnerWorkItem(task.getId(), SettableFuture.<TaskStatus>create(), new DateTime(0), new DateTime(0)) {
@Override
public TaskLocation getLocation() {
return TaskLocation.unknown();
}
});
}
}
return waitingTasks;
}
});
}
Aggregations