#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 #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) {} }; enum class DatabaseOperation : u8 { ADD_DATA, ADD_USER }; struct DatabaseCreateRequest { DISABLE_COPY(DatabaseCreateRequest) u64 timestamp; // In microseconds Group *creatorGroup; std::string name; DatabaseCreateRequest(u64 _timestamp, Group *_creatorGroup, std::string &&_name) : timestamp(_timestamp), creatorGroup(_creatorGroup), name(std::move(_name)) { } DatabaseCreateRequest(DatabaseCreateRequest &&other) { timestamp = other.timestamp; creatorGroup = other.creatorGroup; name = std::move(other.name); other.timestamp = 0; other.creatorGroup = nullptr; } }; struct DatabaseAddRequest { DISABLE_COPY(DatabaseAddRequest) u64 timestamp; // In microseconds const User *creatorUser; Decryption decryptedData; DatabaseAddRequest(u64 _timestamp, const User *_creatorUser, Decryption &&_decryptedData) : timestamp(_timestamp), creatorUser(_creatorUser), decryptedData(std::move(_decryptedData)) { } DatabaseAddRequest(DatabaseAddRequest &&other) { timestamp = other.timestamp; creatorUser = other.creatorUser; decryptedData = std::move(other.decryptedData); other.timestamp = 0; other.creatorUser = nullptr; } }; class DatabaseCreateResponse { public: DatabaseCreateResponse(LocalUser *nodeAdminUser, const std::shared_ptr &key, const std::shared_ptr &hash); const LocalUser* getNodeAdminUser() const; const std::shared_ptr getNodeEncryptionKey() const; const std::shared_ptr getRequestHash() const; private: LocalUser *nodeAdminUser; std::shared_ptr key; std::shared_ptr hash; }; class Database { public: Database(const char *bootstrapNodeAddr, u16 port, boost::filesystem::path storageDir); ~Database(); void seed(const std::shared_ptr hash, const std::shared_ptr encryptionKey); // Throws DatabaseCreateException on failure. std::unique_ptr create(const std::string &ownerName, const std::string &nodeName); // Throws DatabaseAddException on failure void addData(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, DataView dataToAdd); // Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add user @userToAdd to group @groupToAddUserTo void addUserToGroup(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, const std::string &userToAddName, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo); void commit(); 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; DatabaseCreateRequest 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 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 encryptionKey); private: dht::DhtRunner node; std::vector> stagedCreateObjects; std::vector> stagedAddObjects; DatabaseStorage databaseStorage; }; }