From: AsamK Date: Sun, 28 Jan 2024 17:18:40 +0000 (+0100) Subject: Store profile sharing for group v2 X-Git-Tag: v0.13.0~41 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/e2f308a57a5d5162c4820fbc4daa06f72e16a1ab Store profile sharing for group v2 --- diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java index dec9185a..8f7b2869 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java @@ -166,6 +166,7 @@ public class GroupHelper { if (gv2Pair == null) { // Failed to create v2 group, creating v1 group instead var gv1 = new GroupInfoV1(GroupIdV1.createRandom()); + gv1.setProfileSharingEnabled(true); gv1.addMembers(List.of(selfRecipientId)); final var result = updateGroupV1(gv1, name, members, avatarBytes); return new Pair<>(gv1.getGroupId(), result); @@ -175,6 +176,7 @@ public class GroupHelper { final var decryptedGroup = gv2Pair.second(); gv2.setGroup(decryptedGroup); + gv2.setProfileSharingEnabled(true); if (avatarBytes != null) { context.getAvatarStore() .storeGroupAvatar(gv2.getGroupId(), outputStream -> outputStream.write(avatarBytes)); diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java index dbde28a7..5d6b90d4 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java @@ -80,7 +80,7 @@ public final class ProfileHelper { final var activeGroupIds = account.getGroupStore() .getGroups() .stream() - .filter(g -> g instanceof GroupInfoV2 && g.isMember(selfRecipientId)) + .filter(g -> g instanceof GroupInfoV2 && g.isMember(selfRecipientId) && g.isProfileSharingEnabled()) .map(g -> (GroupInfoV2) g) .map(GroupInfoV2::getGroupId) .toList(); diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java index 38e8de17..a9ca6a12 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java @@ -454,6 +454,10 @@ public class SendHelper { if (!g.isMember(account.getSelfRecipientId())) { throw new NotAGroupMemberException(groupId, g.getTitle()); } + if (!g.isProfileSharingEnabled()) { + g.setProfileSharingEnabled(true); + account.getGroupStore().updateGroup(g); + } return g; } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java b/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java index bedf4332..ba51d9c0 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java @@ -33,7 +33,7 @@ import java.util.UUID; public class AccountDatabase extends Database { private static final Logger logger = LoggerFactory.getLogger(AccountDatabase.class); - private static final long DATABASE_VERSION = 22; + private static final long DATABASE_VERSION = 23; private AccountDatabase(final HikariDataSource dataSource) { super(logger, DATABASE_VERSION, dataSource); @@ -565,6 +565,14 @@ public class AccountDatabase extends Database { """); } } + if (oldVersion < 23) { + logger.debug("Updating database: Create group profile sharing column"); + try (final var statement = connection.createStatement()) { + statement.executeUpdate(""" + ALTER TABLE group_v2 ADD profile_sharing INTEGER NOT NULL DEFAULT TRUE; + """); + } + } } private static void createUuidMappingTable( diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java index a16af0ff..7de3a8f9 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java @@ -46,6 +46,10 @@ public sealed abstract class GroupInfo permits GroupInfoV1, GroupInfoV2 { public abstract void setBlocked(boolean blocked); + public abstract boolean isProfileSharingEnabled(); + + public abstract void setProfileSharingEnabled(boolean profileSharingEnabled); + public abstract int getMessageExpirationTimer(); public abstract boolean isAnnouncementGroup(); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java index fd7bfe85..f377ff2d 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java @@ -94,6 +94,15 @@ public final class GroupInfoV1 extends GroupInfo { this.blocked = blocked; } + @Override + public boolean isProfileSharingEnabled() { + return true; + } + + @Override + public void setProfileSharingEnabled(final boolean profileSharingEnabled) { + } + @Override public int getMessageExpirationTimer() { return messageExpirationTime; diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java index 8ddec54e..89306ecd 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java @@ -23,6 +23,7 @@ public final class GroupInfoV2 extends GroupInfo { private final GroupMasterKey masterKey; private final DistributionId distributionId; private boolean blocked; + private boolean profileSharingEnabled; private DecryptedGroup group; private byte[] storageRecord; private boolean permissionDenied; @@ -44,6 +45,7 @@ public final class GroupInfoV2 extends GroupInfo { final DecryptedGroup group, final DistributionId distributionId, final boolean blocked, + final boolean profileSharingEnabled, final boolean permissionDenied, final byte[] storageRecord, final RecipientResolver recipientResolver @@ -53,6 +55,7 @@ public final class GroupInfoV2 extends GroupInfo { this.group = group; this.distributionId = distributionId; this.blocked = blocked; + this.profileSharingEnabled = profileSharingEnabled; this.permissionDenied = permissionDenied; this.storageRecord = storageRecord; this.recipientResolver = recipientResolver; @@ -183,6 +186,16 @@ public final class GroupInfoV2 extends GroupInfo { this.blocked = blocked; } + @Override + public boolean isProfileSharingEnabled() { + return profileSharingEnabled; + } + + @Override + public void setProfileSharingEnabled(final boolean profileSharingEnabled) { + this.profileSharingEnabled = profileSharingEnabled; + } + @Override public int getMessageExpirationTimer() { return this.group != null && this.group.disappearingMessagesTimer != null diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java index 5079da07..5ebac9c5 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java @@ -59,6 +59,7 @@ public class GroupStore { group_data BLOB, distribution_id BLOB UNIQUE NOT NULL, blocked INTEGER NOT NULL DEFAULT FALSE, + profile_sharing INTEGER NOT NULL DEFAULT FALSE, permission_denied INTEGER NOT NULL DEFAULT FALSE ) STRICT; CREATE TABLE group_v1 ( @@ -508,8 +509,8 @@ public class GroupStore { } else if (group instanceof GroupInfoV2 groupV2) { final var sql = ( """ - INSERT OR REPLACE INTO %s (_id, group_id, master_key, group_data, distribution_id, blocked, distribution_id, storage_id) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) + INSERT OR REPLACE INTO %s (_id, group_id, master_key, group_data, distribution_id, blocked, permission_denied, storage_id, profile_sharing) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) """ ).formatted(TABLE_GROUP_V2); try (final var statement = connection.prepareStatement(sql)) { @@ -529,6 +530,7 @@ public class GroupStore { statement.setBoolean(6, groupV2.isBlocked()); statement.setBoolean(7, groupV2.isPermissionDenied()); statement.setBytes(8, KeyUtils.createRawStorageId()); + statement.setBoolean(9, groupV2.isProfileSharingEnabled()); statement.executeUpdate(); } } else { @@ -539,7 +541,7 @@ public class GroupStore { private List getGroupsV2() { final var sql = ( """ - SELECT g.group_id, g.master_key, g.group_data, g.distribution_id, g.blocked, g.permission_denied, g.storage_record + SELECT g.group_id, g.master_key, g.group_data, g.distribution_id, g.blocked, g.profile_sharing, g.permission_denied, g.storage_record FROM %s g """ ).formatted(TABLE_GROUP_V2); @@ -557,7 +559,7 @@ public class GroupStore { public GroupInfoV2 getGroup(Connection connection, GroupIdV2 groupIdV2) throws SQLException { final var sql = ( """ - SELECT g.group_id, g.master_key, g.group_data, g.distribution_id, g.blocked, g.permission_denied, g.storage_record + SELECT g.group_id, g.master_key, g.group_data, g.distribution_id, g.blocked, g.profile_sharing, g.permission_denied, g.storage_record FROM %s g WHERE g.group_id = ? """ @@ -591,7 +593,7 @@ public class GroupStore { public GroupInfoV2 getGroupV2(Connection connection, StorageId storageId) throws SQLException { final var sql = ( """ - SELECT g.group_id, g.master_key, g.group_data, g.distribution_id, g.blocked, g.permission_denied, g.storage_record + SELECT g.group_id, g.master_key, g.group_data, g.distribution_id, g.blocked, g.profile_sharing, g.permission_denied, g.storage_record FROM %s g WHERE g.storage_id = ? """ @@ -614,6 +616,7 @@ public class GroupStore { final var groupData = resultSet.getBytes("group_data"); final var distributionId = resultSet.getBytes("distribution_id"); final var blocked = resultSet.getBoolean("blocked"); + final var profileSharingEnabled = resultSet.getBoolean("profile_sharing"); final var permissionDenied = resultSet.getBoolean("permission_denied"); final var storageRecord = resultSet.getBytes("storage_record"); return new GroupInfoV2(GroupId.v2(groupId), @@ -621,6 +624,7 @@ public class GroupStore { groupData == null ? null : DecryptedGroup.ADAPTER.decode(groupData), DistributionId.from(UuidUtil.parseOrThrow(distributionId)), blocked, + profileSharingEnabled, permissionDenied, storageRecord, recipientResolver); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/LegacyGroupStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/LegacyGroupStore.java index b5698b51..1d8c8799 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/LegacyGroupStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/LegacyGroupStore.java @@ -77,6 +77,7 @@ public class LegacyGroupStore { loadDecryptedGroupLocked(groupId, groupCachePath), g2.distributionId == null ? DistributionId.create() : DistributionId.from(g2.distributionId), g2.blocked, + true, g2.permissionDenied, null, recipientResolver); diff --git a/lib/src/main/java/org/asamk/signal/manager/syncStorage/GroupV2RecordProcessor.java b/lib/src/main/java/org/asamk/signal/manager/syncStorage/GroupV2RecordProcessor.java index 4d41901a..1b182769 100644 --- a/lib/src/main/java/org/asamk/signal/manager/syncStorage/GroupV2RecordProcessor.java +++ b/lib/src/main/java/org/asamk/signal/manager/syncStorage/GroupV2RecordProcessor.java @@ -92,6 +92,7 @@ public final class GroupV2RecordProcessor extends DefaultStorageRecordProcessor< final var group = account.getGroupStore().getGroupOrPartialMigrate(connection, groupMasterKey); group.setBlocked(groupV2Record.isBlocked()); + group.setProfileSharingEnabled(groupV2Record.isProfileSharingEnabled()); account.getGroupStore().updateGroup(connection, group); account.getGroupStore() .storeStorageRecord(connection, diff --git a/lib/src/main/java/org/asamk/signal/manager/syncStorage/StorageSyncModels.java b/lib/src/main/java/org/asamk/signal/manager/syncStorage/StorageSyncModels.java index c438570c..a8d10142 100644 --- a/lib/src/main/java/org/asamk/signal/manager/syncStorage/StorageSyncModels.java +++ b/lib/src/main/java/org/asamk/signal/manager/syncStorage/StorageSyncModels.java @@ -119,7 +119,9 @@ public final class StorageSyncModels { final var builder = new SignalGroupV1Record.Builder(rawStorageId, group.getGroupId().serialize(), group.getStorageRecord()); - builder.setBlocked(group.isBlocked()).setArchived(group.archived); + builder.setBlocked(group.isBlocked()); + builder.setArchived(group.archived); + builder.setProfileSharingEnabled(true); return SignalStorageRecord.forGroupV1(builder.build()); } @@ -130,6 +132,7 @@ public final class StorageSyncModels { group.getMasterKey(), group.getStorageRecord()); builder.setBlocked(group.isBlocked()); + builder.setProfileSharingEnabled(group.isProfileSharingEnabled()); return SignalStorageRecord.forGroupV2(builder.build()); }