Search in sources :

Example 6 with PrivacyMode

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();
}
Also used : SendSignedRequest(com.quorum.tessera.api.SendSignedRequest) PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) SendResponse(com.quorum.tessera.api.SendResponse) LoggerFactory(org.slf4j.LoggerFactory) Valid(jakarta.validation.Valid) NotNull(jakarta.validation.constraints.NotNull) TEXT_PLAIN(jakarta.ws.rs.core.MediaType.TEXT_PLAIN) PrivacyValid(com.quorum.tessera.api.constraint.PrivacyValid) Content(io.swagger.v3.oas.annotations.media.Content) Operation(io.swagger.v3.oas.annotations.Operation) Response(jakarta.ws.rs.core.Response) MIME_TYPE_JSON_4(com.quorum.tessera.version.MandatoryRecipientsVersion.MIME_TYPE_JSON_4) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse) URI(java.net.URI) MessageHash(com.quorum.tessera.data.MessageHash) Schema(io.swagger.v3.oas.annotations.media.Schema) Logger(org.slf4j.Logger) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) ExampleObject(io.swagger.v3.oas.annotations.media.ExampleObject) TransactionManager(com.quorum.tessera.transaction.TransactionManager) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) jakarta.ws.rs(jakarta.ws.rs) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Parameter(io.swagger.v3.oas.annotations.Parameter) URLEncoder(java.net.URLEncoder) SendRequest(com.quorum.tessera.api.SendRequest) Stream(java.util.stream.Stream) UriBuilder(jakarta.ws.rs.core.UriBuilder) Tag(io.swagger.v3.oas.annotations.tags.Tag) SendRequest(com.quorum.tessera.api.SendRequest) MessageHash(com.quorum.tessera.data.MessageHash) URI(java.net.URI) PublicKey(com.quorum.tessera.encryption.PublicKey) SendResponse(com.quorum.tessera.api.SendResponse) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode)

Example 7 with PrivacyMode

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)));
}
Also used : PublishPayloadException(com.quorum.tessera.transaction.publish.PublishPayloadException) Invocation(jakarta.ws.rs.client.Invocation) PublicKey(com.quorum.tessera.encryption.PublicKey) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) Response(jakarta.ws.rs.core.Response) NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) WebTarget(jakarta.ws.rs.client.WebTarget) Test(org.junit.Test)

Example 8 with PrivacyMode

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;
}
Also used : SendRequest(com.quorum.tessera.api.SendRequest) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) SendSignedRequest(com.quorum.tessera.api.SendSignedRequest)

Example 9 with PrivacyMode

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();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) LoggerFactory(org.slf4j.LoggerFactory) Valid(jakarta.validation.Valid) NotNull(jakarta.validation.constraints.NotNull) PrivacyValid(com.quorum.tessera.api.constraint.PrivacyValid) Path(jakarta.ws.rs.Path) Content(io.swagger.v3.oas.annotations.media.Content) Operation(io.swagger.v3.oas.annotations.Operation) Response(jakarta.ws.rs.core.Response) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse) Produces(jakarta.ws.rs.Produces) URI(java.net.URI) MessageHash(com.quorum.tessera.data.MessageHash) Schema(io.swagger.v3.oas.annotations.media.Schema) Consumes(jakarta.ws.rs.Consumes) Logger(org.slf4j.Logger) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) Hidden(io.swagger.v3.oas.annotations.Hidden) POST(jakarta.ws.rs.POST) com.quorum.tessera.api(com.quorum.tessera.api) Predicate(java.util.function.Predicate) TransactionManager(com.quorum.tessera.transaction.TransactionManager) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) URLEncoder(java.net.URLEncoder) Stream(java.util.stream.Stream) UriBuilder(jakarta.ws.rs.core.UriBuilder) Tag(io.swagger.v3.oas.annotations.tags.Tag) APPLICATION_JSON(jakarta.ws.rs.core.MediaType.APPLICATION_JSON) MessageHash(com.quorum.tessera.data.MessageHash) URI(java.net.URI) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) PublicKey(com.quorum.tessera.encryption.PublicKey) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) Path(jakarta.ws.rs.Path) POST(jakarta.ws.rs.POST) Consumes(jakarta.ws.rs.Consumes) Produces(jakarta.ws.rs.Produces) Hidden(io.swagger.v3.oas.annotations.Hidden)

Example 10 with PrivacyMode

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();
}
Also used : SendSignedRequest(com.quorum.tessera.api.SendSignedRequest) MIME_TYPE_JSON_3(com.quorum.tessera.version.PrivacyGroupVersion.MIME_TYPE_JSON_3) PublicKey(com.quorum.tessera.encryption.PublicKey) java.util(java.util) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) SendResponse(com.quorum.tessera.api.SendResponse) LoggerFactory(org.slf4j.LoggerFactory) Valid(jakarta.validation.Valid) NotNull(jakarta.validation.constraints.NotNull) PrivacyValid(com.quorum.tessera.api.constraint.PrivacyValid) Content(io.swagger.v3.oas.annotations.media.Content) Operation(io.swagger.v3.oas.annotations.Operation) Response(jakarta.ws.rs.core.Response) ReceiveResponse(com.quorum.tessera.api.ReceiveResponse) RequestBody(io.swagger.v3.oas.annotations.parameters.RequestBody) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse) MIME_TYPE_JSON_2_1(com.quorum.tessera.version.MultiTenancyVersion.MIME_TYPE_JSON_2_1) URI(java.net.URI) MessageHash(com.quorum.tessera.data.MessageHash) Schema(io.swagger.v3.oas.annotations.media.Schema) Pattern(jakarta.validation.constraints.Pattern) Logger(org.slf4j.Logger) PrivacyGroup(com.quorum.tessera.enclave.PrivacyGroup) ExampleObject(io.swagger.v3.oas.annotations.media.ExampleObject) Predicate(java.util.function.Predicate) TransactionManager(com.quorum.tessera.transaction.TransactionManager) PrivacyGroupManager(com.quorum.tessera.privacygroup.PrivacyGroupManager) jakarta.ws.rs(jakarta.ws.rs) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) ValidBase64(com.quorum.tessera.config.constraints.ValidBase64) Parameter(io.swagger.v3.oas.annotations.Parameter) ArraySchema(io.swagger.v3.oas.annotations.media.ArraySchema) URLEncoder(java.net.URLEncoder) SendRequest(com.quorum.tessera.api.SendRequest) Stream(java.util.stream.Stream) MediaType(jakarta.ws.rs.core.MediaType) UriBuilder(jakarta.ws.rs.core.UriBuilder) Tag(io.swagger.v3.oas.annotations.tags.Tag) SendRequest(com.quorum.tessera.api.SendRequest) MessageHash(com.quorum.tessera.data.MessageHash) URI(java.net.URI) PublicKey(com.quorum.tessera.encryption.PublicKey) SendResponse(com.quorum.tessera.api.SendResponse) PrivacyMode(com.quorum.tessera.enclave.PrivacyMode) Operation(io.swagger.v3.oas.annotations.Operation) ApiResponse(io.swagger.v3.oas.annotations.responses.ApiResponse)

Aggregations

PrivacyMode (com.quorum.tessera.enclave.PrivacyMode)11 PublicKey (com.quorum.tessera.encryption.PublicKey)10 MessageHash (com.quorum.tessera.data.MessageHash)7 URI (java.net.URI)7 SendSignedRequest (com.quorum.tessera.api.SendSignedRequest)5 Operation (io.swagger.v3.oas.annotations.Operation)5 ApiResponse (io.swagger.v3.oas.annotations.responses.ApiResponse)5 Response (jakarta.ws.rs.core.Response)5 SendResponse (com.quorum.tessera.api.SendResponse)4 PrivacyValid (com.quorum.tessera.api.constraint.PrivacyValid)4 PrivacyGroup (com.quorum.tessera.enclave.PrivacyGroup)4 PrivacyGroupManager (com.quorum.tessera.privacygroup.PrivacyGroupManager)4 TransactionManager (com.quorum.tessera.transaction.TransactionManager)4 Content (io.swagger.v3.oas.annotations.media.Content)4 Schema (io.swagger.v3.oas.annotations.media.Schema)4 Tag (io.swagger.v3.oas.annotations.tags.Tag)4 Valid (jakarta.validation.Valid)4 NotNull (jakarta.validation.constraints.NotNull)4 UriBuilder (jakarta.ws.rs.core.UriBuilder)4 URLEncoder (java.net.URLEncoder)4