Skip to content

Commit 304b488

Browse files
Do not publish RLS rules on private tables (#2645)
1 parent 6ebb2ab commit 304b488

4 files changed

Lines changed: 52 additions & 15 deletions

File tree

crates/core/src/sql/parser.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use crate::db::datastore::locking_tx_datastore::state_view::StateView;
12
use crate::db::datastore::locking_tx_datastore::MutTxId;
23
use crate::sql::ast::SchemaViewer;
34
use spacetimedb_expr::check::parse_and_type_sub;
4-
use spacetimedb_expr::errors::TypingError;
55
use spacetimedb_expr::expr::ProjectName;
6+
use spacetimedb_lib::db::auth::StAccess;
67
use spacetimedb_lib::db::raw_def::v9::RawRowLevelSecurityDefV9;
78
use spacetimedb_lib::identity::AuthCtx;
89
use spacetimedb_schema::schema::RowLevelSecuritySchema;
@@ -17,15 +18,26 @@ impl RowLevelExpr {
1718
tx: &mut MutTxId,
1819
auth_ctx: &AuthCtx,
1920
rls: &RawRowLevelSecurityDefV9,
20-
) -> Result<Self, TypingError> {
21+
) -> anyhow::Result<Self> {
2122
let (sql, _) = parse_and_type_sub(&rls.sql, &SchemaViewer::new(tx, auth_ctx), auth_ctx)?;
23+
let table_id = sql.return_table_id().unwrap();
24+
let schema = tx.schema_for_table(table_id)?;
2225

23-
Ok(Self {
24-
def: RowLevelSecuritySchema {
25-
table_id: sql.return_table_id().unwrap(),
26-
sql: rls.sql.clone(),
27-
},
28-
sql,
29-
})
26+
match schema.table_access {
27+
StAccess::Private => {
28+
anyhow::bail!(
29+
"Cannot define RLS rule on private table: {}. \
30+
Please make table public if you wish to restrict access using RLS.",
31+
schema.table_name
32+
)
33+
}
34+
StAccess::Public => Ok(Self {
35+
def: RowLevelSecuritySchema {
36+
table_id,
37+
sql: rls.sql.clone(),
38+
},
39+
sql,
40+
}),
41+
}
3042
}
3143
}

smoketests/tests/auto_migration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class AddTableAutoMigration(Smoketest):
77
MODULE_CODE = """
88
use spacetimedb::{log, ReducerContext, Table, SpacetimeType};
99
10-
#[spacetimedb::table(name = person)]
10+
#[spacetimedb::table(name = person, public)]
1111
pub struct Person {
1212
name: String,
1313
}
@@ -44,7 +44,7 @@ class AddTableAutoMigration(Smoketest):
4444
MODULE_CODE_UPDATED = (
4545
MODULE_CODE
4646
+ """
47-
#[spacetimedb::table(name = book)]
47+
#[spacetimedb::table(name = book, public)]
4848
pub struct Book {
4949
isbn: String,
5050
}

smoketests/tests/fail_initial_publish.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class FailInitialPublish(Smoketest):
77
MODULE_CODE_BROKEN = """
88
use spacetimedb::{client_visibility_filter, Filter};
99
10-
#[spacetimedb::table(name = person)]
10+
#[spacetimedb::table(name = person, public)]
1111
pub struct Person {
1212
name: String,
1313
}
@@ -20,7 +20,7 @@ class FailInitialPublish(Smoketest):
2020
MODULE_CODE_FIXED = """
2121
use spacetimedb::{client_visibility_filter, Filter};
2222
23-
#[spacetimedb::table(name = person)]
23+
#[spacetimedb::table(name = person, public)]
2424
pub struct Person {
2525
name: String,
2626
}

smoketests/tests/rls.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from .. import Smoketest
1+
from .. import Smoketest, random_string
22

3-
class SqlFormat(Smoketest):
3+
class Rls(Smoketest):
44
MODULE_CODE = """
55
use spacetimedb::{Identity, ReducerContext, Table};
66
@@ -53,3 +53,28 @@ def test_rls_rules(self):
5353
name
5454
------
5555
""")
56+
57+
class BrokenRls(Smoketest):
58+
AUTOPUBLISH = False
59+
60+
MODULE_CODE_BROKEN = """
61+
use spacetimedb::{client_visibility_filter, Filter};
62+
63+
#[spacetimedb::table(name = user)]
64+
pub struct User {
65+
identity: Identity,
66+
}
67+
68+
#[client_visibility_filter]
69+
const PERSON_FILTER: Filter = Filter::Sql("SELECT * FROM \"user\" WHERE identity = :sender");
70+
"""
71+
72+
def test_publish_fails_for_rls_on_private_table(self):
73+
"""This tests that publishing an RLS rule on a private table fails"""
74+
75+
name = random_string()
76+
77+
self.write_module_code(self.MODULE_CODE_BROKEN)
78+
79+
with self.assertRaises(Exception):
80+
self.publish_module(name)

0 commit comments

Comments
 (0)