use of com.codahale.metrics.annotation.ExceptionMetered in project keywhiz by square.
the class ClientResource method modifyClient.
/**
* Modify a client
*
* @excludeParams automationClient
* @param currentName Client name
* @param request JSON request to modify the client
*
* @responseMessage 201 Client updated
* @responseMessage 404 Client not found
*/
@Timed
@ExceptionMetered
@POST
@Path("{name}")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public ClientDetailResponseV2 modifyClient(@Auth AutomationClient automationClient, @PathParam("name") String currentName, @Valid ModifyClientRequestV2 request) {
Client client = clientDAOReadWrite.getClient(currentName).orElseThrow(NotFoundException::new);
String newName = request.name();
// TODO: implement change client (name, updatedAt, updatedBy)
throw new NotImplementedException(format("Need to implement mutation methods in DAO to rename %s to %s", client.getName(), newName));
}
use of com.codahale.metrics.annotation.ExceptionMetered in project keywhiz by square.
the class GroupResource method createGroup.
/**
* Creates a group
*
* @excludeParams automationClient
* @param request JSON request to create a group
*
* @responseMessage 201 Created group
* @responseMessage 409 Group already exists
*/
@Timed
@ExceptionMetered
@POST
@Consumes(APPLICATION_JSON)
public Response createGroup(@Auth AutomationClient automationClient, @Valid CreateGroupRequestV2 request) {
String creator = automationClient.getName();
String group = request.name();
groupDAOReadWrite.getGroup(group).ifPresent((g) -> {
logger.info("Automation ({}) - Group {} already exists", creator, group);
throw new ConflictException(format("Group %s already exists", group));
});
groupDAOReadWrite.createGroup(group, creator, request.description(), request.metadata());
Map<String, String> extraInfo = new HashMap<>();
if (request.description() != null) {
extraInfo.put("description", request.description());
}
if (request.metadata() != null) {
extraInfo.put("metadata", request.metadata().toString());
}
auditLog.recordEvent(new Event(Instant.now(), EventTag.GROUP_CREATE, creator, group, extraInfo));
URI uri = UriBuilder.fromResource(GroupResource.class).path(group).build();
return Response.created(uri).build();
}
use of com.codahale.metrics.annotation.ExceptionMetered in project keywhiz by square.
the class GroupResource method groupInfo.
/**
* Retrieve information on a group
*
* @excludeParams automationClient
* @param name Group name
*
* @responseMessage 200 Group information retrieved
* @responseMessage 404 Group not found
*/
@Timed
@ExceptionMetered
@GET
@Path("{name}")
@Produces(APPLICATION_JSON)
public GroupDetailResponseV2 groupInfo(@Auth AutomationClient automationClient, @PathParam("name") String name) {
Group group = groupDAOReadOnly.getGroup(name).orElseThrow(NotFoundException::new);
Set<String> secrets = aclDAOReadOnly.getSanitizedSecretsFor(group).stream().map(SanitizedSecret::name).collect(toSet());
Set<String> clients = aclDAOReadOnly.getClientsFor(group).stream().map(Client::getName).collect(toSet());
return GroupDetailResponseV2.builder().group(group).secrets(secrets).clients(clients).build();
}
use of com.codahale.metrics.annotation.ExceptionMetered in project keywhiz by square.
the class SecretResource method backfillExpiration.
/**
* Backfill expiration for this secret.
*/
@Timed
@ExceptionMetered
@Path("{name}/backfill-expiration")
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public boolean backfillExpiration(@Auth AutomationClient automationClient, @PathParam("name") String name, List<String> passwords) {
Optional<Secret> secretOptional = secretController.getSecretByName(name);
if (!secretOptional.isPresent()) {
throw new NotFoundException("No such secret: " + name);
}
Secret secret = secretOptional.get();
Optional<Instant> existingExpiry = Optional.empty();
if (secret.getExpiry() > 0) {
existingExpiry = Optional.of(Instant.ofEpochMilli(secret.getExpiry()));
}
String secretName = secret.getName();
byte[] secretContent = Base64.getDecoder().decode(secret.getSecret());
// Always try empty password
passwords.add("");
Instant expiry = null;
if (secretName.endsWith(".crt") || secretName.endsWith(".pem") || secretName.endsWith(".key")) {
expiry = ExpirationExtractor.expirationFromEncodedCertificateChain(secretContent);
} else if (secretName.endsWith(".gpg") || secretName.endsWith(".pgp")) {
expiry = ExpirationExtractor.expirationFromOpenPGP(secretContent);
} else if (secretName.endsWith(".p12") || secretName.endsWith(".pfx")) {
while (expiry == null && !passwords.isEmpty()) {
String password = passwords.remove(0);
expiry = ExpirationExtractor.expirationFromKeystore("PKCS12", password, secretContent);
}
} else if (secretName.endsWith(".jceks")) {
while (expiry == null && !passwords.isEmpty()) {
String password = passwords.remove(0);
expiry = ExpirationExtractor.expirationFromKeystore("JCEKS", password, secretContent);
}
} else if (secretName.endsWith(".jks")) {
while (expiry == null && !passwords.isEmpty()) {
String password = passwords.remove(0);
expiry = ExpirationExtractor.expirationFromKeystore("JKS", password, secretContent);
}
}
if (expiry != null) {
if (existingExpiry.isPresent()) {
long offset = existingExpiry.get().until(expiry, HOURS);
if (offset > 24 || offset < -24) {
logger.warn("Extracted expiration of secret {} differs from actual by more than {} hours (extracted = {}, database = {}).", secretName, offset, expiry, existingExpiry.get());
}
// Do not overwrite existing expiry, we just want to check for differences and warn.
return true;
}
logger.info("Found expiry for secret {}: {}", secretName, expiry.getEpochSecond());
boolean success = secretDAO.setExpiration(name, expiry);
if (success) {
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("backfilled expiry", Long.toString(expiry.getEpochSecond()));
auditLog.recordEvent(new Event(Instant.now(), EventTag.SECRET_BACKFILLEXPIRY, automationClient.getName(), name, extraInfo));
}
return success;
}
logger.info("Unable to determine expiry for secret {}", secretName);
return false;
}
use of com.codahale.metrics.annotation.ExceptionMetered in project keywhiz by square.
the class SecretResource method createOrUpdateSecret.
/**
* Creates or updates (if it exists) a secret.
*
* @excludeParams automationClient
* @param request JSON request to create a secret
*
* @responseMessage 201 Created secret and assigned to given groups
*/
@Timed
@ExceptionMetered
@Path("{name}")
@POST
@Consumes(APPLICATION_JSON)
public Response createOrUpdateSecret(@Auth AutomationClient automationClient, @PathParam("name") String name, @Valid CreateOrUpdateSecretRequestV2 request) {
SecretBuilder builder = secretController.builder(name, request.content(), automationClient.getName(), request.expiry()).withDescription(request.description()).withMetadata(request.metadata()).withType(request.type());
builder.createOrUpdate();
Map<String, String> extraInfo = new HashMap<>();
if (request.description() != null) {
extraInfo.put("description", request.description());
}
if (request.metadata() != null) {
extraInfo.put("metadata", request.metadata().toString());
}
extraInfo.put("expiry", Long.toString(request.expiry()));
auditLog.recordEvent(new Event(Instant.now(), EventTag.SECRET_CREATEORUPDATE, automationClient.getName(), name, extraInfo));
UriBuilder uriBuilder = UriBuilder.fromResource(SecretResource.class).path(name);
return Response.created(uriBuilder.build()).build();
}
Aggregations