From ee44af8d04f23b4a16c9b377764f930d69e575f7 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 27 Nov 2022 07:32:42 +0000 Subject: Refactor the internals of the oper system. - Allow overriding privileges from the blocks in the and blocks. - Separate oper types from oper accounts in the code. This enables moving some core stuff out of the config tag later. - Merge the config tags together to make a synthetic tag that can have getXXX called on it instead of using getConfig and then converting it. - Move the details of Have*Permission into the oper type class. - Improve oper events to allow modules to easily hook into the oper system. --- src/configreader.cpp | 66 +++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'src/configreader.cpp') diff --git a/src/configreader.cpp b/src/configreader.cpp index d91f5a389..486bf3ad8 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -91,61 +91,63 @@ ServerConfig::ServerConfig() { } -typedef std::map> LocalIndex; -void ServerConfig::CrossCheckOperClassType() +void ServerConfig::CrossCheckOperBlocks() { - LocalIndex operclass; + std::unordered_map> operclass; for (const auto& [_, tag] : ConfTags("class")) { - std::string name = tag->getString("name"); + const std::string name = tag->getString("name"); if (name.empty()) throw CoreException(" missing from tag at " + tag->source.str()); - if (operclass.find(name) != operclass.end()) + + if (!operclass.emplace(name, tag).second) throw CoreException("Duplicate class block with name " + name + " at " + tag->source.str()); - operclass[name] = tag; } for (const auto& [_, tag] : ConfTags("type")) { - std::string name = tag->getString("name"); + const std::string name = tag->getString("name"); if (name.empty()) throw CoreException(" is missing from tag at " + tag->source.str()); - if (OperTypes.find(name) != OperTypes.end()) - throw CoreException("Duplicate type block with name " + name + " at " + tag->source.str()); - auto ifo = std::make_shared(name); - OperTypes[name] = ifo; - ifo->type_block = tag; + auto type = std::make_shared(name, nullptr); - std::string classname; - irc::spacesepstream str(tag->getString("classes")); - while (str.GetToken(classname)) + // Copy the settings from the oper class. + irc::spacesepstream classlist(tag->getString("classes")); + for (std::string classname; classlist.GetToken(classname); ) { - LocalIndex::iterator cls = operclass.find(classname); - if (cls == operclass.end()) - throw CoreException("Oper type " + name + " has missing class " + classname); - ifo->class_blocks.push_back(cls->second); + auto klass = operclass.find(classname); + if (klass == operclass.end()) + throw CoreException("Oper type " + name + " has missing class " + classname + " at " + tag->source.str()); + + // Apply the settings from the class. + type->Configure(klass->second, false); } + + // Once the classes have been applied we can apply this. + type->Configure(tag, true); + + if (!OperTypes.emplace(name, type).second) + throw CoreException("Duplicate type block with name " + name + " at " + tag->source.str()); } for (const auto& [_, tag] : ConfTags("oper")) { - std::string name = tag->getString("name"); + const std::string name = tag->getString("name"); if (name.empty()) throw CoreException(" missing from tag at " + tag->source.str()); - std::string type = tag->getString("type"); - OperIndex::iterator tblk = OperTypes.find(type); - if (tblk == OperTypes.end()) - throw CoreException("Oper block " + name + " has missing type " + type); - if (oper_blocks.find(name) != oper_blocks.end()) - throw CoreException("Duplicate oper block with name " + name + " at " + tag->source.str()); + const std::string typestr = tag->getString("type"); + if (typestr.empty()) + throw CoreException(" missing from tag at " + tag->source.str()); - auto ifo = std::make_shared(type); - ifo->oper_block = tag; - ifo->type_block = tblk->second->type_block; - ifo->class_blocks.assign(tblk->second->class_blocks.begin(), tblk->second->class_blocks.end()); - oper_blocks[name] = ifo; + auto type = OperTypes.find(typestr); + if (type == OperTypes.end()) + throw CoreException("Oper block " + name + " has missing type " + typestr + " at " + tag->source.str()); + + auto account = std::make_shared(name, type->second, tag); + if (!OperAccounts.emplace(name, account).second) + throw CoreException("Duplicate oper block with name " + name + " at " + tag->source.str()); } } @@ -408,7 +410,7 @@ void ServerConfig::Apply(ServerConfig* old, const std::string& useruid) Fill(); // Handle special items - CrossCheckOperClassType(); + CrossCheckOperBlocks(); CrossCheckConnectBlocks(old); } catch (const CoreException& ce) -- cgit v1.3.1-10-gc9f91