aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/odhtdb/Database.hpp21
-rw-r--r--include/odhtdb/DatabaseStorage.hpp61
-rw-r--r--include/odhtdb/Group.hpp29
-rw-r--r--include/odhtdb/LocalUser.hpp35
-rw-r--r--include/odhtdb/LocalUserEncrypted.hpp50
-rw-r--r--include/odhtdb/OwnedMemory.hpp3
-rw-r--r--include/odhtdb/RemoteUser.hpp24
-rw-r--r--include/odhtdb/User.hpp39
-rw-r--r--src/Database.cpp91
-rw-r--r--src/DatabaseStorage.cpp98
-rw-r--r--src/Group.cpp52
-rw-r--r--src/LocalUser.cpp11
-rw-r--r--src/LocalUserEncrypted.cpp27
-rw-r--r--src/User.cpp37
-rw-r--r--tests/main.cpp24
15 files changed, 105 insertions, 497 deletions
diff --git a/include/odhtdb/Database.hpp b/include/odhtdb/Database.hpp
index 1e4d470..332a784 100644
--- a/include/odhtdb/Database.hpp
+++ b/include/odhtdb/Database.hpp
@@ -20,11 +20,7 @@
#include <functional>
namespace odhtdb
-{
- class User;
- class LocalUser;
- class Group;
-
+{
class CommitCreateException : public std::runtime_error
{
public:
@@ -115,14 +111,15 @@ namespace odhtdb
class DatabaseCreateResponse
{
public:
- DatabaseCreateResponse(LocalUser *nodeAdminUser, std::shared_ptr<OwnedMemory> key, std::shared_ptr<Hash> hash);
+ DatabaseCreateResponse(std::shared_ptr<Signature::KeyPair> nodeAdminKeyPair, std::shared_ptr<OwnedMemory> nodeAdminGroupId, std::shared_ptr<OwnedMemory> key, std::shared_ptr<Hash> hash);
- const LocalUser* getNodeAdminUser() const;
- // Size of encryption key is odhtdb::KEY_BYTE_SIZE (found in Encryption.hpp)
+ const std::shared_ptr<Signature::KeyPair> getNodeAdminKeyPair() const;
+ const std::shared_ptr<OwnedMemory> getNodeAdminGroupId() const;
const std::shared_ptr<OwnedMemory> getNodeEncryptionKey() const;
const std::shared_ptr<Hash> getRequestHash() const;
private:
- LocalUser *nodeAdminUser;
+ std::shared_ptr<Signature::KeyPair> nodeAdminKeyPair;
+ std::shared_ptr<OwnedMemory> nodeAdminGroupId;
std::shared_ptr<OwnedMemory> key;
std::shared_ptr<Hash> hash;
};
@@ -171,12 +168,10 @@ namespace odhtdb
// Throws DatabaseCreateException on failure.
std::unique_ptr<DatabaseCreateResponse> create();
- // Throws DatabaseCreateException on failure.
- std::unique_ptr<DatabaseCreateResponse> create(const Signature::KeyPair &creatorKeyPair);
// Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add data to node
- void addData(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, DataView dataToAdd);
+ void addData(const DatabaseNode &nodeInfo, const Signature::KeyPair &userToPerformActionWith, DataView dataToAdd);
// Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add user @userToAdd to group @groupToAddUserTo
- void addUser(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo);
+ void addUser(const DatabaseNode &nodeInfo, const Signature::KeyPair &userToPerformActionWith, const Signature::PublicKey &userToAddPublicKey, const DataView &groupToAddUserTo);
ntp::NtpTimestamp getSyncedTimestampUtc() const;
private:
diff --git a/include/odhtdb/DatabaseStorage.hpp b/include/odhtdb/DatabaseStorage.hpp
index 3c4d9bc..0d94c91 100644
--- a/include/odhtdb/DatabaseStorage.hpp
+++ b/include/odhtdb/DatabaseStorage.hpp
@@ -6,8 +6,7 @@
#include "Signature.hpp"
#include "Encryption.hpp"
#include "Group.hpp"
-#include "LocalUser.hpp"
-#include "LocalUserEncrypted.hpp"
+#include "Permission.hpp"
#include "OwnedMemory.hpp"
#include "DatabaseOperation.hpp"
#include <vector>
@@ -24,48 +23,6 @@ namespace odhtdb
{
class Database;
- struct DatabaseStorageObjectDecrypted
- {
- DatabaseOperation operation;
- OwnedMemory data;
- };
-
- struct DatabaseStorageObject
- {
- Hash requestHash;
- DataView data;
- u64 createdTimestamp; // In microseconds
- Signature::PublicKey creatorPublicKey;
- DatabaseStorageObjectDecrypted decryptedObject;
-
- DatabaseStorageObject(const Hash &_requestHash, DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey);
- };
-
- struct DatabaseStorageObjectList
- {
- Signature::PublicKey creatorPublicKey;
- DataView data;
- u64 createdTimestamp; // In microseconds
- std::vector<Group*> groups;
- std::vector<DatabaseStorageObject*> objects;
-
- DatabaseStorageObjectList(const Signature::PublicKey &_creatorPublicKey) :
- creatorPublicKey(_creatorPublicKey)
- {
-
- }
- };
-
- struct DatabaseStorageQuarantineObject
- {
- DataView data;
- u64 createdTimestamp; // In microseconds
- u64 storedTimestamp; // In microseconds
- Signature::PublicKey creatorPublicKey;
-
- DatabaseStorageQuarantineObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey);
- };
-
class DatabaseStorageException : public std::runtime_error
{
public:
@@ -103,18 +60,9 @@ namespace odhtdb
DatabaseStorageWrongPassword(const std::string &errMsg) : DatabaseStorageException(errMsg) {}
};
- using DatabaseStorageMap = MapHash<DatabaseStorageObjectList*>;
- using DatabaseStorageQuarantineMap = Signature::MapPublicKey<std::vector<DatabaseStorageQuarantineObject*>>;
-
const int PASSWORD_SALT_LEN = 16;
const int HASHED_PASSWORD_LEN = 32;
- struct NodeLocalUser
- {
- Hash nodeHash;
- LocalUser *localUser;
- };
-
using FetchNodeRawCallbackFunc = std::function<void(const DataView)>;
using FetchNodeAddDataRawCallbackFunc = std::function<void(const DataView)>;
@@ -131,14 +79,14 @@ namespace odhtdb
bool doesDataExist(const Hash &requestHash) const;
// Throws DatabaseStorageAlreadyExists if data with hash already exists
- void createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const void *data, usize size);
+ void createStorage(const Hash &hash, const Signature::PublicKey &adminPublicKey, const DataView &adminGroupId, u64 timestamp, const void *data, usize size);
// Throws DatabaseStorageNotFound if data with @nodeHash hash has not been created yet.
// Throws DatabaseStorageAlreadyExists if same data has been added before (hash of @data, in @dataHash)
void appendStorage(const Hash &nodeHash, const Hash &dataHash, DatabaseOperation operation, const Signature::PublicKey &creatorPublicKey, u64 timestamp, const void *data, usize size, const DataView &additionalDataView);
// Throws DatabaseStorageAlreadyExists if group already exists in node
- void addGroup(const Hash &nodeHash, Group *group);
+ void addGroup(const Hash &nodeHash, const DataView &groupId, const Permission &permissions);
void addUserToGroup(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupId);
@@ -148,6 +96,9 @@ namespace odhtdb
void fetchNodeRaw(const Hash &nodeHash, FetchNodeRawCallbackFunc callbackFunc);
void fetchNodeAddDataRaw(const Hash &nodeHash, FetchNodeAddDataRawCallbackFunc callbackFunc);
+ bool isUserAllowedToAddDataInNode(const Hash &nodeHash, const Signature::PublicKey &userPublicKey) const;
+ bool isUserAllowedToAddUserToGroupInNode(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupToAddUserTo) const;
+
// Username and key pair has to be unique, returns true on success
//bool storeLocalUser(const std::string &username, const Signature::KeyPair &keyPair, const std::string &password);
diff --git a/include/odhtdb/Group.hpp b/include/odhtdb/Group.hpp
index f8de78e..37058fd 100644
--- a/include/odhtdb/Group.hpp
+++ b/include/odhtdb/Group.hpp
@@ -1,35 +1,6 @@
#pragma once
-#include "types.hpp"
-#include "DataView.hpp"
-#include "Permission.hpp"
-#include "utils.hpp"
-#include <vector>
-#include <stdexcept>
-
namespace odhtdb
{
- class User;
-
const int GROUP_ID_LENGTH = 16;
-
- class Group
- {
- DISABLE_COPY(Group)
- friend class User;
- public:
- Group(uint8_t id[GROUP_ID_LENGTH], const Permission &permission);
- ~Group();
-
- DataView getId() const;
- const Permission& getPermission() const;
- const std::vector<const User*>& getUsers() const;
- private:
- void addUser(const User *user);
- bool removeUser(const User *user);
- private:
- uint8_t id[GROUP_ID_LENGTH];
- Permission permission;
- std::vector<const User*> users;
- };
}
diff --git a/include/odhtdb/LocalUser.hpp b/include/odhtdb/LocalUser.hpp
deleted file mode 100644
index b60b516..0000000
--- a/include/odhtdb/LocalUser.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "User.hpp"
-#include "types.hpp"
-
-namespace odhtdb
-{
- class LocalUser : public User
- {
- public:
- static LocalUser* create(const Signature::KeyPair &keyPair, Group *group)
- {
- return new LocalUser(keyPair, group);
- }
-
- const Signature::PublicKey& getPublicKey() const override
- {
- return keyPair.getPublicKey();
- }
-
- const Signature::PrivateKey& getPrivateKey() const
- {
- return keyPair.getPrivateKey();
- }
-
- const Signature::KeyPair& getKeyPair() const
- {
- return keyPair;
- }
- private:
- LocalUser(const Signature::KeyPair &_keyPair, Group *group);
- private:
- Signature::KeyPair keyPair;
- };
-}
diff --git a/include/odhtdb/LocalUserEncrypted.hpp b/include/odhtdb/LocalUserEncrypted.hpp
deleted file mode 100644
index 7919cb3..0000000
--- a/include/odhtdb/LocalUserEncrypted.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include "types.hpp"
-#include "Encryption.hpp"
-#include "Signature.hpp"
-
-namespace odhtdb
-{
- struct EncryptedPrivateKey
- {
- u8 nonce[ENCRYPTION_NONCE_BYTE_SIZE];
- u8 encryptedPrivateKey[ENCRYPTION_CHECKSUM_BYTE_SIZE + PRIVATE_KEY_NUM_BYTES];
-
- EncryptedPrivateKey();
- EncryptedPrivateKey(const EncryptedPrivateKey &other);
-
- // Throws DecryptionException if password (or salt) is wrong
- Signature::PrivateKey decrypt(const DataView &plainPassword, const DataView &salt) const;
- };
-
- // Local user with encrypted private key
- class LocalUserEncrypted
- {
- public:
- static LocalUserEncrypted* create(const Signature::PublicKey &publicKey, const EncryptedPrivateKey &encryptedPrivateKey)
- {
- return new LocalUserEncrypted(publicKey, encryptedPrivateKey);
- }
-
- const Signature::PublicKey& getPublicKey() const
- {
- return publicKey;
- }
-
- const EncryptedPrivateKey& getPrivateKey() const
- {
- return encryptedPrivateKey;
- }
- private:
- LocalUserEncrypted(const Signature::PublicKey &_publicKey, const EncryptedPrivateKey &_encryptedPrivateKey) :
- publicKey(_publicKey),
- encryptedPrivateKey(_encryptedPrivateKey)
- {
-
- }
- private:
- Signature::PublicKey publicKey;
- EncryptedPrivateKey encryptedPrivateKey;
- };
-}
diff --git a/include/odhtdb/OwnedMemory.hpp b/include/odhtdb/OwnedMemory.hpp
index 5dcdf25..67afe06 100644
--- a/include/odhtdb/OwnedMemory.hpp
+++ b/include/odhtdb/OwnedMemory.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "types.hpp"
+#include "DataView.hpp"
namespace odhtdb
{
@@ -16,6 +17,8 @@ namespace odhtdb
OwnedMemory(OwnedMemory&) = delete;
OwnedMemory& operator = (OwnedMemory&) = delete;
+ const DataView getView() const { return DataView(data, size); }
+
void *data;
usize size;
};
diff --git a/include/odhtdb/RemoteUser.hpp b/include/odhtdb/RemoteUser.hpp
deleted file mode 100644
index 2658132..0000000
--- a/include/odhtdb/RemoteUser.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include "User.hpp"
-
-namespace odhtdb
-{
- class RemoteUser : public User
- {
- public:
- static RemoteUser* create(const Signature::PublicKey &publicKey, Group *group)
- {
- return new RemoteUser(publicKey, group);
- }
-
- const Signature::PublicKey& getPublicKey() const override
- {
- return publicKey;
- }
- private:
- RemoteUser(const Signature::PublicKey &_publicKey, Group *group) : User(User::Type::REMOTE, group), publicKey(_publicKey) {}
- private:
- Signature::PublicKey publicKey;
- };
-}
diff --git a/include/odhtdb/User.hpp b/include/odhtdb/User.hpp
deleted file mode 100644
index 15e6492..0000000
--- a/include/odhtdb/User.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include "Signature.hpp"
-#include "types.hpp"
-#include "Permission.hpp"
-#include <stdexcept>
-#include <vector>
-
-namespace odhtdb
-{
- class Group;
- class DatabaseStorage;
-
- class User
- {
- friend class DatabaseStorage;
- public:
- enum class Type : u8
- {
- LOCAL,
- REMOTE
- };
-
- virtual ~User();
-
- virtual void addToGroup(Group *group);
-
- Type getType() const { return type; }
- virtual const std::vector<Group*>& getGroups() const { return groups; }
- virtual const Signature::PublicKey& getPublicKey() const = 0;
-
- virtual bool isAllowedToPerformAction(PermissionType action) const;
- protected:
- User(Type type, Group *group);
- protected:
- Type type;
- std::vector<Group*> groups;
- };
-}
diff --git a/src/Database.cpp b/src/Database.cpp
index 88ac8e4..9985bb9 100644
--- a/src/Database.cpp
+++ b/src/Database.cpp
@@ -1,7 +1,5 @@
#include "../include/odhtdb/Database.hpp"
#include "../include/odhtdb/Group.hpp"
-#include "../include/odhtdb/LocalUser.hpp"
-#include "../include/odhtdb/RemoteUser.hpp"
#include "../include/odhtdb/Encryption.hpp"
#include "../include/odhtdb/DhtKey.hpp"
#include "../include/odhtdb/bin2hex.hpp"
@@ -61,19 +59,25 @@ namespace odhtdb
return DataView(result, allocationSize);
}
- DatabaseCreateResponse::DatabaseCreateResponse(LocalUser *_nodeAdminUser, shared_ptr<OwnedMemory> _key, shared_ptr<Hash> _hash) :
- nodeAdminUser(_nodeAdminUser),
+ DatabaseCreateResponse::DatabaseCreateResponse(std::shared_ptr<Signature::KeyPair> _nodeAdminKeyPair, std::shared_ptr<OwnedMemory> _nodeAdminGroupId, shared_ptr<OwnedMemory> _key, shared_ptr<Hash> _hash) :
+ nodeAdminKeyPair(_nodeAdminKeyPair),
+ nodeAdminGroupId(_nodeAdminGroupId),
key(_key),
hash(_hash)
{
}
- const LocalUser* DatabaseCreateResponse::getNodeAdminUser() const
+ const shared_ptr<Signature::KeyPair> DatabaseCreateResponse::getNodeAdminKeyPair() const
{
- return nodeAdminUser;
+ return nodeAdminKeyPair;
}
-
+
+ const shared_ptr<OwnedMemory> DatabaseCreateResponse::getNodeAdminGroupId() const
+ {
+ return nodeAdminGroupId;
+ }
+
const shared_ptr<OwnedMemory> DatabaseCreateResponse::getNodeEncryptionKey() const
{
return key;
@@ -262,9 +266,6 @@ namespace odhtdb
if(!ok)
Log::warn("Failed to put request to get old data");
});
-
- //node.listen(CREATE_DATA_HASH, bind(&Database::listenCreateData, this, _1));
- //node.listen(ADD_DATA_HASH, bind(&Database::listenAddData, this, _1));
}
void Database::stopSeeding(const Hash &nodeHash)
@@ -285,27 +286,22 @@ namespace odhtdb
{
databaseStorage.loadNode(nodeHash);
}
-
- unique_ptr<DatabaseCreateResponse> Database::create()
- {
- return create(Signature::KeyPair());
- }
- unique_ptr<DatabaseCreateResponse> Database::create(const Signature::KeyPair &creatorKeyPair)
+ unique_ptr<DatabaseCreateResponse> Database::create()
{
+ shared_ptr<Signature::KeyPair> creatorKeyPair = make_shared<Signature::KeyPair>();
+
// TODO: Should this be declared static? is there any difference in behavior/performance?
boost::uuids::random_generator uuidGen;
auto adminGroupId = uuidGen();
assert(adminGroupId.size() == GROUP_ID_LENGTH);
- auto adminGroup = new Group(adminGroupId.data, ADMIN_PERMISSION);
- LocalUser *nodeAdminUser = LocalUser::create(creatorKeyPair, adminGroup);
// Header
sibs::SafeSerializer serializer;
serializer.add(DATABASE_CREATE_PACKET_STRUCTURE_VERSION); // Packet structure version
u64 timestampCombined = getSyncedTimestampUtc().getCombined();
serializer.add(timestampCombined);
- serializer.add((u8*)nodeAdminUser->getPublicKey().getData(), PUBLIC_KEY_NUM_BYTES);
+ serializer.add((u8*)creatorKeyPair->getPublicKey().getData(), PUBLIC_KEY_NUM_BYTES);
serializer.add(adminGroupId.data, adminGroupId.size());
try
@@ -316,7 +312,7 @@ namespace odhtdb
shared_ptr<Hash> hashRequestKey = make_shared<Hash>(serializer.getBuffer().data(), serializer.getBuffer().size());
databaseStorage.setNodeDecryptionKey(*hashRequestKey, DataView(encryptionKey->data, encryptionKey->size));
- databaseStorage.createStorage(*hashRequestKey, adminGroup, timestampCombined, (const u8*)serializer.getBuffer().data(), serializer.getBuffer().size());
+ databaseStorage.createStorage(*hashRequestKey, creatorKeyPair->getPublicKey(), DataView(adminGroupId.data, adminGroupId.size()), timestampCombined, (const u8*)serializer.getBuffer().data(), serializer.getBuffer().size());
DhtKey dhtKey(*hashRequestKey);
Value createDataValue(move(serializer.getBuffer()));
@@ -327,7 +323,9 @@ namespace odhtdb
Log::warn("Failed to put: %s, what to do?", "Database::create");
});
- return make_unique<DatabaseCreateResponse>(nodeAdminUser, encryptionKey, hashRequestKey);
+ shared_ptr<OwnedMemory> adminGroupIdResponse = make_shared<OwnedMemory>(new u8[GROUP_ID_LENGTH], GROUP_ID_LENGTH);
+ memcpy(adminGroupIdResponse->data, adminGroupId.data, GROUP_ID_LENGTH);
+ return make_unique<DatabaseCreateResponse>(creatorKeyPair, adminGroupIdResponse, encryptionKey, hashRequestKey);
}
catch (EncryptionException &e)
{
@@ -335,9 +333,9 @@ namespace odhtdb
}
}
- void Database::addData(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, DataView dataToAdd)
+ void Database::addData(const DatabaseNode &nodeInfo, const Signature::KeyPair &userToPerformActionWith, DataView dataToAdd)
{
- if(!userToPerformActionWith->isAllowedToPerformAction(PermissionType::ADD_DATA))
+ if(!databaseStorage.isUserAllowedToAddDataInNode(*nodeInfo.getRequestHash(), userToPerformActionWith.getPublicKey()))
{
// TODO: User might have permission to perform operation, but we haven't got the packet that adds user to the group with the permission,
// or we haven't received the packet that modifies group with the permission to perform the operation.
@@ -345,7 +343,7 @@ namespace odhtdb
// and remote peers would accept our request to perform operation if they haven't received the operation that removes the user from the group.
// How to handle this?
string errMsg = "User ";
- errMsg += userToPerformActionWith->getPublicKey().toString();
+ errMsg += userToPerformActionWith.getPublicKey().toString();
errMsg += " is not allowed to perform the operation: ADD_USER";
throw PermissionDeniedException(errMsg);
}
@@ -359,11 +357,11 @@ namespace odhtdb
DataView encryptionKey(nodeInfo.getNodeEncryptionKey()->data, ENCRYPTION_KEY_BYTE_SIZE);
Encryption encryptedBody(dataToAdd, DataView(), encryptionKey);
DataView requestData = combine(serializer, encryptedBody);
- string signedRequestData = userToPerformActionWith->getPrivateKey().sign(requestData);
- DataView stagedAddObject = combine(userToPerformActionWith->getPublicKey(), signedRequestData);
+ string signedRequestData = userToPerformActionWith.getPrivateKey().sign(requestData);
+ DataView stagedAddObject = combine(userToPerformActionWith.getPublicKey(), signedRequestData);
Hash requestDataHash(stagedAddObject.data, stagedAddObject.size);
DataView encryptedDataView((char*)requestData.data + serializer.getBuffer().size(), requestData.size - serializer.getBuffer().size());
- databaseStorage.appendStorage(*nodeInfo.getRequestHash(), requestDataHash, DatabaseOperation::ADD_DATA, userToPerformActionWith->getPublicKey(), timestampCombined, (u8*)stagedAddObject.data, stagedAddObject.size, encryptedDataView);
+ databaseStorage.appendStorage(*nodeInfo.getRequestHash(), requestDataHash, DatabaseOperation::ADD_DATA, userToPerformActionWith.getPublicKey(), timestampCombined, (u8*)stagedAddObject.data, stagedAddObject.size, encryptedDataView);
delete[] (char*)requestData.data;
DhtKey dhtKey(requestDataHash);
@@ -377,32 +375,14 @@ namespace odhtdb
});
}
- Group* getGroupWithRightsToAddUserToGroup(const vector<Group*> &groups, Group *groupToAddUserTo)
- {
- for(auto group : groups)
- {
- const auto &groupPermission = group->getPermission();
- if(groupPermission.getFlag(PermissionType::ADD_USER_HIGHER_LEVEL) && groupPermission.getPermissionLevel() < groupToAddUserTo->getPermission().getPermissionLevel())
- {
- return group;
- }
- else if(groupPermission.getFlag(PermissionType::ADD_USER_SAME_LEVEL) && groupPermission.getPermissionLevel() == groupToAddUserTo->getPermission().getPermissionLevel())
- {
- return group;
- }
- }
- return nullptr;
- }
-
- void Database::addUser(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo)
+ void Database::addUser(const DatabaseNode &nodeInfo, const Signature::KeyPair &userToPerformActionWith, const Signature::PublicKey &userToAddPublicKey, const DataView &groupToAddUserTo)
{
- auto groupWithAddUserRights = getGroupWithRightsToAddUserToGroup(userToPerformActionWith->getGroups(), groupToAddUserTo);
- if(!groupWithAddUserRights)
+ if(!databaseStorage.isUserAllowedToAddUserToGroupInNode(*nodeInfo.getRequestHash(), userToPerformActionWith.getPublicKey(), groupToAddUserTo))
{
string errMsg = "The user ";
- errMsg += userToPerformActionWith->getPublicKey().toString();
+ errMsg += userToPerformActionWith.getPublicKey().toString();
errMsg += " does not belong to any group that is allowed to add an user to the group ";
- errMsg += bin2hex((const char*)groupToAddUserTo->getId().data, groupToAddUserTo->getId().size).c_str();
+ errMsg += bin2hex((const char*)groupToAddUserTo.data, groupToAddUserTo.size).c_str();
throw PermissionDeniedException(errMsg);
}
@@ -413,7 +393,7 @@ namespace odhtdb
serializer.add(DatabaseOperation::ADD_USER);
usize additionalDataOffset = serializer.getBuffer().size();
serializer.add((u8*)userToAddPublicKey.getData(), PUBLIC_KEY_NUM_BYTES);
- serializer.add((uint8_t*)groupToAddUserTo->getId().data, groupToAddUserTo->getId().size);
+ serializer.add((uint8_t*)groupToAddUserTo.data, groupToAddUserTo.size);
// TODO: Should this be declared static? is there any difference in behavior/performance?
boost::uuids::random_generator uuidGen;
@@ -422,11 +402,11 @@ namespace odhtdb
serializer.add(padding.data, padding.size());
DataView requestData { serializer.getBuffer().data(), serializer.getBuffer().size() };
- string signedRequestData = userToPerformActionWith->getPrivateKey().sign(requestData);
- DataView stagedAddObject = combine(userToPerformActionWith->getPublicKey(), signedRequestData);
+ string signedRequestData = userToPerformActionWith.getPrivateKey().sign(requestData);
+ DataView stagedAddObject = combine(userToPerformActionWith.getPublicKey(), signedRequestData);
Hash requestDataHash(stagedAddObject.data, stagedAddObject.size);
DataView additionalDataView((void*)(static_cast<const char*>(requestData.data) + additionalDataOffset), requestData.size - additionalDataOffset);
- databaseStorage.appendStorage(*nodeInfo.getRequestHash(), requestDataHash, DatabaseOperation::ADD_USER, userToPerformActionWith->getPublicKey(), timestampCombined, (u8*)stagedAddObject.data, stagedAddObject.size, additionalDataView);
+ databaseStorage.appendStorage(*nodeInfo.getRequestHash(), requestDataHash, DatabaseOperation::ADD_USER, userToPerformActionWith.getPublicKey(), timestampCombined, (u8*)stagedAddObject.data, stagedAddObject.size, additionalDataView);
DhtKey dhtKey(requestDataHash);
Value addDataValue((u8*)stagedAddObject.data, stagedAddObject.size);
@@ -492,10 +472,7 @@ namespace odhtdb
if(deserializer.getSize() < ENCRYPTION_NONCE_BYTE_SIZE)
throw sibs::DeserializeException("Unsigned encrypted body is too small (unable to extract nonce)");
- auto adminGroup = new Group(adminGroupId, ADMIN_PERMISSION);
- // TODO: Username is encrypted, we dont know it... unless we have encryption key, in which case we should modify the user name and set it
- auto creatorUser = RemoteUser::create(userPublicKey, adminGroup);
- databaseStorage.createStorage(hash, adminGroup, creationDate, value->data.data(), value->data.size());
+ databaseStorage.createStorage(hash, userPublicKey, DataView(adminGroupId, GROUP_ID_LENGTH), creationDate, value->data.data(), value->data.size());
}
void Database::deserializeAddRequest(const shared_ptr<dht::Value> &value, const Hash &requestDataHash, const std::shared_ptr<Hash> &nodeHash, const shared_ptr<OwnedMemory> encryptionKey)
diff --git a/src/DatabaseStorage.cpp b/src/DatabaseStorage.cpp
index 501bd35..d7f42bb 100644
--- a/src/DatabaseStorage.cpp
+++ b/src/DatabaseStorage.cpp
@@ -1,7 +1,4 @@
#include "../include/odhtdb/DatabaseStorage.hpp"
-#include "../include/odhtdb/RemoteUser.hpp"
-#include "../include/odhtdb/LocalUser.hpp"
-#include "../include/odhtdb/LocalUserEncrypted.hpp"
#include "../include/odhtdb/Group.hpp"
#include "../include/odhtdb/FileUtils.hpp"
#include "../include/odhtdb/bin2hex.hpp"
@@ -28,22 +25,6 @@ namespace odhtdb
const u64 QUARANTINE_STORAGE_TIME_MICROSECONDS = 60 * 1.0e6;
const u16 STORAGE_VERSION = 3;
-
- DatabaseStorageObject::DatabaseStorageObject(const Hash &_requestHash, DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey) :
- requestHash(_requestHash),
- data(_data),
- createdTimestamp(_timestamp),
- creatorPublicKey(_creatorPublicKey)
- {
-
- }
-
- DatabaseStorageQuarantineObject::DatabaseStorageQuarantineObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey) :
- data(_data), createdTimestamp(_timestamp), creatorPublicKey(_creatorPublicKey)
- {
- auto time = chrono::high_resolution_clock::now().time_since_epoch();
- storedTimestamp = chrono::duration_cast<chrono::microseconds>(time).count();
- }
static void sqlite_exec_checked(sqlite3 *db, const char *sql)
{
@@ -431,11 +412,8 @@ namespace odhtdb
return query.next();
}
- void DatabaseStorage::createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const void *data, usize size)
+ void DatabaseStorage::createStorage(const Hash &hash, const Signature::PublicKey &adminPublicKey, const DataView &adminGroupId, u64 timestamp, const void *data, usize size)
{
- assert(creatorGroup->getUsers().size() == 1);
- User *creator = (User*)creatorGroup->getUsers()[0];
-
sqlite3_exec(sqliteDb, "BEGIN", 0, 0, 0);
{
sqlite3_reset(insertNodeStmt);
@@ -448,15 +426,15 @@ namespace odhtdb
rc = sqlite3_bind_int64(insertNodeStmt, 2, timestamp);
bindCheckError(rc);
- rc = sqlite3_bind_blob(insertNodeStmt, 3, creator->getPublicKey().getData(), creator->getPublicKey().getSize(), SQLITE_STATIC);
+ rc = sqlite3_bind_blob(insertNodeStmt, 3, adminPublicKey.getData(), adminPublicKey.getSize(), SQLITE_STATIC);
bindCheckError(rc);
- rc = sqlite3_bind_blob(insertNodeStmt, 4, creatorGroup->getId().data, GROUP_ID_LENGTH, SQLITE_STATIC);
+ rc = sqlite3_bind_blob(insertNodeStmt, 4, adminGroupId.data, GROUP_ID_LENGTH, SQLITE_STATIC);
bindCheckError(rc);
sqlite_step_rollback_on_failure(sqliteDb, insertNodeStmt, "insert data into Node");
- addGroup(hash, creatorGroup);
- addUser(hash, creator->getPublicKey(), creatorGroup->getId());
+ addGroup(hash, adminGroupId, ADMIN_PERMISSION);
+ addUser(hash, adminPublicKey, adminGroupId);
}
{
sqlite3_reset(insertNodeRawStmt);
@@ -475,7 +453,7 @@ namespace odhtdb
auto nodeDecryptionKeyResult = getNodeDecryptionKey(hash);
if(nodeDecryptionKeyResult.first)
- decryptNodeData(hash, nodeDecryptionKeyResult.second, &creator->getPublicKey(), creatorGroup->getId(), timestamp);
+ decryptNodeData(hash, nodeDecryptionKeyResult.second, &adminPublicKey, adminGroupId, timestamp);
}
void DatabaseStorage::appendStorage(const Hash &nodeHash, const Hash &dataHash, DatabaseOperation operation, const Signature::PublicKey &creatorPublicKey, u64 timestamp, const void *data, usize size, const DataView &additionalDataView)
@@ -591,7 +569,7 @@ namespace odhtdb
sqlite3_exec(sqliteDb, "COMMIT", 0, 0, 0);
}
- void DatabaseStorage::addGroup(const Hash &nodeHash, Group *group)
+ void DatabaseStorage::addGroup(const Hash &nodeHash, const DataView &groupId, const Permission &permissions)
{
sqlite3_reset(insertGroupStmt);
sqlite3_clear_bindings(insertGroupStmt);
@@ -600,17 +578,17 @@ namespace odhtdb
rc = sqlite3_bind_blob(insertGroupStmt, 1, nodeHash.getData(), nodeHash.getSize(), SQLITE_STATIC);
bindCheckError(rc);
- rc = sqlite3_bind_blob(insertGroupStmt, 2, group->getId().data, GROUP_ID_LENGTH, SQLITE_STATIC);
+ rc = sqlite3_bind_blob(insertGroupStmt, 2, groupId.data, GROUP_ID_LENGTH, SQLITE_STATIC);
bindCheckError(rc);
- rc = sqlite3_bind_int(insertGroupStmt, 3, group->getPermission().getPermissionLevel());
+ rc = sqlite3_bind_int(insertGroupStmt, 3, permissions.getPermissionLevel());
bindCheckError(rc);
- rc = sqlite3_bind_int64(insertGroupStmt, 4, group->getPermission().getPermissionFlags());
+ rc = sqlite3_bind_int64(insertGroupStmt, 4, permissions.getPermissionFlags());
bindCheckError(rc);
sqlite_step_rollback_on_failure(sqliteDb, insertGroupStmt, "insert data into NodeGroup");
- Log::debug("Created group %s in node %s", bin2hex((const char*)group->getId().data, GROUP_ID_LENGTH).c_str(), nodeHash.toString().c_str());
+ Log::debug("Created group %s in node %s", bin2hex((const char*)groupId.data, GROUP_ID_LENGTH).c_str(), nodeHash.toString().c_str());
}
void DatabaseStorage::addUserToGroup(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupId)
@@ -669,6 +647,36 @@ namespace odhtdb
callbackFunc(data);
}
}
+
+ bool DatabaseStorage::isUserAllowedToAddDataInNode(const Hash &nodeHash, const Signature::PublicKey &userPublicKey) const
+ {
+ SqlQuery queryCreatorGroupWithRightsToAddData(sqliteDb,
+ "SELECT nodeGroup.rowid FROM NodeUserGroupAssoc AS userGroupAssoc"
+ " INNER JOIN NodeGroup AS nodeGroup ON nodeGroup.groupId = userGroupAssoc.groupId"
+ " WHERE userGroupAssoc.node = ? AND userGroupAssoc.userPublicKey = ? AND (nodeGroup.permissionFlags & ?) != 0",
+ { DataView(nodeHash.getData(), nodeHash.getSize()), DataView((void*)userPublicKey.getData(), userPublicKey.getSize()), (i64)PermissionType::ADD_DATA });
+ return queryCreatorGroupWithRightsToAddData.next();
+ }
+
+ bool DatabaseStorage::isUserAllowedToAddUserToGroupInNode(const Hash &nodeHash, const Signature::PublicKey &userPublicKey, const DataView &groupToAddUserTo) const
+ {
+ SqlQuery queryGroupToAdd(sqliteDb, "SELECT permissionLevel FROM NodeGroup WHERE groupId = ?", { groupToAddUserTo });
+ if(!queryGroupToAdd.next())
+ {
+ // TODO: Add to quarantine?
+ Log::error("There is no group with id %s in node %s", bin2hex((const char*)groupToAddUserTo.data, groupToAddUserTo.size).c_str(), nodeHash.toString().c_str());
+ return false;
+ }
+
+ int groupToAddPermissionLevel = queryGroupToAdd.getInt(0);
+
+ SqlQuery queryCreatorGroupWithRightsToAddUserToGroup(sqliteDb,
+ "SELECT nodeGroup.rowid FROM NodeUserGroupAssoc AS userGroupAssoc"
+ " INNER JOIN NodeGroup AS nodeGroup ON nodeGroup.groupId = userGroupAssoc.groupId"
+ " WHERE userGroupAssoc.node = ? AND userGroupAssoc.userPublicKey = ? AND (nodeGroup.permissionLevel = ? AND ((nodeGroup.permissionFlags & ?) != 0) OR (nodeGroup.permissionLevel > ? AND (nodeGroup.permissionFlags & ?) != 0))",
+ { DataView(nodeHash.getData(), nodeHash.getSize()), DataView((void*)userPublicKey.getData(), userPublicKey.getSize()), groupToAddPermissionLevel, (i64)PermissionType::ADD_USER_SAME_LEVEL, groupToAddPermissionLevel, (i64)PermissionType::ADD_USER_HIGHER_LEVEL });
+ return queryCreatorGroupWithRightsToAddUserToGroup.next();
+ }
#if 0
bool DatabaseStorage::storeLocalUser(const string &username, const Signature::KeyPair &keyPair, const string &password)
{
@@ -943,12 +951,7 @@ namespace odhtdb
bool DatabaseStorage::decryptNodeAddData(i64 rowId, const Hash &nodeHash, const Hash &dataHash, u64 timestamp, const Signature::PublicKey *creatorPublicKey, const DataView &encryptedData, const shared_ptr<OwnedMemory> decryptionKey)
{
- SqlQuery queryCreatorGroupWithRightsToAddData(sqliteDb,
- "SELECT nodeGroup.rowid FROM NodeUserGroupAssoc AS userGroupAssoc"
- " INNER JOIN NodeGroup AS nodeGroup ON nodeGroup.groupId = userGroupAssoc.groupId"
- " WHERE userGroupAssoc.node = ? AND userGroupAssoc.userPublicKey = ? AND (nodeGroup.permissionFlags & ?) != 0",
- { DataView(nodeHash.getData(), nodeHash.getSize()), DataView((void*)creatorPublicKey->getData(), creatorPublicKey->getSize()), (i64)PermissionType::ADD_DATA });
- if(!queryCreatorGroupWithRightsToAddData.next())
+ if(!isUserAllowedToAddDataInNode(nodeHash, *creatorPublicKey))
{
// TODO: User might have permission to perform operation, but we haven't got the packet that adds user to the group with the permission,
// or we haven't received the packet that modifies group with the permission to perform the operation.
@@ -976,22 +979,7 @@ namespace odhtdb
bool DatabaseStorage::decryptNodeAddUser(i64 rowId, const Hash &nodeHash, const Hash &dataHash, u64 timestamp, const Signature::PublicKey *creatorPublicKey, const Signature::PublicKey *userToAddPublicKey, const DataView &groupToAddUserTo, const shared_ptr<OwnedMemory> decryptionKey)
{
- SqlQuery queryGroupToAdd(sqliteDb, "SELECT permissionLevel FROM NodeGroup WHERE groupId = ?", { groupToAddUserTo });
- if(!queryGroupToAdd.next())
- {
- // TODO: Add to quarantine?
- Log::error("There is no group with id %s in node %s", bin2hex((const char*)groupToAddUserTo.data, groupToAddUserTo.size).c_str(), nodeHash.toString().c_str());
- return false;
- }
-
- int groupToAddPermissionLevel = queryGroupToAdd.getInt(0);
-
- SqlQuery queryCreatorGroupWithRightsToAddUserToGroup(sqliteDb,
- "SELECT nodeGroup.rowid FROM NodeUserGroupAssoc AS userGroupAssoc"
- " INNER JOIN NodeGroup AS nodeGroup ON nodeGroup.groupId = userGroupAssoc.groupId"
- " WHERE userGroupAssoc.node = ? AND userGroupAssoc.userPublicKey = ? AND (nodeGroup.permissionLevel = ? AND ((nodeGroup.permissionFlags & ?) != 0) OR (nodeGroup.permissionLevel > ? AND (nodeGroup.permissionFlags & ?) != 0))",
- { DataView(nodeHash.getData(), nodeHash.getSize()), DataView((void*)creatorPublicKey->getData(), creatorPublicKey->getSize()), groupToAddPermissionLevel, (i64)PermissionType::ADD_USER_SAME_LEVEL, groupToAddPermissionLevel, (i64)PermissionType::ADD_USER_HIGHER_LEVEL });
- if(!queryCreatorGroupWithRightsToAddUserToGroup.next())
+ if(!isUserAllowedToAddUserToGroupInNode(nodeHash, *creatorPublicKey, groupToAddUserTo))
{
// TODO: User might have permission to perform operation, but we haven't got the packet that adds user to the group with the permission,
// or we haven't received the packet that modifies group with the permission to perform the operation.
diff --git a/src/Group.cpp b/src/Group.cpp
deleted file mode 100644
index 9db3e4e..0000000
--- a/src/Group.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "../include/odhtdb/Group.hpp"
-#include "../include/odhtdb/User.hpp"
-#include <cstring>
-
-using namespace std;
-
-namespace odhtdb
-{
- Group::Group(uint8_t _id[GROUP_ID_LENGTH], const Permission &_permission) :
- permission(_permission)
- {
- memcpy(id, _id, GROUP_ID_LENGTH);
- }
-
- Group::~Group()
- {
-
- }
-
- void Group::addUser(const User *user)
- {
- users.push_back(user);
- }
-
- bool Group::removeUser(const User *user)
- {
- for(std::vector<const User*>::iterator it = users.begin(); it != users.end(); ++it)
- {
- if(*it == user)
- {
- users.erase(it);
- return true;
- }
- }
- return false;
- }
-
- DataView Group::getId() const
- {
- return { (void*)id, GROUP_ID_LENGTH };
- }
-
- const Permission& Group::getPermission() const
- {
- return permission;
- }
-
- const vector<const User*>& Group::getUsers() const
- {
- return users;
- }
-}
diff --git a/src/LocalUser.cpp b/src/LocalUser.cpp
deleted file mode 100644
index 950c953..0000000
--- a/src/LocalUser.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "../include/odhtdb/LocalUser.hpp"
-
-namespace odhtdb
-{
- LocalUser::LocalUser(const Signature::KeyPair &_keyPair, Group *group) :
- User(User::Type::LOCAL, group),
- keyPair(_keyPair)
- {
-
- }
-}
diff --git a/src/LocalUserEncrypted.cpp b/src/LocalUserEncrypted.cpp
deleted file mode 100644
index a414c89..0000000
--- a/src/LocalUserEncrypted.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "../include/odhtdb/LocalUserEncrypted.hpp"
-#include "../include/odhtdb/PasswordHash.hpp"
-#include <cstring>
-
-namespace odhtdb
-{
- EncryptedPrivateKey::EncryptedPrivateKey()
- {
- memset(nonce, 0, ENCRYPTION_NONCE_BYTE_SIZE);
- memset(encryptedPrivateKey, 0, ENCRYPTION_CHECKSUM_BYTE_SIZE + PRIVATE_KEY_NUM_BYTES);
- }
-
- EncryptedPrivateKey::EncryptedPrivateKey(const EncryptedPrivateKey &other)
- {
- memcpy(nonce, other.nonce, ENCRYPTION_NONCE_BYTE_SIZE);
- memcpy(encryptedPrivateKey, other.encryptedPrivateKey, ENCRYPTION_CHECKSUM_BYTE_SIZE + PRIVATE_KEY_NUM_BYTES);
- }
-
- Signature::PrivateKey EncryptedPrivateKey::decrypt(const DataView &plainPassword, const DataView &salt) const
- {
- OwnedMemory hashedPassword = hashPassword(plainPassword, salt);
- Decryption decryptedPrivateKey(DataView((void*)encryptedPrivateKey, ENCRYPTION_CHECKSUM_BYTE_SIZE + PRIVATE_KEY_NUM_BYTES),
- DataView((void*)nonce, ENCRYPTION_NONCE_BYTE_SIZE),
- DataView(hashedPassword.data, hashedPassword.size));
- return { (const char*)decryptedPrivateKey.getDecryptedText().data, decryptedPrivateKey.getDecryptedText().size };
- }
-}
diff --git a/src/User.cpp b/src/User.cpp
deleted file mode 100644
index 559f8db..0000000
--- a/src/User.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "../include/odhtdb/User.hpp"
-#include "../include/odhtdb/Group.hpp"
-
-namespace odhtdb
-{
- User::User(Type _type, Group *group) : type(_type)
- {
- addToGroup(group);
- }
-
- User::~User()
- {
- for(Group *group : groups)
- {
- group->removeUser(this);
- }
- }
-
- void User::addToGroup(Group *group)
- {
- if(group)
- {
- groups.emplace_back(group);
- group->addUser(this);
- }
- }
-
- bool User::isAllowedToPerformAction(PermissionType action) const
- {
- for(Group *group : getGroups())
- {
- if(group->getPermission().getFlag(action))
- return true;
- }
- return false;
- }
-}
diff --git a/tests/main.cpp b/tests/main.cpp
index 6e1a72f..0174384 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -2,7 +2,6 @@
#include "../include/odhtdb/Log.hpp"
#include "../include/odhtdb/Database.hpp"
#include "../include/odhtdb/Group.hpp"
-#include "../include/odhtdb/LocalUser.hpp"
#include "../include/odhtdb/Encryption.hpp"
#include "../include/odhtdb/Hash.hpp"
#include "../include/odhtdb/hex2bin.hpp"
@@ -49,19 +48,19 @@ void testHash()
Log::debug("hash of 'odhtdb' is: a7b30ec8ab92de60e551b26bb8f78d315697f84dd7f5549a143477e095ec934f");
}
-void testSignData(LocalUser *localUser)
+void testSignData(const Signature::KeyPair &localUserKeyPair)
{
- std::string publicKeyStr = localUser->getPublicKey().toString();
+ std::string publicKeyStr = localUserKeyPair.getPublicKey().toString();
Log::debug("Local user public key: %s", publicKeyStr.c_str());
- std::string privateKeyStr = localUser->getPrivateKey().toString();
+ std::string privateKeyStr = localUserKeyPair.getPrivateKey().toString();
Log::debug("Local user private key: %s", privateKeyStr.c_str());
string expectedUnsignedData = "hello, world!";
- string signedData = localUser->getPrivateKey().sign(DataView((void*)expectedUnsignedData.data(), expectedUnsignedData.size()));
+ string signedData = localUserKeyPair.getPrivateKey().sign(DataView((void*)expectedUnsignedData.data(), expectedUnsignedData.size()));
assertEquals(SIGNED_HASH_SIZE + expectedUnsignedData.size(), signedData.size());
- string unsignedData = localUser->getPublicKey().unsign(DataView((void*)signedData.data(), signedData.size()));
+ string unsignedData = localUserKeyPair.getPublicKey().unsign(DataView((void*)signedData.data(), signedData.size()));
assertEquals(expectedUnsignedData, unsignedData);
try
@@ -180,8 +179,8 @@ int main()
DatabaseNode databaseNode;
{
- LocalUser *localUser = LocalUser::create(Signature::KeyPair(), nullptr);
- testSignData(localUser);
+ Signature::KeyPair localUserKeyPair;
+ testSignData(localUserKeyPair);
// TODO: Setup local bootstrap node for tests
Database database("bootstrap.ring.cx", 4222, storagePath, callbackFuncs);
@@ -189,11 +188,10 @@ int main()
auto databaseCreateResponse = database.create();
databaseNode = { databaseCreateResponse->getNodeEncryptionKey(), databaseCreateResponse->getRequestHash() };
- auto adminUser = (LocalUser*)databaseCreateResponse->getNodeAdminUser();
- database.addData(databaseNode, adminUser, DataView{ (void*)"hello, world!", 13 });
- database.addUser(databaseNode, adminUser, localUser->getPublicKey(), adminUser->getGroups()[0]);
- localUser->addToGroup(adminUser->getGroups()[0]);
- database.addData(databaseNode, localUser, DataView{ (void*)"hello, aaald!", 13 });
+ auto adminUserKey = databaseCreateResponse->getNodeAdminKeyPair();
+ database.addData(databaseNode, *adminUserKey, DataView{ (void*)"hello, world!", 13 });
+ database.addUser(databaseNode, *adminUserKey, localUserKeyPair.getPublicKey(), databaseCreateResponse->getNodeAdminGroupId()->getView());
+ database.addData(databaseNode, localUserKeyPair, DataView{ (void*)"hello, aaald!", 13 });
database.seed(databaseNode);
this_thread::sleep_for(chrono::seconds(3));