#pragma once #include "types.hpp" #include "Key.hpp" #include "DataView.hpp" #include "DatabaseStorage.hpp" #include "Hash.hpp" #include "utils.hpp" #include "StagedObject.hpp" #include "Signature.hpp" #include "Permission.hpp" #include "DatabaseNode.hpp" #include "Encryption.hpp" #include "OwnedMemory.hpp" #include "DatabaseOperation.hpp" #include #include #include #include #include #include namespace odhtdb { class User; class LocalUser; class Group; class CommitCreateException : public std::runtime_error { public: CommitCreateException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; class CommitAddException : public std::runtime_error { public: CommitAddException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; class DatabaseCreateException : public std::runtime_error { public: DatabaseCreateException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; class DatabaseAddException : public std::runtime_error { public: DatabaseAddException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; struct DatabaseCreateNodeRequest { DISABLE_COPY(DatabaseCreateNodeRequest) const Hash *nodeHash; u64 timestamp; // In microseconds const User *creatorUser; std::string name; DatabaseCreateNodeRequest(const Hash *_nodeHash, u64 _timestamp, const User *_creatorUser, std::string &&_name) : nodeHash(_nodeHash), timestamp(_timestamp), creatorUser(_creatorUser), name(std::move(_name)) { } }; struct DatabaseAddNodeRequest { DISABLE_COPY(DatabaseAddNodeRequest) const Hash *nodeHash; const Hash *requestHash; u64 timestamp; // In microseconds const User *creatorUser; const DataView decryptedData; DatabaseAddNodeRequest(const Hash *_nodeHash, const Hash *_requestHash, u64 _timestamp, const User *_creatorUser, const DataView &_decryptedData) : nodeHash(_nodeHash), requestHash(_requestHash), timestamp(_timestamp), creatorUser(_creatorUser), decryptedData(_decryptedData) { } }; struct DatabaseAddUserRequest { DISABLE_COPY(DatabaseAddUserRequest) const Hash *nodeHash; const Hash *requestHash; u64 timestamp; // In microseconds const User *creatorUser; const User *userToAdd; const Group *groupToAddUserTo; DatabaseAddUserRequest(const Hash *_nodeHash, const Hash *_requestHash, u64 _timestamp, const User *_creatorUser, const User *_userToAdd, const Group *_groupToAddUserTo) : timestamp(_timestamp), creatorUser(_creatorUser), userToAdd(_userToAdd), groupToAddUserTo(_groupToAddUserTo) { } }; class DatabaseCreateResponse { public: DatabaseCreateResponse(LocalUser *nodeAdminUser, const std::shared_ptr &key, const std::shared_ptr &hash); const LocalUser* getNodeAdminUser() const; // Size of encryption key is odhtdb::KEY_BYTE_SIZE (found in Encryption.hpp) const std::shared_ptr getNodeEncryptionKey() const; const std::shared_ptr getRequestHash() const; private: LocalUser *nodeAdminUser; std::shared_ptr key; std::shared_ptr hash; }; struct DatabaseSeedInfo { std::shared_ptr> newDataListenerFuture; std::shared_ptr> responseKeyFuture; std::shared_ptr> requestOldDataListenerFuture; std::shared_ptr reponseKeyInfoHash; DatabaseSeedInfo(){} DatabaseSeedInfo(const DatabaseSeedInfo &other) { newDataListenerFuture = other.newDataListenerFuture; responseKeyFuture = other.responseKeyFuture; requestOldDataListenerFuture = other.requestOldDataListenerFuture; reponseKeyInfoHash = other.reponseKeyInfoHash; } }; class Database { DISABLE_COPY(Database) friend class DatabaseStorage; public: Database(const char *bootstrapNodeAddr, u16 port, const boost::filesystem::path &storageDir); ~Database(); // Safe to call multiple times with same node hash, will be ignored if the node is already beeing seeded void seed(const DatabaseNode &nodeToSeed); void stopSeeding(const Hash &nodeHash); // Throws DatabaseCreateException on failure. std::unique_ptr create(const std::string &ownerName, const std::string &nodeName); // Throws DatabaseCreateException on failure. std::unique_ptr create(const std::string &ownerName, const Signature::KeyPair &keyPair, const std::string &nodeName); // Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add data to node void addData(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, DataView dataToAdd); // Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add user @userToAdd to group @groupToAddUserTo void addUser(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, const std::string &userToAddName, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo); void commit(); void setOnCreateNodeCallback(std::function callbackFunc); void setOnAddNodeCallback(std::function callbackFunc); void setOnAddUserCallback(std::function callbackFunc); DatabaseStorage& getStorage(); private: // Throws CommitCreateException on failure void commitStagedCreateObject(const std::unique_ptr &stagedObject); // Throws CommitAddException on failure void commitStagedAddObject(const std::unique_ptr &stagedObject); ntp::NtpTimestamp getSyncedTimestampUtc() const; void deserializeCreateRequest(const std::shared_ptr &value, const Hash &hash, const std::shared_ptr encryptionKey); void deserializeAddRequest(const std::shared_ptr &value, const Hash &requestDataHash, const std::shared_ptr &nodeHash, const std::shared_ptr encryptionKey); bool listenCreateData(std::shared_ptr value, const Hash &hash, const std::shared_ptr encryptionKey); bool listenAddData(std::shared_ptr value, const Hash &requestDataHash, const std::shared_ptr nodeHash, const std::shared_ptr encryptionKey); private: dht::DhtRunner node; std::vector> stagedCreateObjects; std::vector> stagedAddObjects; DatabaseStorage databaseStorage; std::function onCreateNodeCallbackFunc; std::function onAddNodeCallbackFunc; std::function onAddUserCallbackFunc; MapHash seedInfoMap; }; }