diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index f27633af2..a334d090f 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -663,7 +663,7 @@ int RsDataService::updateGroup(std::map &grp) if(!validSize(grpPtr)) continue; std::string grpFile = mServiceDir + "/" + grpPtr->grpId; - std::fstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::app | std::ios::out); + std::fstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::app | std::ios::trunc); ostrm.seekg(0, std::ios::end); // go to end to append uint32_t offset = ostrm.tellg(); // get fill offset diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index 666aa8e98..53f9c4fe8 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -111,7 +111,7 @@ public: * @param grpIds all grpids in store is inserted into this vector * @return error code */ - int RsDataService::retrieveGroupIds(std::vector &grpIds); + int retrieveGroupIds(std::vector &grpIds); /*! * @return the cache size set for this RsGeneralDataService in bytes diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 9a82d3687..c2ba4d8ac 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -167,14 +167,14 @@ public: * @param grpIds ids of groups to be removed * @return error code */ - virtual int removeGroups(std::vector& grpIds) = 0; + virtual int removeGroups(const std::vector& grpIds) = 0; /*! * Retrieves all group ids in store * @param grpIds all grpids in store is inserted into this vector * @return error code */ - virtual int retrieveGroupIds(const std::vector& grpIds) = 0; + virtual int retrieveGroupIds(std::vector& grpIds) = 0; /*! * @return the cache size set for this RsGeneralDataService in bytes @@ -193,13 +193,6 @@ public: */ virtual int storeMessage(std::map& msgs) = 0; - /*! - * Stores a list of signed messages into data store - * @param msg map of message and decoded meta data information - * @return error code - */ - virtual int storeMessage(std::map& msgs) = 0; - /*! * Stores a list of groups in data store * @param grp map of group and decoded meta data diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index eac88e3b0..d67d36c00 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1369,6 +1369,20 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem) } + +void RsGenExchange::updateGroup(uint32_t& token, RsGxsGrpItem* grpItem) +{ + RsStackMutex stack(mGenMtx); + token = mDataAccess->generatePublicToken(); + mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, token)); + +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::updateGroup() token: " << token; + std::cerr << std::endl; +#endif +} + + void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) { RsStackMutex stack(mGenMtx); @@ -1785,6 +1799,76 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI #define PENDING_SIGN_TIMEOUT 10 // 5 seconds + +void RsGenExchange::processGroupUpdatePublish() +{ + + RsStackMutex stack(mGenMtx); + + // get keys for group update publish + + // first build meta request map for groups to be updated + std::map grpMeta; + std::vector::iterator vit = mGroupUpdatePublish.begin(); + + for(; vit != mGroupUpdatePublish.end(); vit++) + { + GroupUpdatePublish& gup = *vit; + const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId; + grpMeta.insert(std::make_pair(groupId, (RsGxsGrpMetaData*)(NULL))); + } + + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + // now + vit = mGroupUpdatePublish.begin(); + for(; vit != mGroupUpdatePublish.end(); vit++) + { + GroupUpdatePublish& gup = *vit; + const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId; + RsGxsGrpMetaData* meta = grpMeta[groupId]; + + GxsGrpPendingSign ggps(ggps.mItem, ggps.mToken); + + bool split = splitKeys(meta->keys, ggps.mPrivateKeys, ggps.mPublicKeys); + + if(split) + { + ggps.mHaveKeys = true; + ggps.mStartTS = time(NULL); + ggps.mLastAttemptTS = 0; + mGrpsToPublish.push_back(ggps); + }else + { + delete gup.grpItem; + mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); + } + + } + + mGroupUpdatePublish.clear(); +} + +bool RsGenExchange::splitKeys(const RsTlvSecurityKeySet& keySet, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet) +{ + + typedef std::map keyMap; + const keyMap& allKeys = keySet.keys; + keyMap::const_iterator cit = allKeys.begin(); + + for(; cit != allKeys.end(); cit++) + { + const RsTlvSecurityKey& key = cit->second; + if(key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY) + publicKeySet.keys.insert(std::make_pair(key.keyId, key)); + else if(key.keyFlags & RSTLV_KEY_TYPE_FULL) + privateKeySet.keys.insert(std::make_pair(key.keyId, key)); + } + + // user must have both private and public parts of publish and admin keys + return (privateKeySet.keys.size() == 2) && (publicKeySet.keys.size() == 2); +} + void RsGenExchange::publishGrps() { RsStackMutex stack(mGenMtx); @@ -1906,7 +1990,11 @@ void RsGenExchange::publishGrps() { grpId = grp->grpId; computeHash(grp->grp, grp->metaData->mHash); - mDataAccess->addGroupData(grp); + + if(ggps.mIsUpdate) + mDataAccess->updateGroupData(grp); + else + mDataAccess->addGroupData(grp); } else { @@ -2195,7 +2283,8 @@ void RsGenExchange::processRecvdGroups() RsStackMutex stack(mGenMtx); NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin(); - std::vector existingGrpIds, grpIds; + std::vector existingGrpIds; + std::list grpIds; std::map grps; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index dc6a5026c..b7dc6e966 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -71,13 +71,14 @@ class GxsGrpPendingSign public: GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token), - mItem(item), mHaveKeys(false) + mItem(item), mHaveKeys(false), mIsUpdate(false) {} time_t mLastAttemptTS, mStartTS; uint32_t mToken; RsGxsGrpItem* mItem; bool mHaveKeys; // mKeys->first == true if key present + bool mIsUpdate; RsTlvSecurityKeySet mPrivateKeys; RsTlvSecurityKeySet mPublicKeys; }; @@ -516,7 +517,6 @@ protected: /*! * Enables publication of a group item \n - * If the item exists already this is simply versioned \n * This will induce a related change message \n * Ownership of item passes to this rsgenexchange \n * @param token @@ -524,6 +524,16 @@ protected: */ void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); + + /*! + * Updates an existing group item \n + * This will induce a related change message \n + * Ownership of item passes to this rsgenexchange \n + * @param token + * @param grpItem + */ + void updateGroup(uint32_t& token, RsGxsGrpItem* grpItem); + public: /*! * Enables publication of a message item \n @@ -629,6 +639,8 @@ private: void publishGrps(); + void processGroupUpdatePublish(); + void publishMsgs(); /*! @@ -750,6 +762,8 @@ private: */ bool updateValid(RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const; + bool splitKeys(const RsTlvSecurityKeySet& keySet, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet); + private: RsMutex mGenMtx; @@ -815,7 +829,10 @@ private: private: - std::vector mGroupUpdates; + std::vector mGroupUpdates, mPeersGroupUpdate; + + std::vector mGroupUpdatePublish; + }; #endif // RSGENEXCHANGE_H diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 5399c746e..39c428b37 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1487,7 +1487,14 @@ bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) { return mDataStore->storeGroup(grpM); } +bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) { + RsStackMutex stack(mDataMutex); + + std::map grpM; + grpM.insert(std::make_pair(grp, grp->metaData)); + return mDataStore->updateGroup(grpM); +} bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) { diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index de5258569..3b0aa8113 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -126,14 +126,21 @@ public: public: /*! - * This adds a groups to the gxs data base, this is a blocking call - * Responsibility for grp still lies with callee \n + * This adds a groups to the gxs data base, this is a blocking call \n * If function returns successfully DataAccess can be queried for grp * @param grp the group to add, responsibility grp passed lies with callee * @return false if group cound not be added */ bool addGroupData(RsNxsGrp* grp); + /*! + * This updates a groups in the gxs data base, this is a blocking call \n + * If function returns successfully DataAccess can be queried for grp + * @param grp the group to add, responsibility grp passed lies with callee + * @return false if group cound not be added + */ + bool updateGroupData(RsNxsGrp* grp); + /*! * This adds a group to the gxs data base, this is a blocking call \n * Responsibility for msg still lies with callee \n