From 1328d943c5016dd1662a4e46d4a408bca010cffc Mon Sep 17 00:00:00 2001 From: Aleksi Lindeman <0xdec05eba@gmail.com> Date: Sun, 11 Mar 2018 00:12:37 +0100 Subject: Add operation to allow users to be added to group WARNING! Lazy implementation everywhere, does not handle out-of-order packets --- include/DataView.hpp | 14 ++++++++++++++ include/Database.hpp | 14 ++++++++++++-- include/DatabaseNode.hpp | 31 ++++++++++++++++++++++++++++++ include/DatabaseStorage.hpp | 10 ++++++++++ include/Group.hpp | 16 +++++++++++++--- include/LocalUser.hpp | 6 +++--- include/Permission.hpp | 46 +++++++++++++++++++++++++++++++++++++++++++++ include/RemoteUser.hpp | 6 +++--- include/User.hpp | 13 ++++++++----- 9 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 include/DatabaseNode.hpp create mode 100644 include/Permission.hpp (limited to 'include') diff --git a/include/DataView.hpp b/include/DataView.hpp index c020f91..0ecf9fb 100644 --- a/include/DataView.hpp +++ b/include/DataView.hpp @@ -1,6 +1,8 @@ #pragma once #include "types.hpp" +#include "Hash.hpp" +#include namespace odhtdb { @@ -9,8 +11,20 @@ namespace odhtdb public: DataView() : data(nullptr), size(0) {} DataView(void *_data, usize _size) : data(_data), size(_size) {} + bool operator == (const DataView &other) const; void *data; usize size; }; + + struct DataViewHasher + { + size_t operator()(const DataView &dataView) const + { + return fnvHash((const unsigned char*)dataView.data, dataView.size); + } + }; + + template + using DataViewMap = std::unordered_map; } diff --git a/include/Database.hpp b/include/Database.hpp index 1024fe0..64a381c 100644 --- a/include/Database.hpp +++ b/include/Database.hpp @@ -8,6 +8,8 @@ #include "utils.hpp" #include "StagedObject.hpp" #include "Signature.hpp" +#include "Permission.hpp" +#include "DatabaseNode.hpp" #include #include #include @@ -44,6 +46,12 @@ namespace odhtdb DatabaseAddException(const std::string &errMsg) : std::runtime_error(errMsg) {} }; + enum class DatabaseOperation : u8 + { + ADD_DATA, + ADD_USER + }; + struct DatabaseCreateRequest { DISABLE_COPY(DatabaseCreateRequest) @@ -122,7 +130,9 @@ namespace odhtdb // Throws DatabaseCreateException on failure. std::unique_ptr create(const std::string &ownerName, const std::string &nodeName); // Throws DatabaseAddException on failure - void add(const std::unique_ptr &nodeInfo, DataView dataToAdd); + 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 @@ -131,7 +141,7 @@ namespace odhtdb 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); - DatabaseAddRequest deserializeAddRequest(const std::shared_ptr &value, const Hash &hash, const std::shared_ptr encryptionKey); + void deserializeAddRequest(const std::shared_ptr &value, const Hash &hash, 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 &hash, const std::shared_ptr encryptionKey); private: diff --git a/include/DatabaseNode.hpp b/include/DatabaseNode.hpp new file mode 100644 index 0000000..3ca4be3 --- /dev/null +++ b/include/DatabaseNode.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "Hash.hpp" +#include + +namespace odhtdb +{ + class DatabaseNode + { + public: + DatabaseNode(const std::shared_ptr &_encryptionKey, const std::shared_ptr &_nodeHash) : + encryptionKey(_encryptionKey), + nodeHash(_nodeHash) + { + + } + + const std::shared_ptr getNodeEncryptionKey() const + { + return encryptionKey; + } + + const std::shared_ptr getRequestHash() const + { + return nodeHash; + } + private: + std::shared_ptr encryptionKey; + std::shared_ptr nodeHash; + }; +} diff --git a/include/DatabaseStorage.hpp b/include/DatabaseStorage.hpp index fd29050..ee4d2ad 100644 --- a/include/DatabaseStorage.hpp +++ b/include/DatabaseStorage.hpp @@ -1,5 +1,6 @@ #pragma once +#include "types.hpp" #include "Hash.hpp" #include "DataView.hpp" #include "Signature.hpp" @@ -65,6 +66,8 @@ namespace odhtdb void addToQuarantine(const Signature::PublicKey &creatorPublicKey, u64 timestamp, const u8 *data, usize dataSize); + void addUser(User *user, const Hash &hash); + // Returns nullptr if no storage with provided hash exists const DatabaseStorageObjectList* getStorage(const Hash &hash) const; @@ -73,10 +76,17 @@ namespace odhtdb // Returns nullptr if no user with public key exists const User* getUserByPublicKey(const Signature::PublicKey &userPublicKey) const; + + // Returns nullptr if a group with id @groupId doesn't exist + Group* getGroupById(uint8_t groupId[16]); + + // Update storage state (remove quarantine objects if they are too old, etc) + void update(); private: DatabaseStorageMap storageMap; DatabaseStorageQuarantineMap quarantineStorageMap; Signature::MapPublicKey userPublicKeyNodeMap; Signature::MapPublicKey publicKeyUserMap; + DataViewMap groupByIdMap; }; } diff --git a/include/Group.hpp b/include/Group.hpp index a8dcf83..315961d 100644 --- a/include/Group.hpp +++ b/include/Group.hpp @@ -1,5 +1,8 @@ #pragma once +#include "types.hpp" +#include "DataView.hpp" +#include "Permission.hpp" #include #include #include @@ -17,19 +20,26 @@ namespace odhtdb } }; + + class Group { + friend class User; public: - Group(const std::string &name); + Group(const std::string &name, uint8_t id[16], const Permission &permission); ~Group(); - void addUser(const User *user); - const std::string& getName() const; + DataView getId() const; + const Permission& getPermission() const; const std::vector& getUsers() const; + private: + void addUser(const User *user); private: std::string name; + uint8_t id[16]; + Permission permission; std::vector users; }; } diff --git a/include/LocalUser.hpp b/include/LocalUser.hpp index 04f483d..d60cb38 100644 --- a/include/LocalUser.hpp +++ b/include/LocalUser.hpp @@ -7,9 +7,9 @@ namespace odhtdb class LocalUser : public User { public: - static LocalUser* create(const Signature::KeyPair &keyPair, const std::string &name) + static LocalUser* create(const Signature::KeyPair &keyPair, const std::string &name, Group *group) { - return new LocalUser(keyPair, name); + return new LocalUser(keyPair, name, group); } const Signature::PublicKey& getPublicKey() const override @@ -22,7 +22,7 @@ namespace odhtdb return keyPair.getPrivateKey(); } private: - LocalUser(const Signature::KeyPair &_keyPair, const std::string &name) : User(name), keyPair(_keyPair) {} + LocalUser(const Signature::KeyPair &_keyPair, const std::string &name, Group *group) : User(name, group), keyPair(_keyPair) {} private: Signature::KeyPair keyPair; }; diff --git a/include/Permission.hpp b/include/Permission.hpp new file mode 100644 index 0000000..1ae2642 --- /dev/null +++ b/include/Permission.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "types.hpp" +#include +#include + +namespace odhtdb +{ + class PermissionDeniedException : public std::runtime_error + { + public: + PermissionDeniedException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + enum class PermissionType : u32 + { + ADD_DATA = (1 << 0), + ADD_USER_SAME_LEVEL = (1 << 1), + ADD_USER_LOWER_LEVEL = (1 << 2), + ADD_GROUP = (1 << 3), + REMOVE_GROUP = (1 << 4) + }; + + const PermissionType ALL_PERMISSION_TYPES = (PermissionType)0xFFFFFFFF; + + const u8 PERMISSION_LEVEL_ADMIN = 0; + const u8 PERMISSION_LEVEL_MODERATOR = 1; + const u8 PERMISSION_LEVEL_REGULAR_USER = 2; + + class Permission + { + public: + // @permissionLevel is hierarchical access right. A group can only modify a group that has higher @permissionLevel value + Permission(u8 permissionLevel, std::initializer_list permissions); + + u8 getPermissionLevel() const { return permissionLevel; } + u32 getPermissionFlags() const { return permissionFlags; } + bool getFlag(PermissionType permissionType) const; + private: + u8 permissionLevel; + u32 permissionFlags; + }; + + static const Permission ADMIN_PERMISSION(PERMISSION_LEVEL_ADMIN, { ALL_PERMISSION_TYPES }); + static const Permission REGULAR_USER_PERMISSION(PERMISSION_LEVEL_REGULAR_USER, { PermissionType::ADD_DATA }); +} diff --git a/include/RemoteUser.hpp b/include/RemoteUser.hpp index 770be61..181a4c4 100644 --- a/include/RemoteUser.hpp +++ b/include/RemoteUser.hpp @@ -7,9 +7,9 @@ namespace odhtdb class RemoteUser : public User { public: - static RemoteUser* create(const Signature::PublicKey &publicKey, const std::string &name) + static RemoteUser* create(const Signature::PublicKey &publicKey, const std::string &name, Group *group) { - return new RemoteUser(publicKey, name); + return new RemoteUser(publicKey, name, group); } const Signature::PublicKey& getPublicKey() const override @@ -17,7 +17,7 @@ namespace odhtdb return publicKey; } private: - RemoteUser(const Signature::PublicKey &_publicKey, const std::string &name) : User(name), publicKey(_publicKey){} + RemoteUser(const Signature::PublicKey &_publicKey, const std::string &name, Group *group) : User(name, group), publicKey(_publicKey){} private: Signature::PublicKey publicKey; }; diff --git a/include/User.hpp b/include/User.hpp index ab5872a..fb37876 100644 --- a/include/User.hpp +++ b/include/User.hpp @@ -3,9 +3,12 @@ #include "Signature.hpp" #include #include +#include namespace odhtdb { + class Group; + class UserNameTooLongException : public std::runtime_error { public: @@ -21,15 +24,15 @@ namespace odhtdb public: virtual ~User(){} + void addToGroup(Group *group); + const std::string& getName() const { return name; } + const std::vector& getGroups() const { return groups; } virtual const Signature::PublicKey& getPublicKey() const = 0; protected: - User(const std::string &_name) : name(_name) - { - if(name.size() > 255) - throw UserNameTooLongException(name); - } + User(const std::string &name, Group *group); private: std::string name; + std::vector groups; }; } -- cgit v1.2.3