From f94443c63dfd63300e5bd29889935fd1f451175e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 21 Dec 2019 21:42:20 +0100 Subject: Identity storage and modification --- src/identity.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'src/identity.cpp') diff --git a/src/identity.cpp b/src/identity.cpp index 0160a69..4833f71 100644 --- a/src/identity.cpp +++ b/src/identity.cpp @@ -2,11 +2,13 @@ #include #include +#include using namespace erebos; using std::async; using std::nullopt; +using std::runtime_error; using std::set; optional Identity::load(const Ref & ref) @@ -41,6 +43,63 @@ optional Identity::owner() const return p->owner; } +optional Identity::ref() const +{ + if (p->data.size() == 1) + return p->data[0].ref; + return nullopt; +} + +Identity::Builder Identity::create(const Storage & st) +{ + return Builder (new Builder::Priv { + .storage = st, + .keyIdentity = SecretKey::generate(st).pub(), + .keyMessage = SecretKey::generate(st).pub(), + }); +} + +Identity::Builder Identity::modify() const +{ + return Builder (new Builder::Priv { + .storage = p->data[0].ref.storage(), + .prev = p->data, + .keyIdentity = p->data[0]->data->keyIdentity, + .keyMessage = p->data[0]->data->keyMessage, + }); +} + + +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]) : nullopt, + .keyIdentity = p->keyIdentity, + .keyMessage = p->keyMessage, + }); + + auto key = SecretKey::load(p->keyIdentity); + if (!key) + throw runtime_error("failed to load secret key"); + + auto sdata = key->sign(idata); + + return Identity(Identity::Priv::validate({ sdata })); +} + +void Identity::Builder::name(const string & val) +{ + p->name = val; +} + +void Identity::Builder::owner(const Identity & val) +{ + p->owner.emplace(val); +} + optional IdentityData::load(const Ref & ref) { auto rec = ref->asRecord(); @@ -65,6 +124,23 @@ optional IdentityData::load(const Ref & ref) }; } +Ref IdentityData::store(const Storage & st) const +{ + vector items; + + 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); + items.emplace_back("key-id", keyIdentity.ref); + if (keyMessage) + items.emplace_back("key-msg", keyMessage->ref); + + return st.storeObject(Record(std::move(items))); +} + bool Identity::Priv::verifySignatures(const Stored> & sdata) { if (!sdata->isSignedBy(sdata->data->keyIdentity)) -- cgit v1.2.3