summaryrefslogtreecommitdiff
path: root/src/identity.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity.cpp')
-rw-r--r--src/identity.cpp76
1 files changed, 76 insertions, 0 deletions
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 <algorithm>
#include <set>
+#include <stdexcept>
using namespace erebos;
using std::async;
using std::nullopt;
+using std::runtime_error;
using std::set;
optional<Identity> Identity::load(const Ref & ref)
@@ -41,6 +43,63 @@ optional<Identity> Identity::owner() const
return p->owner;
}
+optional<Ref> 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> IdentityData::load(const Ref & ref)
{
auto rec = ref->asRecord();
@@ -65,6 +124,23 @@ optional<IdentityData> IdentityData::load(const Ref & ref)
};
}
+Ref IdentityData::store(const Storage & st) const
+{
+ vector<Record::Item> 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<Signed<IdentityData>> & sdata)
{
if (!sdata->isSignedBy(sdata->data->keyIdentity))