Skip to content

Commit

Permalink
[KYUUBI #5657][AUTHZ] Support path privilege of AlterTableSetLocation…
Browse files Browse the repository at this point in the history
…Command/AlterTableAddPartitionCommand

### _Why are the changes needed?_
To close #5657
 Support path privilege of AlterTableSetLocationCommand/AlterTableAddPartitionCommand

### _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 #5658 from AngersZhuuuu/KYUUBO-5657.

Closes #5657

4805619 [Angerszhuuuu] Merge branch 'master' into KYUUBO-5657
ca62b5d [Angerszhuuuu] Update PrivilegesBuilderSuite.scala
aef7e11 [Angerszhuuuu] Update PrivilegesBuilderSuite.scala
338ae16 [Angerszhuuuu] [KYUUBI #5657][AUTHZ] Support path privilege of AlterTableSetLocationCommand/AlterTableAddPartitionCommand

Authored-by: Angerszhuuuu <[email protected]>
Signed-off-by: Cheng Pan <[email protected]>
  • Loading branch information
AngersZhuuuu authored and pan3793 committed Nov 9, 2023
1 parent 88d0d1b commit aa71e08
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

org.apache.kyuubi.plugin.spark.authz.serde.CatalogStorageFormatURIExtractor
org.apache.kyuubi.plugin.spark.authz.serde.BaseRelationFileIndexURIExtractor
org.apache.kyuubi.plugin.spark.authz.serde.PartitionLocsSeqURIExtractor
org.apache.kyuubi.plugin.spark.authz.serde.PropertiesPathUriExtractor
org.apache.kyuubi.plugin.spark.authz.serde.PropertiesLocationUriExtractor
org.apache.kyuubi.plugin.spark.authz.serde.StringURIExtractor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,11 @@
} ],
"opType" : "ALTERTABLE_ADDPARTS",
"queryDescs" : [ ],
"uriDescs" : [ ]
"uriDescs" : [ {
"fieldName" : "partitionSpecsAndLocs",
"fieldExtractor" : "PartitionLocsSeqURIExtractor",
"isInput" : false
} ]
}, {
"classname" : "org.apache.spark.sql.execution.command.AlterTableChangeColumnCommand",
"tableDescs" : [ {
Expand Down Expand Up @@ -835,7 +839,11 @@
} ],
"opType" : "ALTERTABLE_LOCATION",
"queryDescs" : [ ],
"uriDescs" : [ ]
"uriDescs" : [ {
"fieldName" : "location",
"fieldExtractor" : "StringURIExtractor",
"isInput" : false
} ]
}, {
"classname" : "org.apache.spark.sql.execution.command.AlterTableSetPropertiesCommand",
"tableDescs" : [ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,9 @@ class BaseRelationFileIndexURIExtractor extends URIExtractor {
}
}
}

class PartitionLocsSeqURIExtractor extends URIExtractor {
override def apply(v1: AnyRef): Seq[Uri] = {
v1.asInstanceOf[Seq[(_, Option[String])]].flatMap(_._2).map(Uri)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -306,17 +306,26 @@ abstract class PrivilegesBuilderSuite extends AnyFunSuite
val (in, out, operationType) = PrivilegesBuilder.build(plan, spark)

assert(in.isEmpty)
assert(out.size === 1)
val po = out.head
assert(po.actionType === PrivilegeObjectActionType.OTHER)
assert(po.privilegeObjectType === PrivilegeObjectType.TABLE_OR_VIEW)
assert(po.catalog.isEmpty)
assertEqualsIgnoreCase(reusedDb)(po.dbname)
assertEqualsIgnoreCase(reusedPartTableShort)(po.objectName)
assert(po.columns.head === "pid")
checkTableOwner(po)
val accessType = ranger.AccessType(po, operationType, isInput = false)
assert(accessType === AccessType.ALTER)
assert(out.size === 2)
val po0 = out.head
assert(po0.actionType === PrivilegeObjectActionType.OTHER)
assert(po0.privilegeObjectType === PrivilegeObjectType.TABLE_OR_VIEW)
assert(po0.catalog.isEmpty)
assertEqualsIgnoreCase(reusedDb)(po0.dbname)
assertEqualsIgnoreCase(reusedPartTableShort)(po0.objectName)
assert(po0.columns.head === "pid")
checkTableOwner(po0)
val accessType0 = ranger.AccessType(po0, operationType, isInput = false)
assert(accessType0 === AccessType.ALTER)

val po1 = out.last
assert(po1.actionType === PrivilegeObjectActionType.OTHER)
assert(po1.catalog.isEmpty)
assert(po1.dbname === newLoc)
assert(po1.columns === Seq.empty)
checkTableOwner(po1)
val accessType1 = ranger.AccessType(po1, operationType, isInput = false)
assert(accessType1 === AccessType.WRITE)
}

test("AlterTable(Un)SetPropertiesCommand") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ object TableCommands extends CommandSpecs[TableCommandSpec] {
val cmd = "org.apache.spark.sql.execution.command.AlterTableAddPartitionCommand"
val columnDesc =
ColumnDesc("partitionSpecsAndLocs", classOf[PartitionLocsSeqColumnExtractor])
val uriDesc = UriDesc("partitionSpecsAndLocs", classOf[PartitionLocsSeqURIExtractor])
TableCommandSpec(
cmd,
Seq(tableNameDesc.copy(columnDesc = Some(columnDesc))),
ALTERTABLE_ADDPARTS)
ALTERTABLE_ADDPARTS,
uriDescs = Seq(uriDesc))
}

val AlterTableChangeColumn = {
Expand Down Expand Up @@ -150,10 +152,12 @@ object TableCommands extends CommandSpecs[TableCommandSpec] {
val AlterTableSetLocation = {
val cmd = "org.apache.spark.sql.execution.command.AlterTableSetLocationCommand"
val columnDesc = ColumnDesc("partitionSpec", classOf[PartitionOptionColumnExtractor])
val uriDesc = UriDesc("location", classOf[StringURIExtractor])
TableCommandSpec(
cmd,
Seq(tableNameDesc.copy(columnDesc = Some(columnDesc))),
ALTERTABLE_LOCATION)
ALTERTABLE_LOCATION,
uriDescs = Seq(uriDesc))
}

val AlterTableSetProperties = TableCommandSpec(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1197,4 +1197,47 @@ class HiveCatalogRangerSparkExtensionSuite extends RangerSparkExtensionSuite {
}
}
}

test("AlterTableSetLocationCommand/AlterTableAddPartitionCommand") {
val db1 = defaultDb
val table1 = "table1"
val table2 = "table2"
withSingleCallEnabled {
withTempDir { path1 =>
withCleanTmpResources(Seq((s"$db1.$table1", "table"), (s"$db1.$table2", "table"))) {
doAs(
admin,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $db1.$table1(
|id int,
|scope int,
|day string)
|PARTITIONED BY (day)
|""".stripMargin))
interceptContains[AccessControlException](
doAs(someone, sql(s"ALTER TABLE $db1.$table1 SET LOCATION '$path1'")))(
s"does not have [alter] privilege on [$db1/$table1], " +
s"[write] privilege on [[$path1, $path1/]]")

withTempDir { path2 =>
withTempDir { path3 =>
interceptContains[AccessControlException](
doAs(
someone,
sql(
s"""
|ALTER TABLE $db1.$table1
|ADD
|PARTITION (day='2023-01-01') LOCATION '$path2'
|PARTITION (day='2023-01-02') LOCATION '$path3'
|""".stripMargin)))(
s"does not have [alter] privilege on [$db1/$table1/day], " +
s"[write] privilege on [[$path2, $path2/],[$path3, $path3/]]")
}
}
}
}
}
}
}

0 comments on commit aa71e08

Please sign in to comment.