From 8ad68135c8c1394445029d941f29723a377523b2 Mon Sep 17 00:00:00 2001 From: Jonathan Wei Date: Tue, 16 Feb 2021 17:36:45 -0800 Subject: [PATCH] Filter unauthorized views in InformationSchema (#10874) * Filter unauthorized views in InformationSchema * Use fixed name for view schema * Remove unused string --- .../druid/server/security/AuthorizationUtils.java | 9 +++++++++ .../druid/sql/calcite/schema/InformationSchema.java | 10 ++++++---- .../apache/druid/sql/calcite/CalciteQueryTest.java | 1 - .../apache/druid/sql/calcite/util/CalciteTests.java | 12 ++++++++++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java b/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java index 87194ce8d86..64c6330f745 100644 --- a/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java +++ b/server/src/main/java/org/apache/druid/server/security/AuthorizationUtils.java @@ -374,6 +374,15 @@ public class AuthorizationUtils Action.WRITE ); + /** + * Function for the common pattern of generating a resource-action for reading from a view, using the + * view name. + */ + public static final Function VIEW_READ_RA_GENERATOR = input -> new ResourceAction( + new Resource(input, ResourceType.VIEW), + Action.READ + ); + /** * Function for the pattern of generating a {@link ResourceAction} for reading from a given {@link Resource} */ diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java b/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java index 8ee93a21e63..b35f7a784a7 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/schema/InformationSchema.java @@ -111,6 +111,9 @@ public class InformationSchema extends AbstractSchema private static final Function> DRUID_TABLE_RA_GENERATOR = datasourceName -> { return Collections.singletonList(AuthorizationUtils.DATASOURCE_READ_RA_GENERATOR.apply(datasourceName)); }; + private static final Function> VIEW_TABLE_RA_GENERATOR = viewName -> { + return Collections.singletonList(AuthorizationUtils.VIEW_READ_RA_GENERATOR.apply(viewName)); + }; private static final String INFO_TRUE = "YES"; private static final String INFO_FALSE = "NO"; @@ -492,14 +495,13 @@ public class InformationSchema extends AbstractSchema final AuthenticationResult authenticationResult ) { - if (druidSchemaName.equals(subSchema.getName())) { - // The "druid" schema's functions represent views on Druid datasources, authorize them as if they were - // datasources for now + if (NamedViewSchema.NAME.equals(subSchema.getName())) { + // The "view" subschema functions represent views on Druid datasources return ImmutableSet.copyOf( AuthorizationUtils.filterAuthorizedResources( authenticationResult, subSchema.getFunctionNames(), - DRUID_TABLE_RA_GENERATOR, + VIEW_TABLE_RA_GENERATOR, authorizerMapper ) ); diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java index f4a941b6de0..6472b33184f 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java @@ -832,7 +832,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest .add(new Object[]{"view", "bview", "VIEW", "NO", "NO"}) .add(new Object[]{"view", "cview", "VIEW", "NO", "NO"}) .add(new Object[]{"view", "dview", "VIEW", "NO", "NO"}) - .add(new Object[]{"view", "forbiddenView", "VIEW", "NO", "NO"}) .add(new Object[]{"view", "restrictedView", "VIEW", "NO", "NO"}) .build() ); diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java index 9817908b07d..e4a6ec03de9 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java @@ -1074,7 +1074,11 @@ public class CalciteTests SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, false).plus(); InformationSchema informationSchema = - new InformationSchema(rootSchema, authorizerMapper, CalciteTests.DRUID_SCHEMA_NAME); + new InformationSchema( + rootSchema, + authorizerMapper, + CalciteTests.DRUID_SCHEMA_NAME + ); LookupSchema lookupSchema = CalciteTests.createMockLookupSchema(); rootSchema.add(CalciteTests.DRUID_SCHEMA_NAME, druidSchema); rootSchema.add(CalciteTests.INFORMATION_SCHEMA_NAME, informationSchema); @@ -1096,7 +1100,11 @@ public class CalciteTests CalciteTests.createMockSystemSchema(druidSchema, walker, plannerConfig, authorizerMapper); SchemaPlus rootSchema = CalciteSchema.createRootSchema(false, false).plus(); InformationSchema informationSchema = - new InformationSchema(rootSchema, authorizerMapper, CalciteTests.DRUID_SCHEMA_NAME); + new InformationSchema( + rootSchema, + authorizerMapper, + CalciteTests.DRUID_SCHEMA_NAME + ); LookupSchema lookupSchema = CalciteTests.createMockLookupSchema(); rootSchema.add(CalciteTests.DRUID_SCHEMA_NAME, druidSchema); rootSchema.add(CalciteTests.INFORMATION_SCHEMA_NAME, informationSchema);