github-actions[bot] commented on code in PR #67343:
URL: https://github.com/apache/doris/pull/67343#discussion_r3924169077
##########
regression-test/suites/auth_call/test_ddl_dictionary_auth.groovy:
##########
@@ -84,6 +84,68 @@ suite("test_ddl_dictionary_auth", "p0,auth_call") {
sql """use ${dbName}"""
def dictRes = sql """SHOW DICTIONARIES"""
assertTrue(dictRes.size() == 1)
+ // the initial load queued by CREATE DICTIONARY is asynchronous; a refresh
while it is still
+ // LOADING fails on the status guard instead of exercising authorization
+ waitDictionaryReady(dictName)
+
+ // A user with privileges on another object of the database can USE the
database, but must
+ // not learn about dictionaries it has no privilege on, the same way SHOW
TABLES hides tables.
+ String viewer = 'test_ddl_dictionary_auth_viewer'
+ try_sql("DROP USER ${viewer}")
+ sql """CREATE USER '${viewer}' IDENTIFIED BY '${pwd}'"""
+ sql """grant select_priv on regression_test to ${viewer}"""
+ sql """grant SELECT_PRIV on ${dbName}.${tableName} to ${viewer}"""
+ if (isCloudMode()) {
+ def clusters = sql " SHOW CLUSTERS; "
+ def validCluster = clusters[0][0]
+ sql """GRANT USAGE_PRIV ON CLUSTER `${validCluster}` TO ${viewer}""";
+ }
+ connect(viewer, "${pwd}", context.config.jdbcUrl) {
+ sql """use ${dbName}"""
+ def hiddenDicts = sql """SHOW DICTIONARIES"""
+ assertEquals(0, hiddenDicts.size())
+ test {
+ sql """EXPLAIN DICTIONARY ${dictName}"""
+ exception "denied"
+ }
+ test {
+ sql """REFRESH DICTIONARY ${dictName}"""
+ exception "LOAD command denied"
+ }
+ }
+
+ // SHOW_VIEW makes the dictionary visible, including its source table, but
refreshing still
+ // needs LOAD on the dictionary. Dictionaries are not tables of the
database, so GRANT only
+ // accepts them by name for CREATE; these privileges have to be granted on
the database.
+ sql """grant SHOW_VIEW_PRIV on ${dbName}.* to ${viewer}"""
+ connect(viewer, "${pwd}", context.config.jdbcUrl) {
+ sql """use ${dbName}"""
+ def visibleDicts = sql """SHOW DICTIONARIES"""
+ assertEquals(1, visibleDicts.size())
+ assertEquals(dictName, visibleDicts[0][1])
+ assertEquals("internal.${dbName}.${tableName}".toString(),
visibleDicts[0][2])
+ def dictColumns = sql """EXPLAIN DICTIONARY ${dictName}"""
+ assertEquals(2, dictColumns.size())
+ test {
+ sql """REFRESH DICTIONARY ${dictName}"""
+ exception "LOAD command denied"
+ }
+ }
+ // rejected by the command preflight, not inside dataLoad(): the
dictionary was never touched
+ sql """use ${dbName}"""
+ def afterLoadDenied = sql """SHOW DICTIONARIES"""
+ assertEquals("NORMAL", afterLoadDenied[0][4])
+ // LastUpdateResult is "<timestamp>: succeed" after the initial load
+ assertTrue(afterLoadDenied[0][6].toString().endsWith("succeed"))
Review Comment:
[P2] Wait for the success metadata before using it as the preflight oracle
`waitDictionaryReady` returns as soon as SHOW reports `NORMAL`, but
`DictionaryManager.dataLoad` publishes `NORMAL` before it writes the
non-volatile `LastUpdateResult`. If the asynchronous CREATE load is descheduled
after that status CAS, this assertion can still see the empty/stale result and
flake. Conversely, on an implementation that enters `dataLoad` before denying
REFRESH, that refresh can write the denial and then the original loader can
resume and overwrite it with `succeed`, so this suffix check passes without
proving the dictionary was untouched. Please poll until the same row has both
`NORMAL` and the initial success result, snapshot that complete result, and
assert exact equality after the denied refreshes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]