Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(get-domain-from-backend) Use new Helium API to fetch backend domain #WPB-11287 #27

Merged
merged 6 commits into from
Oct 7, 2024
Merged
9 changes: 7 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
<dropwizard.version>2.1.2</dropwizard.version>
<openhtml.version>1.0.10</openhtml.version>
<prometheus.version>0.16.0</prometheus.version>
<helium.version>1.3.0</helium.version>
</properties>

<repositories>
Expand Down Expand Up @@ -68,7 +67,7 @@
<dependency>
<groupId>com.wire</groupId>
<artifactId>helium</artifactId>
<version>${helium.version}</version>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>com.github.smoketurner</groupId>
Expand Down Expand Up @@ -136,6 +135,12 @@
<artifactId>simpleclient_servlet</artifactId>
<version>${prometheus.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.14.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/wire/bots/hold/DAO/MetadataDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.wire.bots.hold.DAO;

import com.wire.bots.hold.model.Metadata;
import org.jdbi.v3.sqlobject.config.RegisterColumnMapper;
import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;

public interface MetadataDAO {
String FALLBACK_DOMAIN_KEY = "FALLBACK_DOMAIN_KEY";

@SqlUpdate("INSERT INTO Metadata (key, value)" +
"VALUES (:key, :value)" +
"ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value")
int insert(@Bind("key") String key, @Bind("value") String value);

@SqlQuery("SELECT key, value FROM Metadata WHERE key = :key LIMIT 1")
@RegisterColumnMapper(MetadataResultSetMapper.class)
Metadata get(@Bind("key") String key);
}
19 changes: 19 additions & 0 deletions src/main/java/com/wire/bots/hold/DAO/MetadataResultSetMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.wire.bots.hold.DAO;

import com.wire.bots.hold.model.Metadata;
import org.jdbi.v3.core.mapper.ColumnMapper;
import org.jdbi.v3.core.statement.StatementContext;

import java.sql.ResultSet;
import java.sql.SQLException;

public class MetadataResultSetMapper implements ColumnMapper<Metadata> {

@Override
public Metadata map(ResultSet rs, int columnNumber, StatementContext ctx) throws SQLException {
return new Metadata(
rs.getString("key"),
rs.getString("value")
);
}
}
68 changes: 68 additions & 0 deletions src/main/java/com/wire/bots/hold/FallbackDomainFetcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.wire.bots.hold;

import com.wire.bots.hold.DAO.MetadataDAO;
import com.wire.bots.hold.model.Metadata;
import com.wire.bots.hold.utils.Cache;
import com.wire.helium.LoginClient;
import com.wire.helium.models.BackendConfiguration;
import com.wire.xenon.exceptions.HttpException;
import com.wire.xenon.tools.Logger;

public class FallbackDomainFetcher implements Runnable {

private final LoginClient loginClient;
private final MetadataDAO metadataDAO;

/**
* Fetcher and handler for fallback domain.
* <p>
* Fetches from API and compares against database value (if any), then inserts into database and updates cache value.
* If value received from the API is different from what is saved in the database, a [RuntimeException] is thrown.
* </p>
* <p>
* This fallback domain is necessary for LegalHold to work with Federation (as it needs id@domain) and not just the ID anymore.
* In case there is a mismatch we are throwing a RuntimeException so it stops the execution of this app, so in an event
* of already having a defined default domain saved in the database and this app restarts with a different domain
* we don't get mismatching domains.
* </p>
* @param loginClient [{@link LoginClient}] as API to get backend configuration containing default domain.
* @param metadataDAO [{@link MetadataDAO}] as DAO to get/insert default domain to database.
*
* @throws RuntimeException if received domain from API is different from the one saved in the database.
*/
FallbackDomainFetcher(LoginClient loginClient, MetadataDAO metadataDAO) {
this.loginClient = loginClient;
this.metadataDAO = metadataDAO;
}

@Override
public void run() {
if (Cache.getFallbackDomain() != null) { return; }

Metadata metadata = metadataDAO.get(MetadataDAO.FALLBACK_DOMAIN_KEY);
try {
BackendConfiguration apiVersionResponse = loginClient.getBackendConfiguration();

if (metadata == null) {
metadataDAO.insert(MetadataDAO.FALLBACK_DOMAIN_KEY, apiVersionResponse.domain);
Cache.setFallbackDomain(apiVersionResponse.domain);
} else {
System.out.println("EEEEEEEE -> " + apiVersionResponse.domain);
if (metadata.value.equals(apiVersionResponse.domain)) {
System.out.println("EEEEEEEE -> p1");
Cache.setFallbackDomain(apiVersionResponse.domain);
} else {
System.out.println("EEEEEEEE -> p2");
String formattedExceptionMessage = String.format(
"Database already has a default domain as %s and instead we got %s from the Backend API.",
metadata.value,
apiVersionResponse.domain
);
throw new RuntimeException(formattedExceptionMessage);
}
}
} catch (HttpException exception) {
Logger.exception(exception, "FallbackDomainFetcher.run, exception: %s", exception.getMessage());
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/wire/bots/hold/HoldMessageResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public HoldMessageResource(MessageHandlerBase handler, HoldClientRepo repo) {
}

protected WireClient getWireClient(UUID userId, Payload payload) throws CryptoException {
return repo.getClient(userId, payload.data.recipient, payload.convId);
return repo.getClient(userId, payload.data.recipient, payload.conversation);
}

public boolean onNewMessage(UUID userId, UUID id, Payload payload) {
Expand Down
71 changes: 39 additions & 32 deletions src/main/java/com/wire/bots/hold/MessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.wire.bots.hold.DAO.EventsDAO;
import com.wire.xenon.MessageHandlerBase;
import com.wire.xenon.WireClient;
import com.wire.xenon.backend.models.QualifiedId;
import com.wire.xenon.backend.models.SystemMessage;
import com.wire.xenon.models.*;
import com.wire.xenon.tools.Logger;
Expand All @@ -26,132 +27,138 @@ public class MessageHandler extends MessageHandlerBase {
@Override
public void onNewConversation(WireClient client, SystemMessage msg) {
UUID eventId = msg.id;
UUID convId = msg.convId;
QualifiedId conversationId = msg.conversation.id;
UUID userId = client.getId();
String type = msg.type;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onConversationRename(WireClient client, SystemMessage msg) {
UUID eventId = msg.id;
UUID convId = msg.convId;
QualifiedId conversationId = msg.conversation.id;
UUID userId = client.getId();
String type = Const.CONVERSATION_RENAME;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onMemberJoin(WireClient client, SystemMessage msg) {
UUID eventId = msg.id;
UUID convId = msg.convId;
QualifiedId conversationId = msg.conversation.id;
UUID userId = client.getId();
String type = msg.type;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onMemberLeave(WireClient client, SystemMessage msg) {
UUID eventId = msg.id;
UUID convId = msg.convId;
QualifiedId conversationId = msg.conversation.id;
UUID userId = client.getId();
String type = msg.type;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onText(WireClient client, TextMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_NEW_TEXT;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onText(WireClient client, EphemeralTextMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_NEW_TEXT;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onEditText(WireClient client, EditedTextMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_EDIT_TEXT;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onPhotoPreview(WireClient client, PhotoPreviewMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_IMAGE_PREVIEW;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}

@Override
public void onFilePreview(WireClient client, FilePreviewMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_FILE_PREVIEW;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}

@Override
public void onAudioPreview(WireClient client, AudioPreviewMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_AUDIO_PREVIEW;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}

@Override
public void onVideoPreview(WireClient client, VideoPreviewMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_VIDEO_PREVIEW;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}

@Override
public void onAssetData(WireClient client, RemoteMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_ASSET_DATA;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);

try {
final byte[] assetData = client.downloadAsset(msg.getAssetId(), msg.getAssetToken(), msg.getSha256(), msg.getOtrKey());
final byte[] assetData = client.downloadAsset(
msg.getAssetId(),
null, // TODO(WPB-11287): Change null to default domain
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be the default domain, it should be the domain of the message you got (well, the domain fo the sender). Someome might have send an image from another domain.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the comment might be a bit misleading to what it needs to be done, but at least we have an overview of where it will need to be changed as well when we do the database migrations from UUID to QualifiedID (id, domain)

msg.getAssetToken(),
msg.getSha256(),
msg.getOtrKey()
);
assetsDAO.insert(msg.getMessageId(), assetData);
} catch (Exception e) {
Logger.exception(e, "onAssetData");
Expand All @@ -161,34 +168,34 @@ public void onAssetData(WireClient client, RemoteMessage msg) {
@Override
public void onDelete(WireClient client, DeletedTextMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_DELETE_TEXT;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public void onCalling(WireClient client, CallingMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_CALL;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

public void onReaction(WireClient client, ReactionMessage msg) {
UUID eventId = msg.getEventId();
UUID convId = msg.getConversationId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_REACTION;

persist(eventId, convId, userId, type, msg);
persist(eventId, conversationId.id, userId, type, msg);
}

@Override
public boolean onConnectRequest(WireClient client, UUID from, UUID to, String status) {
public boolean onConnectRequest(WireClient client, QualifiedId from, QualifiedId to, String status) {
return false;
}

Expand Down
Loading
Loading