From 8323c82dc549c268a9b5b1fff40beb35d6953e0a Mon Sep 17 00:00:00 2001 From: Kostas Kyrimis Date: Fri, 8 Dec 2023 18:08:33 +0200 Subject: [PATCH] feat(acl): add acl keys to acl save/load (#2273) * add acl keys to acl savel/load * add tests --- src/server/acl/acl_family.cc | 6 ++++-- src/server/acl/validator.cc | 1 + src/server/command_registry.h | 4 ++-- src/server/multi_command_squasher.cc | 2 +- src/server/transaction.cc | 2 +- tests/dragonfly/acl_family_test.py | 8 ++++---- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/server/acl/acl_family.cc b/src/server/acl/acl_family.cc index bbce5afd1..ddfb25c63 100644 --- a/src/server/acl/acl_family.cc +++ b/src/server/acl/acl_family.cc @@ -181,12 +181,14 @@ std::string AclFamily::RegistryToString() const { pass == "nopass" ? "nopass " : absl::StrCat("#", PrettyPrintSha(pass, true), " "); const std::string acl_cat = AclCatToString(user.AclCategory()); const std::string acl_commands = AclCommandToString(user.AclCommandsRef()); - const std::string maybe_space = acl_commands.empty() ? "" : " "; + const std::string maybe_space_com = acl_commands.empty() ? "" : " "; + const std::string acl_keys = AclKeysToString(user.Keys()); + const std::string maybe_space = acl_keys.empty() ? "" : " "; using namespace std::string_view_literals; absl::StrAppend(&result, command, username, " ", user.IsActive() ? "ON "sv : "OFF "sv, password, - acl_cat, maybe_space, acl_commands, "\n"); + acl_cat, maybe_space_com, acl_commands, maybe_space, acl_keys, "\n"); } if (!result.empty()) { diff --git a/src/server/acl/validator.cc b/src/server/acl/validator.cc index 37c3e8613..c0406f9d8 100644 --- a/src/server/acl/validator.cc +++ b/src/server/acl/validator.cc @@ -96,6 +96,7 @@ namespace dfly::acl { } } } + return keys_allowed; } diff --git a/src/server/command_registry.h b/src/server/command_registry.h index 39fa88352..6b5d50797 100644 --- a/src/server/command_registry.h +++ b/src/server/command_registry.h @@ -93,11 +93,11 @@ class CommandId : public facade::CommandId { bool IsTransactional() const; bool IsReadOnly() const { - return opt_mask_ & CO::CommandOpt::READONLY; + return opt_mask_ & CO::READONLY; } bool IsWriteOnly() const { - return opt_mask_ & CO::CommandOpt::WRITE; + return opt_mask_ & CO::WRITE; } static const char* OptName(CO::CommandOpt fl); diff --git a/src/server/multi_command_squasher.cc b/src/server/multi_command_squasher.cc index e1e6781d0..d6f28f70c 100644 --- a/src/server/multi_command_squasher.cc +++ b/src/server/multi_command_squasher.cc @@ -98,7 +98,7 @@ MultiCommandSquasher::SquashResult MultiCommandSquasher::TrySquash(StoredCmd* cm auto& sinfo = PrepareShardInfo(last_sid); - sinfo.had_writes |= (cmd->Cid()->IsWriteOnly()); + sinfo.had_writes |= cmd->Cid()->IsWriteOnly(); sinfo.cmds.push_back(cmd); order_.push_back(last_sid); diff --git a/src/server/transaction.cc b/src/server/transaction.cc index 7fad09129..71b127451 100644 --- a/src/server/transaction.cc +++ b/src/server/transaction.cc @@ -1362,7 +1362,7 @@ void Transaction::LogAutoJournalOnShard(EngineShard* shard) { return; // Only write commands and/or no-key-transactional commands are logged - if ((cid_->IsWriteOnly()) == 0 && (cid_->opt_mask() & CO::NO_KEY_TRANSACTIONAL) == 0) + if (cid_->IsWriteOnly() == 0 && (cid_->opt_mask() & CO::NO_KEY_TRANSACTIONAL) == 0) return; // If autojournaling was disabled and not re-enabled, skip it diff --git a/tests/dragonfly/acl_family_test.py b/tests/dragonfly/acl_family_test.py index fa7561204..2a3d29cf4 100644 --- a/tests/dragonfly/acl_family_test.py +++ b/tests/dragonfly/acl_family_test.py @@ -331,13 +331,13 @@ async def test_good_acl_file(df_local_factory, tmp_dir): await client.execute_command("ACL SETUSER roy ON >mypass +@STRING +HSET") await client.execute_command("ACL SETUSER shahar >mypass +@SET") - await client.execute_command("ACL SETUSER vlad +@STRING") + await client.execute_command("ACL SETUSER vlad +@STRING ~foo ~bar*") result = await client.execute_command("ACL LIST") assert 4 == len(result) assert "user roy on ea71c25a7a60224 +@STRING +HSET" in result assert "user shahar off ea71c25a7a60224 +@SET" in result - assert "user vlad off nopass +@STRING" in result + assert "user vlad off nopass +@STRING ~foo ~bar*" in result assert "user default on nopass +@ALL +ALL ~*" in result result = await client.execute_command("ACL DELUSER shahar") @@ -350,8 +350,8 @@ async def test_good_acl_file(df_local_factory, tmp_dir): result = await client.execute_command("ACL LIST") assert 3 == len(result) assert "user roy on ea71c25a7a60224 +@STRING +HSET" in result - assert "user vlad off nopass +@STRING" in result - assert "user default on nopass +@ALL +ALL" in result + assert "user vlad off nopass +@STRING ~foo ~bar*" in result + assert "user default on nopass +@ALL +ALL ~*" in result await client.close()