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 --- include/erebos/identity.h | 2 + src/attach.cpp | 12 +++++- src/identity.cpp | 101 ++++++++++++++++++++++++++++++++++++++++------ src/identity.h | 15 +++---- src/main.cpp | 7 ++-- src/message.cpp | 4 +- src/network.cpp | 2 +- src/network/protocol.cpp | 2 +- src/state.cpp | 2 +- 9 files changed, 118 insertions(+), 29 deletions(-) diff --git a/include/erebos/identity.h b/include/erebos/identity.h index 4792330..fa8fde3 100644 --- a/include/erebos/identity.h +++ b/include/erebos/identity.h @@ -41,7 +41,9 @@ public: bool operator!=(const Identity & other) const; std::optional ref() const; + std::optional extRef() const; std::vector refs() const; + std::vector extRefs() const; std::vector updates() const; class Builder diff --git a/src/attach.cpp b/src/attach.cpp index 3d351f8..887de38 100644 --- a/src/attach.cpp +++ b/src/attach.cpp @@ -75,11 +75,19 @@ void AttachService::handlePairingResult(Context & ctx, Stored at if (!key) throw runtime_error("failed to load secret key"); - auto id = Identity::load(key->signAdd(att->identity).ref()); + vector parts = ctx.local()->identity()->extData(); + parts.emplace_back(key->signAdd(att->identity)); + filterAncestors(parts); + + auto id = Identity::load(parts); if (!id) printf("New identity validation failed\n"); - auto rid = ctx.local().ref().storage().copy(*id->ref()); + optional tmpref = id->extRef(); + if (not tmpref) + tmpref = id->modify().commit().extRef(); + + auto rid = ctx.local().ref().storage().copy(*tmpref); id = Identity::load(rid); auto owner = id->owner(); 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()) { diff --git a/src/identity.h b/src/identity.h index 1653f51..bfa5932 100644 --- a/src/identity.h +++ b/src/identity.h @@ -20,9 +20,9 @@ struct IdentityData static IdentityData load(const Ref &); Ref store(const Storage & st) const; - const vector>> prev; - const optional name; - const optional>> owner; + const vector>> prev {}; + const optional name {}; + const optional>> owner {}; const Stored keyIdentity; const optional> keyMessage; }; @@ -33,9 +33,9 @@ struct IdentityExtension Ref store(const Storage & st) const; const Stored> base; - const vector prev; - const optional name; - const optional owner; + const vector prev {}; + const optional name {}; + const optional owner {}; }; struct Identity::Priv @@ -56,7 +56,8 @@ struct Identity::Priv struct Identity::Builder::Priv { Storage storage; - vector>> prev = {}; + vector>> prevBase = {}; + vector prevExt = {}; optional name = nullopt; optional owner = nullopt; Stored keyIdentity; diff --git a/src/main.cpp b/src/main.cpp index 0eb379b..3100695 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -289,14 +289,15 @@ void startServer(const vector &) config.service() .onUpdate([](const DirectMessageThread & thread, ssize_t, ssize_t) { - if (thread.at(0).from()->sameAs(server->identity())) + if (thread.at(0).from()->sameAs(server->identity().finalOwner())) return; ostringstream ss; string name = ""; - if (auto opt = thread.peer().name()) - name = *opt; + if (auto from = thread.at(0).from()) + if (auto fname = from->name()) + name = *fname; ss << "dm-received" << " from " << name diff --git a/src/message.cpp b/src/message.cpp index 8ae1601..a9d6139 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -69,7 +69,7 @@ Ref DirectMessageData::store(const Storage & st) const for (const auto & prev : prev) items.emplace_back("PREV", prev.ref()); if (from) - items.emplace_back("from", from->ref().value()); + items.emplace_back("from", from->extRef().value()); if (time) items.emplace_back("time", *time); if (text) @@ -373,7 +373,7 @@ DirectMessage DirectMessageService::send(const Identity & to, const string & tex auto threads = loc->shared(); msg = st.store(DirectMessageData { .prev = threads.thread(to).p->head, - .from = server.identity().finalOwner(), + .from = loc->identity()->finalOwner(), .time = ZonedTime::now(), .text = text, }); diff --git a/src/network.cpp b/src/network.cpp index c1c9c0f..7f37cf7 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -736,7 +736,7 @@ void Server::Peer::finalizeChannel(ReplyBuilder & reply, unique_ptr ch) connection.channel().emplace>(move(ch)); vector hitems; - for (const auto & r : server.self.refs()) + for (const auto & r : server.self.extRefs()) reply.header(NetworkProtocol::Header::AnnounceUpdate { r.digest() }); for (const auto & r : server.self.updates()) reply.header(NetworkProtocol::Header::AnnounceUpdate { r.digest() }); diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index 02c3dae..b781693 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -150,7 +150,7 @@ void NetworkProtocol::updateIdentity(Identity id) self = move(id); vector hitems; - for (const auto & r : self->refs()) + for (const auto & r : self->extRefs()) hitems.push_back(Header::AnnounceUpdate { r.digest() }); for (const auto & r : self->updates()) hitems.push_back(Header::AnnounceUpdate { r.digest() }); diff --git a/src/state.cpp b/src/state.cpp index 40d4eec..31171d7 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -38,7 +38,7 @@ Ref LocalState::store(const Storage & st) const vector items; if (p->identity) - items.emplace_back("id", *p->identity->ref()); + items.emplace_back("id", *p->identity->extRef()); for (const auto & x : p->shared.tip) items.emplace_back("shared", x); -- cgit v1.2.3