Improve restrictive policies without permissive ones: in this case the result filter won't be calculated as False always anymore.

This commit is contained in:
Vitaly Baranov 2022-02-12 02:30:38 +07:00
parent 4b9db33ad7
commit a4ef274aa1
6 changed files with 132 additions and 46 deletions

View File

@ -22,19 +22,32 @@ namespace
public: public:
void add(const ASTPtr & filter, RowPolicyKind kind) void add(const ASTPtr & filter, RowPolicyKind kind)
{ {
if (kind == RowPolicyKind::RESTRICTIVE) if (kind == RowPolicyKind::PERMISSIVE)
restrictions.push_back(filter); {
setPermissiveFiltersExist();
permissive_filters.push_back(filter);
}
else else
permissions.push_back(filter); {
restrictive_filters.push_back(filter);
}
}
void setPermissiveFiltersExist()
{
permissive_filters_exist = true;
} }
ASTPtr getResult() && ASTPtr getResult() &&
{
if (permissive_filters_exist)
{ {
/// Process permissive filters. /// Process permissive filters.
restrictions.push_back(makeASTForLogicalOr(std::move(permissions))); restrictive_filters.push_back(makeASTForLogicalOr(std::move(permissive_filters)));
}
/// Process restrictive filters. /// Process restrictive filters.
auto result = makeASTForLogicalAnd(std::move(restrictions)); auto result = makeASTForLogicalAnd(std::move(restrictive_filters));
bool value; bool value;
if (tryGetLiteralBool(result.get(), value) && value) if (tryGetLiteralBool(result.get(), value) && value)
@ -44,8 +57,9 @@ namespace
} }
private: private:
ASTs permissions; ASTs permissive_filters;
ASTs restrictions; bool permissive_filters_exist = false;
ASTs restrictive_filters;
}; };
} }
@ -223,6 +237,11 @@ void RowPolicyCache::mixFiltersFor(EnabledRowPolicies & enabled)
key.filter_type = filter_type; key.filter_type = filter_type;
auto & mixer = mixers[key]; auto & mixer = mixers[key];
mixer.database_and_table_name = info.database_and_table_name; mixer.database_and_table_name = info.database_and_table_name;
if (policy.getKind() == RowPolicyKind::PERMISSIVE)
{
/// We call setPermissiveFiltersExist() even if the current user doesn't match to the current policy's TO clause.
mixer.mixer.setPermissiveFiltersExist();
}
if (match) if (match)
mixer.mixer.add(info.parsed_filters[filter_type_i], policy.getKind()); mixer.mixer.add(info.parsed_filters[filter_type_i], policy.getKind());
} }

View File

@ -435,6 +435,23 @@ def test_grant_create_row_policy():
node.query("DROP USER X") node.query("DROP USER X")
def test_some_users_without_policies():
copy_policy_xml('no_filters.xml')
assert node.query("SHOW POLICIES") == ""
node.query("CREATE USER X, Y")
node.query("GRANT SELECT ON mydb.filtered_table1 TO X, Y")
node.query("CREATE POLICY pA ON mydb.filtered_table1 FOR SELECT USING a<b AS permissive TO X")
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == TSV([[0, 1]])
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == ""
node.query("ALTER POLICY pA ON mydb.filtered_table1 AS restrictive")
assert node.query("SELECT * FROM mydb.filtered_table1", user='X') == TSV([[0, 1]])
assert node.query("SELECT * FROM mydb.filtered_table1", user='Y') == TSV([[0, 0], [0, 1], [1, 0], [1, 1]])
node.query("DROP USER X, Y")
def test_users_xml_is_readonly(): def test_users_xml_is_readonly():
assert re.search("storage is readonly", node.query_and_get_error("DROP POLICY default ON mydb.filtered_table1")) assert re.search("storage is readonly", node.query_and_get_error("DROP POLICY default ON mydb.filtered_table1"))

View File

@ -0,0 +1,33 @@
None
1
2
3
4
R1: x == 1
1
R1, R2: (x == 1) OR (x == 2)
1
2
R1, R2, R3: (x == 1) OR (x == 2) OR (x == 3)
1
2
3
R1, R2, R3, R4: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2)
1
2
R1, R2, R3, R4, R5: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)
2
R2, R3, R4, R5: ((x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)
2
R3, R4, R5: (x == 3) AND (x <= 2) AND (x >= 2)
R4, R5: (x <= 2) AND (x >= 2)
2
R5: (x >= 2)
2
3
4
None
1
2
3
4

View File

@ -0,0 +1,55 @@
DROP TABLE IF EXISTS 02131_multiple_row_policies_on_same_column;
CREATE TABLE 02131_multiple_row_policies_on_same_column (x UInt8) ENGINE = MergeTree ORDER BY x;
INSERT INTO 02131_multiple_row_policies_on_same_column VALUES (1), (2), (3), (4);
DROP ROW POLICY IF EXISTS 02131_filter_1 ON 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY IF EXISTS 02131_filter_2 ON 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY IF EXISTS 02131_filter_3 ON 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY IF EXISTS 02131_filter_4 ON 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY IF EXISTS 02131_filter_5 ON 02131_multiple_row_policies_on_same_column;
SELECT 'None';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_1 ON 02131_multiple_row_policies_on_same_column USING x=1 AS permissive TO ALL;
SELECT 'R1: x == 1';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_2 ON 02131_multiple_row_policies_on_same_column USING x=2 AS permissive TO ALL;
SELECT 'R1, R2: (x == 1) OR (x == 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_3 ON 02131_multiple_row_policies_on_same_column USING x=3 AS permissive TO ALL;
SELECT 'R1, R2, R3: (x == 1) OR (x == 2) OR (x == 3)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_4 ON 02131_multiple_row_policies_on_same_column USING x<=2 AS restrictive TO ALL;
SELECT 'R1, R2, R3, R4: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_5 ON 02131_multiple_row_policies_on_same_column USING x>=2 AS restrictive TO ALL;
SELECT 'R1, R2, R3, R4, R5: ((x == 1) OR (x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_1 ON 02131_multiple_row_policies_on_same_column;
SELECT 'R2, R3, R4, R5: ((x == 2) OR (x == 3)) AND (x <= 2) AND (x >= 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_2 ON 02131_multiple_row_policies_on_same_column;
SELECT 'R3, R4, R5: (x == 3) AND (x <= 2) AND (x >= 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_3 ON 02131_multiple_row_policies_on_same_column;
SELECT 'R4, R5: (x <= 2) AND (x >= 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_4 ON 02131_multiple_row_policies_on_same_column;
SELECT 'R5: (x >= 2)';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_5 ON 02131_multiple_row_policies_on_same_column;
SELECT 'None';
SELECT * FROM 02131_multiple_row_policies_on_same_column;
DROP TABLE 02131_multiple_row_policies_on_same_column;

View File

@ -1,30 +0,0 @@
DROP TABLE IF EXISTS 02131_multiply_row_policies_on_same_column;
CREATE TABLE 02131_multiply_row_policies_on_same_column (x UInt8) ENGINE = MergeTree ORDER BY x;
INSERT INTO 02131_multiply_row_policies_on_same_column VALUES (1), (2), (3), (4);
DROP ROW POLICY IF EXISTS 02131_filter_1 ON 02131_multiply_row_policies_on_same_column;
DROP ROW POLICY IF EXISTS 02131_filter_2 ON 02131_multiply_row_policies_on_same_column;
DROP ROW POLICY IF EXISTS 02131_filter_3 ON 02131_multiply_row_policies_on_same_column;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_1 ON 02131_multiply_row_policies_on_same_column USING x=1 TO ALL;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_2 ON 02131_multiply_row_policies_on_same_column USING x=2 TO ALL;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_3 ON 02131_multiply_row_policies_on_same_column USING x=3 TO ALL;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
CREATE ROW POLICY 02131_filter_4 ON 02131_multiply_row_policies_on_same_column USING x<4 AS RESTRICTIVE TO ALL;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_1 ON 02131_multiply_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_2 ON 02131_multiply_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_3 ON 02131_multiply_row_policies_on_same_column;
DROP ROW POLICY 02131_filter_4 ON 02131_multiply_row_policies_on_same_column;
SELECT count() FROM 02131_multiply_row_policies_on_same_column;
DROP TABLE 02131_multiply_row_policies_on_same_column;