From f27eafad924e60870506661015f9db4b4f3a9de7 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Thu, 17 Oct 2024 15:54:59 -0600 Subject: [PATCH 1/5] Add assertion dep and change comp target for tests --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index ea906553..69c70970 100644 --- a/build.gradle +++ b/build.gradle @@ -149,6 +149,7 @@ configurations { // Test things dependencies { intTestImplementation "junit:junit:4.13.2" + intTestImplementation "org.assertj:assertj-core:3.26.3" } tasks.register('integrationTest', Test) { @@ -157,6 +158,11 @@ tasks.register('integrationTest', Test) { description = 'Runs integration tests.' group = 'verification' + // This is mostly so we can use """strings""" + // in tests and not have it yell at us. + sourceCompatibility = JavaVersion.VERSION_15 + targetCompatibility = JavaVersion.VERSION_15 + testClassesDirs = sourceSets.intTest.output.classesDirs classpath = sourceSets.intTest.runtimeClasspath shouldRunAfter test From 23c38092af9ce70e479f26eead5be4002ce2ffea Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Thu, 17 Oct 2024 15:55:20 -0600 Subject: [PATCH 2/5] Rewrite tests to match authzed-dotnet --- src/intTest/java/TestClient.java | 33 ++ src/intTest/java/V1ClientTest.java | 598 ++++++++++++++++------------- 2 files changed, 371 insertions(+), 260 deletions(-) create mode 100644 src/intTest/java/TestClient.java diff --git a/src/intTest/java/TestClient.java b/src/intTest/java/TestClient.java new file mode 100644 index 00000000..d969b05f --- /dev/null +++ b/src/intTest/java/TestClient.java @@ -0,0 +1,33 @@ +import com.authzed.api.v1.ExperimentalServiceGrpc; +import com.authzed.api.v1.PermissionsServiceGrpc; +import com.authzed.api.v1.SchemaServiceGrpc; +import com.authzed.grpcutil.BearerToken; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +import java.util.Random; + +public class TestClient { + private static final String tokenPrefix = "tc_test_token"; + + public SchemaServiceGrpc.SchemaServiceBlockingStub schemaService; + public PermissionsServiceGrpc.PermissionsServiceBlockingStub permissionsService; + public PermissionsServiceGrpc.PermissionsServiceStub asyncPermissionsService; + public ExperimentalServiceGrpc.ExperimentalServiceBlockingStub experimentalService; + public TestClient() { + ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:50051").usePlaintext().build(); + String token = generateToken(); + schemaService = SchemaServiceGrpc.newBlockingStub(channel) + .withCallCredentials(new BearerToken(token)); + permissionsService = PermissionsServiceGrpc.newBlockingStub(channel) + .withCallCredentials(new BearerToken(token)); + asyncPermissionsService = PermissionsServiceGrpc.newStub(channel) + .withCallCredentials(new BearerToken(token)); + experimentalService = ExperimentalServiceGrpc.newBlockingStub(channel) + .withCallCredentials(new BearerToken(token)); + } + public String generateToken() { + Random random = new Random(); + return tokenPrefix + random.nextInt(1000); + } +} diff --git a/src/intTest/java/V1ClientTest.java b/src/intTest/java/V1ClientTest.java index a078c86e..1aebc6f6 100644 --- a/src/intTest/java/V1ClientTest.java +++ b/src/intTest/java/V1ClientTest.java @@ -1,271 +1,349 @@ -import static com.authzed.api.v1.CheckDebugTrace.Permissionship.PERMISSIONSHIP_HAS_PERMISSION; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - import java.util.HashSet; -import java.util.Iterator; -import java.util.Random; -import java.util.Set; import java.util.concurrent.CountDownLatch; +import com.google.protobuf.Struct; +import com.google.protobuf.Value; + import com.authzed.api.v1.*; -import com.authzed.grpcutil.BearerToken; import io.grpc.stub.StreamObserver; import org.junit.Test; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; +import static org.assertj.core.api.Assertions.assertThat; public class V1ClientTest { - private static final String target = "localhost:50051"; - private static final String tokenPrefix = "tc_test_token"; - - // Write schema - private static final String schema = "definition test/article {\n" + - " relation author: test/user\n" + - " relation commenter: test/user\n" + - " permission can_comment = commenter + author\n" + - "}\n" + - "definition test/user {}"; - - public static String generateToken() { - Random random = new Random(); - return tokenPrefix + random.nextInt(1000); - } - - @Test - public void testSchemaService() { - // Initialize services - ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build(); - String token = generateToken(); - SchemaServiceGrpc.SchemaServiceBlockingStub schemaService = writeTestSchema(token, channel); - - // Read schema - ReadSchemaRequest readRequest = ReadSchemaRequest.newBuilder().build(); - ReadSchemaResponse readResponse = schemaService.readSchema(readRequest); - assertTrue(readResponse.getSchemaText().indexOf("test/article") > 0); - } - - // For an example with flow control, see - // https://github.com/grpc/grpc-java/blob/9071c1ad7c842f4e73b6ae95b71f11c517b177a4/examples/src/main/java/io/grpc/examples/manualflowcontrol/ManualFlowControlClient.java - @Test - public void testCheckPermission() { - // Initialize services - ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build(); - String token = generateToken(); - - PermissionsServiceGrpc.PermissionsServiceBlockingStub permissionsService = PermissionsServiceGrpc - .newBlockingStub(channel) - .withCallCredentials(new BearerToken(token)); - - writeTestSchema(token, channel); - - // Write relationship - String tokenVal = writeRelationship(permissionsService, - "test/article", "java_test", "author", "test/user", "george"); - assertNotNull(tokenVal); - - // Check permission - ZedToken zedToken = ZedToken.newBuilder() - .setToken(tokenVal) - .build(); - CheckPermissionRequest checkRequest = CheckPermissionRequest.newBuilder() - .setConsistency( - Consistency.newBuilder() - .setAtLeastAsFresh(zedToken) - .build()) - .setResource( - ObjectReference.newBuilder() - .setObjectType("test/article") - .setObjectId("java_test") - .build()) - .setSubject( - SubjectReference.newBuilder() - .setObject( - ObjectReference.newBuilder() - .setObjectType("test/user") - .setObjectId("george") - .build()) - .build()) - .setPermission("can_comment") - .build(); - - CheckPermissionResponse checkResponse = permissionsService.checkPermission(checkRequest); - assertEquals(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION, checkResponse.getPermissionship()); - } - - @Test - public void testLookupResources() { - // Initialize services - ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build(); - String token = generateToken(); - PermissionsServiceGrpc.PermissionsServiceBlockingStub permissionsService = PermissionsServiceGrpc - .newBlockingStub(channel) - .withCallCredentials(new BearerToken(token)); - - writeTestSchema(token, channel); - - // Write relationship - writeRelationship(permissionsService, - "test/article", "java_test", "author", "test/user", "george"); - String tokenVal = writeRelationship(permissionsService, - "test/article", "go_test", "author", "test/user", "george"); - - // lookup resources - ZedToken zedToken = ZedToken.newBuilder() - .setToken(tokenVal) - .build(); - LookupResourcesRequest lookupResourcesRequest = LookupResourcesRequest.newBuilder() - .setConsistency( - Consistency.newBuilder() - .setAtLeastAsFresh(zedToken) - .build()) - .setResourceObjectType("test/article") - .setSubject( - SubjectReference.newBuilder() - .setObject( - ObjectReference.newBuilder() - .setObjectType("test/user") - .setObjectId("george") - .build()) - .build()) - .setPermission("can_comment") - .build(); - - Iterator resp = permissionsService.lookupResources(lookupResourcesRequest); - Set resources = new HashSet<>(); - resp.forEachRemaining(lookupResourcesResponse -> { - resources.add(lookupResourcesResponse.getResourceObjectId()); - }); - - assertTrue(resources.contains("java_test")); - assertTrue(resources.contains("go_test")); - } - - private static String writeRelationship(PermissionsServiceGrpc.PermissionsServiceBlockingStub permissionsService, - String resourceType, String resourceID, String relation, String subjectType, - String subjectID) { - WriteRelationshipsRequest relRequest = WriteRelationshipsRequest - .newBuilder() - .addUpdates( - RelationshipUpdate.newBuilder() - .setOperation(RelationshipUpdate.Operation.OPERATION_CREATE) - .setRelationship( - Relationship.newBuilder() - .setResource( - ObjectReference.newBuilder() - .setObjectType(resourceType) - .setObjectId(resourceID) - .build()) - .setRelation(relation) - .setSubject( - SubjectReference.newBuilder() - .setObject( - ObjectReference.newBuilder() - .setObjectType(subjectType) - .setObjectId(subjectID) - .build()) - .build()) - .build()) - .build()) - .build(); - - WriteRelationshipsResponse relResponse = permissionsService.writeRelationships(relRequest); - return relResponse.getWrittenAt().getToken(); - } - - - class BulkImportObserver implements StreamObserver { - final CountDownLatch done = new CountDownLatch(1); - private long loaded; - - @Override - public void onNext(BulkImportRelationshipsResponse resp) { - loaded += resp.getNumLoaded(); - } - - @Override - public void onError(Throwable throwable) { - // TODO need to capture error so that blocking callsite is able to access it - System.out.println("onError"); - done.countDown(); - } - - @Override - public void onCompleted() { - System.out.println("onCompleted"); - done.countDown(); - } - - public void await() throws InterruptedException { - done.await(); - } - - public long loaded() { - return loaded; - } - }; - - @Test - public void testBulkImport() { - - ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build(); - String token = generateToken(); - ExperimentalServiceGrpc.ExperimentalServiceStub experimentalService = ExperimentalServiceGrpc. - newStub(channel) - .withCallCredentials(new BearerToken(token)); - - BulkImportObserver responseObserver = new BulkImportObserver(); - writeTestSchema(token, channel); - io.grpc.stub.StreamObserver - observer = experimentalService.bulkImportRelationships(responseObserver); - - for (int i = 0; i < 10; i++) { - BulkImportRelationshipsRequest req = BulkImportRelationshipsRequest.newBuilder() - .addRelationships(relationship("test/article", "java_test_" + i, "author", "test/user", "george")).build(); - observer.onNext(req); - } - observer.onCompleted(); - - try { - responseObserver.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - assertEquals(10, responseObserver.loaded()); - } - - private static Relationship relationship(String resourceType, String resourceID, String relation, String subjectType, String subjectID) { - return Relationship.newBuilder() - .setResource( - ObjectReference.newBuilder() - .setObjectType(resourceType) - .setObjectId(resourceID) - .build()) - .setRelation(relation) - .setSubject( - SubjectReference.newBuilder() - .setObject( - ObjectReference.newBuilder() - .setObjectType(subjectType) - .setObjectId(subjectID) - .build()) - .build()) - .build(); - } - - private static SchemaServiceGrpc.SchemaServiceBlockingStub writeTestSchema(String token, ManagedChannel channel) { - SchemaServiceGrpc.SchemaServiceBlockingStub schemaService = SchemaServiceGrpc.newBlockingStub(channel) - .withCallCredentials(new BearerToken(token)); - WriteSchemaRequest writeRequest = WriteSchemaRequest - .newBuilder() - .setSchema(schema) - .build(); - schemaService.writeSchema(writeRequest); - - return schemaService; - } + private static final Consistency fullyConsistent = Consistency.newBuilder().setFullyConsistent(true).build(); + + @Test + public void testBasicSchema() { + // Initialize services + var client = new TestClient(); + String schema = """ + definition document { + relation reader: user + } + definition user {} + """; + // Write schema + writeSchema(client, schema); + + // Read schema + var readRequest = ReadSchemaRequest.newBuilder().build(); + var readResponse = client.schemaService.readSchema(readRequest); + assertThat(readResponse.getSchemaText()).contains("definition document"); + assertThat(readResponse.getSchemaText()).contains("definition user"); + } + + @Test + public void testSchemaWithCaveats() { + var client = new TestClient(); + writeTestSchema(client); + } + + // For an example with flow control, see + // https://github.com/grpc/grpc-java/blob/9071c1ad7c842f4e73b6ae95b71f11c517b177a4/examples/src/main/java/io/grpc/examples/manualflowcontrol/ManualFlowControlClient.java + @Test + public void testCheck() { + var client = new TestClient(); + writeTestSchema(client); + var testTuples = writeTestTuples(client); + + var firstResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.emilia) + .setPermission("view") + .build()); + assertThat(firstResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); + + var secondResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.emilia) + .setPermission("write") + .build()); + assertThat(secondResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); + + var thirdResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.beatrice) + .setPermission("view") + .build()); + assertThat(thirdResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); + + var fourthResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.beatrice) + .setPermission("write") + .build()); + assertThat(fourthResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_NO_PERMISSION); + } + + @Test + public void testCaveatedCheck() { + var client = new TestClient(); + writeTestSchema(client); + var testTuples = writeTestTuples(client); + + // Likes Harry Potter + var likesContext = Struct.newBuilder().putFields("likes", Value.newBuilder().setBoolValue(true).build()).build(); + var firstResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.beatrice) + .setPermission("view_as_fan") + .setContext(likesContext) + .build()); + assertThat(firstResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); + + // No longer likes Harry Potter + var dislikesContext = Struct.newBuilder().putFields("likes", Value.newBuilder().setBoolValue(false).build()).build(); + var secondResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.beatrice) + .setPermission("view_as_fan") + .setContext(dislikesContext) + .build()); + assertThat(secondResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_NO_PERMISSION); + + // No longer likes Harry Potter + var thirdResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResource(testTuples.postOne) + .setSubject(testTuples.beatrice) + .setPermission("view_as_fan") + .build()); + assertThat(thirdResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_CONDITIONAL_PERMISSION); + assertThat(thirdResponse.getPartialCaveatInfo().getMissingRequiredContextList()).contains("likes"); + } + + @Test + public void testLookupResources() { + var client = new TestClient(); + writeTestSchema(client); + var testTuples = writeTestTuples(client); + + var lookupResourcesRequest = LookupResourcesRequest.newBuilder() + .setConsistency(fullyConsistent) + .setResourceObjectType("post") + .setSubject(testTuples.emilia) + .setPermission("write") + .build(); + + var resp = client.permissionsService.lookupResources(lookupResourcesRequest); + var resources = new HashSet(); + resp.forEachRemaining(lookupResourcesResponse -> resources.add(lookupResourcesResponse.getResourceObjectId())); + + assertThat(resources).contains(testTuples.postOne.getObjectId()); + assertThat(resources).contains(testTuples.postTwo.getObjectId()); + assertThat(resources).hasSize(2); + } + + @Test + public void testLookupSubjects() { + var client = new TestClient(); + writeTestSchema(client); + var testTuples = writeTestTuples(client); + + var lookupSubjectsRequest = LookupSubjectsRequest.newBuilder() + .setConsistency(fullyConsistent) + .setSubjectObjectType("user") + .setResource(testTuples.postOne) + .setPermission("view") + .build(); + + var resp = client.permissionsService.lookupSubjects(lookupSubjectsRequest); + var users = new HashSet(); + resp.forEachRemaining(response -> + users.add(response.getSubject().getSubjectObjectId())); + + assertThat(users).contains(testTuples.emilia.getObject().getObjectId()); + assertThat(users).contains(testTuples.beatrice.getObject().getObjectId()); + assertThat(users).hasSize(2); + } + + @Test + public void testCheckBulkPermissions() { + var client = new TestClient(); + writeTestSchema(client); + var testTuples = writeTestTuples(client); + + var checkBulkPermissionsRequest = CheckBulkPermissionsRequest.newBuilder() + .setConsistency(fullyConsistent) + .addItems(CheckBulkPermissionsRequestItem.newBuilder() + .setResource(testTuples.postOne) + .setPermission("view") + .setSubject(testTuples.emilia)) + .addItems(CheckBulkPermissionsRequestItem.newBuilder() + .setResource(testTuples.postOne) + .setPermission("write") + .setSubject(testTuples.emilia)) + .build(); + + var response = client.permissionsService.checkBulkPermissions(checkBulkPermissionsRequest); + assertThat(response.getPairsList()).hasSize(2); + assertThat(response.getPairs(0).getItem().getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); + assertThat(response.getPairs(1).getItem().getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); + } + + @Test + public void testBulkImport() throws InterruptedException { + var client = new TestClient(); + writeTestSchema(client); + writeTestTuples(client); + + // Validate export + var exportCall = client.permissionsService.exportBulkRelationships(ExportBulkRelationshipsRequest.newBuilder() + .setConsistency(fullyConsistent) + .build()); + + var relations = new HashSet(); + exportCall.forEachRemaining(response -> + relations.addAll(response.getRelationshipsList())); + + assertThat(relations).hasSize(4); + + // Note that this has a different preshared key + // Validate import + var emptyClient = new TestClient(); + writeTestSchema(emptyClient); + + final CountDownLatch done = new CountDownLatch(1); + + class ImportBulkObserver implements StreamObserver { + private long loaded; + + @Override + public void onNext(ImportBulkRelationshipsResponse resp) { + loaded += resp.getNumLoaded(); + } + + @Override + public void onError(Throwable throwable) { + // TODO need to capture error so that blocking callsite is able to access it + System.out.println("onError"); + done.countDown(); + } + + @Override + public void onCompleted() { + System.out.println("onCompleted"); + done.countDown(); + } + } + + // Do the import + var importObserver = new ImportBulkObserver(); + var wrappedObserver = client.asyncPermissionsService.importBulkRelationships(importObserver); + wrappedObserver.onNext(ImportBulkRelationshipsRequest.newBuilder() + .addAllRelationships(relations).build()); + wrappedObserver.onCompleted(); + + done.await(); + + // Validate that everything was loaded + var postImportExportCall = client.permissionsService.exportBulkRelationships(ExportBulkRelationshipsRequest.newBuilder() + .setConsistency(fullyConsistent) + .build()); + + var importedRelations = new HashSet(); + postImportExportCall.forEachRemaining(response -> + importedRelations.addAll(response.getRelationshipsList())); + + assertThat(importedRelations).hasSize(4); + } + + + + + private TestTuples writeTestTuples(TestClient client) { + var emilia = SubjectReference.newBuilder().setObject(ObjectReference.newBuilder().setObjectId("emilia").setObjectType("user").build()).build(); + var beatrice = SubjectReference.newBuilder().setObject(ObjectReference.newBuilder().setObjectId("beatrice").setObjectType("user").build()).build(); + var postOne = ObjectReference.newBuilder().setObjectId("post-one").setObjectType("post").build(); + var postTwo = ObjectReference.newBuilder().setObjectId("post-two").setObjectType("post").build(); + WriteRelationshipsRequest.Builder builder = WriteRelationshipsRequest.newBuilder() + .addUpdates( + RelationshipUpdate.newBuilder() + .setOperation(RelationshipUpdate.Operation.OPERATION_CREATE) + .setRelationship(Relationship.newBuilder() + .setRelation("writer") + .setResource(postOne) + .setSubject(emilia) + )) + .addUpdates( + RelationshipUpdate.newBuilder() + .setOperation(RelationshipUpdate.Operation.OPERATION_CREATE) + .setRelationship(Relationship.newBuilder() + .setRelation("writer") + .setResource(postTwo) + .setSubject(emilia) + )) + .addUpdates( + RelationshipUpdate.newBuilder() + .setOperation(RelationshipUpdate.Operation.OPERATION_CREATE) + .setRelationship(Relationship.newBuilder() + .setRelation("reader") + .setResource(postOne) + .setSubject(beatrice) + ) + ) + .addUpdates( + RelationshipUpdate.newBuilder() + .setOperation(RelationshipUpdate.Operation.OPERATION_CREATE) + .setRelationship(Relationship.newBuilder() + .setRelation("caveated_reader") + .setResource(postOne) + .setSubject(beatrice) + .setOptionalCaveat(ContextualizedCaveat.newBuilder() + .setCaveatName("likes_harry_potter")) + ) + ); + client.permissionsService.writeRelationships(builder.build()); + return new TestTuples(emilia, beatrice, postOne, postTwo); + } + + private void writeTestSchema(TestClient client) { + String schema = """ + caveat likes_harry_potter(likes bool) { + likes == true + } + + definition post { + relation writer: user + relation reader: user + relation caveated_reader: user with likes_harry_potter + + permission write = writer + permission view = reader + writer + permission view_as_fan = caveated_reader + writer + } + definition user {} + """; + writeSchema(client, schema); + } + + private void writeSchema(TestClient client, String schema) { + WriteSchemaRequest writeRequest = WriteSchemaRequest + .newBuilder() + .setSchema(schema) + .build(); + client.schemaService.writeSchema(writeRequest); + } +} + +class TestTuples { + public SubjectReference emilia; + public SubjectReference beatrice; + public ObjectReference postOne; + public ObjectReference postTwo; + + public TestTuples(SubjectReference one, SubjectReference two, ObjectReference three, ObjectReference four) { + emilia = one; + beatrice = two; + postOne = three; + postTwo = four; + } } From 77383e58e01b197004150afe69d708325d979214 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Thu, 17 Oct 2024 16:13:34 -0600 Subject: [PATCH 3/5] Remove version 15 designation --- build.gradle | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build.gradle b/build.gradle index 69c70970..87f34a73 100644 --- a/build.gradle +++ b/build.gradle @@ -158,11 +158,6 @@ tasks.register('integrationTest', Test) { description = 'Runs integration tests.' group = 'verification' - // This is mostly so we can use """strings""" - // in tests and not have it yell at us. - sourceCompatibility = JavaVersion.VERSION_15 - targetCompatibility = JavaVersion.VERSION_15 - testClassesDirs = sourceSets.intTest.output.classesDirs classpath = sourceSets.intTest.runtimeClasspath shouldRunAfter test From 3e4ff2e8908c115c6ddb6fc1fbe6543198b041a2 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Thu, 17 Oct 2024 16:13:53 -0600 Subject: [PATCH 4/5] Explicitly type everything to make java 8 happy" --- src/intTest/java/V1ClientTest.java | 133 +++++++++++++++-------------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/src/intTest/java/V1ClientTest.java b/src/intTest/java/V1ClientTest.java index 1aebc6f6..0e9af14a 100644 --- a/src/intTest/java/V1ClientTest.java +++ b/src/intTest/java/V1ClientTest.java @@ -1,4 +1,5 @@ import java.util.HashSet; +import java.util.Iterator; import java.util.concurrent.CountDownLatch; import com.google.protobuf.Struct; @@ -7,36 +8,42 @@ import com.authzed.api.v1.*; import io.grpc.stub.StreamObserver; +import jdk.dynalink.linker.support.Lookup; import org.junit.Test; +import javax.security.auth.Subject; + import static org.assertj.core.api.Assertions.assertThat; +/* +NOTE: this file has some un-ergonomic code because we test against Java 8 +and therefore need to conform to Java 8 syntax. When we get to where we can +drop support, we can update this code. + */ public class V1ClientTest { private static final Consistency fullyConsistent = Consistency.newBuilder().setFullyConsistent(true).build(); @Test public void testBasicSchema() { // Initialize services - var client = new TestClient(); - String schema = """ - definition document { - relation reader: user - } - definition user {} - """; + TestClient client = new TestClient(); + String schema = "definition document {\n" + + "relation reader: user\n" + + "}\n" + + "definition user {}"; // Write schema writeSchema(client, schema); // Read schema - var readRequest = ReadSchemaRequest.newBuilder().build(); - var readResponse = client.schemaService.readSchema(readRequest); + ReadSchemaRequest readRequest = ReadSchemaRequest.newBuilder().build(); + ReadSchemaResponse readResponse = client.schemaService.readSchema(readRequest); assertThat(readResponse.getSchemaText()).contains("definition document"); assertThat(readResponse.getSchemaText()).contains("definition user"); } @Test public void testSchemaWithCaveats() { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); } @@ -44,11 +51,11 @@ public void testSchemaWithCaveats() { // https://github.com/grpc/grpc-java/blob/9071c1ad7c842f4e73b6ae95b71f11c517b177a4/examples/src/main/java/io/grpc/examples/manualflowcontrol/ManualFlowControlClient.java @Test public void testCheck() { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); - var testTuples = writeTestTuples(client); + TestTuples testTuples = writeTestTuples(client); - var firstResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + CheckPermissionResponse firstResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.emilia) @@ -56,7 +63,7 @@ public void testCheck() { .build()); assertThat(firstResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); - var secondResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + CheckPermissionResponse secondResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.emilia) @@ -64,7 +71,7 @@ public void testCheck() { .build()); assertThat(secondResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); - var thirdResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + CheckPermissionResponse thirdResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.beatrice) @@ -72,7 +79,7 @@ public void testCheck() { .build()); assertThat(thirdResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); - var fourthResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + CheckPermissionResponse fourthResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.beatrice) @@ -83,13 +90,13 @@ public void testCheck() { @Test public void testCaveatedCheck() { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); - var testTuples = writeTestTuples(client); + TestTuples testTuples = writeTestTuples(client); // Likes Harry Potter - var likesContext = Struct.newBuilder().putFields("likes", Value.newBuilder().setBoolValue(true).build()).build(); - var firstResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + Struct likesContext = Struct.newBuilder().putFields("likes", Value.newBuilder().setBoolValue(true).build()).build(); + CheckPermissionResponse firstResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.beatrice) @@ -99,8 +106,8 @@ public void testCaveatedCheck() { assertThat(firstResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); // No longer likes Harry Potter - var dislikesContext = Struct.newBuilder().putFields("likes", Value.newBuilder().setBoolValue(false).build()).build(); - var secondResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + Struct dislikesContext = Struct.newBuilder().putFields("likes", Value.newBuilder().setBoolValue(false).build()).build(); + CheckPermissionResponse secondResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.beatrice) @@ -110,7 +117,7 @@ public void testCaveatedCheck() { assertThat(secondResponse.getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_NO_PERMISSION); // No longer likes Harry Potter - var thirdResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() + CheckPermissionResponse thirdResponse = client.permissionsService.checkPermission(CheckPermissionRequest.newBuilder() .setConsistency(fullyConsistent) .setResource(testTuples.postOne) .setSubject(testTuples.beatrice) @@ -122,19 +129,19 @@ public void testCaveatedCheck() { @Test public void testLookupResources() { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); - var testTuples = writeTestTuples(client); + TestTuples testTuples = writeTestTuples(client); - var lookupResourcesRequest = LookupResourcesRequest.newBuilder() + LookupResourcesRequest lookupResourcesRequest = LookupResourcesRequest.newBuilder() .setConsistency(fullyConsistent) .setResourceObjectType("post") .setSubject(testTuples.emilia) .setPermission("write") .build(); - var resp = client.permissionsService.lookupResources(lookupResourcesRequest); - var resources = new HashSet(); + Iterator resp = client.permissionsService.lookupResources(lookupResourcesRequest); + HashSet resources = new HashSet(); resp.forEachRemaining(lookupResourcesResponse -> resources.add(lookupResourcesResponse.getResourceObjectId())); assertThat(resources).contains(testTuples.postOne.getObjectId()); @@ -144,19 +151,19 @@ public void testLookupResources() { @Test public void testLookupSubjects() { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); - var testTuples = writeTestTuples(client); + TestTuples testTuples = writeTestTuples(client); - var lookupSubjectsRequest = LookupSubjectsRequest.newBuilder() + LookupSubjectsRequest lookupSubjectsRequest = LookupSubjectsRequest.newBuilder() .setConsistency(fullyConsistent) .setSubjectObjectType("user") .setResource(testTuples.postOne) .setPermission("view") .build(); - var resp = client.permissionsService.lookupSubjects(lookupSubjectsRequest); - var users = new HashSet(); + Iterator resp = client.permissionsService.lookupSubjects(lookupSubjectsRequest); + HashSet users = new HashSet(); resp.forEachRemaining(response -> users.add(response.getSubject().getSubjectObjectId())); @@ -167,11 +174,11 @@ public void testLookupSubjects() { @Test public void testCheckBulkPermissions() { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); - var testTuples = writeTestTuples(client); + TestTuples testTuples = writeTestTuples(client); - var checkBulkPermissionsRequest = CheckBulkPermissionsRequest.newBuilder() + CheckBulkPermissionsRequest checkBulkPermissionsRequest = CheckBulkPermissionsRequest.newBuilder() .setConsistency(fullyConsistent) .addItems(CheckBulkPermissionsRequestItem.newBuilder() .setResource(testTuples.postOne) @@ -183,7 +190,7 @@ public void testCheckBulkPermissions() { .setSubject(testTuples.emilia)) .build(); - var response = client.permissionsService.checkBulkPermissions(checkBulkPermissionsRequest); + CheckBulkPermissionsResponse response = client.permissionsService.checkBulkPermissions(checkBulkPermissionsRequest); assertThat(response.getPairsList()).hasSize(2); assertThat(response.getPairs(0).getItem().getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); assertThat(response.getPairs(1).getItem().getPermissionship()).isEqualTo(CheckPermissionResponse.Permissionship.PERMISSIONSHIP_HAS_PERMISSION); @@ -191,16 +198,16 @@ public void testCheckBulkPermissions() { @Test public void testBulkImport() throws InterruptedException { - var client = new TestClient(); + TestClient client = new TestClient(); writeTestSchema(client); writeTestTuples(client); // Validate export - var exportCall = client.permissionsService.exportBulkRelationships(ExportBulkRelationshipsRequest.newBuilder() + Iterator exportCall = client.permissionsService.exportBulkRelationships(ExportBulkRelationshipsRequest.newBuilder() .setConsistency(fullyConsistent) .build()); - var relations = new HashSet(); + HashSet relations = new HashSet(); exportCall.forEachRemaining(response -> relations.addAll(response.getRelationshipsList())); @@ -208,7 +215,7 @@ public void testBulkImport() throws InterruptedException { // Note that this has a different preshared key // Validate import - var emptyClient = new TestClient(); + TestClient emptyClient = new TestClient(); writeTestSchema(emptyClient); final CountDownLatch done = new CountDownLatch(1); @@ -236,8 +243,8 @@ public void onCompleted() { } // Do the import - var importObserver = new ImportBulkObserver(); - var wrappedObserver = client.asyncPermissionsService.importBulkRelationships(importObserver); + ImportBulkObserver importObserver = new ImportBulkObserver(); + StreamObserver wrappedObserver = client.asyncPermissionsService.importBulkRelationships(importObserver); wrappedObserver.onNext(ImportBulkRelationshipsRequest.newBuilder() .addAllRelationships(relations).build()); wrappedObserver.onCompleted(); @@ -245,11 +252,11 @@ public void onCompleted() { done.await(); // Validate that everything was loaded - var postImportExportCall = client.permissionsService.exportBulkRelationships(ExportBulkRelationshipsRequest.newBuilder() + Iterator postImportExportCall = client.permissionsService.exportBulkRelationships(ExportBulkRelationshipsRequest.newBuilder() .setConsistency(fullyConsistent) .build()); - var importedRelations = new HashSet(); + HashSet importedRelations = new HashSet(); postImportExportCall.forEachRemaining(response -> importedRelations.addAll(response.getRelationshipsList())); @@ -260,10 +267,10 @@ public void onCompleted() { private TestTuples writeTestTuples(TestClient client) { - var emilia = SubjectReference.newBuilder().setObject(ObjectReference.newBuilder().setObjectId("emilia").setObjectType("user").build()).build(); - var beatrice = SubjectReference.newBuilder().setObject(ObjectReference.newBuilder().setObjectId("beatrice").setObjectType("user").build()).build(); - var postOne = ObjectReference.newBuilder().setObjectId("post-one").setObjectType("post").build(); - var postTwo = ObjectReference.newBuilder().setObjectId("post-two").setObjectType("post").build(); + SubjectReference emilia = SubjectReference.newBuilder().setObject(ObjectReference.newBuilder().setObjectId("emilia").setObjectType("user").build()).build(); + SubjectReference beatrice = SubjectReference.newBuilder().setObject(ObjectReference.newBuilder().setObjectId("beatrice").setObjectType("user").build()).build(); + ObjectReference postOne = ObjectReference.newBuilder().setObjectId("post-one").setObjectType("post").build(); + ObjectReference postTwo = ObjectReference.newBuilder().setObjectId("post-two").setObjectType("post").build(); WriteRelationshipsRequest.Builder builder = WriteRelationshipsRequest.newBuilder() .addUpdates( RelationshipUpdate.newBuilder() @@ -306,22 +313,18 @@ private TestTuples writeTestTuples(TestClient client) { } private void writeTestSchema(TestClient client) { - String schema = """ - caveat likes_harry_potter(likes bool) { - likes == true - } - - definition post { - relation writer: user - relation reader: user - relation caveated_reader: user with likes_harry_potter - - permission write = writer - permission view = reader + writer - permission view_as_fan = caveated_reader + writer - } - definition user {} - """; + String schema = "caveat likes_harry_potter(likes bool) {\n" + + "likes == true\n" + + "}\n" + + "definition post {\n" + + "relation writer: user\n" + + "relation reader: user\n" + + "relation caveated_reader: user with likes_harry_potter\n" + + "permission write = writer\n" + + "permission view = reader + writer\n" + + "permission view_as_fan = caveated_reader + writer\n" + + "}\n" + + "definition user {}"; writeSchema(client, schema); } From 35b9772bda8b555fc059d2cd495aa497388cb20e Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Thu, 17 Oct 2024 16:15:59 -0600 Subject: [PATCH 5/5] Remove unintentional imports --- src/intTest/java/V1ClientTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/intTest/java/V1ClientTest.java b/src/intTest/java/V1ClientTest.java index 0e9af14a..d119e04b 100644 --- a/src/intTest/java/V1ClientTest.java +++ b/src/intTest/java/V1ClientTest.java @@ -8,11 +8,8 @@ import com.authzed.api.v1.*; import io.grpc.stub.StreamObserver; -import jdk.dynalink.linker.support.Lookup; import org.junit.Test; -import javax.security.auth.Subject; - import static org.assertj.core.api.Assertions.assertThat; /*