Skip to content

Commit

Permalink
[KYUUBI #5417] should not check in-subquery in permanent view
Browse files Browse the repository at this point in the history
### _Why are the changes needed?_
Fix #5417
If there is is a view with in-subquery, authz will still request this in-subquery's interval privilege, it's not we want.
For view
```
CREATE VIEW db.view1
AS
WITH temp AS (
    SELECT max(scope) max_scope
    FROM db1.table1)
SELECT id as new_id FROM db1.table2
WHERE scope in (SELECT max_scope FROM temp)
```

When we query the view
```
SEELCT * FROM db.view1
```

Before this pr, since spark will first execute subquery, it will first request `[default/table1/scope]` then request `[default/view1/new_id]`

after this pr, it only request  `[default/view1/new_id]`

### _How was this patch tested?_
- [x] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/master/contributing/code/testing.html#running-tests) locally before make a pull request

### _Was this patch authored or co-authored using generative AI tooling?_
no

Closes #5442 from AngersZhuuuu/KYUUBI-5417-FOLLOWUP.

Closes #5417

6919903 [Angerszhuuuu] Update RuleApplyPermanentViewMarker.scala
5097d80 [Angerszhuuuu] [KYUUBI #5417] should not check in-subquery in permanent view

Authored-by: Angerszhuuuu <[email protected]>
Signed-off-by: Kent Yao <[email protected]>
  • Loading branch information
AngersZhuuuu authored and yaooqinn committed Oct 17, 2023
1 parent f6ccc4d commit 8f6b15c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.apache.kyuubi.plugin.spark.authz.ranger

import org.apache.spark.sql.catalyst.expressions.ScalarSubquery
import org.apache.spark.sql.catalyst.expressions.SubqueryExpression
import org.apache.spark.sql.catalyst.plans.logical.{LogicalPlan, View}
import org.apache.spark.sql.catalyst.rules.Rule

Expand All @@ -38,11 +38,11 @@ class RuleApplyPermanentViewMarker extends Rule[LogicalPlan] {
case p: PermanentViewMarker => p
case permanentView: View if hasResolvedPermanentView(permanentView) =>
val resolvedSubquery = permanentView.transformAllExpressions {
case scalarSubquery: ScalarSubquery =>
case subquery: SubqueryExpression =>
// TODO: Currently, we do not do an auth check in the subquery
// as the main query part also secures it. But for performance consideration,
// we also pre-check it in subqueries and fail fast with negative privileges.
scalarSubquery.copy(plan = PermanentViewMarker(scalarSubquery.plan, null))
subquery.withNewPlan(plan = PermanentViewMarker(subquery.plan, null))
}
PermanentViewMarker(resolvedSubquery, resolvedSubquery.desc)
case other => apply(other)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ class HiveCatalogRangerSparkExtensionSuite extends RangerSparkExtensionSuite {
}
}

test("[KYUUBI #5417] should not check dependent subquery plan privilege") {
test("[KYUUBI #5417] should not check scalar-subquery in permanent view") {
val db1 = defaultDb
val table1 = "table1"
val table2 = "table2"
Expand Down Expand Up @@ -791,4 +791,48 @@ class HiveCatalogRangerSparkExtensionSuite extends RangerSparkExtensionSuite {
assert(e2.getMessage.contains(s"does not have [select] privilege on [$db1/$view1/new_id]"))
}
}

test("[KYUUBI #5417] should not check in-subquery in permanent view") {
val db1 = defaultDb
val table1 = "table1"
val table2 = "table2"
val view1 = "view1"
withCleanTmpResources(
Seq((s"$db1.$table1", "table"), (s"$db1.$table2", "table"), (s"$db1.$view1", "view"))) {
doAs(admin, sql(s"CREATE TABLE IF NOT EXISTS $db1.$table1 (id int, scope int)"))
doAs(admin, sql(s"CREATE TABLE IF NOT EXISTS $db1.$table2 (id int, scope int)"))

val e1 = intercept[AccessControlException] {
doAs(
someone,
sql(
s"""
|WITH temp AS (
| SELECT max(scope) max_scope
| FROM $db1.$table1)
|SELECT id as new_id FROM $db1.$table2
|WHERE scope in (SELECT max_scope FROM temp)
|""".stripMargin).show())
}
// Will first check subquery privilege.
assert(e1.getMessage.contains(s"does not have [select] privilege on [$db1/$table1/scope]"))

doAs(
admin,
sql(
s"""
|CREATE VIEW $db1.$view1
|AS
|WITH temp AS (
| SELECT max(scope) max_scope
| FROM $db1.$table1)
|SELECT id as new_id FROM $db1.$table2
|WHERE scope in (SELECT max_scope FROM temp)
|""".stripMargin))
// Will just check permanent view privilege.
val e2 = intercept[AccessControlException](
doAs(someone, sql(s"SELECT * FROM $db1.$view1".stripMargin).show()))
assert(e2.getMessage.contains(s"does not have [select] privilege on [$db1/$view1/new_id]"))
}
}
}

0 comments on commit 8f6b15c

Please sign in to comment.