Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import com.google.common.collect.Maps;
import org.graylog2.contentpacks.ContentPackable;
import org.graylog2.contentpacks.EntityDescriptorIds;
import org.graylog2.contentpacks.NativeEntityConverter;
import org.graylog2.contentpacks.model.entities.EntityDescriptor;
import org.graylog2.contentpacks.model.entities.references.ValueReference;

import javax.annotation.Nullable;
import java.util.Map;
Expand All @@ -43,7 +46,7 @@
property = Parameter.TYPE_FIELD,
visible = true,
defaultImpl = ValueParameter.class)
public interface Parameter extends ContentPackable<Parameter> {
public interface Parameter extends ContentPackable<Parameter>, NativeEntityConverter<Parameter> {
String TYPE_FIELD = "type";

@JsonProperty(TYPE_FIELD)
Expand Down Expand Up @@ -76,10 +79,22 @@ public interface Parameter extends ContentPackable<Parameter> {

Parameter applyBindings(Map<String, Parameter.Binding> bindings);

@Override
default Parameter toContentPackEntity(EntityDescriptorIds entityDescriptorIds) {
return this;
}

/**
* On content pack installation, resolve any content-pack entity references this parameter carries back to native
* entity ids using the resolved {@code nativeEntities}. Default is a no-op for parameters that reference no
* entities; the install-ordering counterpart is {@link NativeEntityConverter#resolveForInstallation}.
*/
@Override
default Parameter toNativeEntity(Map<String, ValueReference> parameters,
Map<EntityDescriptor, Object> nativeEntities) {
return this;
}

interface Builder<SELF> {
@JsonProperty(TYPE_FIELD)
SELF type(String type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,9 @@ public SearchEntity toContentPackEntity(EntityDescriptorIds entityDescriptorIds)
.collect(Collectors.toCollection(LinkedHashSet::new));
final SearchEntity.Builder searchEntityBuilder = SearchEntity.builder()
.queries(ImmutableSet.copyOf(queries))
.parameters(this.parameters())
.parameters(this.parameters().stream()
.map(parameter -> parameter.toContentPackEntity(entityDescriptorIds))
.collect(ImmutableSet.toImmutableSet()))
.requires(this.requires())
.createdAt(this.createdAt());
if (this.owner().isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,9 @@ protected ImmutableSet<EntityDescriptor> resolve(Collection<GRN> entities) {
dependencyGraph.predecessors(dependency).stream().anyMatch(
predecessor -> !ModelTypes.STREAM_V1.equals(predecessor.type()))
)
// Ignore lookup tables, adapters, and caches as dependencies. Lookup tables don't have a corresponding
// GRN type registered and cannot be resolved for permission checks.
.filter(dependency -> !ModelTypes.LOOKUP_TABLE_V1.equals(dependency.type()) &&
!ModelTypes.LOOKUP_ADAPTER_V1.equals(dependency.type()) &&
!ModelTypes.LOOKUP_CACHE_V1.equals(dependency.type()))
// Ignore dependency types that have no corresponding GRN type registered and therefore cannot
// be resolved for permission checks (lookup tables, adapters, caches - see ignoredDependencyTypes()).
.filter(dependency -> !ignoredDependencyTypes().contains(dependency.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.
Expand All @@ -98,6 +96,16 @@ protected ImmutableSet<EntityDescriptor> resolve(Collection<GRN> entities) {
.collect(ImmutableSet.toImmutableSet());
}

/**
* Content pack dependency types to exclude from permission dependency resolution: they have no
* corresponding GRN type registered and therefore cannot be resolved for permission checks. Lookup
* tables, adapters, and caches are excluded here because their access is not permission-gated in this
* context; subclasses may extend this for plugin-specific reference-only types.
*/
protected Set<ModelType> ignoredDependencyTypes() {
return Set.of(ModelTypes.LOOKUP_TABLE_V1, ModelTypes.LOOKUP_ADAPTER_V1, ModelTypes.LOOKUP_CACHE_V1);
}

@Override
public EntityDescriptor descriptorFromGRN(GRN entity) {
return descriptorFromGRN(entity, entityExcerpts(), grantService.getOwnersForTargets(ImmutableSet.of(entity)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ public Search toNativeEntity(Map<String, ValueReference> parameters,
.collect(Collectors.toCollection(LinkedHashSet::new));
final Search.Builder searchBuilder = Search.builder()
.queries(ImmutableSet.copyOf(queries))
.parameters(this.parameters())
.parameters(this.parameters().stream()
.map(parameter -> parameter.toNativeEntity(parameters, nativeEntities))
.collect(ImmutableSet.toImmutableSet()))
.requires(this.requires())
.createdAt(this.createdAt());
if (this.owner().isPresent()) {
Expand All @@ -137,5 +139,6 @@ public void resolveForInstallation(EntityV1 entity,
Map<EntityDescriptor, Entity> entities,
MutableGraph<Entity> graph) {
queries().forEach(query -> query.resolveForInstallation(entity, parameters, entities, graph));
parameters().forEach(parameter -> parameter.resolveForInstallation(entity, parameters, entities, graph));
}
}
Loading