use of com.quorum.tessera.enclave.PrivacyMode in project tessera by ConsenSys.
the class TransactionResource4 method send.
@POST
@Path("send")
@Consumes({ MIME_TYPE_JSON_4 })
@Produces({ MIME_TYPE_JSON_4 })
public Response send(@NotNull @Valid @PrivacyValid final SendRequest sendRequest) {
final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
final Optional<PrivacyGroup.Id> privacyGroupId = Optional.ofNullable(sendRequest.getPrivacyGroupId()).map(PrivacyGroup.Id::fromBase64String);
final List<PublicKey> recipientList = privacyGroupId.map(privacyGroupManager::retrievePrivacyGroup).map(PrivacyGroup::getMembers).orElse(Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList()));
final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(base64Decoder::decode).map(MessageHash::new).collect(Collectors.toSet());
final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
final PrivacyMode privacyMode = PrivacyMode.fromFlag(sendRequest.getPrivacyFlag());
final Set<PublicKey> mandatoryRecipients = Stream.ofNullable(sendRequest.getMandatoryRecipients()).flatMap(Arrays::stream).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toUnmodifiableSet());
final com.quorum.tessera.transaction.SendRequest.Builder requestBuilder = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(privacyMode).withAffectedContractTransactions(affectedTransactions).withMandatoryRecipients(mandatoryRecipients);
privacyGroupId.ifPresent(requestBuilder::withPrivacyGroupId);
final com.quorum.tessera.transaction.SendResponse response = transactionManager.send(requestBuilder.build());
final String encodedKey = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).get();
final String[] managedParties = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getManagedParties).orElse(Collections.emptySet()).stream().map(PublicKey::encodeToBase64).toArray(String[]::new);
final SendResponse sendResponse = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).map(messageHash -> new SendResponse(messageHash, managedParties, sender.encodeToBase64())).get();
final URI location = UriBuilder.fromPath("transaction").path(URLEncoder.encode(encodedKey, StandardCharsets.UTF_8)).build();
return Response.created(location).entity(sendResponse).build();
}
use of com.quorum.tessera.enclave.PrivacyMode in project tessera by ConsenSys.
the class RestPayloadPublisherTest method publish.
@Test
public void publish() {
final String targetUrl = "nodeUrl";
final EncodedPayload encodedPayload = mock(EncodedPayload.class);
final PublicKey publicKey = mock(PublicKey.class);
for (Response.Status expectedResponseStatus : Response.Status.values()) {
for (PrivacyMode privacyMode : PrivacyMode.values()) {
when(encodedPayload.getPrivacyMode()).thenReturn(privacyMode);
final NodeInfo nodeInfo = mock(NodeInfo.class);
when(nodeInfo.supportedApiVersions()).thenReturn(Set.of(EnhancedPrivacyVersion.API_VERSION_2, "2.1", "3.0", "4.0"));
when(nodeInfo.getUrl()).thenReturn(targetUrl);
when(discovery.getRemoteNodeInfo(publicKey)).thenReturn(nodeInfo);
final byte[] payloadData = "Payload".getBytes();
when(payloadEncoder.encode(encodedPayload)).thenReturn(payloadData);
WebTarget webTarget = mock(WebTarget.class);
when(client.target(targetUrl)).thenReturn(webTarget);
when(webTarget.path("/push")).thenReturn(webTarget);
Invocation.Builder invocationBuilder = mock(Invocation.Builder.class);
Response response = Response.status(expectedResponseStatus).build();
when(invocationBuilder.post(Entity.entity(payloadData, MediaType.APPLICATION_OCTET_STREAM_TYPE))).thenReturn(response);
when(webTarget.request()).thenReturn(invocationBuilder);
if (expectedResponseStatus == Response.Status.OK || expectedResponseStatus == Response.Status.CREATED) {
payloadPublisher.publishPayload(encodedPayload, publicKey);
} else {
PublishPayloadException publishPayloadException = Assertions.catchThrowableOfType(() -> payloadPublisher.publishPayload(encodedPayload, publicKey), PublishPayloadException.class);
assertThat(publishPayloadException).hasMessage(String.format("Unable to push payload to recipient url %s", targetUrl));
}
}
}
int iterations = Response.Status.values().length * PrivacyMode.values().length;
verify(client, times(iterations)).target(targetUrl);
verify(discovery, times(iterations)).getRemoteNodeInfo(publicKey);
verify(payloadEncoder, times(iterations)).encode(encodedPayload);
payloadEncoderFactoryFunction.verify(times(iterations), () -> PayloadEncoder.create(any(EncodedPayloadCodec.class)));
}
use of com.quorum.tessera.enclave.PrivacyMode in project tessera by ConsenSys.
the class RequestPrivacyValidator method isValid.
@Override
public boolean isValid(Object request, ConstraintValidatorContext context) {
PrivacyMode privacyMode;
String execHash;
if (request instanceof SendRequest) {
privacyMode = PrivacyMode.fromFlag(((SendRequest) request).getPrivacyFlag());
execHash = ((SendRequest) request).getExecHash();
} else if (request instanceof SendSignedRequest) {
privacyMode = PrivacyMode.fromFlag(((SendSignedRequest) request).getPrivacyFlag());
execHash = ((SendSignedRequest) request).getExecHash();
} else {
context.buildConstraintViolationWithTemplate("Invalid usage. This validator can only be apply to SendRequest or SendSignedRequest").addConstraintViolation();
return false;
}
if (PrivacyMode.PRIVATE_STATE_VALIDATION == privacyMode) {
if (Objects.isNull(execHash) || execHash.length() == 0) {
context.buildConstraintViolationWithTemplate("Exec hash missing").addConstraintViolation();
return false;
}
}
return true;
}
use of com.quorum.tessera.enclave.PrivacyMode in project tessera by ConsenSys.
the class BesuTransactionResource method send.
@Hidden
@POST
@Path("send")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response send(@NotNull @Valid @PrivacyValid final SendRequest sendRequest) {
final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
final Optional<PrivacyGroup.Id> optionalPrivacyGroup = Optional.ofNullable(sendRequest.getPrivacyGroupId()).map(PrivacyGroup.Id::fromBase64String);
final List<PublicKey> recipientList = optionalPrivacyGroup.map(privacyGroupManager::retrievePrivacyGroup).map(PrivacyGroup::getMembers).orElse(Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList()));
final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(base64Decoder::decode).map(MessageHash::new).collect(Collectors.toSet());
final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
final PrivacyMode privacyMode = PrivacyMode.fromFlag(sendRequest.getPrivacyFlag());
final com.quorum.tessera.transaction.SendRequest.Builder requestBuilder = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(privacyMode).withAffectedContractTransactions(affectedTransactions);
optionalPrivacyGroup.ifPresentOrElse(requestBuilder::withPrivacyGroupId, () -> {
PrivacyGroup legacyGroup = privacyGroupManager.createLegacyPrivacyGroup(sender, recipientList);
requestBuilder.withPrivacyGroupId(legacyGroup.getId());
});
final com.quorum.tessera.transaction.SendResponse response = transactionManager.send(requestBuilder.build());
final String encodedKey = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).get();
final SendResponse sendResponse = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).map(messageHash -> new SendResponse(messageHash, null, null)).get();
final URI location = UriBuilder.fromPath("transaction").path(URLEncoder.encode(encodedKey, StandardCharsets.UTF_8)).build();
return Response.status(Response.Status.OK).type(APPLICATION_JSON).location(location).entity(sendResponse).build();
}
use of com.quorum.tessera.enclave.PrivacyMode in project tessera by ConsenSys.
the class TransactionResource3 method send.
// path /send is overloaded (application/json and application/vnd.tessera-2.1+json); swagger
// annotations cannot
// handle situations like this so this operation documents both
@Operation(summary = "/send", operationId = "encryptStoreAndSendJson", description = "encrypts a payload, stores result in database, and publishes result to recipients", requestBody = @RequestBody(content = { @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendRequest.class)), @Content(mediaType = MIME_TYPE_JSON_2_1, schema = @Schema(implementation = SendRequest.class)) }))
@ApiResponse(responseCode = "201", description = "encrypted payload hash", content = { @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendResponse.class)), @Content(mediaType = MIME_TYPE_JSON_2_1, schema = @Schema(implementation = SendResponse.class)) })
@ApiResponse(responseCode = "200", description = "hash returned when running in orion mode", content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendResponse.class)))
@POST
@Path("send")
@Consumes({ MIME_TYPE_JSON_2_1, MIME_TYPE_JSON_3 })
@Produces({ MIME_TYPE_JSON_2_1, MIME_TYPE_JSON_3 })
public Response send(@NotNull @Valid @PrivacyValid final SendRequest sendRequest) {
final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
final Optional<PrivacyGroup.Id> privacyGroupId = Optional.ofNullable(sendRequest.getPrivacyGroupId()).map(PrivacyGroup.Id::fromBase64String);
final List<PublicKey> recipientList = privacyGroupId.map(privacyGroupManager::retrievePrivacyGroup).map(PrivacyGroup::getMembers).orElse(Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList()));
final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(base64Decoder::decode).map(MessageHash::new).collect(Collectors.toSet());
final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
final PrivacyMode privacyMode = PrivacyMode.fromFlag(sendRequest.getPrivacyFlag());
final com.quorum.tessera.transaction.SendRequest.Builder requestBuilder = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(privacyMode).withAffectedContractTransactions(affectedTransactions);
privacyGroupId.ifPresent(requestBuilder::withPrivacyGroupId);
final com.quorum.tessera.transaction.SendResponse response = transactionManager.send(requestBuilder.build());
final String encodedKey = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).get();
final String[] managedParties = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getManagedParties).orElse(Collections.emptySet()).stream().map(PublicKey::encodeToBase64).toArray(String[]::new);
final SendResponse sendResponse = Optional.of(response).map(com.quorum.tessera.transaction.SendResponse::getTransactionHash).map(MessageHash::getHashBytes).map(base64Encoder::encodeToString).map(messageHash -> new SendResponse(messageHash, managedParties, sender.encodeToBase64())).get();
final URI location = UriBuilder.fromPath("transaction").path(URLEncoder.encode(encodedKey, StandardCharsets.UTF_8)).build();
return Response.created(location).entity(sendResponse).build();
}
Aggregations