bool Annotations::setAnnotation(const Jid &AStreamJid, const Jid &AContactJid, const QString &ANote) { if (isEnabled(AStreamJid)) { if (!ANote.isEmpty()) { Annotation &item = FAnnotations[AStreamJid][AContactJid.bare()]; item.modified = DateTime(QDateTime::currentDateTime()); if (!item.created.isValid()) item.created = item.modified; item.note = ANote; } else { FAnnotations[AStreamJid].remove(AContactJid.bare()); } updateDataHolder(AStreamJid,QList<Jid>()<<AContactJid); emit annotationModified(AStreamJid,AContactJid); FSavePendingStreams += AStreamJid; FSaveTimer.start(); return true; } else { LOG_STRM_WARNING(AStreamJid,QString("Failed to set annotation to=%1: Annotations is not enabled").arg(AContactJid.bare())); } return false; }
bool Roster::stanzaReadWrite(int AHandlerId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { if (AHandlerId == FSHIRosterPush) { if (isOpen() && AStanza.isFromServer()) { AAccept = true; LOG_STRM_DEBUG(streamJid(),"Roster items push received"); processItemsElement(AStanza.firstElement("query",NS_JABBER_ROSTER),false); Stanza result = FStanzaProcessor->makeReplyResult(AStanza); FStanzaProcessor->sendStanzaOut(AStreamJid,result); } else if (!isOpen()) { REPORT_ERROR("Failed to process roster items push: Roster is closed"); } else if (!AStanza.isFromServer()) { REPORT_ERROR("Failed to process roster items push: Invalid stanza sender"); } } else if (AHandlerId == FSHISubscription) { Jid contactJid = AStanza.from(); QString status = AStanza.firstElement("status").text(); if (AStanza.type() == SUBSCRIPTION_SUBSCRIBE) { AAccept = true; FSubscriptionRequests += contactJid.bare(); LOG_STRM_INFO(streamJid(),QString("Subscribe presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Subscribe,status); } else if (AStanza.type() == SUBSCRIPTION_SUBSCRIBED) { AAccept = true; LOG_STRM_INFO(streamJid(),QString("Subscribed presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Subscribed,status); } else if (AStanza.type() == SUBSCRIPTION_UNSUBSCRIBE) { AAccept = true; FSubscriptionRequests -= contactJid.bare(); LOG_STRM_INFO(streamJid(),QString("Unsubscribe presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Unsubscribe,status); } else if (AStanza.type() == SUBSCRIPTION_UNSUBSCRIBED) { AAccept = true; LOG_STRM_INFO(streamJid(),QString("Unsubscribed presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Unsubscribed,status); } } return false; }
QString JIDUtil::accountToString(const Jid& j, bool withResource) { QString s = j.node(); // if (!defaultDomain().isEmpty()) { // return (withResource && !j.resource().isEmpty() ? j.node() + "/" + j.resource() : j.node()); // } // else { return (withResource ? j.full() : j.bare()); //} }
bool Stanza::isFromServer() const { if (!to().isEmpty()) { Jid toJid = to(); Jid fromJid = from(); return fromJid.isEmpty() || fromJid==toJid || fromJid==toJid.bare() || fromJid==toJid.domain(); } return false; }
void AppServer::commandReceived(const Jid& from, const std::string& id, const std::string& action, const std::string& node, const XData& payload) { if(action != "execute") { sendCommandError(from, id, node, action, "modify", "bad-request", "bad-action"); return; } if(node == "list-push-registrations") { XData xdata {"result"}; { std::lock_guard<std::mutex> lk {mRegsMutex}; for(const auto& p : mRegs) { XData::Item item; if(p.second.getUser().bare() == from.bare()) { std::string deviceName {p.second.getDeviceName()}; if(not deviceName.empty()) { item.addField({"", "device-name", {deviceName}}); } item.addField({"", "node", {p.first}}); } xdata.addItem(item); } } sendCommandCompleted(from, id, node, xdata); } else if(node == "unregister-push") { deleteRegistrations(from, id, payload); } else { addRegistration(from, id, node, payload); } }
void JT_SapoDebug::getDebuggerStatus(const Jid &toJID) { QDomElement iq = doc()->createElement("iq"); QDomElement query = doc()->createElement("query"); iq.setAttribute("id", id()); iq.setAttribute("type", "get"); iq.setAttribute("to", toJID.bare()); iq.appendChild(query); query.setAttribute("xmlns", "sapo:debug"); query.setAttribute("version", "1"); _iq = iq; _toJID = toJID; }
void ClientInfo::showClientInfo(const Jid &AStreamJid, const Jid &AContactJid, int AInfoTypes) { if (AStreamJid.isValid() && AContactJid.isValid() && AInfoTypes>0) { ClientInfoDialog *dialog = FClientInfoDialogs.value(AContactJid,NULL); if (!dialog) { QString contactName = AContactJid.uNode(); if (FDiscovery!=NULL && FDiscovery->discoInfo(AStreamJid,AContactJid.bare()).identity.value(0).category=="conference") contactName = AContactJid.resource(); if (contactName.isEmpty()) contactName = FDiscovery!=NULL ? FDiscovery->discoInfo(AStreamJid,AContactJid).identity.value(0).name : AContactJid.domain(); if (FRosterManager) { IRoster *roster = FRosterManager->findRoster(AStreamJid); if (roster) { IRosterItem ritem = roster->findItem(AContactJid); if (!ritem.name.isEmpty()) contactName = ritem.name; } } dialog = new ClientInfoDialog(this,AStreamJid,AContactJid,!contactName.isEmpty() ? contactName : AContactJid.uFull(),AInfoTypes); connect(dialog,SIGNAL(clientInfoDialogClosed(const Jid &)),SLOT(onClientInfoDialogClosed(const Jid &))); FClientInfoDialogs.insert(AContactJid,dialog); dialog->show(); } else { dialog->setInfoTypes(dialog->infoTypes() | AInfoTypes); WidgetManager::showActivateRaiseWindow(dialog); } } }
std::size_t AppServer::makeDeviceHash(const Jid& user, const std::string& deviceId) { std::string concat {user.bare() + deviceId}; return std::hash<std::string> {} (concat); }
void AppServer::deleteRegistrations(const Jid& user, const std::string& stanzaId, const XData& payload) { XData xdata {"result"}; std::vector<NodeIdT> nodes { payload.getField("nodes", "list-multi").values }; if(not nodes.empty()) { std::vector<NodeIdT> deletedNodes; for(auto it = nodes.begin(); it != nodes.end(); ++it) { bool deleted { deleteRegistration( *it, [&user](const Registration& r) {return r.getUser().bare() == user.bare();} ) }; if(deleted) { deletedNodes.push_back(*it); } } if(not deletedNodes.empty()) { xdata.addField({"list-multi", "nodes", deletedNodes}); } } else { std::string deviceId {payload.getField("device-id").singleValue()}; if(deviceId.empty()) { deviceId = user.getResource(); } if(deviceId.empty()) { sendCommandError(user, stanzaId, "execute", "modify", "bad-request", "bad-payload"); return; } auto pred = [&user, &deviceId](const std::pair<NodeIdT, Registration>& p) { return p.second.getUser().bare() == user.bare() and p.second.getDeviceId() == deviceId; }; { std::lock_guard<std::mutex> lk {mRegsMutex}; auto result = std::find_if(mRegs.begin(), mRegs.end(), pred); if(result == mRegs.end()) { sendCommandError(user, stanzaId, "execute", "modify", "bad-request", "bad-payload"); return; } deletePubsubNode(makeRandomString(), result->first); mRegs.erase(result); } } sendCommandCompleted(user, stanzaId, "unregister-push", xdata); }
void AppServer::addRegistration(const Jid& user, const std::string& stanzaId, const std::string& node, const XData& payload) { using Action = typename PendingReg::Action; std::string deviceId {payload.getField("device-id").singleValue()}; std::string deviceName {payload.getField("device-name").singleValue()}; std::string token {payload.getField("token").singleValue()}; std::string appId {payload.getField("application-id").singleValue()}; if(deviceId.empty()) { deviceId = user.getResource(); } bool payloadOk; Backend::Type backendType; if(node == "register-push-apns") { payloadOk = not (deviceId.empty() or token.empty()); backendType = Backend::Type::Apns; } else if(node == "register-push-gcm") { payloadOk = not (deviceId.empty() or token.empty()); backendType = Backend::Type::Gcm; } else if(node == "register-push-mozilla") { payloadOk = not (deviceId.empty() or token.empty()); backendType = Backend::Type::Mozilla; } else if(node == "register-push-ubuntu") { payloadOk = not (deviceId.empty() or token.empty() or appId.empty()); backendType = Backend::Type::Ubuntu; } else if(node == "register-push-wns") { payloadOk = not (deviceId.empty() or token.empty()); backendType = Backend::Type::Wns; } else { sendCommandError(user, stanzaId, node, "execute", "modify", "bad-request", "malformed-action"); return; } if(not payloadOk) { sendCommandError(user, stanzaId, node, "execute", "modify", "bad-request", "bad-payload"); return; } Backend::IdT backendId {Backend::makeBackendId(backendType, getJid())}; if(mBackends.find(backendId) == mBackends.cend()) { sendCommandError(user, stanzaId, node, "execute", "modify", "item-not-found"); return; } std::string secret {makeRandomString(32)}; Registration reg { user, deviceId, deviceName, token, appId, backendId, std::time(nullptr) }; // DEBUG: std::cout << "DEBUG: adding registration:" << std::endl << "user: "******"deviceId: " << reg.getDeviceId() << std::endl << "deviceName: " << reg.getDeviceName() << std::endl << "token: " << reg.getToken() << std::endl << "appId: " << reg.getAppId() << std::endl << "backendId: " << reg.getBackendId() << std::endl << "timestmap: " << reg.getTimestamp() << std::endl; auto regPred = [&user, &deviceId](const std::pair<NodeIdT, Registration>& p) { return p.second.getUser().bare() == user.bare() and p.second.getDeviceId() == deviceId; }; { std::lock_guard<std::mutex> lk {mRegsMutex}; auto regResult = std::find_if(mRegs.begin(), mRegs.end(), regPred); if(regResult != mRegs.end()) { deletePubsubNode(makeRandomString(), regResult->first); mRegs.erase(regResult); } } auto pendingPred = [&user, &deviceId](const std::pair<StanzaIdT, PendingReg>& p) { return p.second.getRegistration().getUser().bare() == user.bare() and p.second.getRegistration().getDeviceId() == deviceId; }; auto pendingResult = std::find_if(mPendingRegs.begin(), mPendingRegs.end(), pendingPred); if(pendingResult != mPendingRegs.end()) { deletePubsubNode(makeRandomString(), pendingResult->first); mPendingRegs.erase(pendingResult); } std::string newNode {makeRandomString()}; std::string createNodeId {makeRandomString()}; XData nodeConfig { "submit", { {"hidden", "FORM_TYPE", {"http://jabber.org/protocol/pubsub#node_config"}}, {"", "pubsub#secret", {secret}} } }; mPendingRegs.insert({newNode, PendingReg {secret, stanzaId, reg}}); mPendingActions.insert({createNodeId, {Action::CreateNode, newNode}}); createPubsubNode(createNodeId, newNode, nodeConfig); }
void PEPManager::get(const Jid& jid, const QString& node, const QString& id) { PEPGetTask* g = new PEPGetTask(client_->rootTask(),jid.bare(),node,id); connect(g, SIGNAL(finished()), SLOT(getFinished())); g->go(true); }
void Gateways::resolveNickName(const Jid &AStreamJid, const Jid &AContactJid) { IRoster *roster = FRosterPlugin!=NULL ? FRosterPlugin->findRoster(AStreamJid) : NULL; IRosterItem ritem = roster!=NULL ? roster->rosterItem(AContactJid) : IRosterItem(); if (ritem.isValid && roster->isOpen()) { if (FVCardPlugin->hasVCard(ritem.itemJid)) { static const QList<QString> nickFields = QList<QString>() << VVN_NICKNAME << VVN_FULL_NAME << VVN_GIVEN_NAME << VVN_FAMILY_NAME; LOG_STRM_INFO(AStreamJid,QString("Resolving contact nick name from vCard, jid=%1").arg(AContactJid.bare())); IVCard *vcard = FVCardPlugin->getVCard(ritem.itemJid); foreach(const QString &field, nickFields) { QString nick = vcard->value(field); if (!nick.isEmpty()) { if (ritem.name != nick) roster->renameItem(ritem.itemJid,nick); break; } } vcard->unlock(); } else {
QString JIDUtil::toString(const Jid& j, bool withResource) { return (withResource ? j.full() : j.bare()); }
QDateTime Annotations::annotationModifyDate(const Jid &AStreamJid, const Jid &AContactJid) const { return FAnnotations.value(AStreamJid).value(AContactJid.bare()).modified.toLocal(); }
QString Annotations::annotation(const Jid &AStreamJid, const Jid &AContactJid) const { return FAnnotations.value(AStreamJid).value(AContactJid.bare()).note; }