ignore 'subscribe' presence for blocked contacts

This commit is contained in:
Daniel Gultsch 2024-02-16 16:59:21 +01:00
parent 5692cccf70
commit d175843cbd
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2

View file

@ -2,11 +2,6 @@ package eu.siacs.conversations.parser;
import android.util.Log;
import org.openintents.openpgp.util.OpenPgpUtils;
import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@ -28,15 +23,22 @@ import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
public class PresenceParser extends AbstractParser implements
OnPresencePacketReceived {
import org.openintents.openpgp.util.OpenPgpUtils;
import java.util.ArrayList;
import java.util.List;
public class PresenceParser extends AbstractParser implements OnPresencePacketReceived {
public PresenceParser(XmppConnectionService service) {
super(service);
}
public void parseConferencePresence(PresencePacket packet, Account account) {
final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().asBareJid());
final Conversation conversation =
packet.getFrom() == null
? null
: mXmppConnectionService.find(account, packet.getFrom().asBareJid());
if (conversation != null) {
final MucOptions mucOptions = conversation.getMucOptions();
boolean before = mucOptions.online();
@ -47,7 +49,8 @@ public class PresenceParser extends AbstractParser implements
if (!tileUserAfter.equals(tileUserBefore)) {
mXmppConnectionService.getAvatarService().clear(mucOptions);
}
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
if (before != mucOptions.online()
|| (mucOptions.online() && count != mucOptions.getUserCount())) {
mXmppConnectionService.updateConversationUi();
} else if (mucOptions.online()) {
mXmppConnectionService.updateMucRosterUi();
@ -71,20 +74,26 @@ public class PresenceParser extends AbstractParser implements
if (item != null && !from.isBareJid()) {
mucOptions.setError(MucOptions.Error.NONE);
MucOptions.User user = parseItem(conversation, item, from);
if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && jid.equals(InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"))))) {
if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE)
|| (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED)
&& jid.equals(
InvalidJid.getNullForInvalid(
item.getAttributeAsJid("jid"))))) {
if (mucOptions.setOnline()) {
mXmppConnectionService.getAvatarService().clear(mucOptions);
}
if (mucOptions.setSelf(user)) {
Log.d(Config.LOGTAG, "role or affiliation changed");
mXmppConnectionService.databaseBackend.updateConversation(conversation);
mXmppConnectionService.databaseBackend.updateConversation(
conversation);
}
mXmppConnectionService.persistSelfNick(user);
invokeRenameListener(mucOptions, true);
}
boolean isNew = mucOptions.updateUser(user);
final AxolotlService axolotlService = conversation.getAccount().getAxolotlService();
final AxolotlService axolotlService =
conversation.getAccount().getAxolotlService();
Contact contact = user.getContact();
if (isNew
&& user.getRealJid() != null
@ -93,12 +102,16 @@ public class PresenceParser extends AbstractParser implements
&& axolotlService.hasEmptyDeviceList(user.getRealJid())) {
axolotlService.fetchDeviceIds(user.getRealJid());
}
if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) {
Log.d(Config.LOGTAG,account.getJid().asBareJid()
if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED)
&& mucOptions.autoPushConfiguration()) {
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": room '"
+ mucOptions.getConversation().getJid().asBareJid()
+ "' created. pushing default configuration");
mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(),
mXmppConnectionService.pushConferenceConfiguration(
mucOptions.getConversation(),
IqGenerator.defaultChannelConfiguration(),
null);
}
@ -107,7 +120,13 @@ public class PresenceParser extends AbstractParser implements
if (signed != null) {
Element status = packet.findChild("status");
String msg = status == null ? "" : status.getContent();
long keyId = mXmppConnectionService.getPgpEngine().fetchKeyId(mucOptions.getAccount(), msg, signed.getContent());
long keyId =
mXmppConnectionService
.getPgpEngine()
.fetchKeyId(
mucOptions.getAccount(),
msg,
signed.getContent());
if (keyId != 0) {
user.setPgpKeyId(keyId);
}
@ -120,7 +139,11 @@ public class PresenceParser extends AbstractParser implements
mXmppConnectionService.getAvatarService().clear(user);
}
if (user.getRealJid() != null) {
final Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid());
final Contact c =
conversation
.getAccount()
.getRoster()
.getContact(user.getRealJid());
c.setAvatar(avatar);
mXmppConnectionService.syncRoster(conversation.getAccount());
mXmppConnectionService.getAvatarService().clear(c);
@ -136,10 +159,18 @@ public class PresenceParser extends AbstractParser implements
final boolean fullJidMatches = from.equals(mucOptions.getSelf().getFullJid());
if (x.hasChild("destroy") && fullJidMatches) {
Element destroy = x.findChild("destroy");
final Jid alternate = destroy == null ? null : InvalidJid.getNullForInvalid(destroy.getAttributeAsJid("jid"));
final Jid alternate =
destroy == null
? null
: InvalidJid.getNullForInvalid(
destroy.getAttributeAsJid("jid"));
mucOptions.setError(MucOptions.Error.DESTROYED);
if (alternate != null) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": muc destroyed. alternate location " + alternate);
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": muc destroyed. alternate location "
+ alternate);
}
} else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN) && fullJidMatches) {
mucOptions.setError(MucOptions.Error.SHUTDOWN);
@ -217,7 +248,11 @@ public class PresenceParser extends AbstractParser implements
}
mucOptions.setError(MucOptions.Error.DESTROYED);
if (alternate != null) {
Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": muc destroyed. alternate location " + alternate);
Log.d(
Config.LOGTAG,
conversation.getAccount().getJid().asBareJid()
+ ": muc destroyed. alternate location "
+ alternate);
}
} else {
final String text = error.findChildContent("text");
@ -272,7 +307,8 @@ public class PresenceParser extends AbstractParser implements
final Contact contact = account.getRoster().getContact(from);
if (type == null) {
final String resource = from.isBareJid() ? "" : from.getResource();
Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
final Avatar avatar =
Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
if (avatar != null && (!contact.isSelf() || account.getAvatar() == null)) {
avatar.owner = from.asBareJid();
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
@ -298,7 +334,7 @@ public class PresenceParser extends AbstractParser implements
return;
}
int sizeBefore = contact.getPresences().size();
final int sizeBefore = contact.getPresences().size();
final String show = packet.findChildContent("show");
final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
@ -326,13 +362,19 @@ public class PresenceParser extends AbstractParser implements
}
}
PgpEngine pgp = mXmppConnectionService.getPgpEngine();
Element x = packet.findChild("x", "jabber:x:signed");
final PgpEngine pgp = mXmppConnectionService.getPgpEngine();
final Element x = packet.findChild("x", "jabber:x:signed");
if (pgp != null && x != null) {
final String status = packet.findChildContent("status");
final long keyId = pgp.fetchKeyId(account, status, x.getContent());
if (keyId != 0 && contact.setPgpKeyId(keyId)) {
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": found OpenPGP key id for "+contact.getJid()+" "+OpenPgpUtils.convertKeyIdToHex(keyId));
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": found OpenPGP key id for "
+ contact.getJid()
+ " "
+ OpenPgpUtils.convertKeyIdToHex(keyId));
mXmppConnectionService.syncRoster(account);
}
}
@ -352,27 +394,36 @@ public class PresenceParser extends AbstractParser implements
}
mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
} else if (type.equals("subscribe")) {
if (contact.isBlocked()) {
Log.d(
Config.LOGTAG,
account.getJid().asBareJid()
+ ": ignoring 'subscribe' presence from blocked "
+ from);
return;
}
if (contact.setPresenceName(packet.findChildContent("nick", Namespace.NICK))) {
mXmppConnectionService.syncRoster(account);
mXmppConnectionService.getAvatarService().clear(contact);
}
if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
mXmppConnectionService.sendPresencePacket(account,
mPresenceGenerator.sendPresenceUpdatesTo(contact));
mXmppConnectionService.sendPresencePacket(
account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
} else {
contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
final Conversation conversation = mXmppConnectionService.findOrCreateConversation(
final Conversation conversation =
mXmppConnectionService.findOrCreateConversation(
account, contact.getJid().asBareJid(), false, false);
final String statusMessage = packet.findChildContent("status");
if (statusMessage != null
&& !statusMessage.isEmpty()
&& conversation.countMessages() == 0) {
conversation.add(new Message(
conversation.add(
new Message(
conversation,
statusMessage,
Message.ENCRYPTION_NONE,
Message.STATUS_RECEIVED
));
Message.STATUS_RECEIVED));
}
}
}
@ -385,7 +436,8 @@ public class PresenceParser extends AbstractParser implements
this.parseConferencePresence(packet, account);
} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
this.parseConferencePresence(packet, account);
} else if ("error".equals(packet.getAttribute("type")) && mXmppConnectionService.isMuc(account, packet.getFrom())) {
} else if ("error".equals(packet.getAttribute("type"))
&& mXmppConnectionService.isMuc(account, packet.getFrom())) {
this.parseConferencePresence(packet, account);
} else {
this.parseContactPresence(packet, account);