Skip to content

Commit

Permalink
Merge pull request #29 from wireapp/WPB-11298
Browse files Browse the repository at this point in the history
feat(migrate-legalhold-database-to-support-qualified-ids) Migrate Database to support QualifiedId  #WPB-11298
  • Loading branch information
alexandreferris authored Oct 15, 2024
2 parents 6f622c0 + 2d6e7c0 commit 72bf66a
Show file tree
Hide file tree
Showing 26 changed files with 206 additions and 137 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.wire.bots</groupId>
<artifactId>hold</artifactId>
<version>1.0.7</version>
<version>1.1.0</version>

<name>Legal Hold</name>
<description>Legal Hold Service For Wire</description>
Expand All @@ -26,7 +26,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<dropwizard.version>2.1.2</dropwizard.version>
<dropwizard.version>2.1.12</dropwizard.version>
<openhtml.version>1.0.10</openhtml.version>
<prometheus.version>0.16.0</prometheus.version>
</properties>
Expand Down
33 changes: 21 additions & 12 deletions src/main/java/com/wire/bots/hold/DAO/AccessDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,42 @@
import java.util.UUID;

public interface AccessDAO {
@SqlUpdate("INSERT INTO Access (userId, clientId, cookie, updated, created, enabled) " +
"VALUES (:userId, :clientId, :cookie, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1) " +
"ON CONFLICT (userId) DO UPDATE SET cookie = EXCLUDED.cookie, clientId = EXCLUDED.clientId, " +
@SqlUpdate("INSERT INTO Access (userId, userDomain, clientId, cookie, updated, created, enabled) " +
"VALUES (:userId, :userDomain, :clientId, :cookie, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1) " +
"ON CONFLICT (userId, userDomain) DO UPDATE SET cookie = EXCLUDED.cookie, clientId = EXCLUDED.clientId, " +
"updated = EXCLUDED.updated, enabled = EXCLUDED.enabled")
int insert(@Bind("userId") UUID userId,
@Bind("userDomain") String userDomain,
@Bind("clientId") String clientId,
@Bind("cookie") String cookie);

@SqlUpdate("UPDATE Access SET enabled = 0, updated = CURRENT_TIMESTAMP WHERE userId = :userId")
int disable(@Bind("userId") UUID userId);
@SqlUpdate("UPDATE Access SET enabled = 0, updated = CURRENT_TIMESTAMP WHERE userId = :userId " +
"AND (( :userDomain IS NULL AND userDomain IS null ) or ( :userDomain IS NOT NULL AND userDomain = :userDomain ))")
int disable(@Bind("userId") UUID userId,
@Bind("userDomain") String userDomain);

@SqlUpdate("UPDATE Access SET token = :token, cookie = :cookie, updated = CURRENT_TIMESTAMP WHERE userId = :userId")
@SqlUpdate("UPDATE Access SET token = :token, cookie = :cookie, updated = CURRENT_TIMESTAMP WHERE userId = :userId " +
"AND (( :userDomain IS NULL AND userDomain IS null ) OR ( :userDomain IS NOT NULL AND userDomain = :userDomain ))")
int update(@Bind("userId") UUID userId,
@Bind("token") String token,
@Bind("cookie") String cookie);
@Bind("userDomain") String userDomain,
@Bind("token") String token,
@Bind("cookie") String cookie);

@SqlUpdate("UPDATE Access SET last = :last, updated = CURRENT_TIMESTAMP WHERE userId = :userId")
@SqlUpdate("UPDATE Access SET last = :last, updated = CURRENT_TIMESTAMP WHERE userId = :userId AND (( :userDomain IS NULL AND userDomain IS null ) " +
"OR ( :userDomain IS NOT NULL AND userDomain = :userDomain ))")
int updateLast(@Bind("userId") UUID userId,
@Bind("last") UUID last);
@Bind("userDomain") String userDomain,
@Bind("last") UUID last);

@SqlQuery("SELECT * FROM Access WHERE token IS NOT NULL AND enabled = 1 ORDER BY created DESC LIMIT 1")
@RegisterColumnMapper(AccessResultSetMapper.class)
LHAccess getSingle();

@SqlQuery("SELECT * FROM Access WHERE userId = :userId")
@SqlQuery("SELECT * FROM Access WHERE userId = :userId AND (( :userDomain IS NULL AND userDomain is null ) " +
"or ( :userDomain is NOT NULL AND userDomain = :userDomain ))")
@RegisterColumnMapper(AccessResultSetMapper.class)
LHAccess get(@Bind("userId") UUID userId);
LHAccess get(@Bind("userId") UUID userId,
@Bind("userDomain") String userDomain);

@SqlQuery("SELECT * FROM Access WHERE enabled = 1 ORDER BY created DESC")
@RegisterColumnMapper(AccessResultSetMapper.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wire.bots.hold.DAO;

import com.wire.bots.hold.model.database.LHAccess;
import com.wire.xenon.backend.models.QualifiedId;
import org.jdbi.v3.core.mapper.ColumnMapper;
import org.jdbi.v3.core.statement.StatementContext;

Expand All @@ -13,7 +14,9 @@ public class AccessResultSetMapper implements ColumnMapper<LHAccess> {
public LHAccess map(ResultSet rs, int columnNumber, StatementContext ctx) throws SQLException {
LHAccess LHAccess = new LHAccess();
LHAccess.last = (UUID) rs.getObject("last");
LHAccess.userId = (UUID) rs.getObject("userId");
UUID userId = (UUID) rs.getObject("userId");
String userDomain = rs.getString("userDomain");
LHAccess.userId = new QualifiedId(userId, userDomain);
LHAccess.clientId = rs.getString("clientId");
LHAccess.token = rs.getString("token");
LHAccess.cookie = rs.getString("cookie");
Expand Down
26 changes: 20 additions & 6 deletions src/main/java/com/wire/bots/hold/DAO/EventsDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,40 @@
import java.util.UUID;

public interface EventsDAO {
@SqlUpdate("INSERT INTO Events (eventId, conversationId, userId, type, payload, time) " +
"VALUES (:eventId, :conversationId, :userId, :type, to_jsonb(:payload)::json, CURRENT_TIMESTAMP) " +
@SqlUpdate("INSERT INTO Events (eventId, conversationId, conversationDomain, userId, userDomain, type, payload, time) " +
"VALUES (:eventId, :conversationId, :conversationDomain, :userId, :userDomain, :type, to_jsonb(:payload)::json, CURRENT_TIMESTAMP) " +
"ON CONFLICT (eventId) DO NOTHING")
int insert(@Bind("eventId") UUID eventId,
@Bind("conversationId") UUID conversationId,
@Bind("conversationDomain") String conversationDomain,
@Bind("userId") UUID userId,
@Bind("userDomain") String userDomain,
@Bind("type") String type,
@Bind("payload") String payload);

@SqlQuery("SELECT * FROM Events WHERE eventId = :eventId")
@RegisterColumnMapper(EventsResultSetMapper.class)
Event get(@Bind("eventId") UUID eventId);

@SqlQuery("SELECT * FROM Events WHERE conversationId = :conversationId ORDER BY time DESC")
@SqlQuery("SELECT * FROM Events WHERE conversationId = :conversationId AND (conversationDomain IS NULL OR conversationDomain = :conversationDomain) ORDER BY time DESC")
@RegisterColumnMapper(EventsResultSetMapper.class)
List<Event> listAll(@Bind("conversationId") UUID conversationId);
List<Event> listAllDefaultDomain(@Bind("conversationId") UUID conversationId,
@Bind("conversationDomain") String conversationDomain);

@SqlQuery("SELECT * FROM Events WHERE conversationId = :conversationId ORDER BY time ASC")
@SqlQuery("SELECT * FROM Events WHERE conversationId = :conversationId AND conversationDomain = :conversationDomain ORDER BY time DESC")
@RegisterColumnMapper(EventsResultSetMapper.class)
List<Event> listAllAsc(@Bind("conversationId") UUID conversationId);
List<Event> listAll(@Bind("conversationId") UUID conversationId,
@Bind("conversationDomain") String conversationDomain);

@SqlQuery("SELECT * FROM Events WHERE conversationId = :conversationId AND (conversationDomain IS NULL OR conversationDomain = :conversationDomain) ORDER BY time ASC")
@RegisterColumnMapper(EventsResultSetMapper.class)
List<Event> listAllDefaultDomainAsc(@Bind("conversationId") UUID conversationId,
@Bind("conversationDomain") String conversationDomain);

@SqlQuery("SELECT * FROM Events WHERE conversationId = :conversationId AND conversationDomain = :conversationDomain ORDER BY time ASC")
@RegisterColumnMapper(EventsResultSetMapper.class)
List<Event> listAllAsc(@Bind("conversationId") UUID conversationId,
@Bind("conversationDomain") String conversationDomain);

@SqlQuery("SELECT DISTINCT conversationId, MAX(time) AS time " +
"FROM Events " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public Event map(ResultSet rs, int columnNumber, StatementContext ctx) throws SQ
Event event = new Event();
event.eventId = (UUID) rs.getObject("eventId");
event.conversationId = getUuid(rs, "conversationId");
event.conversationDomain = rs.getString("conversationDomain");
event.userId = getUuid(rs, "userId");
event.userDomain = rs.getString("userDomain");
event.time = rs.getString("time");
event.type = rs.getString("type");
event.payload = getPayload(rs);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/wire/bots/hold/HoldMessageResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.wire.xenon.MessageResourceBase;
import com.wire.xenon.WireClient;
import com.wire.xenon.backend.models.Payload;
import com.wire.xenon.backend.models.QualifiedId;
import com.wire.xenon.exceptions.MissingStateException;
import com.wire.xenon.tools.Logger;

Expand All @@ -19,12 +20,11 @@ public HoldMessageResource(MessageHandlerBase handler, HoldClientRepo repo) {
this.repo = repo;
}

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

public boolean onNewMessage(UUID userId, UUID id, Payload payload) {

public boolean onNewMessage(QualifiedId userId, UUID id, Payload payload) {
try (WireClient client = getWireClient(userId, payload)) {
handleMessage(id, payload, client);
} catch (CryptoException | MissingStateException e) {
Expand Down
68 changes: 29 additions & 39 deletions src/main/java/com/wire/bots/hold/MessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.wire.xenon.WireClient;
import com.wire.xenon.backend.models.QualifiedId;
import com.wire.xenon.backend.models.SystemMessage;
import com.wire.xenon.backend.models.User;
import com.wire.xenon.models.*;
import com.wire.xenon.tools.Logger;
import org.jdbi.v3.core.Jdbi;
Expand All @@ -28,80 +29,72 @@ public class MessageHandler extends MessageHandlerBase {
public void onNewConversation(WireClient client, SystemMessage msg) {
UUID eventId = msg.id;
QualifiedId conversationId = msg.conversation.id;
UUID userId = client.getId();
String type = msg.type;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}
Expand All @@ -110,10 +103,9 @@ public void onPhotoPreview(WireClient client, PhotoPreviewMessage msg) {
public void onFilePreview(WireClient client, FilePreviewMessage msg) {
UUID eventId = msg.getEventId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_FILE_PREVIEW;

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

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}
Expand All @@ -122,10 +114,9 @@ public void onFilePreview(WireClient client, FilePreviewMessage msg) {
public void onAudioPreview(WireClient client, AudioPreviewMessage msg) {
UUID eventId = msg.getEventId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_AUDIO_PREVIEW;

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

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}
Expand All @@ -134,10 +125,9 @@ public void onAudioPreview(WireClient client, AudioPreviewMessage msg) {
public void onVideoPreview(WireClient client, VideoPreviewMessage msg) {
UUID eventId = msg.getEventId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_VIDEO_PREVIEW;

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

assetsDAO.insert(msg.getMessageId(), msg.getMimeType());
}
Expand All @@ -146,15 +136,14 @@ public void onVideoPreview(WireClient client, VideoPreviewMessage msg) {
public void onAssetData(WireClient client, RemoteMessage msg) {
UUID eventId = msg.getEventId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_ASSET_DATA;

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

try {
final byte[] assetData = client.downloadAsset(
msg.getAssetId(),
null, // TODO(WPB-11287): Change null to default domain
msg.getUserId().domain,
msg.getAssetToken(),
msg.getSha256(),
msg.getOtrKey()
Expand All @@ -169,29 +158,26 @@ public void onAssetData(WireClient client, RemoteMessage msg) {
public void onDelete(WireClient client, DeletedTextMessage msg) {
UUID eventId = msg.getEventId();
QualifiedId conversationId = msg.getConversationId();
UUID userId = client.getId();
String type = Const.CONVERSATION_OTR_MESSAGE_ADD_DELETE_TEXT;

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

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

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

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

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

@Override
Expand All @@ -204,16 +190,20 @@ public void validatePreKeys(WireClient client, int size) {

}

private void persist(UUID eventId, UUID convId, UUID userId, String type, Object msg) {
private void persist(UUID eventId, QualifiedId conversationId, WireClient client, String type, Object msg) {
try {
User user = client.getSelf();
String payload = mapper.writeValueAsString(msg);
eventsDAO.insert(eventId, convId, userId, type, payload);
} catch (Exception e) {
Logger.exception(e, "%s: conv: %s, user: %s, id: %s, e: %s",
type,
convId,
userId,
eventId);

eventsDAO.insert(eventId, conversationId.id, conversationId.domain, user.id.id, user.id.domain, type, payload);
} catch (Exception exception) {
Logger.exception(
exception,
"%s: conversation: %s, event: %s, e: %s",
type,
conversationId,
eventId
);
}
}
}
Loading

0 comments on commit 72bf66a

Please sign in to comment.