mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-29 05:04:54 +01:00
Group invite link epoch support.
This commit is contained in:
committed by
Greyson Parrelli
parent
e006306036
commit
477bb45df7
@@ -1,26 +1,32 @@
|
||||
package org.thoughtcrime.securesms.groups.v2;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.signal.storageservice.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.protos.groups.Member;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ChangeBuilder {
|
||||
|
||||
private final DecryptedGroupChange.Builder builder;
|
||||
private final DecryptedGroupChange.Builder builder;
|
||||
@Nullable private final UUID editor;
|
||||
|
||||
public static ChangeBuilder changeBy(@NonNull UUID editor) {
|
||||
return new ChangeBuilder(editor);
|
||||
@@ -31,12 +37,14 @@ public final class ChangeBuilder {
|
||||
}
|
||||
|
||||
ChangeBuilder(@NonNull UUID editor) {
|
||||
builder = DecryptedGroupChange.newBuilder()
|
||||
.setEditor(UuidUtil.toByteString(editor));
|
||||
this.editor = editor;
|
||||
this.builder = DecryptedGroupChange.newBuilder()
|
||||
.setEditor(UuidUtil.toByteString(editor));
|
||||
}
|
||||
|
||||
ChangeBuilder() {
|
||||
builder = DecryptedGroupChange.newBuilder();
|
||||
this.editor = null;
|
||||
this.builder = DecryptedGroupChange.newBuilder();
|
||||
}
|
||||
|
||||
public ChangeBuilder addMember(@NonNull UUID newMember) {
|
||||
@@ -139,7 +147,58 @@ public final class ChangeBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChangeBuilder inviteLinkAccess(@NonNull AccessControl.AccessRequired accessRequired) {
|
||||
builder.setNewInviteLinkAccess(accessRequired);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChangeBuilder resetGroupLink() {
|
||||
builder.setNewInviteLinkPassword(ByteString.copyFrom(GroupLinkPassword.createNew().serialize()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChangeBuilder requestJoin() {
|
||||
if (editor == null) throw new AssertionError();
|
||||
return requestJoin(editor, newProfileKey());
|
||||
}
|
||||
|
||||
public ChangeBuilder requestJoin(@NonNull UUID requester) {
|
||||
return requestJoin(requester, newProfileKey());
|
||||
}
|
||||
|
||||
public ChangeBuilder requestJoin(@NonNull ProfileKey profileKey) {
|
||||
if (editor == null) throw new AssertionError();
|
||||
return requestJoin(editor, profileKey);
|
||||
}
|
||||
|
||||
public ChangeBuilder requestJoin(@NonNull UUID requester, @NonNull ProfileKey profileKey) {
|
||||
builder.addNewRequestingMembers(DecryptedRequestingMember.newBuilder()
|
||||
.setUuid(UuidUtil.toByteString(requester))
|
||||
.setProfileKey(ByteString.copyFrom(profileKey.serialize())));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChangeBuilder approveRequest(@NonNull UUID approvedMember) {
|
||||
builder.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
|
||||
.setRole(Member.Role.DEFAULT)
|
||||
.setUuid(UuidUtil.toByteString(approvedMember)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChangeBuilder denyRequest(@NonNull UUID approvedMember) {
|
||||
builder.addDeleteRequestingMembers(UuidUtil.toByteString(approvedMember));
|
||||
return this;
|
||||
}
|
||||
|
||||
public DecryptedGroupChange build() {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static ProfileKey newProfileKey() {
|
||||
try {
|
||||
return new ProfileKey(Util.getSecretBytes(32));
|
||||
} catch (InvalidInputException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.junit.Test;
|
||||
import org.signal.storageservice.protos.groups.GroupInviteLink;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||
import org.thoughtcrime.securesms.util.Base64UrlSafe;
|
||||
import org.whispersystems.util.Base64UrlSafe;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -6,13 +6,11 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.testutil.LogRecorder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.thoughtcrime.securesms.groups.v2.ChangeBuilder.changeBy;
|
||||
@@ -179,4 +177,29 @@ public final class ProfileKeySetTest {
|
||||
assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty());
|
||||
assertThat(logRecorder.getWarnings(), hasMessages("Bad profile key in group"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void new_requesting_member_if_editor_is_authoritative() {
|
||||
UUID editor = UUID.randomUUID();
|
||||
ProfileKey profileKey = ProfileKeyUtil.createNew();
|
||||
ProfileKeySet profileKeySet = new ProfileKeySet();
|
||||
|
||||
profileKeySet.addKeysFromGroupChange(changeBy(editor).requestJoin(profileKey).build());
|
||||
|
||||
assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(editor, profileKey)));
|
||||
assertTrue(profileKeySet.getProfileKeys().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void new_requesting_member_if_not_editor_is_not_authoritative() {
|
||||
UUID editor = UUID.randomUUID();
|
||||
UUID requesting = UUID.randomUUID();
|
||||
ProfileKey profileKey = ProfileKeyUtil.createNew();
|
||||
ProfileKeySet profileKeySet = new ProfileKeySet();
|
||||
|
||||
profileKeySet.addKeysFromGroupChange(changeBy(editor).requestJoin(requesting, profileKey).build());
|
||||
|
||||
assertTrue(profileKeySet.getAuthoritativeProfileKeys().isEmpty());
|
||||
assertThat(profileKeySet.getProfileKeys(), is(Collections.singletonMap(requesting, profileKey)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user