下面列出了怎么用com.codahale.metrics.annotation.ExceptionMetered的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Deletes a group
*
* @param automationClient the client with automation access performing this operation
* @param groupId the ID of the group to delete
* @return 200 if the group was removed successfully, 404 if the group was not found
*
* description Deletes a single group by id
* responseMessage 200 Deleted group
* responseMessage 404 Group not found by id
*/
@Timed @ExceptionMetered
@DELETE
@Path("{groupId}")
public Response deleteGroup(
@Auth AutomationClient automationClient,
@PathParam("groupId") LongParam groupId) {
Group group = groupDAO.getGroupById(groupId.get()).orElseThrow(NotFoundException::new);
groupDAO.deleteGroup(group);
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("deprecated", "true");
auditLog.recordEvent(
new Event(Instant.now(), EventTag.GROUP_DELETE, automationClient.getName(), group.getName(),
extraInfo));
return Response.ok().build();
}
/**
* Load configuration to check whether a field should be enabled for a given format
*/
@DirectMethod
@Timed
@ExceptionMetered
@RequiresAuthentication
@RequiresPermissions("nexus:*")
@Validate
public Map<String, Map<String, Boolean>> getApplicableFields(final List<String> fields) {
Map<String, Map<String, Boolean>> applicability = new HashMap<>();
for (Entry<String, CleanupPolicyConfiguration> config : cleanupPolicyConfiguration.entrySet()) {
String format = config.getKey();
Map<String, Boolean> fieldApplicability = fields.stream()
.collect(toMap(identity(), f -> isFieldApplicable(format, f)));
applicability.put(format, fieldApplicability);
}
return applicability;
}
@DirectMethod
@Timed
@ExceptionMetered
@Validate
public UserXO authenticate(@NotEmpty final String base64Username, @NotEmpty final String base64Password)
throws Exception
{
Subject subject = securitySystem.getSubject();
// FIXME: Subject is not nullable, but we have code that checks for nulls, likely from testing setups, verify and simplify
checkState(subject != null);
try {
subject.login(new UsernamePasswordToken(
Strings2.decodeBase64(base64Username),
Strings2.decodeBase64(base64Password),
false
));
}
catch (Exception e) {
throw new Exception("Authentication failed", e);
}
return getUser();
}
@DirectMethod
@Timed
@ExceptionMetered
public UserXO getUser() {
UserXO userXO = null;
Subject subject = securitySystem.getSubject();
if (subject != null && subject.isAuthenticated()) {
userXO = new UserXO();
userXO.setAuthenticated(subject.isAuthenticated());
userXO.setAuthenticatedRealms(subject.getPrincipals().getRealmNames());
// HACK: roles for the current user are not exposed to the UI.
// HACK: but we need to know if user is admin or not for some things (like outreach)
if (subject.isPermitted(new WildcardPermission2("nexus:*"))) {
userXO.setAdministrator(true);
}
Object principal = subject.getPrincipal();
if (principal != null) {
userXO.setId(principal.toString());
}
}
return userXO;
}
@DirectMethod
@Timed
@ExceptionMetered
public void recordEvent(final LogEventXO event) {
if (!enabled) {
return;
}
checkNotNull(event);
Level level = levels.get(event.getLevel());
checkState(level != null, "Invalid level: %s", event.getLevel());
Logger logger = LoggerFactory.getLogger(event.getLogger());
level.log(logger, event.getMessage());
}
/**
* Logout and remove any session cookies
*
* @return 200 on success
* description Log out and remove any session cookies
* responseMessage 200 Logged out successfully
*/
@Timed @ExceptionMetered
@POST
@Produces(APPLICATION_JSON)
public Response logout(@Nullable @CookieParam(value = "session") Cookie sessionCookie) {
if (sessionCookie != null) {
Optional<User> user = cookieAuthenticator.authenticate(sessionCookie);
if (user.isPresent()) {
logger.info("User logged out: {}", user.get().getName());
} else {
logger.warn("Invalid user cookie on logout.");
}
}
NewCookie expiredCookie = cookieFactory.getExpiredSessionCookie();
return Response.ok()
.header(HttpHeaders.SET_COOKIE, expiredCookie.toString())
.build();
}
/**
* Delete Client by ID
*
* @param user the admin user deleting this client
* @param clientId the ID of the Client to be deleted
* @return 200 if the deletion was successful, 404 if the client was not found
* <p>
* description Deletes a single Client if found. Used by Keywhiz CLI and the web ui.
* <p>
* responseMessage 200 Found and deleted Client with given ID
* <p>
* responseMessage 404 Client with given ID not Found
*/
@Path("{clientId}")
@Timed @ExceptionMetered
@DELETE
public Response deleteClient(@Auth User user, @PathParam("clientId") LongParam clientId) {
logger.info("User '{}' deleting client id={}.", user, clientId);
Optional<Client> client = clientDAO.getClientById(clientId.get());
if (!client.isPresent()) {
throw new NotFoundException("Client not found.");
}
clientDAO.deleteClient(client.get());
auditLog.recordEvent(
new Event(Instant.now(), EventTag.CLIENT_DELETE, user.getName(), client.get().getName()));
return Response.noContent().build();
}
/**
* Reset the current version of the given secret to the given version index.
*
* @param request A request to update a given secret
*
* responseMessage 201 Secret series current version updated successfully
* responseMessage 400 Invalid secret version specified
* responseMessage 404 Secret series not found
*/
@Timed @ExceptionMetered
@Path("{name}/setversion")
@POST
public Response resetSecretVersion(@Auth AutomationClient automationClient,
@Valid SetSecretVersionRequestV2 request) {
secretDAO.setCurrentSecretVersionByName(request.name(), request.version(),
automationClient.getName());
// If the secret wasn't found or the request was misformed, setCurrentSecretVersionByName
// already threw an exception
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("new version", Long.toString(request.version()));
auditLog.recordEvent(new Event(Instant.now(), EventTag.SECRET_CHANGEVERSION,
automationClient.getName(), request.name(), extraInfo));
return Response.status(Response.Status.CREATED).build();
}
/**
* Delete Group by ID
*
* @param user the admin user performing this operation
* @param groupId the ID of the Group to be deleted
* @return 200 if the deletion succeeded, 404 if the group was not found
*
* description Deletes a single Group if found.
* Used by Keywhiz CLI and the web ui.
* responseMessage 200 Found and deleted Group with given ID
* responseMessage 404 Group with given ID not Found
*/
@Path("{groupId}")
@Timed @ExceptionMetered
@DELETE
public Response deleteGroup(@Auth User user, @PathParam("groupId") LongParam groupId) {
logger.info("User '{}' deleting group id={}.", user, groupId);
Optional<Group> group = groupDAO.getGroupById(groupId.get());
if (!group.isPresent()) {
throw new NotFoundException("Group not found.");
}
groupDAO.deleteGroup(group.get());
auditLog.recordEvent(new Event(Instant.now(), EventTag.GROUP_DELETE, user.getName(), group.get().getName()));
return Response.noContent().build();
}
/**
* Retrieve Secret by a specified name and version, or all Secrets if name is not given
*
* @param user the admin user performing this operation
* @param name the name of the Secret to retrieve, if provided
* @param nameOnly if set, the result only contains the id and name for the secrets.
* @param idx if set, the desired starting index in a list of secrets to be retrieved
* @param num if set, the number of secrets to retrieve
* @param newestFirst whether to order the secrets by creation date with newest first; defaults to
* true
* @return a single Secret or a set of all Secrets for this user.
* <p>
* Used by Keywhiz CLI and the web ui.
* <p>
* responseMessage 200 Found and retrieved Secret(s)
* <p>
* responseMessage 404 Secret with given name not found (if name provided)
*/
@Timed @ExceptionMetered
@GET
public Response findSecrets(@Auth User user, @DefaultValue("") @QueryParam("name") String name,
@DefaultValue("") @QueryParam("nameOnly") String nameOnly, @QueryParam("idx") Integer idx,
@QueryParam("num") Integer num,
@DefaultValue("true") @QueryParam("newestFirst") Boolean newestFirst) {
if (!name.isEmpty() && idx != null && num != null) {
throw new BadRequestException("Name and idx/num cannot both be specified");
}
validateArguments(name, nameOnly, idx, num);
if (name.isEmpty()) {
if (nameOnly.isEmpty()) {
if (idx == null || num == null) {
return Response.ok().entity(listSecrets(user)).build();
} else {
return Response.ok().entity(listSecretsBatched(user, idx, num, newestFirst)).build();
}
} else {
return Response.ok().entity(listSecretsNameOnly(user)).build();
}
}
return Response.ok().entity(retrieveSecret(user, name)).build();
}
public EventDriverMetrics(final Class<?> endpointClass, MetricRegistry metrics) {
final Class<?> klass = endpointClass;
Metered metered = klass.getAnnotation(Metered.class);
Timed timed = klass.getAnnotation(Timed.class);
ExceptionMetered em = klass.getAnnotation(ExceptionMetered.class);
this.onTextMeter = metered != null
? Optional.of(metrics.meter(MetricRegistry.name(metered.name(), klass.getName(), OnMessage.class.getSimpleName())))
: Optional.empty();
this.countOpened = metered != null
? Optional.of(metrics.counter(MetricRegistry.name(metered.name(), klass.getName(), OPEN_CONNECTIONS)))
: Optional.empty();
this.timer = timed != null
? Optional.of(metrics.timer(MetricRegistry.name(timed.name(), klass.getName())))
: Optional.empty();
this.exceptionMetered = em != null
? Optional.of(metrics.meter(MetricRegistry.name(em.name(), klass.getName(), OnError.class.getSimpleName())))
: Optional.empty();
}
/**
* Remove Secret from Group
*
* @param automationClient the client with automation access performing this operation
* @param secretId the ID of the Secret to unassign
* @param groupId the ID of the Group to be removed from
* @return 200 on success, 404 if the secret or group is absent
*
* description Unassigns the Secret specified by the secretID from the Group specified by the groupID
* responseMessage 200 Successfully removed Secret from Group
* responseMessage 404 Could not find Secret or Group
*/
@Timed @ExceptionMetered
@DELETE
public Response disallowAccess(
@Auth AutomationClient automationClient,
@PathParam("secretId") LongParam secretId,
@PathParam("groupId") LongParam groupId) {
logger.info("Client '{}' disallowing groupId={} access to secretId={}",
automationClient, secretId, groupId);
try {
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("deprecated", "true");
aclDAO.findAndRevokeAccess(secretId.get(), groupId.get(), auditLog, automationClient.getName(), extraInfo);
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Rollback to a previous secret version
*
* @param user the admin user performing this operation
* @param secretName the name of the secret to rollback
* @param versionId the ID of the version to return to
* @return 200 if the rollback was successful, 404 for missing secret or bad input
* <p>
* description Returns the previous versions of the secret if found Used by Keywhiz CLI.
* <p>
* responseMessage 200 Found and reset the secret to this version
* <p>
* responseMessage 404 Secret with given name not found or invalid version provided
*/
@Path("rollback/{secretName}/{versionId}")
@Timed @ExceptionMetered
@POST
public Response resetSecretVersion(@Auth User user, @PathParam("secretName") String secretName,
@PathParam("versionId") LongParam versionId) {
logger.info("User '{}' rolling back secret '{}' to version with ID '{}'.", user, secretName,
versionId);
secretDAOReadWrite.setCurrentSecretVersionByName(secretName, versionId.get(), user.getName());
// If the secret wasn't found or the request was misformed, setCurrentSecretVersionByName
// already threw an exception
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("new version", versionId.toString());
auditLog.recordEvent(
new Event(Instant.now(), EventTag.SECRET_CHANGEVERSION, user.getName(), secretName,
extraInfo));
// Send the new secret in response
URI uri = UriBuilder.fromResource(SecretsResource.class)
.path("rollback/{secretName}/{versionID}")
.build(secretName, versionId);
return Response.created(uri).entity(secretDetailResponseFromName(secretName)).build();
}
/**
* Retrieve Group by a specified name, or all Groups if no name given
*
* @param automationClient the client with automation access performing this operation
* @param name the name of the Group to retrieve, if provided
* @return details on the specified group, or an all groups if no name specified
*
* optionalParams name
* description Returns a single Group or a set of all Groups
* responseMessage 200 Found and retrieved Group(s)
* responseMessage 404 Group with given name not found (if name provided)
*/
@Timed @ExceptionMetered
@GET
public Response getGroupByName(
@Auth AutomationClient automationClient,
@QueryParam("name") Optional<String> name) {
if (name.isPresent()) {
Group group = groupDAO.getGroup(name.get()).orElseThrow(NotFoundException::new);
ImmutableList<Client> clients = ImmutableList.copyOf(aclDAO.getClientsFor(group));
ImmutableList<SanitizedSecret> sanitizedSecrets =
ImmutableList.copyOf(aclDAO.getSanitizedSecretsFor(group));
return Response.ok()
.entity(GroupDetailResponse.fromGroup(group, sanitizedSecrets, clients))
.build();
}
ImmutableList<SanitizedSecret> emptySecrets = ImmutableList.of();
ImmutableList<Client> emptyClients = ImmutableList.of();
List<GroupDetailResponse> groups = groupDAO.getGroups().stream()
.map((g) -> GroupDetailResponse.fromGroup(g, emptySecrets, emptyClients))
.collect(toList());
return Response.ok()
.entity(groups)
.build();
}
/**
* Allow a Group to access this Secret
*
* @param user the admin user performing this operation
* @param secretId ID value of a Secret
* @param groupId ID value of a Group
* @return 200 on success, 404 if secret or group is missing
*
* description Assigns the Secret specified by the secretID to the Group specified by the groupID
* Used by Keywhiz CLI and the web ui.
* responseMessage 200 Successfully enrolled Secret in Group
* responseMessage 404 Could not find Secret or Group
*/
@Path("/secrets/{secretId}/groups/{groupId}")
@Timed @ExceptionMetered
@PUT
public Response allowAccess(
@Auth User user,
@PathParam("secretId") LongParam secretId,
@PathParam("groupId") LongParam groupId) {
logger.info("User '{}' allowing groupId {} access to secretId {}", user, groupId, secretId);
try {
aclDAO.findAndAllowAccess(secretId.get(), groupId.get(), auditLog, user.getName(), new HashMap<>());
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Disallow a Group to access this Secret
*
* @param user the admin user performing this operation
* @param secretId ID value of a Secret
* @param groupId ID value of a Group
* @return 200 if operation successful, 404 if secret or group not present
*
* description Unassigns the Secret specified by the secretID from the Group specified by the groupID
* Used by Keywhiz CLI and the web ui.
* responseMessage 200 Successfully removed Secret from Group
* responseMessage 404 Could not find Secret or Group
*/
@Path("/secrets/{secretId}/groups/{groupId}")
@Timed @ExceptionMetered
@DELETE
public Response disallowAccess(
@Auth User user,
@PathParam("secretId") LongParam secretId,
@PathParam("groupId") LongParam groupId) {
logger.info("User '{}' disallowing groupId {} access to secretId {}", user, groupId, secretId);
try {
aclDAO.findAndRevokeAccess(secretId.get(), groupId.get(), auditLog, user.getName(), new HashMap<>());
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Enroll a Client into a Group
*
* @param user the admin user performing this operation
* @param clientId ID value of a Client
* @param groupId ID value of a Group
* @return 200 on success, 404 if client or group not found
*
* description Assigns the Client specified by the clientID to the Group specified by the groupID
* responseMessage 200 Successfully enrolled Client in Group
* responseMessage 404 Could not find Client or Group
*/
@Path("/clients/{clientId}/groups/{groupId}")
@Timed @ExceptionMetered
@PUT
public Response enrollClient(
@Auth User user,
@PathParam("clientId") LongParam clientId,
@PathParam("groupId") LongParam groupId) {
logger.info("User {} enrolling clientId {} in groupId {}.", user.getName(), clientId, groupId);
try {
aclDAO.findAndEnrollClient(clientId.get(), groupId.get(), auditLog, user.getName(), new HashMap<>());
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Remove a Client from a Group
*
* @param user the admin user performing this operation
* @param clientId ID value of a Client
* @param groupId ID value of a Group
* @return 200 on success, 404 if client or group not found
*
* description Unassigns the Client specified by the clientID from the Group specified by the groupID
* responseMessage 200 Successfully removed Client from Group
* responseMessage 404 Could not find Client or Group
*/
@Path("/clients/{clientId}/groups/{groupId}")
@Timed @ExceptionMetered
@DELETE
public Response evictClient(
@Auth User user,
@PathParam("clientId") LongParam clientId,
@PathParam("groupId") LongParam groupId) {
logger.info("User {} evicting clientId {} from groupId {}.", user.getName(), clientId, groupId);
try {
aclDAO.findAndEvictClient(clientId.get(), groupId.get(), auditLog, user.getName(), new HashMap<>());
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Retrieve Client by ID
*
* @param automationClient the client with automation access performing this operation
* @param clientId the ID of the Client to retrieve
* @return the specified client, if found
*
* description Returns a single Client if found
* responseMessage 200 Found and retrieved Client with given ID
* responseMessage 404 Client with given ID not Found
*/
@Timed @ExceptionMetered
@GET
@Path("{clientId}")
public Response findClientById(
@Auth AutomationClient automationClient,
@PathParam("clientId") LongParam clientId) {
logger.info("Automation ({}) - Looking up an ID {}", automationClient.getName(), clientId);
Client client = clientDAO.getClientById(clientId.get())
.orElseThrow(NotFoundException::new);
ImmutableList<Group> groups = ImmutableList.copyOf(aclDAO.getGroupsFor(client));
return Response.ok()
.entity(ClientDetailResponse.fromClient(client, groups, ImmutableList.of()))
.build();
}
/**
* Retrieve Client by a specified name, or all Clients if no name given
*
* @param automationClient the client with automation access performing this operation
* @param name the name of the Client to retrieve, if provided
* @return the specified client if found, or all clients if name omitted
*
* optionalParams name
* description Returns a single Client or a set of all Clients
* responseMessage 200 Found and retrieved Client(s)
* responseMessage 404 Client with given name not found (if name provided)
*/
@Timed @ExceptionMetered
@GET
public Response findClient(
@Auth AutomationClient automationClient,
@QueryParam("name") Optional<String> name) {
logger.info("Automation ({}) - Looking up a name {}", automationClient.getName(), name);
if (name.isPresent()) {
Client client = clientDAO.getClientByName(name.get()).orElseThrow(NotFoundException::new);
ImmutableList<Group> groups = ImmutableList.copyOf(aclDAO.getGroupsFor(client));
return Response.ok()
.entity(ClientDetailResponse.fromClient(client, groups, ImmutableList.of()))
.build();
}
List<ClientDetailResponse> clients = clientDAO.getClients().stream()
.map(c -> ClientDetailResponse.fromClient(c, ImmutableList.copyOf(aclDAO.getGroupsFor(c)),
ImmutableList.of()))
.collect(toList());
return Response.ok().entity(clients).build();
}
/**
* Enroll Client in Group
*
* @param automationClient the client with automation access performing this operation
* @param clientId the ID of the Client to assign
* @param groupId the ID of the Group to be assigned to
* @return 200 on success, 404 if client or group is missing
*
* description Assigns the Client specified by the clientID to the Group specified by the
* groupID
* responseMessage 200 Successfully enrolled Client in Group
* responseMessage 404 Could not find Client or Group
*/
@Timed @ExceptionMetered
@PUT
public Response enrollClientInGroup(
@Auth AutomationClient automationClient,
@PathParam("clientId") LongParam clientId,
@PathParam("groupId") LongParam groupId) {
try {
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("deprecated", "true");
aclDAO.findAndEnrollClient(clientId.get(), groupId.get(), auditLog,
automationClient.getName(), extraInfo);
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Remove Client from Group
*
* @param automationClient the client with automation access performing this operation
* @param clientId the ID of the Client to unassign
* @param groupId the ID of the Group to be removed from
* @return 200 on succes, 404 if client or group not present
*
* description Unassigns the Client specified by the clientID from the Group specified by the
* groupID
* responseMessage 200 Successfully removed Client from Group
* responseMessage 404 Could not find Client or Group
*/
@Timed @ExceptionMetered
@DELETE
public Response evictClientFromGroup(
@Auth AutomationClient automationClient,
@PathParam("clientId") long clientId,
@PathParam("groupId") long groupId) {
try {
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("deprecated", "true");
aclDAO.findAndEvictClient(clientId, groupId, auditLog, automationClient.getName(), extraInfo);
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}
/**
* Retrieve secret by ID
*
* @param automationClient the client with automation access performing this operation
* @param secretId the ID of the secret to retrieve
* @return details on the specified secret
*
* description Returns a single secret if found
* responseMessage 200 Found and retrieved secret with given ID
* responseMessage 404 Secret with given ID not found
*/
@Path("{secretId}")
@Timed @ExceptionMetered
@GET
public AutomationSecretResponse readSecretById(
@Auth AutomationClient automationClient,
@PathParam("secretId") LongParam secretId) {
Optional<Secret> secret = secretController.getSecretById(secretId.get());
if (!secret.isPresent()) {
throw new NotFoundException("Secret not found.");
}
ImmutableList<Group> groups = ImmutableList.copyOf(aclDAO.getGroupsFor(secret.get()));
return AutomationSecretResponse.fromSecret(secret.get(), groups);
}
/**
* Deletes all versions of a secret series
*
* @param automationClient the client with automation access performing this operation
* @param secretName the name of the secret series to delete
* @return 200 if the deletion is successful, or 404 if the given secret was not found
*
* description Deletes all versions of a secret series. This will delete a single secret ID.
* responseMessage 200 Deleted secret series
* responseMessage 404 Secret series not Found
*/
@Path("{secretName}")
@Timed @ExceptionMetered
@DELETE
public Response deleteSecretSeries(
@Auth AutomationClient automationClient,
@PathParam("secretName") String secretName) {
Secret secret = secretController.getSecretByName(secretName).orElseThrow(() -> new NotFoundException("Secret series not found."));
Set<String> groups = aclDAO.getGroupsFor(secret).stream().map(Group::getName).collect(toSet());
secretDAO.deleteSecretsByName(secretName);
// Record all groups to which this secret belongs, so they can be restored manually if necessary
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("deprecated", "true");
extraInfo.put("groups", groups.toString());
extraInfo.put("current version", secret.getVersion().toString());
auditLog.recordEvent(new Event(Instant.now(), EventTag.SECRET_DELETE, automationClient.getName(), secretName, extraInfo));
return Response.ok().build();
}
/**
* Delete a client
*
* @param name Client name
* @return 200 if the deletion was successful, 404 if the client was not found
* <p>
* responseMessage 204 Client deleted
* <p>
* responseMessage 404 Client not found
*/
@Timed @ExceptionMetered
@DELETE
@Path("{name}")
public Response deleteClient(@Auth AutomationClient automationClient,
@PathParam("name") String name) {
Client client = clientDAOReadWrite.getClientByName(name)
.orElseThrow(NotFoundException::new);
// Group memberships are deleted automatically by DB cascading.
clientDAOReadWrite.deleteClient(client);
auditLog.recordEvent(
new Event(Instant.now(), EventTag.CLIENT_DELETE, automationClient.getName(),
client.getName()));
return Response.noContent().build();
}
/**
* Modify a client
*
* @param currentName Client name
* @param request JSON request to modify the client
* @return the updated client
* <p>
* responseMessage 201 Client updated
* <p>
* 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.getClientByName(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));
}
/**
* Creates a group
*
* @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();
}
/**
* Retrieve information on a group
*
* @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();
}
/**
* Delete a secret series
*
* @param name Secret series name
*
* responseMessage 204 Secret series deleted
* responseMessage 404 Secret series not found
*/
@Timed @ExceptionMetered
@DELETE
@Path("{name}")
public Response deleteSecretSeries(@Auth AutomationClient automationClient,
@PathParam("name") String name) {
Secret secret = secretController.getSecretByName(name).orElseThrow(() -> new NotFoundException("Secret series not found."));
// Get the groups for this secret so they can be restored manually if necessary
Set<String> groups = aclDAO.getGroupsFor(secret).stream().map(Group::getName).collect(toSet());
secretDAO.deleteSecretsByName(name);
// Record the deletion in the audit log
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("groups", groups.toString());
extraInfo.put("current version", secret.getVersion().toString());
auditLog.recordEvent(new Event(Instant.now(), EventTag.SECRET_DELETE, automationClient.getName(), name, extraInfo));
return Response.noContent().build();
}
/**
* Assign Secret to Group
*
* @param automationClient the client with automation access performing this operation
* @param secretId the ID of the Secret to assign
* @param groupId the ID of the Group to be assigned to
* @return 200 on success, 404 if the secret or group is absent
*
* description Assigns the Secret specified by the secretID to the Group specified by the groupID
* responseMessage 200 Successfully enrolled Secret in Group
* responseMessage 404 Could not find Secret or Group
*/
@Timed @ExceptionMetered
@PUT
public Response allowAccess(
@Auth AutomationClient automationClient,
@PathParam("secretId") LongParam secretId,
@PathParam("groupId") LongParam groupId) {
logger.info("Client '{}' allowing groupId={} access to secretId={}",
automationClient, secretId, groupId);
try {
Map<String, String> extraInfo = new HashMap<>();
extraInfo.put("deprecated", "true");
aclDAO.findAndAllowAccess(secretId.get(), groupId.get(), auditLog, automationClient.getName(), extraInfo);
} catch (IllegalStateException e) {
throw new NotFoundException();
}
return Response.ok().build();
}