fix(AclFamily): do not allow to delete default user (#1954)

* do not allow to delete default user
* upon loading an acl file, if default does not exist create them
* add test
This commit is contained in:
Kostas Kyrimis 2023-09-28 09:22:45 +03:00 committed by GitHub
parent 8dd34b9ce3
commit 949cedf66c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 25 additions and 5 deletions

View File

@ -125,6 +125,11 @@ void AclFamily::EvictOpenConnectionsOnAllProactors(std::string_view user) {
void AclFamily::DelUser(CmdArgList args, ConnectionContext* cntx) {
std::string_view username = facade::ToSV(args[0]);
if (username == "default") {
cntx->SendError("The'default' user cannot be removed");
return;
}
auto& registry = *registry_;
if (!registry.RemoveUser(username)) {
cntx->SendError(absl::StrCat("User ", username, " does not exist"));
@ -255,6 +260,11 @@ std::optional<facade::ErrorReply> AclFamily::LoadToRegistryFromFile(std::string_
commands.push_back(user.AclCommands());
}
if (!registry.contains("default")) {
auto& user = registry["default"];
user.Update(registry_->DefaultUserUpdateRequest());
}
if (!init) {
StreamUpdatesToAllProactorConnections(usernames, categories, commands);
}

View File

@ -44,6 +44,9 @@ TEST_F(AclFamilyTest, AclDelUser) {
auto resp = Run({"ACL", "DELUSER"});
EXPECT_THAT(resp, ErrArg("ERR wrong number of arguments for 'acl deluser' command"));
resp = Run({"ACL", "DELUSER", "default"});
EXPECT_THAT(resp, ErrArg("ERR The'default' user cannot be removed"));
resp = Run({"ACL", "DELUSER", "NOTEXISTS"});
EXPECT_THAT(resp, ErrArg("ERR User NOTEXISTS does not exist"));

View File

@ -76,16 +76,20 @@ UserRegistry::UserWithWriteLock UserRegistry::MaybeAddAndUpdateWithLock(std::str
return {std::move(lock), user, exists};
}
void UserRegistry::Init() {
// Add default user
User::UpdateRequest UserRegistry::DefaultUserUpdateRequest() const {
User::UpdateRequest::CommandsUpdateType tmp(NumberOfFamilies());
size_t id = 0;
for (auto& elem : tmp) {
elem = {User::Sign::PLUS, id++, acl::ALL_COMMANDS};
}
std::pair<User::Sign, uint32_t> acl{User::Sign::PLUS, acl::ALL};
User::UpdateRequest req{{}, {acl}, true, false, std::move(tmp)};
MaybeAddAndUpdate("default", std::move(req));
return {{}, {acl}, true, false, std::move(tmp)};
}
void UserRegistry::Init() {
// Add default user
User::UpdateRequest::CommandsUpdateType tmp(NumberOfFamilies());
MaybeAddAndUpdate("default", DefaultUserUpdateRequest());
}
} // namespace dfly::acl

View File

@ -79,6 +79,8 @@ class UserRegistry {
UserWithWriteLock MaybeAddAndUpdateWithLock(std::string_view username, User::UpdateRequest req);
User::UpdateRequest DefaultUserUpdateRequest() const;
private:
RegistryType registry_;
mutable util::SharedMutex mu_;

View File

@ -344,9 +344,10 @@ async def test_good_acl_file(df_local_factory, tmp_dir):
result = await client.execute_command("ACL LOAD")
result = await client.execute_command("ACL LIST")
assert 2 == len(result)
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
await client.close()