SelfProfile related things is done, not tested yet.
diff --git a/src/contact-storage.cpp b/src/contact-storage.cpp
index f42ec21..3eb8ac1 100644
--- a/src/contact-storage.cpp
+++ b/src/contact-storage.cpp
@@ -13,11 +13,35 @@
#include <string>
#include <boost/filesystem.hpp>
+#include "logging.h"
using namespace std;
using namespace ndn;
namespace fs = boost::filesystem;
+INIT_LOGGER ("ContactStorage");
+
+const string INIT_SP_TABLE = "\
+CREATE TABLE IF NOT EXISTS \n \
+ SelfProfile( \n \
+ profile_id INTEGER PRIMARY KEY AUTOINCREMENT, \n \
+ profile_type BLOB NOT NULL, \n \
+ profile_value BLOB NOT NULL \n \
+ ); \n \
+ \
+CREATE INDEX sp_index ON SelfProfile(profile_type); \n \
+";
+
+const string INIT_PD_TABLE = "\
+CREATE TABLE IF NOT EXISTS \n \
+ ProfileData( \n \
+ identity BLOB NOT NULL UNIQUE, \n \
+ profile_data BLOB NOT NULL, \n \
+ \
+ PRIMARY KEY (identity) \n \
+ ); \n \
+CREATE INDEX pd_index ON ProfileData(identity); \n \
+";
const string INIT_TC_TABLE = "\
CREATE TABLE IF NOT EXISTS \n \
@@ -46,7 +70,8 @@
CREATE INDEX nc_index ON NormalContact(contact_namespace); \n \
";
-ContactStorage::ContactStorage()
+ContactStorage::ContactStorage(Ptr<security::IdentityManager> identityManager)
+ : m_identityManager(identityManager)
{
fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
fs::create_directories (chronosDir);
@@ -55,8 +80,43 @@
if (res != SQLITE_OK)
throw LnException("Chronos DB cannot be open/created");
- // Check if TrustedContact table exists
+ // Check if SelfProfile table exists
sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='SelfProfile'", -1, &stmt, 0);
+ res = sqlite3_step (stmt);
+
+ bool spTableExist = false;
+ if (res == SQLITE_ROW)
+ spTableExist = true;
+ sqlite3_finalize (stmt);
+
+ if(!spTableExist)
+ {
+ char *errmsg = 0;
+ res = sqlite3_exec (m_db, INIT_SP_TABLE.c_str (), NULL, NULL, &errmsg);
+ if (res != SQLITE_OK && errmsg != 0)
+ throw LnException("Init \"error\" in SelfProfile");
+ }
+
+ // Check if ProfileData table exists
+ sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='ProfileData'", -1, &stmt, 0);
+ res = sqlite3_step (stmt);
+
+ bool pdTableExist = false;
+ if (res == SQLITE_ROW)
+ pdTableExist = true;
+ sqlite3_finalize (stmt);
+
+ if(!pdTableExist)
+ {
+ char *errmsg = 0;
+ res = sqlite3_exec (m_db, INIT_PD_TABLE.c_str (), NULL, NULL, &errmsg);
+ if (res != SQLITE_OK && errmsg != 0)
+ throw LnException("Init \"error\" in ProfileData");
+ }
+
+
+ // Check if TrustedContact table exists
sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='TrustedContact'", -1, &stmt, 0);
res = sqlite3_step (stmt);
@@ -71,7 +131,6 @@
res = sqlite3_exec (m_db, INIT_TC_TABLE.c_str (), NULL, NULL, &errmsg);
if (res != SQLITE_OK && errmsg != 0)
throw LnException("Init \"error\" in TrustedContact");
- sqlite3_finalize (stmt);
}
// Check if NormalContact table exists
@@ -93,6 +152,102 @@
}
}
+bool
+ContactStorage::doesSelfEntryExist(const string& profileType)
+{
+ bool result = false;
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM SelfProfile WHERE profile_type=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
+
+ int res = sqlite3_step (stmt);
+
+ if (res == SQLITE_ROW)
+ {
+ int countAll = sqlite3_column_int (stmt, 0);
+ if (countAll > 0)
+ result = true;
+ }
+ sqlite3_finalize (stmt);
+ return result;
+}
+
+void
+ContactStorage::setSelfProfileIdentity(const Name& identity)
+{
+ string profileType("IDENTITY");
+ Blob identityBlob(identity.toUri().c_str(), identity.toUri().size());
+
+ sqlite3_stmt *stmt;
+ if(doesSelfEntryExist(profileType))
+ {
+ sqlite3_prepare_v2 (m_db, "UPDATE SelfProfile SET profile_value=? WHERE profile_type=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, identityBlob.buf(), identityBlob.size(), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
+ }
+ else
+ {
+ sqlite3_prepare_v2 (m_db, "INSERT INTO SelfProfile (profile_type, profile_value) values (?, ?)", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, identityBlob.buf(), identityBlob.size(), SQLITE_TRANSIENT);
+ }
+ sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+}
+
+void
+ContactStorage::setSelfProfileEntry(const string& profileType, const Blob& profileValue)
+{
+ if(profileType == string("IDENTITY"))
+ return;
+
+ sqlite3_stmt *stmt;
+ if(doesSelfEntryExist(profileType))
+ {
+ sqlite3_prepare_v2 (m_db, "UPDATE SelfProfile SET profile_value=? WHERE profile_type=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, profileValue.buf(), profileValue.size(), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
+ }
+ else
+ {
+ sqlite3_prepare_v2 (m_db, "INSERT INTO SelfProfile (profile_type, profile_value) values (?, ?)", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, profileValue.buf(), profileValue.size(), SQLITE_TRANSIENT);
+ }
+ sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+}
+
+Ptr<Profile>
+ContactStorage::getSelfProfile()
+{
+ string idString("IDENTITY");
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2(m_db, "SELECT profile_value FROM SelfProfile WHERE profile_type=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, idString.c_str(), idString.size(), SQLITE_TRANSIENT);
+
+ Name nameSpace;
+ int res = sqlite3_step (stmt);
+ if (res == SQLITE_ROW)
+ nameSpace.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
+
+ Ptr<Profile> profile = Ptr<Profile>(new Profile(nameSpace));
+
+ sqlite3_prepare_v2(m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_type!=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, idString.c_str(), idString.size(), SQLITE_TRANSIENT);
+
+ while( sqlite3_step (stmt) == SQLITE_ROW)
+ {
+ string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+ Blob profileValue(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1));
+
+ profile->setProfileEntry(profileType, profileValue );
+ }
+
+ return profile;
+}
+
void
ContactStorage::addTrustedContact(const TrustedContact& trustedContact)
{
@@ -213,3 +368,96 @@
return normalContacts;
}
+
+void
+ContactStorage::updateProfileData() const
+{
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db, "SELECT identity, profile_data FROM ProfileData", -1, &stmt, 0);
+
+ if(sqlite3_step (stmt) != SQLITE_ROW)
+ {
+ sqlite3_finalize (stmt);
+ return;
+ }
+
+ Name identity(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
+
+ Ptr<Blob> profileDataBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
+ Ptr<Data> plainData = Data::decodeFromWire(profileDataBlob);
+ const Blob& oldProfileBlob = plainData->content();
+ sqlite3_finalize (stmt);
+
+ Ptr<Profile> newProfile = getSelfProfile();
+ if(NULL == newProfile)
+ return;
+ Ptr<Blob> newProfileBlob = newProfile->toDerBlob();
+
+ if(oldProfileBlob == *newProfileBlob)
+ return;
+
+ string idString("IDENTITY");
+ Ptr<const Blob> identityBlob = newProfile->getProfileEntry(idString);
+ Name newIdentity(string(identityBlob->buf(), identityBlob->size()));
+
+ Ptr<ProfileData> newProfileData = getSignedSelfProfileData(newIdentity, *newProfile);
+ Ptr<Blob> newProfileDataBlob = newProfileData->encodeToWire();
+
+ if(identity == newIdentity)
+ {
+ sqlite3_prepare_v2 (m_db, "UPDATE ProfileData SET profile_data=? WHERE identity=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, newProfileDataBlob->buf(), newProfileDataBlob->size(), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, newIdentity.toUri().c_str(), newIdentity.toUri().size(), SQLITE_TRANSIENT);
+ }
+ else
+ {
+ sqlite3_prepare_v2 (m_db, "INSERT INTO ProfileData (identity, profile_data) values (?, ?)", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 2, newIdentity.toUri().c_str(), newIdentity.toUri().size(), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 1, newProfileDataBlob->buf(), newProfileDataBlob->size(), SQLITE_TRANSIENT);
+ }
+}
+
+Ptr<Profile>
+ContactStorage::getSelfProfile() const
+{
+ string idString("IDENTITY");
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db, "SELECT profile_value FROM SelfProfile WHERE profile_type=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, idString.c_str(), idString.size(), SQLITE_TRANSIENT);
+
+ if(sqlite3_step (stmt) != SQLITE_ROW)
+ {
+ sqlite3_finalize (stmt);
+ return NULL;
+ }
+
+ Name identity(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
+
+ Ptr<Profile> profile = Ptr<Profile>(new Profile(identity));
+ sqlite3_finalize (stmt);
+
+ sqlite3_prepare_v2 (m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_type!=? and profile_type!=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, idString.c_str(), idString.size(), SQLITE_TRANSIENT);
+
+ while( sqlite3_step (stmt) == SQLITE_ROW)
+ {
+ string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+ Blob profileValue(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1));
+ profile->setProfileEntry(profileType, profileValue);
+ }
+
+ return profile;
+}
+
+Ptr<ProfileData>
+ContactStorage::getSignedSelfProfileData(const Name& identity,
+ const Profile& profile) const
+{
+ Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(identity);
+ Ptr<ProfileData> profileData = Ptr<ProfileData>(new ProfileData(identity, profile));
+ m_identityManager->signByCertificate(*profileData, certificateName);
+
+ return profileData;
+}
+