From c80357889018a04443ecdf01f6762481c23053a5 Mon Sep 17 00:00:00 2001 From: Kaitmazian Maksim <m.kaitmazian@picodata.io> Date: Sat, 10 Feb 2024 22:47:25 +0300 Subject: [PATCH] feat: implement SQL support for grant procedure --- doc/sql/query.ebnf | 2 ++ sbroad-core/src/frontend/sql.rs | 9 +++++++ sbroad-core/src/frontend/sql/query.pest | 5 +++- sbroad-core/src/ir/acl.rs | 35 +++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/doc/sql/query.ebnf b/doc/sql/query.ebnf index 388dfdd1d0..6632d84c37 100644 --- a/doc/sql/query.ebnf +++ b/doc/sql/query.ebnf @@ -13,6 +13,8 @@ privilege ::= (('CREATE' | 'ALTER' | 'DROP') 'USER') | ('DROP' 'ON' 'ROLE' (role | user)) | (('READ' | 'WRITE' | 'CREATE' | 'ALTER' | 'DROP') 'TABLE') | (('ALTER' | 'DROP' | 'READ' | 'WRITE') 'ON' 'TABLE'? table) + | (('CREATE' | 'EXECUTE') 'PROCEDURE') + | ('EXECUTE' 'PROCEDURE' procedure ('(' type (',' type)* ')')?) | role create_procedure ::= 'CREATE PROCEDURE' procedure '(' type (',' type)* ')' ('language' 'SQL')? (('as' '$$' body '$$') | ('begin' 'atomic' body 'end')) diff --git a/sbroad-core/src/frontend/sql.rs b/sbroad-core/src/frontend/sql.rs index bb5cd6f798..453e945ec5 100644 --- a/sbroad-core/src/frontend/sql.rs +++ b/sbroad-core/src/frontend/sql.rs @@ -655,6 +655,15 @@ fn parse_grant_revoke( let table_name = parse_identifier(ast, *table_node_id)?; GrantRevokeType::specific_table(privilege, table_name)? } + Rule::PrivBlockProcedure => GrantRevokeType::procedure(privilege)?, + Rule::PrivBlockSpecificProcedure => { + let proc_node_id = inner_privilege_block_node.children.first().expect( + "Expected to see Name as a first child of PrivBlockSpecificProcedure", + ); + let proc_node = ast.nodes.get_node(*proc_node_id)?; + let (proc_name, proc_params) = parse_proc_with_optional_params(ast, proc_node)?; + GrantRevokeType::specific_procedure(privilege, proc_name, proc_params)? + } _ => { return Err(SbroadError::Invalid( Entity::ParseNode, diff --git a/sbroad-core/src/frontend/sql/query.pest b/sbroad-core/src/frontend/sql/query.pest index ba399ce5e3..ae0fd58c0e 100644 --- a/sbroad-core/src/frontend/sql/query.pest +++ b/sbroad-core/src/frontend/sql/query.pest @@ -30,7 +30,8 @@ ACL = _{ DropRole | DropUser | CreateRole | CreateUser | AlterUser | GrantPrivil RevokePrivilege = { ^"revoke" ~ PrivBlock ~ ^"from" ~ Identifier ~ TimeoutOption? } PrivBlock = _{ PrivBlockPrivilege | PrivBlockRolePass } PrivBlockPrivilege = {Privilege ~ (PrivBlockUser | PrivBlockSpecificUser | PrivBlockRole - | PrivBlockSpecificRole | PrivBlockTable | PrivBlockSpecificTable)} + | PrivBlockSpecificRole | PrivBlockTable | PrivBlockSpecificTable + | PrivBlockProcedure | PrivBlockSpecificProcedure)} PrivBlockUser = { ^"user" } PrivBlockSpecificUser = { ^"on" ~ ^"user" ~ Identifier } PrivBlockRole = { ^"role" } @@ -38,6 +39,8 @@ ACL = _{ DropRole | DropUser | CreateRole | CreateUser | AlterUser | GrantPrivil PrivBlockTable = { ^"table" } PrivBlockSpecificTable = { ^"on" ~ ^"table" ~ Table } PrivBlockRolePass = { Identifier } + PrivBlockProcedure = { ^"procedure" } + PrivBlockSpecificProcedure = { ^"on" ~ ^"procedure" ~ ProcWithOptionalParams } Privilege = _{ PrivilegeRead | PrivilegeWrite | PrivilegeExecute | PrivilegeCreate | PrivilegeAlter | PrivilegeDrop | PrivilegeSession | PrivilegeUsage } diff --git a/sbroad-core/src/ir/acl.rs b/sbroad-core/src/ir/acl.rs index 339c9e1d46..1bfb77377e 100644 --- a/sbroad-core/src/ir/acl.rs +++ b/sbroad-core/src/ir/acl.rs @@ -2,6 +2,8 @@ use crate::ir::{Entity, Node, Plan, SbroadError}; use serde::{Deserialize, Serialize}; use tarantool::decimal::Decimal; +use super::ddl::ParamDef; + ::tarantool::define_str_enum! { /// Revoked or granted privilege. pub enum Privilege { @@ -43,6 +45,14 @@ pub enum GrantRevokeType { privilege: Privilege, table_name: String, }, + Procedure { + privilege: Privilege, + }, + SpecificProcedure { + privilege: Privilege, + proc_name: String, + proc_params: Option<Vec<ParamDef>>, + }, RolePass { role_name: String, }, @@ -131,6 +141,31 @@ impl GrantRevokeType { }) } + /// # Errors + /// - Unacceptable privilege for procedure was passed. + pub fn procedure(privilege: Privilege) -> Result<Self, SbroadError> { + check_privilege( + privilege, + &[Privilege::Create, Privilege::Drop, Privilege::Execute], + )?; + Ok(Self::Procedure { privilege }) + } + + /// # Errors + /// - Unacceptable privilege for specific procedure was passed. + pub fn specific_procedure( + privilege: Privilege, + proc_name: String, + proc_params: Option<Vec<ParamDef>>, + ) -> Result<Self, SbroadError> { + check_privilege(privilege, &[Privilege::Drop, Privilege::Execute])?; + Ok(Self::SpecificProcedure { + privilege, + proc_name, + proc_params, + }) + } + #[must_use] pub fn role_pass(role_name: String) -> Self { Self::RolePass { role_name } -- GitLab