look up sender in group chats

This commit is contained in:
Daniel Gultsch 2023-03-11 12:10:26 +01:00
parent d9e8918727
commit ee1c938f2a
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
4 changed files with 101 additions and 7 deletions

View file

@ -13,6 +13,7 @@ import im.conversations.android.database.model.PresenceType;
import im.conversations.android.xmpp.model.muc.user.MucUser;
import java.util.Arrays;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
@Dao
@ -66,4 +67,27 @@ public abstract class PresenceDao {
mucUser);
insert(entity);
}
@Query(
"SELECT mucUserJid FROM presence WHERE accountId=:account AND address=:address AND"
+ " occupantId=:occupantId")
protected abstract Jid getMucUserJidByOccupantId(
long account, BareJid address, String occupantId);
@Query(
"SELECT mucUserJid FROM presence WHERE accountId=:account AND address=:address AND"
+ " resource=:resource")
protected abstract Jid getMucUserJidByResource(
long account, BareJid address, Resourcepart resource);
public BareJid getMucUserJidByOccupantId(Account account, BareJid address, String occupantId) {
final var jid = getMucUserJidByOccupantId(account.id, address, occupantId);
return jid == null ? null : jid.asBareJid();
}
public BareJid getMucUserJidByResource(
final Account account, final BareJid address, final Resourcepart resource) {
final var jid = getMucUserJidByResource(account.id, address, resource);
return jid == null ? null : jid.asBareJid();
}
}

View file

@ -1,29 +1,49 @@
package im.conversations.android.transformer;
import android.content.Context;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import im.conversations.android.database.model.StanzaId;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.Entity;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.manager.DiscoManager;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.muc.user.MucUser;
import im.conversations.android.xmpp.model.occupant.OccupantId;
import im.conversations.android.xmpp.model.stanza.Message;
import java.time.Instant;
import java.util.List;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.Jid;
public class TransformationFactory extends XmppConnection.Delegate {
public TransformationFactory(Context context, XmppConnection connection) {
private final Mode mode;
public TransformationFactory(Context context, XmppConnection connection, final Mode mode) {
super(context, connection);
this.mode = mode;
}
public MessageTransformation create(final Message message, final StanzaId stanzaId) {
return create(message, stanzaId == null ? null : stanzaId.id, Instant.now());
Preconditions.checkState(
mode == Mode.LIVE,
"Creating a MessageTransformation with automatic timestamp is only allowed in live"
+ " mode");
return create(message, stanzaId == null ? null : stanzaId.id, Instant.now(), null);
}
public MessageTransformation create(
final Message message, final String stanzaId, final Instant receivedAt) {
final Message message,
final String stanzaId,
final Instant receivedAt,
final List<Extension> privilegedExtensions) {
if (privilegedExtensions != null) {
Preconditions.checkArgument(
this.mode == Mode.ARCHIVE,
"Privileged extensions can only supplied in archive mode");
}
final var boundAddress = connection.getBoundAddress().asBareJid();
final var from = message.getFrom();
final var to = message.getTo();
@ -48,11 +68,43 @@ public class TransformationFactory extends XmppConnection.Delegate {
}
final BareJid senderIdentity;
if (message.getType() == Message.Type.GROUPCHAT) {
senderIdentity = null; // TODO discover real jid
final var mucUser =
mode == Mode.ARCHIVE ? getExtension(privilegedExtensions, MucUser.class) : null;
final var mucUserItem = mucUser == null ? null : mucUser.getItem();
final Jid mucUserJid = mucUserItem == null ? null : mucUserItem.getJid();
if (mucUserJid != null) {
senderIdentity = mucUserJid.asBareJid();
} else if (occupantId != null) {
senderIdentity =
getDatabase()
.presenceDao()
.getMucUserJidByOccupantId(
getAccount(), from.asBareJid(), occupantId);
} else if (mode == Mode.LIVE && from != null && from.hasResource()) {
senderIdentity =
getDatabase()
.presenceDao()
.getMucUserJidByResource(
getAccount(), from.asBareJid(), from.getResourceOrThrow());
} else {
senderIdentity = null;
}
} else {
senderIdentity = from == null ? boundAddress : from.asBareJid();
}
return MessageTransformation.of(
message, receivedAt, remote, stanzaId, senderIdentity, occupantId);
}
private static <E extends Extension> E getExtension(
final List<Extension> extensions, final Class<E> clazz) {
final var extension =
extensions == null ? null : Iterables.find(extensions, clazz::isInstance, null);
return extension == null ? null : clazz.cast(extension);
}
public enum Mode {
LIVE,
ARCHIVE
}
}

View file

@ -17,13 +17,17 @@ import im.conversations.android.database.ConversationsDatabase;
import im.conversations.android.transformer.MessageTransformation;
import im.conversations.android.transformer.TransformationFactory;
import im.conversations.android.transformer.Transformer;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.Entity;
import im.conversations.android.xmpp.Page;
import im.conversations.android.xmpp.Range;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.delay.Delay;
import im.conversations.android.xmpp.model.mam.Fin;
import im.conversations.android.xmpp.model.mam.Query;
import im.conversations.android.xmpp.model.mam.Result;
import im.conversations.android.xmpp.model.muc.user.MucUser;
import im.conversations.android.xmpp.model.rsm.Set;
import im.conversations.android.xmpp.model.stanza.Iq;
import im.conversations.android.xmpp.model.stanza.Message;
@ -47,7 +51,8 @@ public class ArchiveManager extends AbstractManager {
public ArchiveManager(Context context, XmppConnection connection) {
super(context, connection);
this.transformationFactory = new TransformationFactory(context, connection);
this.transformationFactory =
new TransformationFactory(context, connection, TransformationFactory.Mode.ARCHIVE);
}
public void handle(final Message message) {
@ -78,8 +83,20 @@ public class ArchiveManager extends AbstractManager {
return;
}
final ImmutableList.Builder<Extension> privilegedExtensionBuilder =
new ImmutableList.Builder<>();
if (forwardedMessage.getType() == Message.Type.GROUPCHAT) {
final var mucUser = forwardedMessage.getExtension(MucUser.class);
if (mucUser != null
&& getManager(DiscoManager.class)
.hasFeature(Entity.discoItem(archive), Namespace.MUC)) {
privilegedExtensionBuilder.add(mucUser);
}
}
final var transformation =
this.transformationFactory.create(forwardedMessage, stanzaId, receivedAt);
this.transformationFactory.create(
forwardedMessage, stanzaId, receivedAt, privilegedExtensionBuilder.build());
// TODO only when there is something to transform
runningQuery.addTransformation(transformation);
}

View file

@ -39,7 +39,8 @@ public class MessageProcessor extends XmppConnection.Delegate implements Consume
final Context context, final XmppConnection connection, final Level level) {
super(context, connection);
this.level = level;
this.transformationFactory = new TransformationFactory(context, connection);
this.transformationFactory =
new TransformationFactory(context, connection, TransformationFactory.Mode.LIVE);
}
@Override