diff options
author | Sadie Powell <sadie@witchery.services> | 2020-09-10 15:15:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-10 15:15:34 +0100 |
commit | 8180dd414ecd43758290c20315e70af72f0833bf (patch) | |
tree | 195ea018ed2d477a114b422caee94053419e77ef /src/nickcore.cpp | |
parent | ff28985384cb6e60fc7479f93778c4363c322ea7 (diff) |
Implement support for immutable account identifiers.
Diffstat (limited to 'src/nickcore.cpp')
-rw-r--r-- | src/nickcore.cpp | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/src/nickcore.cpp b/src/nickcore.cpp index b43a8b3c1..6b6a00138 100644 --- a/src/nickcore.cpp +++ b/src/nickcore.cpp @@ -13,10 +13,12 @@ #include "modules.h" #include "account.h" #include "config.h" +#include <climits> Serialize::Checker<nickcore_map> NickCoreList("NickCore"); +nickcoreid_map NickCoreIdList; -NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"), chanaccess("ChannelInfo"), aliases("NickAlias") +NickCore::NickCore(const Anope::string &coredisplay, uint64_t coreid) : Serializable("NickCore"), chanaccess("ChannelInfo"), aliases("NickAlias") { if (coredisplay.empty()) throw CoreException("Empty display passed to NickCore constructor"); @@ -26,12 +28,16 @@ NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"), this->lastmail = 0; this->display = coredisplay; + this->id = coreid; size_t old = NickCoreList->size(); (*NickCoreList)[this->display] = this; if (old == NickCoreList->size()) Log(LOG_DEBUG) << "Duplicate account " << coredisplay << " in nickcore table?"; + if (this->id) + NickCoreIdList[this->id] = this; + FOREACH_MOD(OnNickCoreCreate, (this)); } @@ -52,6 +58,8 @@ NickCore::~NickCore() this->users.clear(); NickCoreList->erase(this->display); + if (this->id) + NickCoreIdList.erase(this->id); this->ClearAccess(); @@ -66,6 +74,7 @@ NickCore::~NickCore() void NickCore::Serialize(Serialize::Data &data) const { data["display"] << this->display; + data["id"] << this->id; data["pass"] << this->pass; data["email"] << this->email; data["language"] << this->language; @@ -82,13 +91,15 @@ Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data) NickCore *nc; Anope::string sdisplay; - data["display"] >> sdisplay; + uint64_t sid = 0; + data["id"] >> sid; + if (obj) nc = anope_dynamic_static_cast<NickCore *>(obj); else - nc = new NickCore(sdisplay); + nc = new NickCore(sdisplay, sid); data["pass"] >> nc->pass; data["email"] >> nc->email; @@ -267,3 +278,41 @@ NickCore* NickCore::Find(const Anope::string &nick) return NULL; } + +uint64_t NickCore::GetId() +{ + if (this->id) + return this->id; + + NickAlias *na = NickAlias::Find(this->display); + if (!na) + { + Log(LOG_DEBUG) << "Unable to find the display NickAlias for NickCore: " << this->display; + return 0; + } + + Anope::string secretid = this->display + "\0" + stringify(na->time_registered); + + // Generate the account id. This should almost always only have one + // iteration but in the rare case that we generate a duplicate id we try + // again with a new key. + while (!this->id) + { + // Generate a random key for SipHash. + char key[16]; + for (size_t i = 0; i < sizeof(key); ++i) + key[i] = rand() % CHAR_MAX; + + uint64_t newid = Anope::SipHash24(secretid.c_str(), secretid.length(), key); + nickcoreid_map::const_iterator it = NickCoreIdList.find(newid); + if (it == NickCoreIdList.end()) + { + this->id = newid; + NickCoreIdList[this->id] = this; + this->QueueUpdate(); + break; + } + } + + return this->id; +} |