@GET @Path("_table") @Timed(name = "bv.emodb.blob.BlobStoreResource1.listTables", absolute = true) @ApiOperation (value = "List all the tables.", notes = "Returns a list of tables.", response = Table.class ) public Iterator<Table> listTables(@QueryParam("from") final String fromKeyExclusive, @QueryParam("limit") @DefaultValue("10") LongParam limit, final @Authenticated Subject subject) { return streamingIterator( StreamSupport.stream(Spliterators.spliteratorUnknownSize(_blobStore.listTables(Strings.emptyToNull(fromKeyExclusive), Long.MAX_VALUE), 0), false) .filter(input -> subject.hasPermission(Permissions.readBlobTable(new NamedResource(input.getName())))) .limit(limit.get()) .iterator() ); }
@GET @Path ("{subscription}/size") @RequiresPermissions ("databus|get_status|{subscription}") @Timed (name = "bv.emodb.databus.DatabusResource1.getEventCount", absolute = true) @ApiOperation (value = "Gets the event count.", notes = "Returns a long.", response = long.class ) public long getEventCount(@QueryParam ("partitioned") BooleanParam partitioned, @PathParam ("subscription") String subscription, @QueryParam ("limit") LongParam limit, @Authenticated Subject subject) { // Call different getEventCount* methods to collect metrics data that distinguish limited vs. unlimited calls. if (limit == null || limit.get() == Long.MAX_VALUE) { return getClient(partitioned).getEventCount(subject, subscription); } else { return getClient(partitioned).getEventCountUpTo(subject, subscription, limit.get()); } }
@GET @Path("{queue}/size") @RequiresPermissions("queue|get_status|{queue}") @Timed(name = "bv.emodb.queue.QueueResource1.getMessageCount", absolute = true) @ApiOperation (value = "gets the Message count.", notes = "Returns a long.", response = long.class ) public long getMessageCount(@PathParam("queue") String queue, @QueryParam("limit") LongParam limit) { // Not partitioned--any server can count messages in Cassandra. Claims are ignored. // Call different getMessageCount* methods to collect metrics data that distinguish limited vs. unlimited calls. if (limit == null || limit.get() == Long.MAX_VALUE) { return _queueService.getMessageCount(queue); } else { return _queueService.getMessageCountUpTo(queue, limit.get()); } }
@GET @Path("{queue}/size") @RequiresPermissions("queue|get_status|{queue}") @Timed(name = "bv.emodb.dedupq.DedupQueueResource1.getMessageCount", absolute = true) @ApiOperation (value = "Gets the messsage count.", notes = "Returns a long.", response = long.class ) public long getMessageCount(@QueryParam("partitioned") BooleanParam partitioned, @PathParam("queue") String queue, @QueryParam("limit") LongParam limit, @Authenticated Subject subject) { // Call different getMessageCount* methods to collect metrics data that distinguish limited vs. unlimited calls. if (limit == null || limit.get() == Long.MAX_VALUE) { return getService(partitioned, subject.getAuthenticationId()).getMessageCount(queue); } else { return getService(partitioned, subject.getAuthenticationId()).getMessageCountUpTo(queue, limit.get()); } }
@GET @Path ("_table") @Timed (name = "bv.emodb.sor.DataStoreResource1.listTables", absolute = true) @ApiOperation (value = "Returns all the existing tables", notes = "Returns a Iterator of Table", response = Table.class ) public Iterator<Table> listTables(final @QueryParam("from") String fromKeyExclusive, final @QueryParam("limit") @DefaultValue("10") LongParam limitParam, final @Authenticated Subject subject) { return streamingIterator( StreamSupport.stream(Spliterators.spliteratorUnknownSize(_dataStore.listTables(Strings.emptyToNull(fromKeyExclusive), Long.MAX_VALUE), 0), false) .filter(input -> subject.hasPermission(Permissions.readSorTable(new NamedResource(input.getName())))) .limit(limitParam.get()) .iterator(), null ); }
/** * Retrieves all recorded history for a piece of content in the data store. */ @GET @Path ("{table}/{key}/timeline") @RequiresPermissions ("sor|read|{table}") @Timed (name = "bv.emodb.sor.DataStoreResource1.getTimeline", absolute = true) @ApiOperation (value = "Retrieves all recorded history for a piece of content in the data store.", notes = "Retrieves all recorded history for a piece of content in the data store.", response = Iterator.class ) public Iterator<Change> getTimeline(@PathParam ("table") String table, @PathParam ("key") String key, @QueryParam ("data") @DefaultValue ("true") BooleanParam includeContentData, @QueryParam ("audit") @DefaultValue ("false") BooleanParam includeAuditInformation, @QueryParam ("start") String startParam, @QueryParam ("end") String endParam, @QueryParam ("reversed") @DefaultValue ("true") BooleanParam reversed, @QueryParam ("limit") @DefaultValue ("10") LongParam limit, @QueryParam ("consistency") @DefaultValue ("STRONG") ReadConsistencyParam consistency) { // For the REST API, start & end may be either UUIDs or ISO 8601 timestamps. If timestamps, they are inclusive // w/granularity of a millisecond so adjust upper endpoints to be the last valid time UUID for the millisecond. UUID start = parseUuidOrTimestamp(startParam, reversed.get()); UUID end = parseUuidOrTimestamp(endParam, !reversed.get()); return streamingIterator(_dataStore.getTimeline(table, key, includeContentData.get(), includeAuditInformation.get(), start, end, reversed.get(), limit.get(), consistency.get()), null); }
/** * Retrieves a list of content items in a particular table. To retrieve <em>all</em> items in a table set the * limit param to a very large value (eg. Long.MAX_VALUE), but for large tables be sure your client can stream the * results without exhausting all available memory. */ @GET @Path ("{table}") @RequiresPermissions ("sor|read|{table}") @Timed (name = "bv.emodb.sor.DataStoreResource1.scan", absolute = true) @ApiOperation (value = "Retrieves a list of content items in a particular table.", notes = "Retrieves a list of content items in a particular table. To retrieve <em>all</em> items in a table set the\n" + " limit param to a very large value (eg. Long.MAX_VALUE), but for large tables be sure your client can stream the\n" + " results without exhausting all available memory.", response = Iterator.class ) @ApiImplicitParams ({@ApiImplicitParam (name = "APIKey", required = true, dataType = "string", paramType = "query")}) public Iterator<Map<String, Object>> scan(@PathParam ("table") String table, @QueryParam ("from") String fromKeyExclusive, @QueryParam ("limit") @DefaultValue ("10") LongParam limit, @QueryParam ("consistency") @DefaultValue ("STRONG") ReadConsistencyParam consistency, @QueryParam ("debug") BooleanParam debug) { return streamingIterator( _dataStore.scan(table, Strings.emptyToNull(fromKeyExclusive), limit.get(), consistency.get()), debug); }
/** * Retrieves a list of content items in a particular table split. */ @GET @Path ("_split/{table}/{split}") @RequiresPermissions ("sor|read|{table}") @ThrottleConcurrentRequests (maxRequests = 550) @Timed (name = "bv.emodb.sor.DataStoreResource1.getSplit", absolute = true) @ApiOperation (value = "Retrieves a list of content items in a particular table split.", notes = "Retrieves a list of content items in a particular table split.", response = Iterator.class ) public Iterator<Map<String, Object>> getSplit(@PathParam ("table") String table, @PathParam ("split") String split, @QueryParam ("from") String key, @QueryParam ("limit") @DefaultValue ("10") LongParam limit, @QueryParam ("consistency") @DefaultValue ("STRONG") ReadConsistencyParam consistency, @QueryParam ("debug") BooleanParam debug) { return streamingIterator( _dataStore.getSplit(table, split, Strings.emptyToNull(key), limit.get(), consistency.get()), debug); }
/** * Delete Client by ID * * @excludeParams user * @param clientId the ID of the Client to be deleted * * @description Deletes a single Client if found. * Used by Keywhiz CLI and the web ui. * @responseMessage 200 Found and deleted Client with given ID * @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(); }
/** * Delete Group by ID * * @excludeParams user * @param groupId the ID of the Group to be deleted * * @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(); }
/** * Rollback to a previous secret version * * @param secretName the name of the secret to rollback * @param versionId the ID of the version to return to * @excludeParams user * @description Returns the previous versions of the secret if found Used by Keywhiz CLI. * @responseMessage 200 Found and reset the secret to this version * @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(); }
/** * Delete Secret by ID * * @excludeParams user * @param secretId the ID of the Secret to be deleted * * @description Deletes a single Secret if found. * Used by Keywhiz CLI and the web ui. * @responseMessage 200 Found and deleted Secret with given ID * @responseMessage 404 Secret with given ID not Found */ @Path("{secretId}") @Timed @ExceptionMetered @DELETE public Response deleteSecret(@Auth User user, @PathParam("secretId") LongParam secretId) { Optional<Secret> secret = secretController.getSecretById(secretId.get()); if (!secret.isPresent()) { logger.info("User '{}' tried deleting a secret which was not found (id={})", user, secretId.get()); throw new NotFoundException("Secret not found."); } logger.info("User '{}' deleting secret id={}, name='{}'", user, secretId, secret.get().getName()); // Get the groups for this secret, so they can be restored manually if necessary Set<String> groups = aclDAOReadOnly.getGroupsFor(secret.get()).stream().map(Group::getName).collect(toSet()); secretDAOReadWrite.deleteSecretsByName(secret.get().getName()); // Record the deletion Map<String, String> extraInfo = new HashMap<>(); extraInfo.put("groups", groups.toString()); extraInfo.put("current version", secret.get().getVersion().toString()); auditLog.recordEvent(new Event(Instant.now(), EventTag.SECRET_DELETE, user.getName(), secret.get().getName(), extraInfo)); return Response.noContent().build(); }
/** * Allow a Group to access this Secret * * @excludeParams user * @param secretId ID value of a Secret * @param groupId ID value of a Group * * @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 * * @excludeParams user * @param secretId ID value of a Secret * @param groupId ID value of a Group * * @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 * * @excludeParams user * @param clientId ID value of a Client * @param groupId ID value of a Group * * @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 * * @excludeParams user * @param clientId ID value of a Client * @param groupId ID value of a Group * * @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 clientId the ID of the Client to retrieve * @excludeParams automationClient * @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(); }
/** * Enroll Client in Group * * @param clientId the ID of the Client to assign * @param groupId the ID of the Group to be assigned to * @excludeParams automationClient * @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(); }
/** * Retrieve secret by ID * * @excludeParams automationClient * @param secretId the ID of the secret to retrieve * * @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 a group * * @param groupId the ID of the group to delete * @excludeParams automationClient * @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(); }
/** * Assign Secret to Group * * @excludeParams automationClient * @param secretId the ID of the Secret to assign * @param groupId the ID of the Group to be assigned to * * @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(); }
/** * Remove Secret from Group * * @excludeParams automationClient * @param secretId the ID of the Secret to unassign * @param groupId the ID of the Group to be removed from * * @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(); }
@Test public void getSpecificIncludesAllTheThings() { when(groupDAO.getGroupById(4444)).thenReturn(Optional.of(group)); SanitizedSecret secret = SanitizedSecret.of(1, "name", null, "checksum", now, "creator", now, "creator", null, null, null, 1136214245, 125L, now, "creator"); when(aclDAO.getSanitizedSecretsFor(group)).thenReturn(ImmutableSet.of(secret)); Client client = new Client(1, "client", "desc", now, "creator", now, "creator", null, true, false); when(aclDAO.getClientsFor(group)).thenReturn(ImmutableSet.of(client)); GroupDetailResponse response = resource.getGroup(user, new LongParam("4444")); assertThat(response.getId()).isEqualTo(group.getId()); assertThat(response.getName()).isEqualTo(group.getName()); assertThat(response.getDescription()).isEqualTo(group.getDescription()); assertThat(response.getCreationDate()).isEqualTo(group.getCreatedAt()); assertThat(response.getCreatedBy()).isEqualTo(group.getCreatedBy()); assertThat(response.getUpdateDate()).isEqualTo(group.getUpdatedAt()); assertThat(response.getUpdatedBy()).isEqualTo(group.getUpdatedBy()); assertThat(response.getSecrets()).containsExactly(secret); assertThat(response.getClients()).containsExactly(client); }
@Test public void includesTheSecret() { when(secretController.getSecretById(22)).thenReturn(Optional.of(secret)); when(aclDAO.getGroupsFor(secret)).thenReturn(Collections.emptySet()); when(aclDAO.getClientsFor(secret)).thenReturn(Collections.emptySet()); SecretDetailResponse response = resource.retrieveSecret(user, new LongParam("22")); assertThat(response.id).isEqualTo(secret.getId()); assertThat(response.name).isEqualTo(secret.getName()); assertThat(response.description).isEqualTo(secret.getDescription()); assertThat(response.createdAt).isEqualTo(secret.getCreatedAt()); assertThat(response.createdBy).isEqualTo(secret.getCreatedBy()); assertThat(response.updatedAt).isEqualTo(secret.getUpdatedAt()); assertThat(response.updatedBy).isEqualTo(secret.getUpdatedBy()); assertThat(response.metadata).isEqualTo(secret.getMetadata()); }
@Path("/{id}/") @PUT public void shareItem(@Auth OaccPrincipal oaccPrincipal, @PathParam("id") LongParam todoItemId, @QueryParam("share_with") String email) { todoItemService.shareItem(oaccPrincipal.getAccessControlContext(), todoItemId.get(), email); }
@Path("/{id}") @PATCH // @Consumes(MediaType.APPLICATION_MERGE_PATCH_JSON) public TodoItem updateItem(@Auth OaccPrincipal oaccPrincipal, @PathParam("id") LongParam todoItemId, TodoItem patchItem) { return todoItemService.updateItem(oaccPrincipal.getAccessControlContext(), todoItemId.get(), patchItem); }
@GET @Path("/{id}") @Timed @UnitOfWork public Blog findBlogById(@PathParam("id") LongParam id) { if (!blogDao.findById(id.get()).isPresent()) { throw new NotFoundException("No such blog"); } return blogDao.findById(id.get()).get(); }
@POST @Path("/{id}") @UnitOfWork public Blog createOrUpdate(@PathParam("id") LongParam id, Blog blog) { blog.setId(id.get()); if(id.get() < 1) blog.setId(null); return blogDao.createAndUpdate(blog); }
/** * Retrieves a list of content items in a particular table. */ @GET @Path("{table}") @RequiresPermissions("blob|read|{table}") @Timed(name = "bv.emodb.blob.BlobStoreResource1.scanMetadata", absolute = true) @ApiOperation (value = "Retrieves a list of content items in a particular table.", notes = "Retuns BlobMetadata.", response = BlobMetadata.class ) public Iterator<BlobMetadata> scanMetadata(@PathParam("table") String table, @QueryParam("from") String blobId, @QueryParam("limit") @DefaultValue("10") LongParam limit) { return streamingIterator(_blobStore.scanMetadata(table, Strings.emptyToNull(blobId), limit.get())); }
@GET @Timed (name = "bv.emodb.databus.DatabusResource1.listSubscription", absolute = true) @ApiOperation (value = "Lists Subscription.", notes = "Returns an Iterator of Subscription.", response = Subscription.class ) public Iterator<Subscription> listSubscription(@QueryParam ("from") String fromKeyExclusive, @QueryParam ("limit") @DefaultValue ("10") LongParam limit, @Authenticated Subject subject) { return streamingIterator(_databus.listSubscriptions(subject, Strings.emptyToNull(fromKeyExclusive), limit.get())); }
/** * Deletes a client * * @param clientId the ID of the client to delete * @excludeParams automationClient * @description Deletes a single client by id * @responseMessage 200 Deleted client * @responseMessage 404 Client not found by id */ @Timed @ExceptionMetered @DELETE @Path("{clientId}") public Response deleteClient(@Auth AutomationClient automationClient, @PathParam("clientId") LongParam clientId) { Client client = clientDAO.getClientById(clientId.get()).orElseThrow(NotFoundException::new); clientDAO.deleteClient(client); Map<String, String> extraInfo = new HashMap<>(); extraInfo.put("deprecated", "true"); auditLog.recordEvent( new Event(Instant.now(), EventTag.CLIENT_DELETE, automationClient.getName(), client.getName(), extraInfo)); return Response.ok().build(); }
/** * Retrieve Group by ID * * @param groupId the ID of the group to retrieve * @excludeParams automationClient * @description Returns a single Group if found * @responseMessage 200 Found and retrieved Group with given ID * @responseMessage 404 Group with given ID not Found */ @Timed @ExceptionMetered @GET @Path("{groupId}") public GroupDetailResponse getGroupById( @Auth AutomationClient automationClient, @PathParam("groupId") LongParam groupId) { Group group = groupDAO.getGroupById(groupId.get()).orElseThrow(NotFoundException::new); ImmutableList<Client> clients = ImmutableList.copyOf(aclDAO.getClientsFor(group)); ImmutableList<SanitizedSecret> sanitizedSecrets = ImmutableList.copyOf(aclDAO.getSanitizedSecretsFor(group)); return GroupDetailResponse.fromGroup(group, sanitizedSecrets, clients); }
@Test public void includesTheClient() { when(clientDAO.getClientById(1)).thenReturn(Optional.of(client)); when(aclDAO.getGroupsFor(client)).thenReturn(Collections.emptySet()); when(aclDAO.getSanitizedSecretsFor(client)).thenReturn(ImmutableSet.of()); ClientDetailResponse response = resource.getClient(user, new LongParam("1")); assertThat(response.id).isEqualTo(client.getId()); assertThat(response.name).isEqualTo(client.getName()); assertThat(response.description).isEqualTo(client.getDescription()); assertThat(response.creationDate).isEqualTo(client.getCreatedAt()); assertThat(response.createdBy).isEqualTo(client.getCreatedBy()); assertThat(response.updateDate).isEqualTo(client.getUpdatedAt()); assertThat(response.updatedBy).isEqualTo(client.getUpdatedBy()); }
@Test public void handlesNoAssociations() { when(clientDAO.getClientById(1)).thenReturn(Optional.of(client)); when(aclDAO.getGroupsFor(client)).thenReturn(Collections.emptySet()); when(aclDAO.getSanitizedSecretsFor(client)).thenReturn(ImmutableSet.of()); ClientDetailResponse response = resource.getClient(user, new LongParam("1")); assertThat(response.groups).isEmpty(); assertThat(response.secrets).isEmpty(); }
@Test public void includesAssociations() { Group group1 = new Group(0, "group1", null, null, null, null, null, null); Group group2 = new Group(0, "group2", null, null, null, null, null, null); Secret secret = new Secret(15, "secret", null, () -> "supersecretdata", "checksum", now, "creator", now, "updater", null, null, null, 0, 1L, now, "updater"); when(clientDAO.getClientById(1)).thenReturn(Optional.of(client)); when(aclDAO.getGroupsFor(client)).thenReturn(Sets.newHashSet(group1, group2)); when(aclDAO.getSanitizedSecretsFor(client)) .thenReturn(ImmutableSet.of(SanitizedSecret.fromSecret(secret))); ClientDetailResponse response = resource.getClient(user, new LongParam("1")); assertThat(response.groups).containsOnly(group1, group2); assertThat(response.secrets).containsOnly(SanitizedSecret.fromSecret(secret)); }
@Test public void deleteCallsDelete() { when(clientDAO.getClientById(12)).thenReturn(Optional.of(client)); Response blah = resource.deleteClient(user, new LongParam("12")); verify(clientDAO).deleteClient(client); assertThat(blah.getStatus()).isEqualTo(204); }
@Test public void canDelete() { when(groupDAO.getGroupById(0xdeadbeef)).thenReturn(Optional.of(group)); Response response = resource.deleteGroup(user, new LongParam(Long.toString(0xdeadbeef))); verify(groupDAO).deleteGroup(group); assertThat(response.getStatus()).isEqualTo(204); }
@Test public void rollbackSuccess() { Secret secret1 = new Secret(1, "name1", "desc", () -> "secret", "checksum", NOW, "user", NOW, "user", emptyMap, null, null, 1136214245, 125L, NOW, "user"); when(secretController.getSecretByName("name1")).thenReturn(Optional.of(secret1)); Response response = resource.resetSecretVersion(user, "name1", new LongParam("125")); assertThat(response.getStatus()).isEqualTo(HttpStatus.SC_CREATED); }
@Test public void canDelete() { when(secretController.getSecretById(0xdeadbeef)).thenReturn(Optional.of(secret)); HashSet<Group> groups = new HashSet<>(); groups.add(new Group(0, "group1", "", NOW, null, NOW, null, null)); groups.add(new Group(0, "group2", "", NOW, null, NOW, null, null)); when(aclDAO.getGroupsFor(secret)).thenReturn(groups); Response response = resource.deleteSecret(user, new LongParam(Long.toString(0xdeadbeef))); verify(secretDAO).deleteSecretsByName("name"); assertThat(response.getStatus()).isEqualTo(204); }
@Test public void handlesNoAssociations() { when(secretController.getSecretById(22)).thenReturn(Optional.of(secret)); when(aclDAO.getGroupsFor(secret)).thenReturn(Collections.emptySet()); when(aclDAO.getClientsFor(secret)).thenReturn(Collections.emptySet()); SecretDetailResponse response = resource.retrieveSecret(user, new LongParam("22")); assertThat(response.groups).isEmpty(); assertThat(response.clients).isEmpty(); }