Add `auth listuser` subaction

next
Sayan Nandan 3 years ago
parent 37ba222428
commit ad2f87de7a
No known key found for this signature in database
GPG Key ID: 8BC07A0A4D41DD52

@ -14,6 +14,7 @@ All changes in this project will be noted in this file.
- `auth deluser <username>`
- `auth restore <username>`
- `auth restore <origin key> <username>`
- `auth listuser`
- Shell now supports multiple `--eval` expressions
- Partial entity syntax: `:table` can be used for referring to the current table. For example
you can use `use :default` instead of `use default:default`

4
Cargo.lock generated

@ -1209,7 +1209,7 @@ dependencies = [
[[package]]
name = "skytable"
version = "0.7.0-alpha.4"
source = "git+https://github.com/skytable/client-rust?branch=next#bea0bb07d6a8af8650fa445744b9a77eae413fcb"
source = "git+https://github.com/skytable/client-rust?branch=next#6d1affbc5a0ec9c9d4a1cb98f6542962fef6aac1"
dependencies = [
"async-trait",
"bb8",
@ -1223,7 +1223,7 @@ dependencies = [
[[package]]
name = "skytable"
version = "0.7.0-alpha.4"
source = "git+https://github.com/skytable/client-rust.git#bea0bb07d6a8af8650fa445744b9a77eae413fcb"
source = "git+https://github.com/skytable/client-rust.git#6d1affbc5a0ec9c9d4a1cb98f6542962fef6aac1"
dependencies = [
"r2d2",
]

@ -38,6 +38,7 @@
mod keys;
pub mod provider;
use crate::resp::{writer::NonNullArrayWriter, TSYMBOL_UNICODE_STRING};
pub use provider::{AuthProvider, AuthResult, Authmap};
pub mod errors;
pub use errors::AuthError;
@ -53,6 +54,7 @@ const AUTH_LOGOUT: &[u8] = b"logout";
const AUTH_ADDUSER: &[u8] = b"adduser";
const AUTH_DELUSER: &[u8] = b"deluser";
const AUTH_RESTORE: &[u8] = b"restore";
const AUTH_LISTUSER: &[u8] = b"listuser";
action! {
/// Handle auth. Should have passed the `auth` token
@ -86,9 +88,22 @@ action! {
Ok(())
}
AUTH_RESTORE => self::auth_restore(con, auth, &mut iter).await,
AUTH_LISTUSER => self::auth_listuser(con, auth, &mut iter).await,
_ => util::err(groups::UNKNOWN_ACTION),
}
}
fn auth_listuser(con: &mut T, auth: &mut AuthProviderHandle<'_, T, Strm>, iter: &mut ActionIter<'_>) {
ensure_boolean_or_aerr(iter.len() == 0)?;
let usernames = auth.provider().collect_usernames()?;
let mut array_writer = unsafe {
// The symbol is definitely correct, obvious from this context
NonNullArrayWriter::new(con, TSYMBOL_UNICODE_STRING, usernames.len())
}.await?;
for username in usernames {
array_writer.write_element(username).await?;
}
Ok(())
}
fn auth_restore(con: &mut T, auth: &mut AuthProviderHandle<'_, T, Strm>, iter: &mut ActionIter<'_>) {
let newkey = match iter.len() {
1 => {

@ -233,6 +233,15 @@ impl AuthProvider {
Err(AuthError::BadCredentials)
}
}
/// List all the users
pub fn collect_usernames(&self) -> AuthResult<Vec<String>> {
self.ensure_root()?;
Ok(self
.authmap
.iter()
.map(|kv| String::from_utf8_lossy(kv.key()).to_string())
.collect())
}
}
impl Clone for AuthProvider {

@ -35,6 +35,8 @@ use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;
pub mod writer;
pub const TSYMBOL_UNICODE_STRING: u8 = b'+';
type FutureIoResult<'s> = FutureResult<'s, Result<(), IoError>>;
/// # The `Writable` trait
@ -88,7 +90,7 @@ pub struct StringWrapper(pub String);
impl Writable for StringWrapper {
fn write<'s>(self, con: &'s mut impl IsConnection) -> FutureIoResult<'s> {
Box::pin(async move {
con.write_lowlevel(&[b'+']).await?;
con.write_lowlevel(&[TSYMBOL_UNICODE_STRING]).await?;
// Now get the size of the Bytes object as bytes
let size = Integer64::from(self.0.len());
// Write this to the stream
@ -129,7 +131,7 @@ impl Writable for &'static str {
// string (we represent `String`s as `Byte` objects internally)
// and since `Bytes` are effectively `String`s we will append the
// type operator `+` to the stream
con.write_lowlevel(&[b'+']).await?;
con.write_lowlevel(&[TSYMBOL_UNICODE_STRING]).await?;
// Now get the size of the Bytes object as bytes
let size = Integer64::from(self.len());
// Write this to the stream
@ -153,7 +155,7 @@ impl Writable for BytesWrapper {
// and since `Bytes` are effectively `String`s we will append the
// type operator `+` to the stream
let bytes = self.finish_into_bytes();
con.write_lowlevel(&[b'+']).await?;
con.write_lowlevel(&[TSYMBOL_UNICODE_STRING]).await?;
// Now get the size of the Bytes object as bytes
let size = Integer64::from(bytes.len());
// Write this to the stream
@ -206,7 +208,7 @@ impl Writable for ObjectID {
// string (we represent `String`s as `Byte` objects internally)
// and since `Bytes` are effectively `String`s we will append the
// type operator `+` to the stream
con.write_lowlevel(&[b'+']).await?;
con.write_lowlevel(&[TSYMBOL_UNICODE_STRING]).await?;
// Now get the size of the Bytes object as bytes
let size = Integer64::from(self.len());
// Write this to the stream

@ -43,13 +43,13 @@ macro_rules! assert_auth_disabled {
macro_rules! assert_auth_perm_error {
($con:expr, $query:expr) => {
assert_autherror!($con, $query, RespCode::ErrorString("11".to_owned()))
assert_autherror!($con, $query, RespCode::AuthPermissionError)
};
}
macro_rules! assert_auth_bad_credentials {
($con:expr, $query:expr) => {
assert_autherror!($con, $query, RespCode::ErrorString("10".to_owned()))
assert_autherror!($con, $query, RespCode::AuthBadCredentials)
};
}
@ -241,6 +241,22 @@ async fn restore_okay_with_origin_key() {
);
}
// auth listuser
#[sky_macros::dbtest_func]
async fn listuser_fail_because_disabled() {
assert_auth_disabled!(con, query!("auth", "listuser"));
}
#[sky_macros::dbtest_func(port = 2005, auth_testuser = true)]
async fn listuser_fail_because_not_root() {
assert_auth_perm_error!(con, query!("auth", "listuser"))
}
#[sky_macros::dbtest_func(port = 2005, auth_rootuser = true)]
async fn listuser_okay_because_root() {
let ret: Vec<String> = con.run_query(query!("auth", "listuser")).await.unwrap();
assert!(ret.contains(&"root".to_owned()));
assert!(ret.contains(&"testuser".to_owned()));
}
mod syntax_checks {
use super::{NOAUTH, ONLYAUTH};
use crate::auth::provider::testsuite_data::{
@ -313,6 +329,10 @@ mod syntax_checks {
query!("auth", "restore", "someuser", "origin", "but extra data")
);
}
#[sky_macros::dbtest_func(port = 2005, norun = true)]
async fn listuser_aerr() {
assert_authn_aerr!(con, query!("auth", "listuser", "extra argument"), ONLYAUTH);
}
#[sky_macros::dbtest_func(port = 2005, norun = true, auth_testuser = true)]
async fn unknown_auth_action() {
runeq!(

Loading…
Cancel
Save