use of co.cask.cdap.common.security.AuditPolicy in project cdap by caskdata.
the class RouteConfigHttpHandler method storeRouteConfig.
@PUT
@Path("/routeconfig")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void storeRouteConfig(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-id") String appId, @PathParam("service-id") String serviceId) throws Exception {
NamespaceId namespace = new NamespaceId(namespaceId);
ProgramId programId = namespace.app(appId).service(serviceId);
Map<String, Integer> routes = parseBody(request, ROUTE_CONFIG_TYPE);
if (routes == null || routes.isEmpty()) {
throw new BadRequestException("Route config contains invalid format or empty content.");
}
List<ProgramId> nonExistingServices = new ArrayList<>();
for (String version : routes.keySet()) {
ProgramId routeProgram = namespace.app(appId, version).service(serviceId);
if (lifecycleService.getProgramSpecification(routeProgram) == null) {
nonExistingServices.add(routeProgram);
}
}
if (nonExistingServices.size() > 0) {
throw new BadRequestException("The following versions of the application/service could not be found : " + nonExistingServices);
}
RouteConfig routeConfig = new RouteConfig(routes);
if (!routeConfig.isValid()) {
throw new BadRequestException("Route Percentage needs to add up to 100.");
}
routeStore.store(programId, routeConfig);
responder.sendStatus(HttpResponseStatus.OK);
}
use of co.cask.cdap.common.security.AuditPolicy in project cdap by caskdata.
the class SecureStoreHandler method create.
@Path("/{key-name}")
@PUT
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void create(HttpRequest httpRequest, HttpResponder httpResponder, @PathParam("namespace-id") String namespace, @PathParam("key-name") String name) throws Exception {
SecureKeyId secureKeyId = new SecureKeyId(namespace, name);
SecureKeyCreateRequest secureKeyCreateRequest = parseBody(httpRequest, SecureKeyCreateRequest.class);
if (secureKeyCreateRequest == null) {
SecureKeyCreateRequest dummy = new SecureKeyCreateRequest("<description>", "<data>", ImmutableMap.of("key", "value"));
throw new BadRequestException("Unable to parse the request. The request body should be of the following format." + " \n" + GSON.toJson(dummy));
}
secureStoreManager.putSecureData(namespace, name, secureKeyCreateRequest.getData(), secureKeyCreateRequest.getDescription(), secureKeyCreateRequest.getProperties());
httpResponder.sendStatus(HttpResponseStatus.OK);
}
use of co.cask.cdap.common.security.AuditPolicy in project cdap by caskdata.
the class ExploreExecutorHttpHandler method enableStream.
@POST
@Path("streams/{stream}/tables/{table}/enable")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void enableStream(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespace, @PathParam("stream") String streamName, @PathParam("table") final String tableName) throws Exception {
final StreamId streamId = new StreamId(namespace, streamName);
try (Reader reader = new InputStreamReader(new ChannelBufferInputStream(request.getContent()))) {
final FormatSpecification format = GSON.fromJson(reader, FormatSpecification.class);
if (format == null) {
throw new BadRequestException("Expected format in the body");
}
QueryHandle handle = impersonator.doAs(streamId, new Callable<QueryHandle>() {
@Override
public QueryHandle call() throws Exception {
return exploreTableManager.enableStream(tableName, streamId, format);
}
});
JsonObject json = new JsonObject();
json.addProperty("handle", handle.getHandle());
responder.sendJson(HttpResponseStatus.OK, json);
} catch (UnsupportedTypeException e) {
LOG.error("Exception while generating create statement for stream {}", streamName, e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
}
}
use of co.cask.cdap.common.security.AuditPolicy in project cdap by caskdata.
the class RouterAuditLookUp method createMatcher.
private int createMatcher() {
List<Class<?>> handlerClasses;
try {
handlerClasses = getAllHandlerClasses();
} catch (IOException e) {
LOG.error("Failed to get all handler classes for audit logging: {}", e.getCause());
return -1;
}
int count = 0;
for (Class<?> handlerClass : handlerClasses) {
Path classPath = handlerClass.getAnnotation(Path.class);
String classPathStr = classPath == null ? "" : classPath.value();
for (Method method : handlerClass.getMethods()) {
Path methodPath = method.getAnnotation(Path.class);
AuditPolicy auditPolicy = method.getAnnotation(AuditPolicy.class);
HttpMethod httpMethod = getHttpMethod(method);
if (methodPath == null || auditPolicy == null || httpMethod == null) {
continue;
}
String methodPathStr = methodPath.value();
String completePath = classPathStr.endsWith("/") || methodPathStr.startsWith("/") ? classPathStr + methodPathStr : classPathStr + "/" + methodPathStr;
List<AuditDetail> auditContents = Arrays.asList(auditPolicy.value());
List<String> headerNames = new ArrayList<>();
if (auditContents.contains(AuditDetail.HEADERS)) {
Annotation[][] annotations = method.getParameterAnnotations();
for (Annotation[] annotationArr : annotations) {
if (annotationArr.length > 0) {
for (Annotation annotation : annotationArr) {
if (annotation instanceof HeaderParam) {
headerNames.add(((HeaderParam) annotation).value());
}
}
}
}
}
AuditLogContent auditLogContent = new AuditLogContent(httpMethod, auditContents.contains(AuditDetail.REQUEST_BODY), auditContents.contains(AuditDetail.RESPONSE_BODY), headerNames);
LOG.trace("Audit log lookup: bootstrapped with path: {}", completePath);
patternMatcher.add(completePath, auditLogContent);
count++;
}
}
LOG.debug("Audit log lookup: bootstrapped with {} paths", count);
return count;
}
use of co.cask.cdap.common.security.AuditPolicy in project cdap by caskdata.
the class AppLifecycleHttpHandler method updateApp.
/**
* Updates an existing application.
*/
@POST
@Path("/apps/{app-id}/update")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void updateApp(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") final String namespaceId, @PathParam("app-id") final String appName) throws NotFoundException, BadRequestException, UnauthorizedException, IOException {
ApplicationId appId = validateApplicationId(namespaceId, appName);
AppRequest appRequest;
try (Reader reader = new InputStreamReader(new ChannelBufferInputStream(request.getContent()), Charsets.UTF_8)) {
appRequest = GSON.fromJson(reader, AppRequest.class);
} catch (IOException e) {
LOG.error("Error reading request to update app {} in namespace {}.", appName, namespaceId, e);
throw new IOException("Error reading request body.");
} catch (JsonSyntaxException e) {
throw new BadRequestException("Request body is invalid json: " + e.getMessage());
}
try {
applicationLifecycleService.updateApp(appId, appRequest, createProgramTerminator());
responder.sendString(HttpResponseStatus.OK, "Update complete.");
} catch (InvalidArtifactException e) {
throw new BadRequestException(e.getMessage());
} catch (ConflictException e) {
responder.sendString(HttpResponseStatus.CONFLICT, e.getMessage());
} catch (NotFoundException | UnauthorizedException e) {
throw e;
} catch (Exception e) {
// this is the same behavior as deploy app pipeline, but this is bad behavior. Error handling needs improvement.
LOG.error("Deploy failure", e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
}
}
Aggregations