From cac3c90aa9b546f52d4001b7ccd37b848352ec1b Mon Sep 17 00:00:00 2001 From: Ryan <103449971+ryan-carroll-graylog@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:30:53 -0500 Subject: [PATCH] Handle Stream reference dependencies for entity sharing (#17891) (#17918) * Add `stream_title` type to GRNRegistry * Replace stream_title dependencies with the acutal stream * Add unit test * Add changelog entry --- changelog/unreleased/issue-17882.toml | 5 +++ .../entities/EntityDependencyResolver.java | 7 +++- .../EntityDependencyResolverTest.java | 34 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 changelog/unreleased/issue-17882.toml diff --git a/changelog/unreleased/issue-17882.toml b/changelog/unreleased/issue-17882.toml new file mode 100644 index 000000000000..a845faa81b6d --- /dev/null +++ b/changelog/unreleased/issue-17882.toml @@ -0,0 +1,5 @@ +type = "fixed" +message = "Fixed error when attempting to share entities with stream dependencies." + +issues = ["17882"] +pulls = ["17891"] diff --git a/graylog2-server/src/main/java/org/graylog/security/entities/EntityDependencyResolver.java b/graylog2-server/src/main/java/org/graylog/security/entities/EntityDependencyResolver.java index 498bcaa75bba..bea688b7aaf8 100644 --- a/graylog2-server/src/main/java/org/graylog/security/entities/EntityDependencyResolver.java +++ b/graylog2-server/src/main/java/org/graylog/security/entities/EntityDependencyResolver.java @@ -29,7 +29,6 @@ import org.graylog2.contentpacks.model.ModelId; import org.graylog2.contentpacks.model.ModelType; import org.graylog2.contentpacks.model.ModelTypes; -import org.graylog2.contentpacks.model.entities.EntityExcerpt; import javax.annotation.Nullable; import javax.inject.Inject; @@ -85,6 +84,12 @@ public ImmutableSet resolve(GRN entity) { final Set ignoredDeps = IGNORED_DEPENDENCIES.getOrDefault(entity.grnType(), ImmutableSet.of()); return !ignoredDeps.contains(dep.type()); }) + // TODO: Work around from using the content pack dependency resolver: + // We've added stream_title content pack entities in https://github.com/Graylog2/graylog2-server/pull/17089, + // but in this context we want to return the actual dependent Stream to add additional permissions to. + .map(descriptor -> ModelTypes.STREAM_REF_V1.equals(descriptor.type()) + ? org.graylog2.contentpacks.model.entities.EntityDescriptor.create(descriptor.id(), ModelTypes.STREAM_V1) + : descriptor) .map(descriptor -> grnRegistry.newGRN(descriptor.type().name(), descriptor.id().id())) .filter(dependency -> !entity.equals(dependency)) // Don't include the given entity in dependencies .collect(ImmutableSet.toImmutableSet()); diff --git a/graylog2-server/src/test/java/org/graylog/security/entities/EntityDependencyResolverTest.java b/graylog2-server/src/test/java/org/graylog/security/entities/EntityDependencyResolverTest.java index adafe9ad9e4f..23a86d9beb85 100644 --- a/graylog2-server/src/test/java/org/graylog/security/entities/EntityDependencyResolverTest.java +++ b/graylog2-server/src/test/java/org/graylog/security/entities/EntityDependencyResolverTest.java @@ -121,4 +121,38 @@ void resolveWithInclompleteDependency() { assertThat(descriptor.title()).isEqualTo("unknown dependency: "); }); } + + @Test + @DisplayName("Try a stream reference dependency resolve") + void resolveStreamReference() { + final String TEST_TITLE = "Test Stream Title"; + final EntityExcerpt streamExcerpt = EntityExcerpt.builder() + .type(ModelTypes.STREAM_V1) + .id(ModelId.of("54e3deadbeefdeadbeefaffe")) + .title(TEST_TITLE).build(); + final EntityExcerpt streamRefExcerpt = EntityExcerpt.builder() + .type(ModelTypes.STREAM_REF_V1) + .id(ModelId.of("54e3deadbeefdeadbeefaffe")) + .title(TEST_TITLE).build(); + when(contentPackService.listAllEntityExcerpts()).thenReturn(ImmutableSet.of(streamExcerpt, streamRefExcerpt)); + + final EntityDescriptor streamDescriptor = EntityDescriptor.builder().type(ModelTypes.STREAM_REF_V1).id(ModelId.of("54e3deadbeefdeadbeefaffe")).build(); + when(contentPackService.resolveEntities(any())).thenReturn(ImmutableSet.of(streamDescriptor)); + + when(grnDescriptorService.getDescriptor(any(GRN.class))).thenAnswer(a -> { + GRN grnArg = a.getArgument(0); + return GRNDescriptor.builder().grn(grnArg).title("dummy").build(); + }); + final GRN dashboard = grnRegistry.newGRN("dashboard", "33e3deadbeefdeadbeefaffe"); + + final ImmutableSet missingDependencies = entityDependencyResolver.resolve(dashboard); + assertThat(missingDependencies).hasSize(1); + assertThat(missingDependencies.asList().get(0)).satisfies(descriptor -> { + assertThat(descriptor.id().toString()).isEqualTo("grn::::stream:54e3deadbeefdeadbeefaffe"); + assertThat(descriptor.title()).isEqualTo(TEST_TITLE); + + assertThat(descriptor.owners()).hasSize(1); + assertThat(descriptor.owners().asList().get(0).grn().toString()).isEqualTo("grn::::user:jane"); + }); + } }