Search in sources :

Example 36 with ExceptionMetered

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));
}
Also used : NotImplementedException(org.apache.commons.lang3.NotImplementedException) NotFoundException(javax.ws.rs.NotFoundException) AutomationClient(keywhiz.api.model.AutomationClient) Client(keywhiz.api.model.Client) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) Timed(com.codahale.metrics.annotation.Timed) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 37 with ExceptionMetered

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();
}
Also used : ConflictException(keywhiz.service.exceptions.ConflictException) HashMap(java.util.HashMap) Event(keywhiz.log.Event) URI(java.net.URI) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Timed(com.codahale.metrics.annotation.Timed) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 38 with ExceptionMetered

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();
}
Also used : Group(keywhiz.api.model.Group) NotFoundException(javax.ws.rs.NotFoundException) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) Timed(com.codahale.metrics.annotation.Timed) GET(javax.ws.rs.GET) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 39 with ExceptionMetered

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;
}
Also used : Secret(keywhiz.api.model.Secret) SanitizedSecret(keywhiz.api.model.SanitizedSecret) HashMap(java.util.HashMap) Instant(java.time.Instant) NotFoundException(javax.ws.rs.NotFoundException) Event(keywhiz.log.Event) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) Timed(com.codahale.metrics.annotation.Timed) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 40 with ExceptionMetered

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();
}
Also used : SecretBuilder(keywhiz.service.daos.SecretController.SecretBuilder) HashMap(java.util.HashMap) Event(keywhiz.log.Event) UriBuilder(javax.ws.rs.core.UriBuilder) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Timed(com.codahale.metrics.annotation.Timed) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Aggregations

ExceptionMetered (com.codahale.metrics.annotation.ExceptionMetered)54 Timed (com.codahale.metrics.annotation.Timed)53 Path (javax.ws.rs.Path)36 Event (keywhiz.log.Event)29 HashMap (java.util.HashMap)28 NotFoundException (javax.ws.rs.NotFoundException)27 POST (javax.ws.rs.POST)25 Consumes (javax.ws.rs.Consumes)20 Produces (javax.ws.rs.Produces)20 DELETE (javax.ws.rs.DELETE)18 GET (javax.ws.rs.GET)17 Group (keywhiz.api.model.Group)16 SanitizedSecret (keywhiz.api.model.SanitizedSecret)16 Response (javax.ws.rs.core.Response)12 AutomationClient (keywhiz.api.model.AutomationClient)12 ConflictException (keywhiz.service.exceptions.ConflictException)12 Client (keywhiz.api.model.Client)11 Secret (keywhiz.api.model.Secret)11 URI (java.net.URI)9 PUT (javax.ws.rs.PUT)9