|
|
@ -25,23 +25,23 @@
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
use crate::engine::{
|
|
|
|
use crate::engine::{
|
|
|
|
data::{
|
|
|
|
data::DictGeneric,
|
|
|
|
tag::{DataTag, TagClass},
|
|
|
|
|
|
|
|
DictGeneric,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
error::{QueryError, QueryResult},
|
|
|
|
error::{QueryError, QueryResult},
|
|
|
|
ql::{
|
|
|
|
ql::{
|
|
|
|
ast::{traits, QueryData, State},
|
|
|
|
ast::{traits, QueryData, State},
|
|
|
|
ddl::syn,
|
|
|
|
ddl::syn,
|
|
|
|
|
|
|
|
lex::Ident,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum SysctlCommand<'a> {
|
|
|
|
pub enum SysctlCommand<'a> {
|
|
|
|
/// `sysctl create user ...`
|
|
|
|
/// `sysctl create user ...`
|
|
|
|
CreateUser(UserAdd<'a>),
|
|
|
|
CreateUser(UserDecl<'a>),
|
|
|
|
/// `sysctl drop user ...`
|
|
|
|
/// `sysctl drop user ...`
|
|
|
|
DropUser(UserDel<'a>),
|
|
|
|
DropUser(UserDel<'a>),
|
|
|
|
|
|
|
|
/// `systcl alter user ...`
|
|
|
|
|
|
|
|
AlterUser(UserDecl<'a>),
|
|
|
|
/// `sysctl status`
|
|
|
|
/// `sysctl status`
|
|
|
|
ReportStatus,
|
|
|
|
ReportStatus,
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -62,16 +62,19 @@ impl<'a> traits::ASTNode<'a> for SysctlCommand<'a> {
|
|
|
|
return Err(QueryError::QLUnexpectedEndOfStatement);
|
|
|
|
return Err(QueryError::QLUnexpectedEndOfStatement);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let (a, b) = (state.fw_read(), state.fw_read());
|
|
|
|
let (a, b) = (state.fw_read(), state.fw_read());
|
|
|
|
|
|
|
|
let alter = Token![alter].eq(a) & b.ident_eq("user");
|
|
|
|
let create = Token![create].eq(a) & b.ident_eq("user");
|
|
|
|
let create = Token![create].eq(a) & b.ident_eq("user");
|
|
|
|
let drop = Token![drop].eq(a) & b.ident_eq("user");
|
|
|
|
let drop = Token![drop].eq(a) & b.ident_eq("user");
|
|
|
|
let status = a.ident_eq("report") & b.ident_eq("status");
|
|
|
|
let status = a.ident_eq("report") & b.ident_eq("status");
|
|
|
|
if !(create | drop | status) {
|
|
|
|
if !(create | drop | status | alter) {
|
|
|
|
return Err(QueryError::QLUnknownStatement);
|
|
|
|
return Err(QueryError::QLUnknownStatement);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if create {
|
|
|
|
if create {
|
|
|
|
UserAdd::parse(state).map(SysctlCommand::CreateUser)
|
|
|
|
UserDecl::parse(state).map(SysctlCommand::CreateUser)
|
|
|
|
} else if drop {
|
|
|
|
} else if drop {
|
|
|
|
UserDel::parse(state).map(SysctlCommand::DropUser)
|
|
|
|
UserDel::parse(state).map(SysctlCommand::DropUser)
|
|
|
|
|
|
|
|
} else if alter {
|
|
|
|
|
|
|
|
UserDecl::parse(state).map(SysctlCommand::AlterUser)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Ok(SysctlCommand::ReportStatus)
|
|
|
|
Ok(SysctlCommand::ReportStatus)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -89,7 +92,7 @@ fn parse<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<UserMe
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let token_buffer = state.current();
|
|
|
|
let token_buffer = state.current();
|
|
|
|
// initial sig
|
|
|
|
// initial sig
|
|
|
|
let signature_okay = token_buffer[0].is_lit()
|
|
|
|
let signature_okay = token_buffer[0].is_ident()
|
|
|
|
& token_buffer[1].eq(&Token![with])
|
|
|
|
& token_buffer[1].eq(&Token![with])
|
|
|
|
& token_buffer[2].eq(&Token![open {}]);
|
|
|
|
& token_buffer[2].eq(&Token![open {}]);
|
|
|
|
// get props
|
|
|
|
// get props
|
|
|
@ -100,45 +103,38 @@ fn parse<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<UserMe
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let maybe_username = unsafe {
|
|
|
|
let maybe_username = unsafe {
|
|
|
|
// UNSAFE(@ohsayan): the dict parse ensures state correctness
|
|
|
|
// UNSAFE(@ohsayan): the dict parse ensures state correctness
|
|
|
|
token_buffer[0].uck_read_lit()
|
|
|
|
token_buffer[0].uck_read_ident()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
state.poison_if_not(maybe_username.kind().tag_class() == TagClass::Str);
|
|
|
|
|
|
|
|
if state.not_exhausted() | !state.okay() {
|
|
|
|
if state.not_exhausted() | !state.okay() {
|
|
|
|
// we shouldn't have more tokens
|
|
|
|
// we shouldn't have more tokens
|
|
|
|
return Err(QueryError::QLInvalidSyntax);
|
|
|
|
return Err(QueryError::QLInvalidSyntax);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(UserMeta {
|
|
|
|
Ok(UserMeta {
|
|
|
|
username: unsafe {
|
|
|
|
username: maybe_username,
|
|
|
|
// UNSAFE(@ohsayan): +tagck in state
|
|
|
|
|
|
|
|
maybe_username.str()
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
options: dict,
|
|
|
|
options: dict,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct UserMeta<'a> {
|
|
|
|
struct UserMeta<'a> {
|
|
|
|
username: &'a str,
|
|
|
|
username: Ident<'a>,
|
|
|
|
options: DictGeneric,
|
|
|
|
options: DictGeneric,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct UserAdd<'a> {
|
|
|
|
pub struct UserDecl<'a> {
|
|
|
|
username: &'a str,
|
|
|
|
username: Ident<'a>,
|
|
|
|
options: DictGeneric,
|
|
|
|
options: DictGeneric,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> UserAdd<'a> {
|
|
|
|
impl<'a> UserDecl<'a> {
|
|
|
|
pub(in crate::engine::ql) fn new(username: &'a str, options: DictGeneric) -> Self {
|
|
|
|
pub(in crate::engine::ql) fn new(username: Ident<'a>, options: DictGeneric) -> Self {
|
|
|
|
Self { username, options }
|
|
|
|
Self { username, options }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Parse a `user add` DCL command
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// MUSTENDSTREAM: YES
|
|
|
|
|
|
|
|
pub fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
|
|
|
|
pub fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
|
|
|
|
parse(state).map(|UserMeta { username, options }: UserMeta| Self::new(username, options))
|
|
|
|
parse(state).map(|UserMeta { username, options }: UserMeta| Self::new(username, options))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn username(&self) -> &str {
|
|
|
|
pub fn username(&self) -> &str {
|
|
|
|
self.username
|
|
|
|
self.username.as_str()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn options_mut(&mut self) -> &mut DictGeneric {
|
|
|
|
pub fn options_mut(&mut self) -> &mut DictGeneric {
|
|
|
|
&mut self.options
|
|
|
|
&mut self.options
|
|
|
@ -150,33 +146,28 @@ impl<'a> UserAdd<'a> {
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct UserDel<'a> {
|
|
|
|
pub struct UserDel<'a> {
|
|
|
|
username: &'a str,
|
|
|
|
username: Ident<'a>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> UserDel<'a> {
|
|
|
|
impl<'a> UserDel<'a> {
|
|
|
|
pub(in crate::engine::ql) fn new(username: &'a str) -> Self {
|
|
|
|
pub(in crate::engine::ql) fn new(username: Ident<'a>) -> Self {
|
|
|
|
Self { username }
|
|
|
|
Self { username }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Parse a `user del` DCL command
|
|
|
|
/// Parse a `user del` DCL command
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// MUSTENDSTREAM: YES
|
|
|
|
/// MUSTENDSTREAM: YES
|
|
|
|
pub fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
|
|
|
|
pub fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> QueryResult<Self> {
|
|
|
|
if state.can_read_lit_rounded() & (state.remaining() == 1) {
|
|
|
|
if state.cursor_has_ident_rounded() & (state.remaining() == 1) {
|
|
|
|
let lit = unsafe {
|
|
|
|
let username = unsafe {
|
|
|
|
// UNSAFE(@ohsayan): +boundck
|
|
|
|
// UNSAFE(@ohsayan): +boundck
|
|
|
|
state.read_cursor_lit_unchecked()
|
|
|
|
state.read().uck_read_ident()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
state.cursor_ahead();
|
|
|
|
state.cursor_ahead();
|
|
|
|
if lit.kind().tag_class() == TagClass::Str {
|
|
|
|
return Ok(Self::new(username));
|
|
|
|
return Ok(Self::new(unsafe {
|
|
|
|
|
|
|
|
// UNSAFE(@ohsayan): +tagck
|
|
|
|
|
|
|
|
lit.str()
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(QueryError::QLInvalidSyntax)
|
|
|
|
Err(QueryError::QLInvalidSyntax)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn username(&self) -> &str {
|
|
|
|
pub fn username(&self) -> &str {
|
|
|
|
self.username
|
|
|
|
self.username.as_str()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|