diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 6ff854360..32bc8e547 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -301,14 +301,35 @@ public: const std::set& gxsIdMembers = std::set(), const std::set& localMembers = std::set() ) = 0; - /** - * @brief Edit own existing circle - * @jsonapi{development} - * @param[inout] cData Circle data with modifications, storage for data - * updatedad during the operation. - * @return false if something failed, true otherwhise - */ - virtual bool editCircle(RsGxsCircleGroup& cData) = 0; +// TODO. If so, remove the other editCircle that has the same name, otherwise jsonapi will crash +// +// /** +// * @brief Edit an existing circle +// * @jsonapi{development} +// * @param[in] circleId Optional storage to output created circle id +// * @param[in] circleName String containing cirlce name +// * @param[in] circleType Circle type +// * @param[in] restrictedId Optional id of a pre-existent circle that see the +// * created circle. Meaningful only if circleType == EXTERNAL, must be null +// * in all other cases. +// * @param[in] authorId Optional author of the circle. +// * @param[in] gxsIdMembers GXS ids of the members of the circle. +// * @param[in] localMembers PGP ids of the members if the circle. +// * @return false if something failed, true otherwhise +// */ +// virtual bool editCircle( const RsGxsCircleId& circleId, const std::string& circleName, RsGxsCircleType circleType, +// const RsGxsCircleId& restrictedId, +// const RsGxsId& authorId, const std::set& gxsIdMembers, +// const std::set& localMembers ) =0; + + /** + * @brief Edit own existing circle + * @jsonapi{development} + * @param[inout] cData Circle data with modifications, storage for data + * updatedad during the operation. + * @return false if something failed, true otherwhise + */ + virtual bool editCircle(RsGxsCircleGroup& cData) = 0; /** * @brief Get circle details. Memory cached diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index b1a3bc5e2..f1f39a792 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -194,96 +194,111 @@ bool p3GxsCircles::createCircle( { // 1 - Check consistency of the request data - if(circleName.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; - return false; - } - - switch(circleType) - { - case RsGxsCircleType::PUBLIC: - if(!restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId - << " must be null with RsGxsCircleType::PUBLIC" - << std::endl; - return false; - } - break; - case RsGxsCircleType::EXTERNAL: - if(restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId can't be null " - << "with RsGxsCircleType::EXTERNAL" << std::endl; - return false; - } - break; - case RsGxsCircleType::NODES_GROUP: - if(localMembers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " localMembers can't be empty " - << "with RsGxsCircleType::NODES_GROUP" << std::endl; - return false; - } - break; - case RsGxsCircleType::LOCAL: - break; - case RsGxsCircleType::EXT_SELF: - if(!restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId - << " must be null with RsGxsCircleType::EXT_SELF" - << std::endl; - return false; - } - if(gxsIdMembers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " gxsIdMembers can't be empty " - << "with RsGxsCircleType::EXT_SELF" << std::endl; - return false; - } - break; - case RsGxsCircleType::YOUR_EYES_ONLY: - break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Invalid circle type: " - << static_cast(circleType) << std::endl; - return false; - } + if(!checkCircleParamConsistency(circleName,circleType,restrictedId,authorId,gxsIdMembers,localMembers)) + { + RsErr() << __PRETTY_FUNCTION__ << " Circle parameters are inconsistent" << std::endl; + return false; + } // 2 - Create the actual request - RsGxsCircleGroup cData; - cData.mMeta.mGroupName = circleName; - cData.mMeta.mAuthorId = authorId; - cData.mMeta.mCircleType = static_cast(circleType); - cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - cData.mMeta.mCircleId = restrictedId; - cData.mLocalFriends = localMembers; - cData.mInvitedMembers = gxsIdMembers; + RsGxsCircleGroup cData; + cData.mMeta.mGroupName = circleName; + cData.mMeta.mAuthorId = authorId; + cData.mMeta.mCircleType = static_cast(circleType); + cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; + cData.mMeta.mCircleId = restrictedId; + cData.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ | GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; + cData.mLocalFriends = localMembers; + cData.mInvitedMembers = gxsIdMembers; + // 3 - Send it and wait, for a sync response. - uint32_t token; - createGroup(token, cData); + uint32_t token; + createGroup(token, cData); - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; - return false; - } + if(waitToken(token) != RsTokenService::COMPLETE) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; + return false; + } - if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting created" << " group data." << std::endl; - return false; - } + if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting created" << " group data." << std::endl; + return false; + } - circleId = static_cast(cData.mMeta.mGroupId); - return true; + circleId = static_cast(cData.mMeta.mGroupId); + return true; }; +bool p3GxsCircles::checkCircleParamConsistency( const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) const +{ + if(circleName.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; + return false; + } + + switch(circleType) + { + case RsGxsCircleType::PUBLIC: + if(!restrictedId.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId + << " must be null with RsGxsCircleType::PUBLIC" + << std::endl; + return false; + } + break; + case RsGxsCircleType::EXTERNAL: + if(restrictedId.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " restrictedId can't be null " + << "with RsGxsCircleType::EXTERNAL" << std::endl; + return false; + } + break; + case RsGxsCircleType::NODES_GROUP: + if(localMembers.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " localMembers can't be empty " + << "with RsGxsCircleType::NODES_GROUP" << std::endl; + return false; + } + break; + case RsGxsCircleType::LOCAL: + break; + case RsGxsCircleType::EXT_SELF: + if(!restrictedId.isNull()) + { + RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId + << " must be null with RsGxsCircleType::EXT_SELF" + << std::endl; + return false; + } + if(gxsIdMembers.empty()) + { + RsErr() << __PRETTY_FUNCTION__ << " gxsIdMembers can't be empty " + << "with RsGxsCircleType::EXT_SELF" << std::endl; + return false; + } + break; + case RsGxsCircleType::YOUR_EYES_ONLY: + break; + default: + RsErr() << __PRETTY_FUNCTION__ << " Invalid circle type: " + << static_cast(circleType) << std::endl; + return false; + } + return true; +} + bool p3GxsCircles::editCircle(RsGxsCircleGroup& cData) { uint32_t token; @@ -306,6 +321,52 @@ bool p3GxsCircles::editCircle(RsGxsCircleGroup& cData) return true; } +bool p3GxsCircles::editCircle(const RsGxsCircleId &circleId, const std::string& circleName, RsGxsCircleType circleType, const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) +{ + // 1 - Check consistency of the request data + + if(!checkCircleParamConsistency(circleName,circleType,restrictedId,authorId,gxsIdMembers,localMembers)) + { + RsErr() << __PRETTY_FUNCTION__ << " Circle data is not consistent." << std::endl; + return false; + } + + // 2 - Create the actual request + + RsGxsCircleGroup cData; + cData.mMeta.mGroupId = RsGxsGroupId(circleId); + cData.mMeta.mGroupName = circleName; + cData.mMeta.mAuthorId = authorId; + cData.mMeta.mCircleType = static_cast(circleType); + cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; + cData.mMeta.mCircleId = restrictedId; + cData.mLocalFriends = localMembers; + cData.mInvitedMembers = gxsIdMembers; + + // 3 - Send it and wait, for a sync response. + + uint32_t token; + updateGroup(token, cData); + + if(waitToken(token) != RsTokenService::COMPLETE) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." + << std::endl; + return false; + } + + if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated" + << " group data." << std::endl; + return false; + } + + return true; +}; + bool p3GxsCircles::getCirclesSummaries(std::list& circles) { uint32_t token; diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index a98e09184..e71e26ed0 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -227,7 +227,12 @@ public: const std::set& localMembers = std::set() ) override; - /// @see RsGxsCircles + bool editCircle( const RsGxsCircleId& circleId,const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) ; + + /// @see RsGxsCircles bool editCircle(RsGxsCircleGroup& cData) override; /// @see RsGxsCircles @@ -303,6 +308,10 @@ public: virtual void service_tick() override; protected: + bool checkCircleParamConsistency( const std::string& circleName, RsGxsCircleType circleType, + const RsGxsCircleId& restrictedId, + const RsGxsId& authorId, const std::set& gxsIdMembers, + const std::set& localMembers ) const ; // overloads p3Config virtual bool saveList(bool &cleanup, std::list&saveList) override; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d34f406a6..d35d3afe0 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1139,6 +1139,7 @@ bool p3IdService::updateIdentity( const RsGxsId& id, const std::string& name, co goto LabelUpdateIdentityCleanup; } } + mKeyCache.erase(id); if(!updateGroup(token, group)) { @@ -1154,6 +1155,9 @@ bool p3IdService::updateIdentity( const RsGxsId& id, const std::string& name, co goto LabelUpdateIdentityCleanup; } + // clean the Identity cache as well + cache_request_load(id); + LabelUpdateIdentityCleanup: if(!pseudonimous && !pgpPassword.empty()) rsNotify->clearPgpPassphrase(); diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp index d0640e4ea..2b9d3b804 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp @@ -449,7 +449,9 @@ void CreateCircleDialog::createCircle() case GxsIdChooser::KnowId: case GxsIdChooser::UnKnowId: circle.mMeta.mAuthorId = authorId; -#ifdef DEBUG_CREATE_CIRCLE_DIALOG + circle.mMeta.mAuthenFlags = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; + +#ifdef DEBUG_CREATE_CIRCLE_DIALOG std::cerr << "CreateCircleDialog::createCircle() AuthorId: " << authorId; std::cerr << std::endl; #endif @@ -457,6 +459,8 @@ void CreateCircleDialog::createCircle() break; case GxsIdChooser::NoId: case GxsIdChooser::None: + circle.mMeta.mAuthorId.clear(); + circle.mMeta.mAuthenFlags = 0; default: ; #ifdef DEBUG_CREATE_CIRCLE_DIALOG std::cerr << "CreateCircleDialog::createCircle() No AuthorId Chosen!"; diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 016a8cb27..e8c39e75d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -408,9 +408,7 @@ IdDialog::IdDialog(QWidget *parent) connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool))); updateIdTimer.setSingleShot(true); - updateCircleTimer.setSingleShot(true); connect(&updateIdTimer, SIGNAL(timeout()), this, SLOT(updateIdList())); - connect(&updateCircleTimer, SIGNAL(timeout()), this, SLOT(updateCircles())); } void IdDialog::handleEvent_main_thread(std::shared_ptr event) @@ -429,7 +427,10 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsIdentityEventCode::UPDATED_IDENTITY: if (isVisible()) { - updateIdTimer.start(5000); + if(rsIdentity->isOwnId(RsGxsId(e->mIdentityId))) + updateIdList(); + else + updateIdTimer.start(3000); // use a timer for events not generated by local changes } else needUpdateIdsOnNextShow = true; @@ -460,9 +461,7 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsCircleEventCode::CACHE_DATA_UPDATED: if (isVisible()) - { - updateCircleTimer.start(5000); - } + updateCircles(); else needUpdateCirclesOnNextShow = true; default: diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 709fd3692..4e465fc5d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -154,7 +154,6 @@ private: RsEventsHandlerId_t mEventHandlerId_circles; QTimer updateIdTimer; - QTimer updateCircleTimer; bool needUpdateIdsOnNextShow; bool needUpdateCirclesOnNextShow; diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index 2b9dcab67..442055f3b 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -1213,18 +1213,6 @@ NewFriendList QTreeView#peerTreeWidget { font-size: 12pt; } -NewFriendList QTreeView::branch:has-children:!has-siblings:closed, -NewFriendList QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(:/images/arrow-right.png); -} - -NewFriendList QTreeView::branch:open:has-children:!has-siblings, -NewFriendList QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(:/images/arrow-down.png); -} - WikiEditDialog QPushButton#pushButton_History { font: bold; font-size: 15px;