From aac8ec8a36a418fe5405c3e830f7fe7e5909e749 Mon Sep 17 00:00:00 2001 From: Micha de Vries Date: Wed, 6 Dec 2023 01:06:53 +0100 Subject: [PATCH] Default table permissions should be `NONE` (#3074) --- lib/src/syn/v1/part/permission.rs | 90 +++++++++++++++-------------- lib/src/syn/v1/stmt/define/field.rs | 4 +- lib/src/syn/v1/stmt/define/table.rs | 9 ++- lib/tests/define.rs | 18 +++--- lib/tests/remove.rs | 2 +- lib/tests/table.rs | 2 +- 6 files changed, 65 insertions(+), 60 deletions(-) diff --git a/lib/src/syn/v1/part/permission.rs b/lib/src/syn/v1/part/permission.rs index ca8d1218..75c8f22c 100644 --- a/lib/src/syn/v1/part/permission.rs +++ b/lib/src/syn/v1/part/permission.rs @@ -17,10 +17,10 @@ use nom::{ sequence::tuple, }; -pub fn permissions(i: &str) -> IResult<&str, Permissions> { +pub fn permissions(i: &str, default: Permission) -> IResult<&str, Permissions> { let (i, _) = tag_no_case("PERMISSIONS")(i)?; let (i, _) = shouldbespace(i)?; - cut(alt((none, full, specific)))(i) + cut(alt((none, full, specific(default))))(i) } fn none(i: &str) -> IResult<&str, Permissions> { @@ -33,49 +33,51 @@ fn full(i: &str) -> IResult<&str, Permissions> { Ok((i, Permissions::full())) } -fn specific(i: &str) -> IResult<&str, Permissions> { - let (i, perms) = separated_list1(commasorspace, rule)(i)?; - Ok(( - i, - Permissions { - select: perms - .iter() - .find_map(|x| { - x.iter().find_map(|y| match y { - (PermissionKind::Select, ref v) => Some(v.to_owned()), - _ => None, +fn specific(default: Permission) -> impl Fn(&str) -> IResult<&str, Permissions> { + move |i: &str| -> IResult<&str, Permissions> { + let (i, perms) = separated_list1(commasorspace, rule)(i)?; + Ok(( + i, + Permissions { + select: perms + .iter() + .find_map(|x| { + x.iter().find_map(|y| match y { + (PermissionKind::Select, ref v) => Some(v.to_owned()), + _ => None, + }) }) - }) - .unwrap_or_default(), - create: perms - .iter() - .find_map(|x| { - x.iter().find_map(|y| match y { - (PermissionKind::Create, ref v) => Some(v.to_owned()), - _ => None, + .unwrap_or(default.to_owned()), + create: perms + .iter() + .find_map(|x| { + x.iter().find_map(|y| match y { + (PermissionKind::Create, ref v) => Some(v.to_owned()), + _ => None, + }) }) - }) - .unwrap_or_default(), - update: perms - .iter() - .find_map(|x| { - x.iter().find_map(|y| match y { - (PermissionKind::Update, ref v) => Some(v.to_owned()), - _ => None, + .unwrap_or(default.to_owned()), + update: perms + .iter() + .find_map(|x| { + x.iter().find_map(|y| match y { + (PermissionKind::Update, ref v) => Some(v.to_owned()), + _ => None, + }) }) - }) - .unwrap_or_default(), - delete: perms - .iter() - .find_map(|x| { - x.iter().find_map(|y| match y { - (PermissionKind::Delete, ref v) => Some(v.to_owned()), - _ => None, + .unwrap_or(default.to_owned()), + delete: perms + .iter() + .find_map(|x| { + x.iter().find_map(|y| match y { + (PermissionKind::Delete, ref v) => Some(v.to_owned()), + _ => None, + }) }) - }) - .unwrap_or_default(), - }, - )) + .unwrap_or(default.to_owned()), + }, + )) + } } pub fn permission(i: &str) -> IResult<&str, Permission> { @@ -126,7 +128,7 @@ mod test { #[test] fn permissions_none() { let sql = "PERMISSIONS NONE"; - let res = permissions(sql); + let res = permissions(sql, Permission::Full); let out = res.unwrap().1; assert_eq!("PERMISSIONS NONE", format!("{}", out)); assert_eq!(out, Permissions::none()); @@ -135,7 +137,7 @@ mod test { #[test] fn permissions_full() { let sql = "PERMISSIONS FULL"; - let res = permissions(sql); + let res = permissions(sql, Permission::None); let out = res.unwrap().1; assert_eq!("PERMISSIONS FULL", format!("{}", out)); assert_eq!(out, Permissions::full()); @@ -145,7 +147,7 @@ mod test { fn permissions_specific() { let sql = "PERMISSIONS FOR select FULL, FOR create, update WHERE public = true, FOR delete NONE"; - let res = permissions(sql); + let res = permissions(sql, Permission::None); let out = res.unwrap().1; assert_eq!( "PERMISSIONS FOR select FULL, FOR create, update WHERE public = true, FOR delete NONE", diff --git a/lib/src/syn/v1/stmt/define/field.rs b/lib/src/syn/v1/stmt/define/field.rs index 99887df4..cb375592 100644 --- a/lib/src/syn/v1/stmt/define/field.rs +++ b/lib/src/syn/v1/stmt/define/field.rs @@ -9,7 +9,7 @@ use super::super::super::{ value::value, IResult, }; -use crate::sql::{statements::DefineFieldStatement, Kind, Permissions, Strand, Value}; +use crate::sql::{statements::DefineFieldStatement, Kind, Permission, Permissions, Strand, Value}; use nom::{ branch::alt, bytes::complete::tag_no_case, @@ -141,6 +141,6 @@ fn field_comment(i: &str) -> IResult<&str, DefineFieldOption> { fn field_permissions(i: &str) -> IResult<&str, DefineFieldOption> { let (i, _) = shouldbespace(i)?; - let (i, v) = permissions(i)?; + let (i, v) = permissions(i, Permission::Full)?; Ok((i, DefineFieldOption::Permissions(v))) } diff --git a/lib/src/syn/v1/stmt/define/table.rs b/lib/src/syn/v1/stmt/define/table.rs index 6badc755..8f1ef680 100644 --- a/lib/src/syn/v1/stmt/define/table.rs +++ b/lib/src/syn/v1/stmt/define/table.rs @@ -6,7 +6,9 @@ use super::super::super::{ part::{changefeed, permission::permissions, view}, IResult, }; -use crate::sql::{statements::DefineTableStatement, ChangeFeed, Permissions, Strand, View}; +use crate::sql::{ + statements::DefineTableStatement, ChangeFeed, Permission, Permissions, Strand, View, +}; use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0}; pub fn table(i: &str) -> IResult<&str, DefineTableStatement> { @@ -21,6 +23,7 @@ pub fn table(i: &str) -> IResult<&str, DefineTableStatement> { // Create the base statement let mut res = DefineTableStatement { name, + permissions: Permissions::none(), ..Default::default() }; // Assign any defined options @@ -116,7 +119,7 @@ fn table_comment(i: &str) -> IResult<&str, DefineTableOption> { fn table_permissions(i: &str) -> IResult<&str, DefineTableOption> { let (i, _) = shouldbespace(i)?; - let (i, v) = permissions(i)?; + let (i, v) = permissions(i, Permission::None)?; Ok((i, DefineTableOption::Permissions(v))) } @@ -127,7 +130,7 @@ mod tests { #[test] fn define_table_with_changefeed() { - let sql = "TABLE mytable SCHEMALESS CHANGEFEED 1h"; + let sql = "TABLE mytable SCHEMALESS CHANGEFEED 1h PERMISSIONS NONE"; let res = table(sql); let out = res.unwrap().1; assert_eq!(format!("DEFINE {sql}"), format!("{}", out)); diff --git a/lib/tests/define.rs b/lib/tests/define.rs index ad52372b..34e6e89e 100644 --- a/lib/tests/define.rs +++ b/lib/tests/define.rs @@ -122,7 +122,7 @@ async fn define_statement_table_drop() -> Result<(), Error> { functions: {}, params: {}, scopes: {}, - tables: { test: 'DEFINE TABLE test DROP SCHEMALESS' }, + tables: { test: 'DEFINE TABLE test DROP SCHEMALESS PERMISSIONS NONE' }, users: {}, }", ); @@ -153,7 +153,7 @@ async fn define_statement_table_schemaless() -> Result<(), Error> { functions: {}, params: {}, scopes: {}, - tables: { test: 'DEFINE TABLE test SCHEMALESS' }, + tables: { test: 'DEFINE TABLE test SCHEMALESS PERMISSIONS NONE' }, users: {}, }", ); @@ -188,7 +188,7 @@ async fn define_statement_table_schemafull() -> Result<(), Error> { functions: {}, params: {}, scopes: {}, - tables: { test: 'DEFINE TABLE test SCHEMAFULL' }, + tables: { test: 'DEFINE TABLE test SCHEMAFULL PERMISSIONS NONE' }, users: {}, }", ); @@ -219,7 +219,7 @@ async fn define_statement_table_schemaful() -> Result<(), Error> { functions: {}, params: {}, scopes: {}, - tables: { test: 'DEFINE TABLE test SCHEMAFULL' }, + tables: { test: 'DEFINE TABLE test SCHEMAFULL PERMISSIONS NONE' }, users: {}, }", ); @@ -259,8 +259,8 @@ async fn define_statement_table_foreigntable() -> Result<(), Error> { params: {}, scopes: {}, tables: { - test: 'DEFINE TABLE test SCHEMAFULL', - view: 'DEFINE TABLE view SCHEMALESS AS SELECT count() FROM test GROUP ALL', + test: 'DEFINE TABLE test SCHEMAFULL PERMISSIONS NONE', + view: 'DEFINE TABLE view SCHEMALESS AS SELECT count() FROM test GROUP ALL PERMISSIONS NONE', }, users: {}, }", @@ -272,7 +272,7 @@ async fn define_statement_table_foreigntable() -> Result<(), Error> { "{ events: {}, fields: {}, - tables: { view: 'DEFINE TABLE view SCHEMALESS AS SELECT count() FROM test GROUP ALL' }, + tables: { view: 'DEFINE TABLE view SCHEMALESS AS SELECT count() FROM test GROUP ALL PERMISSIONS NONE' }, indexes: {}, lives: {}, }", @@ -291,7 +291,7 @@ async fn define_statement_table_foreigntable() -> Result<(), Error> { params: {}, scopes: {}, tables: { - test: 'DEFINE TABLE test SCHEMAFULL', + test: 'DEFINE TABLE test SCHEMAFULL PERMISSIONS NONE', }, users: {}, }", @@ -1871,7 +1871,7 @@ async fn permissions_checks_define_table() { // Define the expected results for the check statement when the test statement succeeded and when it failed let check_results = [ - vec!["{ analyzers: { }, functions: { }, params: { }, scopes: { }, tables: { TB: 'DEFINE TABLE TB SCHEMALESS' }, tokens: { }, users: { } }"], + vec!["{ analyzers: { }, functions: { }, params: { }, scopes: { }, tables: { TB: 'DEFINE TABLE TB SCHEMALESS PERMISSIONS NONE' }, tokens: { }, users: { } }"], vec!["{ analyzers: { }, functions: { }, params: { }, scopes: { }, tables: { }, tokens: { }, users: { } }"] ]; diff --git a/lib/tests/remove.rs b/lib/tests/remove.rs index 87dafb3f..fdc9de2c 100644 --- a/lib/tests/remove.rs +++ b/lib/tests/remove.rs @@ -601,7 +601,7 @@ async fn permissions_checks_remove_table() { // Define the expected results for the check statement when the test statement succeeded and when it failed let check_results = [ vec!["{ analyzers: { }, functions: { }, params: { }, scopes: { }, tables: { }, tokens: { }, users: { } }"], - vec!["{ analyzers: { }, functions: { }, params: { }, scopes: { }, tables: { TB: 'DEFINE TABLE TB SCHEMALESS' }, tokens: { }, users: { } }"], + vec!["{ analyzers: { }, functions: { }, params: { }, scopes: { }, tables: { TB: 'DEFINE TABLE TB SCHEMALESS PERMISSIONS NONE' }, tokens: { }, users: { } }"], ]; let test_cases = [ diff --git a/lib/tests/table.rs b/lib/tests/table.rs index cf4432cd..7c2c9a3c 100644 --- a/lib/tests/table.rs +++ b/lib/tests/table.rs @@ -43,7 +43,7 @@ async fn define_foreign_table() -> Result<(), Error> { "{ events: {}, fields: {}, - tables: { person_by_age: 'DEFINE TABLE person_by_age SCHEMALESS AS SELECT count(), age, math::sum(age) AS total, math::mean(score) AS average FROM person GROUP BY age' }, + tables: { person_by_age: 'DEFINE TABLE person_by_age SCHEMALESS AS SELECT count(), age, math::sum(age) AS total, math::mean(score) AS average FROM person GROUP BY age PERMISSIONS NONE' }, indexes: {}, lives: {}, }",