added new events for circles

This commit is contained in:
csoler 2019-12-12 00:00:51 +01:00
parent 27793627e3
commit eef5a5a8ef
No known key found for this signature in database
GPG key ID: 7BCA522266C0804C
10 changed files with 289 additions and 120 deletions

View file

@ -855,12 +855,8 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci)
{
#ifdef RS_DIRECT_CHAT
/* notify public chat message */
RsServer::notify()->AddPopupMessage(
RS_POPUP_GROUPCHAT,
ci->PeerId().toStdString(), "", message );
RsServer::notify()->AddFeedItem(
RS_FEED_ITEM_CHAT_NEW,
ci->PeerId().toStdString(), message, "" );
RsServer::notify()->AddPopupMessage( RS_POPUP_GROUPCHAT, ci->PeerId().toStdString(), "", message );
//RsServer::notify()->AddFeedItem( RS_FEED_ITEM_CHAT_NEW, ci->PeerId().toStdString(), message, "" );
#else // def RS_DIRECT_CHAT
/* Ignore deprecated direct node broadcast chat messages */
return false;

View file

@ -1262,8 +1262,10 @@ int pqissl::accept_locked( SSL *ssl, int fd,
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if(rsBanList && !rsBanList->isAddressAccepted(
foreign_addr, checking_flags, check_result ))
if( RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) != PeerId())
std::cerr << "(EE) pqissl::accept_locked(): PeerId() is " << PeerId() << " but certificate ID is " << RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) << std::endl;
if(rsBanList && !rsBanList->isAddressAccepted( foreign_addr, checking_flags, check_result ))
{
RsErr() << __PRETTY_FUNCTION__
<< " Refusing incoming SSL connection from blacklisted "
@ -1273,11 +1275,19 @@ int pqissl::accept_locked( SSL *ssl, int fd,
<< std::endl;
print_stacktrace();
RsServer::notify()->AddFeedItem(
RS_FEED_ITEM_SEC_IP_BLACKLISTED,
PeerId().toStdString(),
sockaddr_storage_iptostring(foreign_addr), "", "",
check_result);
if(rsEvents)
{
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
X509 *x509 = SSL_get_peer_certificate(ssl) ;
ev->mSslId = RsX509Cert::getCertSslId(*x509);
ev->mLocator = RsUrl(foreign_addr);
ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::IP_IS_BLACKLISTED;
rsEvents->postEvent(ev);
}
reset_locked();
return failure;
}

View file

@ -70,6 +70,9 @@ enum class RsEventType : uint32_t
/// @see RsMailStatusEvent
MAIL_STATUS_CHANGE = 7,
/// @see RsGxsCircleEvent
GXS_CIRCLES = 8,
MAX /// Used to detect invalid event type passed
};

View file

@ -123,7 +123,7 @@ struct RsGxsCircleDetails : RsSerializable
{
RsGxsCircleDetails() :
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
mAmIAllowed(false) {}
mAmIAllowed(false),mAmIAdmin(false) {}
~RsGxsCircleDetails() override;
RsGxsCircleId mCircleId;
@ -136,6 +136,9 @@ struct RsGxsCircleDetails : RsSerializable
* list & subscribed list). */
bool mAmIAllowed;
/// true when we're an administrator of the circle group, meaning that we can add/remove members from the invitee list.
bool mAmIAdmin;
/// This crosses admin list and subscribed list
std::set<RsGxsId> mAllowedGxsIds;
std::set<RsPgpId> mAllowedNodes;
@ -152,12 +155,41 @@ struct RsGxsCircleDetails : RsSerializable
RS_SERIAL_PROCESS(mCircleType);
RS_SERIAL_PROCESS(mRestrictedCircleId);
RS_SERIAL_PROCESS(mAmIAllowed);
RS_SERIAL_PROCESS(mAmIAdmin);
RS_SERIAL_PROCESS(mAllowedGxsIds);
RS_SERIAL_PROCESS(mAllowedNodes);
RS_SERIAL_PROCESS(mSubscriptionFlags);
}
};
struct RsGxsCircleEvent: RsEvent
{
RsGxsCircleEvent()
: RsEvent(RsEventType::GXS_CIRCLES), mCircleEventType(UNKNOWN) {}
enum CircleEventType: uint8_t {
UNKNOWN = 0x00,
CIRCLE_MEMBERSHIP_REQUEST = 0x01, // mCircleId contains the circle id and mGxsId is the id requesting membership
CIRCLE_MEMBERSHIP_INVITE = 0x02, // mCircleId is the circle that invites me, and mGxsId is my own Id that is invited
CIRCLE_MEMBERSHIP_LEAVE = 0x03, // mCircleId contains the circle id and mGxsId is the id dropping membership
CIRCLE_MEMBERSHIP_JOIN = 0x04, // mCircleId contains the circle id and mGxsId is the id of the new member
CIRCLE_MEMBERSHIP_REVOQUED= 0x05, // mCircleId contains the circle id and mGxsId is the id that was revoqued by admin
};
CircleEventType mCircleEventType;
RsGxsCircleId mCircleId;
RsGxsId mGxsId;
///* @see RsEvent @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mCircleEventType);
RS_SERIAL_PROCESS(mCircleId);
RS_SERIAL_PROCESS(mGxsId);
}
};
class RsGxsCircles: public RsGxsIfaceHelper
{
public:
@ -243,6 +275,17 @@ public:
*/
virtual bool getCircleRequests( const RsGxsGroupId& circleId,
std::vector<RsGxsCircleMsg>& requests ) = 0;
/**
* @brief Get specific circle request
* @jsonapi{development}
* @param[in] circleId id of the circle of which the requests are requested
* @param[in] msgId id of the request
* @param[out] msg storage for the circle request
* @return false if something failed, true otherwhise
*/
virtual bool getCircleRequest(const RsGxsGroupId& circleId,
const RsGxsMessageId& msgId,
RsGxsCircleMsg& msg) =0;
/**
* @brief Invite identities to circle

View file

@ -115,8 +115,11 @@ const uint32_t RS_FEED_ITEM_CHAT_NEW = RS_FEED_TYPE_CHAT | 0x0001;
const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001;
const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED = RS_FEED_TYPE_CIRCLE | 0x0005;
const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001;

View file

@ -305,6 +305,32 @@ bool p3GxsCircles::getCircleRequests( const RsGxsGroupId& circleId,
return getMsgData(token, requests);
}
bool p3GxsCircles::getCircleRequest(const RsGxsGroupId& circleId,const RsGxsMessageId& msgId,RsGxsCircleMsg& msg)
{
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
std::set<RsGxsMessageId> contentsIds;
contentsIds.insert(msgId);
GxsMsgReq msgIds;
msgIds[circleId] = contentsIds;
uint32_t token;
if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE )
return false;
std::vector<RsGxsCircleMsg> msgs;
if(getMsgData(token, msgs) && msgs.size() == 1)
{
msg = msgs.front();
return true;
}
else
return false;
}
bool p3GxsCircles::inviteIdsToCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId )
{
@ -372,6 +398,7 @@ void p3GxsCircles::service_tick()
return;
}
void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
#ifdef DEBUG_CIRCLES
@ -397,13 +424,35 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
#ifdef DEBUG_CIRCLES
std::cerr << " Msgs for Group: " << mit->first << std::endl;
#endif
force_cache_reload(RsGxsCircleId(mit->first));
RsGxsCircleId circle_id(mit->first);
if (notify && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
force_cache_reload(circle_id);
RsGxsCircleDetails details;
getCircleDetails(circle_id,details);
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
for (auto msgIdIt(mit->second.begin()), end(mit->second.end()); msgIdIt != end; ++msgIdIt)
{
const RsGxsMessageId& msgId = *msgIdIt;
notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_MEMB_REQ,RsGxsCircleId(mit->first).toStdString(),msgId.toStdString());
// @Gio: should this be async?
RsGxsCircleMsg msg;
getCircleRequest(RsGxsGroupId(circle_id),*msgIdIt,msg);
// notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_MEMB_REQ,RsGxsCircleId(mit->first).toStdString(),msgId.toStdString());
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleId = circle_id;
ev->mGxsId = msg.mMeta.mAuthorId;
if (msg.stuff == "SUBSCRIPTION_REQUEST_UNSUBSCRIBE")
ev->mCircleEventType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_LEAVE;
else if(details.mAllowedGxsIds.find(msg.mMeta.mAuthorId) != details.mAllowedGxsIds.end())
ev->mCircleEventType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_JOIN;
else
ev->mCircleEventType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_REQUEST;
rsEvents->sendEvent(ev);
}
}
@ -436,15 +485,60 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
if(groupChange)
{
std::list<RsGxsId> own_ids;
rsIdentity->getOwnIds(own_ids);
for(std::list<RsGxsGroupId>::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl;
#endif
force_cache_reload(RsGxsCircleId(*git)) ;
if (notify && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_INVIT_REC,RsGxsCircleId(*git).toStdString(),"");
}
#ifdef TODO
// This code will not work: we would like to detect changes in the circle data that reflects the fact that one of the
// owned GXS ids is invited. But there's no way to compare the old circle data to the new if cache has to be updated.
// For this we need to add the old metadata and group data in the RsGxsGroupChange structure and account for it.
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
{
RsGxsCircleId circle_id(*git);
force_cache_reload(circle_id);
RsGxsCircleDetails details;
getCircleDetails(circle_id,details);
// We check that the change corresponds to one of our own ids. Since we do not know what the change is, we notify
// for whatever is different from what is currently known. Other ids, that get invited only trigger a notification when the
// ID also accepts the invitation, so it becomes a member of the circle.
for(auto own_id: own_ids)
{
auto it = details.mSubscriptionFlags.find(own_id);
if(it == details.mSubscriptionFlags.end())
continue;
bool invited ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
bool subscrb ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
if(std::find(details.mAllowedGxsIds.begin(),details.mAllowedGxsIds.end(),id) != details.mAllowedGxsIds.end() && !me_in_circle)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_INVITE;
ev->mCircleId = circle_id;
ev->mGxsId = ;
rsEvents->sendEvent(ev);
}
}
//notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_INVIT_REC,RsGxsCircleId(*git).toStdString(),"");
}
#endif
}
}
}
RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements
@ -479,6 +573,7 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
details.mSubscriptionFlags.clear();
details.mAllowedGxsIds.clear();
details.mAmIAllowed = false ;
details.mAmIAdmin = bool(data.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
for(std::map<RsGxsId,RsGxsCircleMembershipStatus>::const_iterator it(data.mMembershipStatus.begin());it!=data.mMembershipStatus.end();++it)
{
@ -789,7 +884,7 @@ RsGxsCircleCache::RsGxsCircleCache()
mUpdateTime = 0;
mGroupStatus = 0;
mGroupSubscribeFlags = 0;
mLastUpdatedMembershipTS = 0 ;
mLastUpdatedMembershipTS = 0 ;
return;
}

View file

@ -207,6 +207,11 @@ virtual RsServiceInfo getServiceInfo();
bool inviteIdsToCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId ) override;
/// @see RsGxsCircles
bool getCircleRequest(const RsGxsGroupId& circleId,
const RsGxsMessageId& msgId,
RsGxsCircleMsg& msg) override;
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details);
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds);