Add authn tests

next
Sayan Nandan 3 years ago
parent bf3b62c077
commit 58b3f0dda7
No known key found for this signature in database
GPG Key ID: 8BC07A0A4D41DD52

@ -1,2 +1,3 @@
[env]
ROOT_DIR = { value = "", relative = true }
TEST_ORIGIN_KEY = "4527387f92a381cbe804593f33991d327d456a97"

@ -138,25 +138,18 @@ impl AuthProvider {
}
}
fn are_you_root(&self) -> AuthResult<bool> {
self.ensure_enabled()?;
match self.whoami.as_ref().map(|v| v.eq(&USER_ROOT)) {
Some(v) => Ok(v),
None => Err(AuthError::Anonymous),
}
}
pub fn claim_user(&self, claimant: &[u8]) -> AuthResult<String> {
if self.are_you_root()? {
self._claim_user(claimant)
} else {
Err(AuthError::PermissionDenied)
}
self.ensure_root()?;
self._claim_user(claimant)
}
pub fn _claim_user(&self, claimant: &[u8]) -> AuthResult<String> {
let (key, store) = keys::generate_full();
println!(
"For {claimant}, store: {:?}, key: {key}",
store,
claimant = String::from_utf8_lossy(claimant)
);
if self.authmap.true_if_insert(
Array::try_from_slice(claimant).ok_or(AuthError::Other(errors::AUTH_ERROR_TOO_LONG))?,
store,
@ -185,6 +178,7 @@ impl AuthProvider {
}
}
pub fn logout(&mut self) -> AuthResult<()> {
self.ensure_enabled()?;
self.whoami.take().map(|_| ()).ok_or(AuthError::Anonymous)
}
fn ensure_enabled(&self) -> AuthResult<()> {

@ -66,6 +66,8 @@ const PATH: &str = ".sky_pid";
#[cfg(test)]
const ROOT_DIR: &str = env!("ROOT_DIR");
#[cfg(test)]
const TEST_AUTH_ORIGIN_KEY: &str = env!("TEST_ORIGIN_KEY");
#[cfg(all(not(target_env = "msvc"), not(miri)))]
use jemallocator::Jemalloc;

@ -24,12 +24,149 @@
*
*/
#[sky_macros::dbtest_func(username = "abcd", password = "1234")]
#[should_panic]
async fn test_auth_fail() {}
use skytable::{query, Element, RespCode};
macro_rules! assert_autherror {
($con:expr, $query:expr, $eq:expr) => {
runeq!($con, $query, Element::RespCode($eq))
};
}
macro_rules! assert_auth_disabled {
($con:expr, $query:expr) => {
assert_autherror!(
$con,
$query,
RespCode::ErrorString("err-auth-disabled".to_owned())
)
};
}
macro_rules! assert_auth_perm_error {
($con:expr, $query:expr) => {
assert_autherror!($con, $query, RespCode::ErrorString("11".to_owned()))
};
}
macro_rules! assert_auth_bad_credentials {
($con:expr, $query:expr) => {
assert_autherror!($con, $query, RespCode::ErrorString("10".to_owned()))
};
}
// auth claim
// auth claim fail because it is disabled
#[sky_macros::dbtest_func]
async fn auth_claim_fail_disabled() {
assert_auth_disabled!(con, query!("auth", "claim", "blah"))
}
// auth claim fail because it has already been claimed
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn claim_root_fail_already_claimed() {
runeq!(
con,
query!("auth", "claim", crate::TEST_AUTH_ORIGIN_KEY),
Element::RespCode(RespCode::ErrorString("err-already-claimed".to_owned()))
)
}
// auth login
// auth login fail because it is disabled
#[sky_macros::dbtest_func]
async fn auth_login_fail() {
assert_auth_disabled!(con, query!("auth", "login", "user", "blah"))
}
// auth login okay (testuser)
#[sky_macros::dbtest_func(port = 2005, auth_testuser = true)]
async fn auth_login_testuser() {
runeq!(
con,
query!("heya", "abcd"),
Element::String("abcd".to_owned())
)
}
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn auth_login_testuser_fail_bad_creds() {
assert_auth_bad_credentials!(con, query!("auth", "login", "testuser", "badpass"))
}
// auth login okay (root)
#[sky_macros::dbtest_func(port = 2005, auth_rootuser = true)]
async fn auth_login_rootuser() {
runeq!(
con,
query!("heya", "abcd"),
Element::String("abcd".to_owned())
)
}
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn auth_login_rootuser_fail_bad_creds() {
assert_auth_bad_credentials!(con, query!("auth", "login", "root", "badpass"))
}
// auth adduser
// auth adduser fail because disabled
#[sky_macros::dbtest_func]
async fn auth_adduser_fail_because_disabled() {
assert_auth_disabled!(con, query!("auth", "adduser", "user"))
}
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn auth_adduser_fail_because_anonymous() {
assert_auth_perm_error!(con, query!("auth", "adduser", "someuser"))
}
// auth adduser okay because root
#[sky_macros::dbtest_func(port = 2005, auth_rootuser = true)]
async fn auth_createuser_root_okay() {
runmatch!(con, query!("auth", "adduser", "someuser"), Element::String)
}
// auth adduser fail because not root
#[sky_macros::dbtest_func(port = 2005, auth_testuser = true)]
async fn test_auth_testuser() {}
async fn auth_createuser_testuser_fail() {
assert_auth_perm_error!(con, query!("auth", "adduser", "someuser"))
}
// auth logout
// auth logout failed because auth is disabled
#[sky_macros::dbtest_func]
async fn auth_logout_fail_because_disabled() {
assert_auth_disabled!(con, query!("auth", "logout"))
}
// auth logout failed because user is anonymous
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn auth_logout_fail_because_anonymous() {
assert_auth_perm_error!(con, query!("auth", "logout"))
}
// auth logout okay because the correct user is logged in
#[sky_macros::dbtest_func(port = 2005, auth_testuser = true, norun = true)]
async fn auth_logout_okay_testuser() {
assert_okay!(con, query!("auth", "logout"))
}
// auth logout okay because the correct user is logged in
#[sky_macros::dbtest_func(port = 2005, auth_rootuser = true, norun = true)]
async fn auth_logout_okay_rootuser() {
assert_okay!(con, query!("auth", "logout"))
}
// auth deluser
// auth deluser failed because auth is disabled
#[sky_macros::dbtest_func]
async fn auth_deluser_fail_because_auth_disabled() {
assert_auth_disabled!(con, query!("auth", "deluser", "testuser"))
}
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn auth_deluser_fail_because_anonymous() {
assert_auth_perm_error!(con, query!("auth", "deluser", "someuser"))
}
// auth deluser failed because not root
#[sky_macros::dbtest_func(port = 2005, auth_testuser = true)]
async fn auth_deluser_fail_because_not_root() {
assert_auth_perm_error!(con, query!("auth", "deluser", "testuser"))
}
// auth deluser okay because root
#[sky_macros::dbtest_func(port = 2005, auth_rootuser = true)]
async fn test_auth_rootuser() {}
async fn auth_deluser_okay_because_root() {
runmatch!(
con,
query!("auth", "adduser", "supercooluser"),
Element::String
);
assert_okay!(con, query!("auth", "deluser", "supercooluser"))
}

@ -55,6 +55,23 @@ macro_rules! runeq {
};
}
macro_rules! runmatch {
($con:expr, $query:expr, $match:path) => {{
let ret = $con.run_simple_query(&$query).await.unwrap();
assert!(matches!(ret, $match(_)))
}};
}
macro_rules! assert_okay {
($con:expr, $query:expr) => {
runeq!(
$con,
$query,
::skytable::Element::RespCode(::skytable::RespCode::Okay)
)
};
}
macro_rules! assert_skyhash_arrayeq {
(str, $con:expr, $query:expr, $($val:expr),*) => {
runeq!(

@ -39,6 +39,7 @@ pub struct DBTestFunctionConfig {
login: (OptString, OptString),
testuser: bool,
rootuser: bool,
norun: bool,
}
impl DBTestFunctionConfig {
@ -51,6 +52,7 @@ impl DBTestFunctionConfig {
login: (None, None),
testuser: false,
rootuser: false,
norun: false,
}
}
pub fn get_connection_tokens(&self) -> impl quote::ToTokens {
@ -172,6 +174,7 @@ pub fn parse_dbtest_func_args(
"auth_rootuser" => {
fcfg.rootuser = util::parse_bool(lit, span, "auth_testuser").expect("Expected a bool")
}
"norun" => fcfg.norun = util::parse_bool(lit, span, "norun").expect("Expected a bool"),
x => panic!("unknown attribute {x} specified"),
}
}
@ -216,64 +219,66 @@ fn generate_dbtest(
};
}
// now create keyspace
body = quote! {
#body
let __create_ks =
con.run_simple_query(
&skytable::query!("create", "keyspace", "testsuite")
).await.unwrap();
if !(
__create_ks == skytable::Element::RespCode(skytable::RespCode::Okay) ||
__create_ks == skytable::Element::RespCode(
skytable::RespCode::ErrorString(
skytable::error::errorstring::ERR_ALREADY_EXISTS.to_owned()
if !fcfg.norun {
// now create keyspace
body = quote! {
#body
let __create_ks =
con.run_simple_query(
&skytable::query!("create", "keyspace", "testsuite")
).await.unwrap();
if !(
__create_ks == skytable::Element::RespCode(skytable::RespCode::Okay) ||
__create_ks == skytable::Element::RespCode(
skytable::RespCode::ErrorString(
skytable::error::errorstring::ERR_ALREADY_EXISTS.to_owned()
)
)
)
) {
panic!("Failed to create keyspace: {:?}", __create_ks);
}
};
// now switch keyspace
body = quote! {
#body
let __switch_ks =
con.run_simple_query(
&skytable::query!("use", "testsuite")
).await.unwrap();
if (__switch_ks != skytable::Element::RespCode(skytable::RespCode::Okay)) {
panic!("Failed to switch keyspace: {:?}", __switch_ks);
}
};
// now create table
let create_table_tokens = fcfg.get_create_table_tokens(&rand_string);
body = quote! {
#body
assert_eq!(
#create_table_tokens,
skytable::Element::RespCode(skytable::RespCode::Okay),
"Failed to create table"
);
};
// now generate the __MYENTITY__ string
body = quote! {
#body
let mut __concat_entity = std::string::String::new();
__concat_entity.push_str("testsuite:");
__concat_entity.push_str(&#rand_string);
let __MYENTITY__: String = __concat_entity.clone();
};
// now switch to the temporary table we created
body = quote! {
#body
let __switch_entity =
con.run_simple_query(
&skytable::query!("use", __concat_entity)
).await.unwrap();
assert_eq!(
__switch_entity, skytable::Element::RespCode(skytable::RespCode::Okay), "Failed to switch"
);
};
) {
panic!("Failed to create keyspace: {:?}", __create_ks);
}
};
// now switch keyspace
body = quote! {
#body
let __switch_ks =
con.run_simple_query(
&skytable::query!("use", "testsuite")
).await.unwrap();
if (__switch_ks != skytable::Element::RespCode(skytable::RespCode::Okay)) {
panic!("Failed to switch keyspace: {:?}", __switch_ks);
}
};
// now create table
let create_table_tokens = fcfg.get_create_table_tokens(&rand_string);
body = quote! {
#body
assert_eq!(
#create_table_tokens,
skytable::Element::RespCode(skytable::RespCode::Okay),
"Failed to create table"
);
};
// now generate the __MYENTITY__ string
body = quote! {
#body
let mut __concat_entity = std::string::String::new();
__concat_entity.push_str("testsuite:");
__concat_entity.push_str(&#rand_string);
let __MYENTITY__: String = __concat_entity.clone();
};
// now switch to the temporary table we created
body = quote! {
#body
let __switch_entity =
con.run_simple_query(
&skytable::query!("use", __concat_entity)
).await.unwrap();
assert_eq!(
__switch_entity, skytable::Element::RespCode(skytable::RespCode::Okay), "Failed to switch"
);
};
}
// now give the query ghost variable
body = quote! {
#body
@ -284,17 +289,19 @@ fn generate_dbtest(
#body
#testbody
};
// now we're done with the test so flush the table
body = quote! {
#body
{
let mut __flush__ = skytable::Query::from("flushdb");
std::assert_eq!(
con.run_simple_query(&__flush__).await.unwrap(),
skytable::Element::RespCode(skytable::RespCode::Okay)
);
}
};
if !fcfg.norun {
// now we're done with the test so flush the table
body = quote! {
#body
{
let mut __flush__ = skytable::Query::from("flushdb");
std::assert_eq!(
con.run_simple_query(&__flush__).await.unwrap(),
skytable::Element::RespCode(skytable::RespCode::Okay)
);
}
};
}
let result = quote! {
#header
#(#attrs)*

@ -72,6 +72,7 @@ pub fn dbtest_module(args: TokenStream, item: TokenStream) -> TokenStream {
/// - `password -> str`: Password for authn
/// - `auth_testuser -> bool`: Login as the test user
/// - `auth_rootuser -> bool`: Login as the root user
/// - `norun -> bool`: Don't execute anything on the connection
///
/// ## _Ghost_ values
/// This macro gives:

Loading…
Cancel
Save