From 0bcef826baaa6a335d8fddafdbebd00fbf421c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Fri, 15 Dec 2023 22:13:36 +0100 Subject: Use extended identity data for name --- src/identity.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 12 deletions(-) (limited to 'src/identity.cpp') diff --git a/src/identity.cpp b/src/identity.cpp index ae20b3b..8b6ee2a 100644 --- a/src/identity.cpp +++ b/src/identity.cpp @@ -9,7 +9,7 @@ using namespace erebos; using std::async; -using std::get_if; +using std::holds_alternative; using std::nullopt; using std::runtime_error; using std::set; @@ -89,6 +89,7 @@ vector>> Identity::data() const for (const auto & d : p->data) base.push_back(d.base()); + filterAncestors(base); return base; } @@ -149,7 +150,25 @@ optional Identity::ref() const return nullopt; } +optional Identity::extRef() const +{ + if (p->data.size() == 1) + return p->data[0].ref(); + return nullopt; +} + vector Identity::refs() const +{ + auto base = data(); + vector res; + res.reserve(base.size()); + + for (const auto & d : base) + res.push_back(d.ref()); + return res; +} + +vector Identity::extRefs() const { vector res; res.reserve(p->data.size()); @@ -178,9 +197,22 @@ Identity::Builder Identity::create(const Storage & st) Identity::Builder Identity::modify() const { + vector>> prevBase; + vector prevExt; + + prevBase.reserve(p->data.size()); + for (const auto & d : p->data) { + prevBase.push_back(d.base()); + if (holds_alternative>>(d.part)) + prevExt.push_back(d); + } + + filterAncestors(prevBase); + return Builder (new Builder::Priv { .storage = p->data[0].ref().storage(), - .prev = data(), + .prevBase = move(prevBase), + .prevExt = move(prevExt), .keyIdentity = p->data[0].base()->data->keyIdentity, .keyMessage = p->data[0].base()->data->keyMessage, }); @@ -247,11 +279,18 @@ Identity::Builder::Builder(Priv * p): p(p) {} Identity Identity::Builder::commit() const { - auto idata = p->storage.store(IdentityData { - .prev = p->prev, - .name = p->name, - .owner = p->owner && p->owner->p->data.size() == 1 ? - optional(p->owner->p->data[0].base()) : nullopt, + optional>> ownerBaseData; + optional ownerExtData; + if (p->owner && p->owner->p->data.size() == 1) { + ownerExtData = p->owner->p->data[0]; + ownerBaseData = ownerExtData->base(); + if (holds_alternative>>(ownerExtData->part)) + ownerExtData.reset(); + } + + auto base = p->storage.store(IdentityData { + .prev = p->prevBase, + .owner = ownerBaseData, .keyIdentity = p->keyIdentity, .keyMessage = p->keyMessage, }); @@ -260,15 +299,38 @@ Identity Identity::Builder::commit() const if (!key) throw runtime_error("failed to load secret key"); - auto sdata = key->sign(idata); - if (idata->owner) { - if (auto okey = SecretKey::load((*idata->owner)->data->keyIdentity)) - sdata = okey->signAdd(sdata); + auto sbase = key->sign(base); + if (base->owner) { + if (auto okey = SecretKey::load((*base->owner)->data->keyIdentity)) + sbase = okey->signAdd(sbase); else throw runtime_error("failed to load secret key"); } - auto p = Identity::Priv::validate({ StoredIdentityPart(sdata) }); + optional spart; + + if (not p->prevExt.empty() || p->name || ownerExtData) { + auto ext = p->storage.store(IdentityExtension { + .base = sbase, + .prev = p->prevExt, + .name = p->name, + .owner = ownerExtData, + }); + + auto sext = key->sign(ext); + if (ext->owner) { + if (auto okey = SecretKey::load(p->owner->keyIdentity())) + sext = okey->signAdd(sext); + else + throw runtime_error("failed to load secret key"); + } + + spart.emplace(sext); + } else { + spart.emplace(sbase); + } + + auto p = Identity::Priv::validate({ *spart }); if (!p) throw runtime_error("failed to validate committed identity"); @@ -350,6 +412,21 @@ IdentityExtension IdentityExtension::load(const Ref & ref) }; } +Ref IdentityExtension::store(const Storage & st) const +{ + vector items; + + items.emplace_back("SBASE", base); + for (const auto & p : prev) + items.emplace_back("SPREV", p.ref()); + if (name) + items.emplace_back("name", *name); + if (owner) + items.emplace_back("owner", owner->ref()); + + return st.storeObject(Record(std::move(items))); +} + StoredIdentityPart StoredIdentityPart::load(const Ref & ref) { if (auto srec = ref->asRecord()) { -- cgit v1.2.3