Skip to content

Commit

Permalink
acl command changes (#16)
Browse files Browse the repository at this point in the history
* support for multiple commands in setuser; fixes + tests

* run acl tests in CI
  • Loading branch information
dadleyy committed Apr 12, 2023
1 parent 7f6520e commit 30e4b52
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ jobs:
env:
REDIS_HOST: localhost
REDIS_PORT: ${{ job.services.redis.ports[6379] }}
- name: test-sync-acl
run: cargo test --features acl
env:
REDIS_HOST: localhost
REDIS_PORT: ${{ job.services.redis.ports[6379] }}
- name: "clippy: acl"
run: cargo clippy --features acl
- name: "clippy: async"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kramer"
version = "1.3.2"
version = "2.0.0"
authors = ["Danny Hadley <dadleyy@gmail.com>"]
edition = "2018"
license = "MIT"
Expand Down
29 changes: 25 additions & 4 deletions src/acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::modifiers::{format_bulk_string, Arity};
#[derive(Debug)]
pub struct SetUser<S>
where
S:,
S: std::fmt::Display,
{
/// The name of the ACL entry.
pub name: S,
Expand All @@ -27,7 +27,7 @@ where
pub password: Option<S>,

/// The set of commands the ACL entry should have the ability to execute.
pub commands: Option<S>,
pub commands: Option<Vec<S>>,

/// The set of keys the ACL entry should have access to.
pub keys: Option<S>,
Expand Down Expand Up @@ -82,7 +82,12 @@ where
format_bulk_string("on"),
format_bulk_string(format!(">{password}")),
format_bulk_string(format!("~{key_pattern}")),
format_bulk_string(format!("+{command_pattern}")),
format_bulk_string(
command_pattern
.iter()
.fold(String::new(), |acc, command| acc + format!("+{command} ").as_str())
.trim_end()
)
)
}
(_, _, _) => Ok(()),
Expand All @@ -101,7 +106,7 @@ mod tests {
let command = AclCommand::SetUser(SetUser {
name: "library-member",
password: Some("many-books"),
commands: Some("hgetall"),
commands: Some(vec!["hgetall"]),
keys: Some("books"),
});

Expand All @@ -112,6 +117,22 @@ mod tests {
);
}

#[test]
fn format_full_setuser_multi_command() {
let command = AclCommand::SetUser(SetUser {
name: "library-member",
password: Some("many-books"),
commands: Some(vec!["hgetall", "blpop"]),
keys: Some("books"),
});

assert_eq!(format!("{}", command), "*7\r\n$3\r\nACL\r\n$7\r\nSETUSER\r\n$14\r\nlibrary-member\r\n$2\r\non\r\n$11\r\n>many-books\r\n$6\r\n~books\r\n$15\r\n+hgetall +blpop\r\n");
assert_eq!(
humanize_command::<&str, &str>(&crate::Command::Acl(command)),
"ACL SETUSER library-member on >many-books ~books +hgetall +blpop"
);
}

#[test]
fn format_deluser_one() {
let command = AclCommand::DelUser(Arity::One("my-user"));
Expand Down
2 changes: 1 addition & 1 deletion src/sync_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ where
S: std::fmt::Display,
C: std::io::Write + std::io::Read + std::marker::Unpin,
{
write!(connection, "{}", message)?;
write!(connection, "{message}")?;
read(connection)
}

Expand Down
20 changes: 20 additions & 0 deletions tests/execute_sync_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ extern crate kramer;
use kramer::{execute, Arity, AuthCredentials, Command, Insertion, Response, ResponseValue, SetCommand, StringCommand};
use std::env::var;

#[cfg(feature = "acl")]
use kramer::{AclCommand, SetUser};

#[cfg(test)]
fn get_redis_url() -> String {
let host = var("REDIS_HOST").unwrap_or(String::from("0.0.0.0"));
Expand Down Expand Up @@ -195,6 +198,23 @@ fn test_inter_none() {
assert_eq!(result, Response::Array(vec![]));
}

#[cfg(feature = "acl")]
#[test]
fn test_acl_sweep() {
let mut con = std::net::TcpStream::connect(get_redis_url()).expect("connection");
let set_user: Command<&str, &str> = Command::Acl(AclCommand::SetUser(SetUser {
commands: Some(vec!["lpop"]),
keys: Some("--test"),
password: Some("--test"),
name: "--test",
}));
let res = execute(&mut con, set_user);
assert_eq!(res.is_ok(), true);
let del_user: Command<&str, &str> = Command::Acl(AclCommand::DelUser(Arity::One("--test")));
let res = execute(&mut con, del_user);
assert_eq!(res.is_ok(), true);
}

#[test]
fn test_inter_some() {
let (one, two) = ("test_inter_some_1", "test_inter_some_2");
Expand Down

0 comments on commit 30e4b52

Please sign in to comment.