Store profile sharing for group v2

This commit is contained in:
AsamK 2024-01-28 18:18:40 +01:00
parent 76fe6ad799
commit e2f308a57a
11 changed files with 57 additions and 8 deletions

View file

@ -166,6 +166,7 @@ public class GroupHelper {
if (gv2Pair == null) { if (gv2Pair == null) {
// Failed to create v2 group, creating v1 group instead // Failed to create v2 group, creating v1 group instead
var gv1 = new GroupInfoV1(GroupIdV1.createRandom()); var gv1 = new GroupInfoV1(GroupIdV1.createRandom());
gv1.setProfileSharingEnabled(true);
gv1.addMembers(List.of(selfRecipientId)); gv1.addMembers(List.of(selfRecipientId));
final var result = updateGroupV1(gv1, name, members, avatarBytes); final var result = updateGroupV1(gv1, name, members, avatarBytes);
return new Pair<>(gv1.getGroupId(), result); return new Pair<>(gv1.getGroupId(), result);
@ -175,6 +176,7 @@ public class GroupHelper {
final var decryptedGroup = gv2Pair.second(); final var decryptedGroup = gv2Pair.second();
gv2.setGroup(decryptedGroup); gv2.setGroup(decryptedGroup);
gv2.setProfileSharingEnabled(true);
if (avatarBytes != null) { if (avatarBytes != null) {
context.getAvatarStore() context.getAvatarStore()
.storeGroupAvatar(gv2.getGroupId(), outputStream -> outputStream.write(avatarBytes)); .storeGroupAvatar(gv2.getGroupId(), outputStream -> outputStream.write(avatarBytes));

View file

@ -80,7 +80,7 @@ public final class ProfileHelper {
final var activeGroupIds = account.getGroupStore() final var activeGroupIds = account.getGroupStore()
.getGroups() .getGroups()
.stream() .stream()
.filter(g -> g instanceof GroupInfoV2 && g.isMember(selfRecipientId)) .filter(g -> g instanceof GroupInfoV2 && g.isMember(selfRecipientId) && g.isProfileSharingEnabled())
.map(g -> (GroupInfoV2) g) .map(g -> (GroupInfoV2) g)
.map(GroupInfoV2::getGroupId) .map(GroupInfoV2::getGroupId)
.toList(); .toList();

View file

@ -454,6 +454,10 @@ public class SendHelper {
if (!g.isMember(account.getSelfRecipientId())) { if (!g.isMember(account.getSelfRecipientId())) {
throw new NotAGroupMemberException(groupId, g.getTitle()); throw new NotAGroupMemberException(groupId, g.getTitle());
} }
if (!g.isProfileSharingEnabled()) {
g.setProfileSharingEnabled(true);
account.getGroupStore().updateGroup(g);
}
return g; return g;
} }

View file

@ -33,7 +33,7 @@ import java.util.UUID;
public class AccountDatabase extends Database { public class AccountDatabase extends Database {
private static final Logger logger = LoggerFactory.getLogger(AccountDatabase.class); 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) { private AccountDatabase(final HikariDataSource dataSource) {
super(logger, DATABASE_VERSION, 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( private static void createUuidMappingTable(

View file

@ -46,6 +46,10 @@ public sealed abstract class GroupInfo permits GroupInfoV1, GroupInfoV2 {
public abstract void setBlocked(boolean blocked); public abstract void setBlocked(boolean blocked);
public abstract boolean isProfileSharingEnabled();
public abstract void setProfileSharingEnabled(boolean profileSharingEnabled);
public abstract int getMessageExpirationTimer(); public abstract int getMessageExpirationTimer();
public abstract boolean isAnnouncementGroup(); public abstract boolean isAnnouncementGroup();

View file

@ -94,6 +94,15 @@ public final class GroupInfoV1 extends GroupInfo {
this.blocked = blocked; this.blocked = blocked;
} }
@Override
public boolean isProfileSharingEnabled() {
return true;
}
@Override
public void setProfileSharingEnabled(final boolean profileSharingEnabled) {
}
@Override @Override
public int getMessageExpirationTimer() { public int getMessageExpirationTimer() {
return messageExpirationTime; return messageExpirationTime;

View file

@ -23,6 +23,7 @@ public final class GroupInfoV2 extends GroupInfo {
private final GroupMasterKey masterKey; private final GroupMasterKey masterKey;
private final DistributionId distributionId; private final DistributionId distributionId;
private boolean blocked; private boolean blocked;
private boolean profileSharingEnabled;
private DecryptedGroup group; private DecryptedGroup group;
private byte[] storageRecord; private byte[] storageRecord;
private boolean permissionDenied; private boolean permissionDenied;
@ -44,6 +45,7 @@ public final class GroupInfoV2 extends GroupInfo {
final DecryptedGroup group, final DecryptedGroup group,
final DistributionId distributionId, final DistributionId distributionId,
final boolean blocked, final boolean blocked,
final boolean profileSharingEnabled,
final boolean permissionDenied, final boolean permissionDenied,
final byte[] storageRecord, final byte[] storageRecord,
final RecipientResolver recipientResolver final RecipientResolver recipientResolver
@ -53,6 +55,7 @@ public final class GroupInfoV2 extends GroupInfo {
this.group = group; this.group = group;
this.distributionId = distributionId; this.distributionId = distributionId;
this.blocked = blocked; this.blocked = blocked;
this.profileSharingEnabled = profileSharingEnabled;
this.permissionDenied = permissionDenied; this.permissionDenied = permissionDenied;
this.storageRecord = storageRecord; this.storageRecord = storageRecord;
this.recipientResolver = recipientResolver; this.recipientResolver = recipientResolver;
@ -183,6 +186,16 @@ public final class GroupInfoV2 extends GroupInfo {
this.blocked = blocked; this.blocked = blocked;
} }
@Override
public boolean isProfileSharingEnabled() {
return profileSharingEnabled;
}
@Override
public void setProfileSharingEnabled(final boolean profileSharingEnabled) {
this.profileSharingEnabled = profileSharingEnabled;
}
@Override @Override
public int getMessageExpirationTimer() { public int getMessageExpirationTimer() {
return this.group != null && this.group.disappearingMessagesTimer != null return this.group != null && this.group.disappearingMessagesTimer != null

View file

@ -59,6 +59,7 @@ public class GroupStore {
group_data BLOB, group_data BLOB,
distribution_id BLOB UNIQUE NOT NULL, distribution_id BLOB UNIQUE NOT NULL,
blocked INTEGER NOT NULL DEFAULT FALSE, blocked INTEGER NOT NULL DEFAULT FALSE,
profile_sharing INTEGER NOT NULL DEFAULT FALSE,
permission_denied INTEGER NOT NULL DEFAULT FALSE permission_denied INTEGER NOT NULL DEFAULT FALSE
) STRICT; ) STRICT;
CREATE TABLE group_v1 ( CREATE TABLE group_v1 (
@ -508,8 +509,8 @@ public class GroupStore {
} else if (group instanceof GroupInfoV2 groupV2) { } else if (group instanceof GroupInfoV2 groupV2) {
final var sql = ( final var sql = (
""" """
INSERT OR REPLACE INTO %s (_id, group_id, master_key, group_data, distribution_id, blocked, distribution_id, storage_id) INSERT OR REPLACE INTO %s (_id, group_id, master_key, group_data, distribution_id, blocked, permission_denied, storage_id, profile_sharing)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""" """
).formatted(TABLE_GROUP_V2); ).formatted(TABLE_GROUP_V2);
try (final var statement = connection.prepareStatement(sql)) { try (final var statement = connection.prepareStatement(sql)) {
@ -529,6 +530,7 @@ public class GroupStore {
statement.setBoolean(6, groupV2.isBlocked()); statement.setBoolean(6, groupV2.isBlocked());
statement.setBoolean(7, groupV2.isPermissionDenied()); statement.setBoolean(7, groupV2.isPermissionDenied());
statement.setBytes(8, KeyUtils.createRawStorageId()); statement.setBytes(8, KeyUtils.createRawStorageId());
statement.setBoolean(9, groupV2.isProfileSharingEnabled());
statement.executeUpdate(); statement.executeUpdate();
} }
} else { } else {
@ -539,7 +541,7 @@ public class GroupStore {
private List<GroupInfoV2> getGroupsV2() { private List<GroupInfoV2> getGroupsV2() {
final var sql = ( 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 FROM %s g
""" """
).formatted(TABLE_GROUP_V2); ).formatted(TABLE_GROUP_V2);
@ -557,7 +559,7 @@ public class GroupStore {
public GroupInfoV2 getGroup(Connection connection, GroupIdV2 groupIdV2) throws SQLException { public GroupInfoV2 getGroup(Connection connection, GroupIdV2 groupIdV2) throws SQLException {
final var sql = ( 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 FROM %s g
WHERE g.group_id = ? WHERE g.group_id = ?
""" """
@ -591,7 +593,7 @@ public class GroupStore {
public GroupInfoV2 getGroupV2(Connection connection, StorageId storageId) throws SQLException { public GroupInfoV2 getGroupV2(Connection connection, StorageId storageId) throws SQLException {
final var sql = ( 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 FROM %s g
WHERE g.storage_id = ? WHERE g.storage_id = ?
""" """
@ -614,6 +616,7 @@ public class GroupStore {
final var groupData = resultSet.getBytes("group_data"); final var groupData = resultSet.getBytes("group_data");
final var distributionId = resultSet.getBytes("distribution_id"); final var distributionId = resultSet.getBytes("distribution_id");
final var blocked = resultSet.getBoolean("blocked"); final var blocked = resultSet.getBoolean("blocked");
final var profileSharingEnabled = resultSet.getBoolean("profile_sharing");
final var permissionDenied = resultSet.getBoolean("permission_denied"); final var permissionDenied = resultSet.getBoolean("permission_denied");
final var storageRecord = resultSet.getBytes("storage_record"); final var storageRecord = resultSet.getBytes("storage_record");
return new GroupInfoV2(GroupId.v2(groupId), return new GroupInfoV2(GroupId.v2(groupId),
@ -621,6 +624,7 @@ public class GroupStore {
groupData == null ? null : DecryptedGroup.ADAPTER.decode(groupData), groupData == null ? null : DecryptedGroup.ADAPTER.decode(groupData),
DistributionId.from(UuidUtil.parseOrThrow(distributionId)), DistributionId.from(UuidUtil.parseOrThrow(distributionId)),
blocked, blocked,
profileSharingEnabled,
permissionDenied, permissionDenied,
storageRecord, storageRecord,
recipientResolver); recipientResolver);

View file

@ -77,6 +77,7 @@ public class LegacyGroupStore {
loadDecryptedGroupLocked(groupId, groupCachePath), loadDecryptedGroupLocked(groupId, groupCachePath),
g2.distributionId == null ? DistributionId.create() : DistributionId.from(g2.distributionId), g2.distributionId == null ? DistributionId.create() : DistributionId.from(g2.distributionId),
g2.blocked, g2.blocked,
true,
g2.permissionDenied, g2.permissionDenied,
null, null,
recipientResolver); recipientResolver);

View file

@ -92,6 +92,7 @@ public final class GroupV2RecordProcessor extends DefaultStorageRecordProcessor<
final var group = account.getGroupStore().getGroupOrPartialMigrate(connection, groupMasterKey); final var group = account.getGroupStore().getGroupOrPartialMigrate(connection, groupMasterKey);
group.setBlocked(groupV2Record.isBlocked()); group.setBlocked(groupV2Record.isBlocked());
group.setProfileSharingEnabled(groupV2Record.isProfileSharingEnabled());
account.getGroupStore().updateGroup(connection, group); account.getGroupStore().updateGroup(connection, group);
account.getGroupStore() account.getGroupStore()
.storeStorageRecord(connection, .storeStorageRecord(connection,

View file

@ -119,7 +119,9 @@ public final class StorageSyncModels {
final var builder = new SignalGroupV1Record.Builder(rawStorageId, final var builder = new SignalGroupV1Record.Builder(rawStorageId,
group.getGroupId().serialize(), group.getGroupId().serialize(),
group.getStorageRecord()); 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()); return SignalStorageRecord.forGroupV1(builder.build());
} }
@ -130,6 +132,7 @@ public final class StorageSyncModels {
group.getMasterKey(), group.getMasterKey(),
group.getStorageRecord()); group.getStorageRecord());
builder.setBlocked(group.isBlocked()); builder.setBlocked(group.isBlocked());
builder.setProfileSharingEnabled(group.isProfileSharingEnabled());
return SignalStorageRecord.forGroupV2(builder.build()); return SignalStorageRecord.forGroupV2(builder.build());
} }