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