From a81d0e50c52391ee471ea7185306938b168314dc Mon Sep 17 00:00:00 2001 From: Elizabeth Healy <35498075+elizabethhealy@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:13:12 -0400 Subject: [PATCH 1/2] Revert "feat(core): Add attributes client (#118)" This reverts commit 98ba6a9e91f8e4b1903f907583356c084abb3313. --- .github/workflows/checks.yaml | 4 +- .../java/io/opentdf/platform/Command.java | 12 +-- .../platform/sdk/AttributesClient.java | 40 --------- .../java/io/opentdf/platform/sdk/SDK.java | 16 +--- .../io/opentdf/platform/sdk/SDKBuilder.java | 8 +- .../platform/sdk/AttributeClientTest.java | 84 ------------------- 6 files changed, 9 insertions(+), 155 deletions(-) delete mode 100644 sdk/src/main/java/io/opentdf/platform/sdk/AttributesClient.java delete mode 100644 sdk/src/test/java/io/opentdf/platform/sdk/AttributeClientTest.java diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index d985651e..b24db9e5 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -139,7 +139,7 @@ jobs: --client-secret=secret \ --platform-endpoint=localhost:8080 \ -i \ - encrypt --kas-url=localhost:8080 --mime-type=text/plain --attr https://example.com/attr/attr1/value/value1 -f data -m 'here is some metadata' > test.tdf + encrypt --kas-url=localhost:8080 --mime-type=text/plain -f data -m 'here is some metadata' > test.tdf java -jar target/cmdline.jar \ --client-id=opentdf-sdk \ @@ -175,7 +175,7 @@ jobs: --client-secret=secret \ --platform-endpoint=localhost:8080 \ -i \ - encryptnano --kas-url=http://localhost:8080 --attr https://example.com/attr/attr1/value/value1 -f data -m 'here is some metadata' > nano.ntdf + encryptnano --kas-url=http://localhost:8080 -f data -m 'here is some metadata' > nano.ntdf java -jar target/cmdline.jar \ --client-id=opentdf-sdk \ diff --git a/cmdline/src/main/java/io/opentdf/platform/Command.java b/cmdline/src/main/java/io/opentdf/platform/Command.java index 64886f65..d886886b 100644 --- a/cmdline/src/main/java/io/opentdf/platform/Command.java +++ b/cmdline/src/main/java/io/opentdf/platform/Command.java @@ -31,7 +31,6 @@ import java.util.List; import java.util.Optional; import java.util.function.Consumer; -import java.util.stream.Stream; @CommandLine.Command(name = "tdf") class Command { @@ -53,8 +52,6 @@ void encrypt( @Option(names = {"-f", "--file"}, defaultValue = Option.NULL_VALUE) Optional file, @Option(names = {"-k", "--kas-url"}, required = true, split = ",") List kas, @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata, - // cant split on optional parameters - @Option(names = {"-a", "--attr"}, defaultValue = Option.NULL_VALUE) Optional attributes, @Option(names = {"--mime-type"}, defaultValue = Option.NULL_VALUE) Optional mimeType) throws IOException, JOSEException { @@ -69,9 +66,6 @@ void encrypt( configs.add(Config.withKasInformation(kasInfos)); metadata.map(Config::withMetaData).ifPresent(configs::add); mimeType.map(Config::withMimeType).ifPresent(configs::add); - attributes.ifPresent(attr -> { - configs.add(Config.withDataAttributes(attr.split(","))); - }); var tdfConfig = Config.newTDFConfig(configs.toArray(Consumer[]::new)); try (var in = file.isEmpty() ? new BufferedInputStream(System.in) : new FileInputStream(file.get())) { @@ -119,8 +113,7 @@ void readMetadata(@Option(names = {"-f", "--file"}, required = true) Path tdfPat void createNanoTDF( @Option(names = {"-f", "--file"}, defaultValue = Option.NULL_VALUE) Optional file, @Option(names = {"-k", "--kas-url"}, required = true) List kas, - @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata, - @Option(names = {"-a", "--attr"}, defaultValue = Option.NULL_VALUE) Optional attributes) throws Exception { + @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata) throws Exception { var sdk = buildSDK(); var kasInfos = kas.stream().map(k -> { @@ -131,9 +124,6 @@ void createNanoTDF( List> configs = new ArrayList<>(); configs.add(Config.withNanoKasInformation(kasInfos)); - attributes.ifPresent(attr -> { - configs.add(Config.witDataAttributes(attr.split(","))); - }); var nanoTDFConfig = Config.newNanoTDFConfig(configs.toArray(Consumer[]::new)); try (var in = file.isEmpty() ? new BufferedInputStream(System.in) : new FileInputStream(file.get())) { diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/AttributesClient.java b/sdk/src/main/java/io/opentdf/platform/sdk/AttributesClient.java deleted file mode 100644 index 85be7b60..00000000 --- a/sdk/src/main/java/io/opentdf/platform/sdk/AttributesClient.java +++ /dev/null @@ -1,40 +0,0 @@ -package io.opentdf.platform.sdk; - -import io.grpc.ManagedChannel; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsRequest; -import io.opentdf.platform.policy.attributes.AttributesServiceGrpc; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsResponse; - - -public class AttributesClient implements SDK.AttributesService { - - private final ManagedChannel channel; - - /*** - * A client that communicates with KAS - * @param channelFactory A function that produces channels that can be used to communicate - * @param dpopKey - */ - public AttributesClient(ManagedChannel channel) { - this.channel = channel; - } - - - @Override - public synchronized void close() { - this.channel.shutdownNow(); - } - - - // make this protected so we can test the address normalization logic - synchronized AttributesServiceGrpc.AttributesServiceBlockingStub getStub() { - return AttributesServiceGrpc.newBlockingStub(channel); - } - - - @Override - public GetAttributeValuesByFqnsResponse getAttributeValuesByFqn(GetAttributeValuesByFqnsRequest request) { - return getStub().getAttributeValuesByFqns(request); - } - -} diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/SDK.java b/sdk/src/main/java/io/opentdf/platform/sdk/SDK.java index 3f5f7c45..426b6c3b 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/SDK.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/SDK.java @@ -5,7 +5,6 @@ import io.opentdf.platform.authorization.AuthorizationServiceGrpc; import io.opentdf.platform.authorization.AuthorizationServiceGrpc.AuthorizationServiceFutureStub; import io.opentdf.platform.policy.attributes.AttributesServiceGrpc; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsRequest; import io.opentdf.platform.policy.attributes.AttributesServiceGrpc.AttributesServiceFutureStub; import io.opentdf.platform.policy.namespaces.NamespaceServiceGrpc; import io.opentdf.platform.policy.namespaces.NamespaceServiceGrpc.NamespaceServiceFutureStub; @@ -14,9 +13,6 @@ import io.opentdf.platform.policy.subjectmapping.SubjectMappingServiceGrpc; import io.opentdf.platform.policy.subjectmapping.SubjectMappingServiceGrpc.SubjectMappingServiceFutureStub; import io.opentdf.platform.sdk.nanotdf.NanoTDFType; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsResponse; - -import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,20 +45,17 @@ public interface KAS extends AutoCloseable { byte[] unwrapNanoTDF(NanoTDFType.ECCurve curve, String header, String kasURL); } - public interface AttributesService extends AutoCloseable { - GetAttributeValuesByFqnsResponse getAttributeValuesByFqn(GetAttributeValuesByFqnsRequest request); - } - // TODO: add KAS public interface Services extends AutoCloseable { AuthorizationServiceFutureStub authorization(); - AttributesService attributes(); + AttributesServiceFutureStub attributes(); NamespaceServiceFutureStub namespaces(); SubjectMappingServiceFutureStub subjectMappings(); ResourceMappingServiceFutureStub resourceMappings(); KAS kas(); - static Services newServices(ManagedChannel channel, KAS kas, AttributesService attributeService) { + static Services newServices(ManagedChannel channel, KAS kas) { + var attributeService = AttributesServiceGrpc.newFutureStub(channel); var namespaceService = NamespaceServiceGrpc.newFutureStub(channel); var subjectMappingService = SubjectMappingServiceGrpc.newFutureStub(channel); var resourceMappingService = ResourceMappingServiceGrpc.newFutureStub(channel); @@ -72,12 +65,11 @@ static Services newServices(ManagedChannel channel, KAS kas, AttributesService a @Override public void close() throws Exception { channel.shutdownNow(); - attributeService.close(); kas.close(); } @Override - public AttributesService attributes() { + public AttributesServiceFutureStub attributes() { return attributeService; } diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/SDKBuilder.java b/sdk/src/main/java/io/opentdf/platform/sdk/SDKBuilder.java index 5caf0daa..ad156f42 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/SDKBuilder.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/SDKBuilder.java @@ -193,24 +193,20 @@ ServicesAndInternals buildServices() { var authInterceptor = getGrpcAuthInterceptor(dpopKey); ManagedChannel channel; - ManagedChannel attributesChannel; Function managedChannelFactory; if (authInterceptor == null) { channel = getManagedChannelBuilder(platformEndpoint).build(); - attributesChannel = getManagedChannelBuilder(platformEndpoint).build(); managedChannelFactory = (String endpoint) -> getManagedChannelBuilder(endpoint).build(); } else { channel = getManagedChannelBuilder(platformEndpoint).intercept(authInterceptor).build(); - attributesChannel = getManagedChannelBuilder(platformEndpoint).intercept(authInterceptor).build(); managedChannelFactory = (String endpoint) -> getManagedChannelBuilder(endpoint).intercept(authInterceptor).build(); } - var kasclient = new KASClient(managedChannelFactory, dpopKey); - var attrclient = new AttributesClient(attributesChannel); + var client = new KASClient(managedChannelFactory, dpopKey); return new ServicesAndInternals( authInterceptor, sslFactory == null ? null : sslFactory.getTrustManager().orElse(null), - SDK.Services.newServices(channel, kasclient, attrclient) + SDK.Services.newServices(channel, client) ); } diff --git a/sdk/src/test/java/io/opentdf/platform/sdk/AttributeClientTest.java b/sdk/src/test/java/io/opentdf/platform/sdk/AttributeClientTest.java deleted file mode 100644 index 8dd04c50..00000000 --- a/sdk/src/test/java/io/opentdf/platform/sdk/AttributeClientTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package io.opentdf.platform.sdk; - -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.Server; -import io.grpc.ServerBuilder; -import io.opentdf.platform.policy.attributes.AttributesServiceGrpc; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsRequest; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsResponse; -import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsResponse.AttributeAndValue; -import io.opentdf.platform.policy.Attribute; -import io.opentdf.platform.policy.Namespace; -import io.opentdf.platform.policy.Value; -import io.opentdf.platform.policy.AttributeRuleTypeEnum; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import static io.opentdf.platform.sdk.SDKBuilderTest.getRandomPort; -import static org.assertj.core.api.Assertions.assertThat; - - -public class AttributeClientTest { - @Test - void testGettingAttributeByFqn() throws IOException { - AttributesServiceGrpc.AttributesServiceImplBase attributesService = new AttributesServiceGrpc.AttributesServiceImplBase() { - @Override - public void getAttributeValuesByFqns(GetAttributeValuesByFqnsRequest request, - io.grpc.stub.StreamObserver responseObserver) { - Attribute attribute1 = Attribute.newBuilder().setId("CLS").setNamespace( - Namespace.newBuilder().setId("v").setName("virtru.com").setFqn("https://virtru.com").build()) - .setName("Classification").setRule(AttributeRuleTypeEnum.ATTRIBUTE_RULE_TYPE_ENUM_HIERARCHY).setFqn("https://virtru.com/attr/classification").build(); - - Value attributeValue1 = Value.newBuilder() - .setValue("value1") - .build(); - - // Create a sample AttributeValues object - AttributeAndValue attributeAndValues = AttributeAndValue.newBuilder().setAttribute(attribute1) - .setValue(attributeValue1) - .build(); - GetAttributeValuesByFqnsResponse response = GetAttributeValuesByFqnsResponse.newBuilder() - .putFqnAttributeValues("https://virtru.com/attr/classification/value/value1",attributeAndValues) - .build(); - responseObserver.onNext(response); - responseObserver.onCompleted(); - - } - }; - - Server attrServer = null; - try { - attrServer = startServer(attributesService); - String attrServerUrl = "localhost:" + attrServer.getPort(); - ManagedChannel channel = ManagedChannelBuilder - .forTarget(attrServerUrl) - .usePlaintext() - .build(); - try (var attr = new AttributesClient(channel)) { - GetAttributeValuesByFqnsResponse resp = attr.getAttributeValuesByFqn(GetAttributeValuesByFqnsRequest.newBuilder().build()); - Set fqnSet = new HashSet<>(Arrays.asList("https://virtru.com/attr/classification/value/value1")); - assertThat(resp.getFqnAttributeValuesMap().keySet()).isEqualTo(fqnSet); - assertThat(resp.getFqnAttributeValuesCount()).isEqualTo(1); - } - } finally { - if (attrServer != null) { - attrServer.shutdownNow(); - } - } - } - private static Server startServer(AttributesServiceGrpc.AttributesServiceImplBase attrService) throws IOException { - return ServerBuilder - .forPort(getRandomPort()) - .directExecutor() - .addService(attrService) - .build() - .start(); - } - -} From e874308a8651819d96483d94863111615a04a8f1 Mon Sep 17 00:00:00 2001 From: Elizabeth Healy Date: Tue, 20 Aug 2024 15:17:34 -0400 Subject: [PATCH 2/2] keep cli changes --- .github/workflows/checks.yaml | 4 ++-- .../src/main/java/io/opentdf/platform/Command.java | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index b24db9e5..d985651e 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -139,7 +139,7 @@ jobs: --client-secret=secret \ --platform-endpoint=localhost:8080 \ -i \ - encrypt --kas-url=localhost:8080 --mime-type=text/plain -f data -m 'here is some metadata' > test.tdf + encrypt --kas-url=localhost:8080 --mime-type=text/plain --attr https://example.com/attr/attr1/value/value1 -f data -m 'here is some metadata' > test.tdf java -jar target/cmdline.jar \ --client-id=opentdf-sdk \ @@ -175,7 +175,7 @@ jobs: --client-secret=secret \ --platform-endpoint=localhost:8080 \ -i \ - encryptnano --kas-url=http://localhost:8080 -f data -m 'here is some metadata' > nano.ntdf + encryptnano --kas-url=http://localhost:8080 --attr https://example.com/attr/attr1/value/value1 -f data -m 'here is some metadata' > nano.ntdf java -jar target/cmdline.jar \ --client-id=opentdf-sdk \ diff --git a/cmdline/src/main/java/io/opentdf/platform/Command.java b/cmdline/src/main/java/io/opentdf/platform/Command.java index d886886b..3a8d1bb8 100644 --- a/cmdline/src/main/java/io/opentdf/platform/Command.java +++ b/cmdline/src/main/java/io/opentdf/platform/Command.java @@ -52,6 +52,8 @@ void encrypt( @Option(names = {"-f", "--file"}, defaultValue = Option.NULL_VALUE) Optional file, @Option(names = {"-k", "--kas-url"}, required = true, split = ",") List kas, @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata, + // cant split on optional parameters + @Option(names = {"-a", "--attr"}, defaultValue = Option.NULL_VALUE) Optional attributes, @Option(names = {"--mime-type"}, defaultValue = Option.NULL_VALUE) Optional mimeType) throws IOException, JOSEException { @@ -66,6 +68,9 @@ void encrypt( configs.add(Config.withKasInformation(kasInfos)); metadata.map(Config::withMetaData).ifPresent(configs::add); mimeType.map(Config::withMimeType).ifPresent(configs::add); + attributes.ifPresent(attr -> { + configs.add(Config.withDataAttributes(attr.split(","))); + }); var tdfConfig = Config.newTDFConfig(configs.toArray(Consumer[]::new)); try (var in = file.isEmpty() ? new BufferedInputStream(System.in) : new FileInputStream(file.get())) { @@ -113,7 +118,8 @@ void readMetadata(@Option(names = {"-f", "--file"}, required = true) Path tdfPat void createNanoTDF( @Option(names = {"-f", "--file"}, defaultValue = Option.NULL_VALUE) Optional file, @Option(names = {"-k", "--kas-url"}, required = true) List kas, - @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata) throws Exception { + @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata, + @Option(names = {"-a", "--attr"}, defaultValue = Option.NULL_VALUE) Optional attributes) throws Exception { var sdk = buildSDK(); var kasInfos = kas.stream().map(k -> { @@ -124,6 +130,9 @@ void createNanoTDF( List> configs = new ArrayList<>(); configs.add(Config.withNanoKasInformation(kasInfos)); + attributes.ifPresent(attr -> { + configs.add(Config.witDataAttributes(attr.split(","))); + }); var nanoTDFConfig = Config.newNanoTDFConfig(configs.toArray(Consumer[]::new)); try (var in = file.isEmpty() ? new BufferedInputStream(System.in) : new FileInputStream(file.get())) {