diff --git a/.editorconfig b/.editorconfig index 6e2269f..8faa189 100644 --- a/.editorconfig +++ b/.editorconfig @@ -149,7 +149,7 @@ ij_java_generate_final_parameters = true ij_java_if_brace_force = always ij_java_imports_layout = $*,|,* ij_java_indent_case_from_switch = true -ij_java_insert_inner_class_imports = true +ij_java_insert_inner_class_imports = false ij_java_insert_override_annotation = true ij_java_keep_blank_lines_before_right_brace = 2 ij_java_keep_blank_lines_between_package_declaration_and_header = 2 diff --git a/src/test/java/org/signal/storageservice/controllers/BaseGroupsControllerTest.java b/src/test/java/org/signal/storageservice/controllers/BaseGroupsControllerTest.java index 20696fd..fafbb51 100644 --- a/src/test/java/org/signal/storageservice/controllers/BaseGroupsControllerTest.java +++ b/src/test/java/org/signal/storageservice/controllers/BaseGroupsControllerTest.java @@ -15,7 +15,6 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.common.io.BaseEncoding; import com.google.protobuf.ByteString; import io.dropwizard.auth.AuthValueFactoryProvider; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -34,6 +33,7 @@ import org.mockito.ArgumentCaptor; import org.signal.libsignal.zkgroup.InvalidInputException; import org.signal.libsignal.zkgroup.NotarySignature; import org.signal.libsignal.zkgroup.VerificationFailedException; +import org.signal.libsignal.zkgroup.auth.ClientZkAuthOperations; import org.signal.libsignal.zkgroup.groups.GroupPublicParams; import org.signal.libsignal.zkgroup.groups.GroupSecretParams; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; @@ -65,9 +65,13 @@ abstract class BaseGroupsControllerTest { protected final ProfileKeyCredentialPresentation validUserThreePresentation = new ClientZkProfileOperations(AuthHelper.GROUPS_SERVER_KEY.getPublicParams()).createProfileKeyCredentialPresentation(groupSecretParams, AuthHelper.VALID_USER_THREE_PROFILE_CREDENTIAL); protected final ProfileKeyCredentialPresentation validUserFourPresentation = new ClientZkProfileOperations(AuthHelper.GROUPS_SERVER_KEY.getPublicParams()).createProfileKeyCredentialPresentation(groupSecretParams, AuthHelper.VALID_USER_FOUR_PROFILE_CREDENTIAL); protected final ByteString validUserId = ByteString.copyFrom(validUserPresentation.getUuidCiphertext().serialize()); + protected final ByteString validUserPniId = ByteString.copyFrom(new ClientZkAuthOperations(AuthHelper.GROUPS_SERVER_KEY.getPublicParams()).createAuthCredentialPresentation(groupSecretParams, AuthHelper.VALID_USER_PNI_AUTH_CREDENTIAL).getPniCiphertext().serialize()); protected final ByteString validUserTwoId = ByteString.copyFrom(validUserTwoPresentation.getUuidCiphertext().serialize()); + protected final ByteString validUserTwoPniId = ByteString.copyFrom(new ClientZkAuthOperations(AuthHelper.GROUPS_SERVER_KEY.getPublicParams()).createAuthCredentialPresentation(groupSecretParams, AuthHelper.VALID_USER_TWO_PNI_AUTH_CREDENTIAL).getPniCiphertext().serialize()); protected final ByteString validUserThreeId = ByteString.copyFrom(validUserThreePresentation.getUuidCiphertext().serialize()); + protected final ByteString validUserThreePniId = ByteString.copyFrom(new ClientZkAuthOperations(AuthHelper.GROUPS_SERVER_KEY.getPublicParams()).createAuthCredentialPresentation(groupSecretParams, AuthHelper.VALID_USER_THREE_PNI_AUTH_CREDENTIAL).getPniCiphertext().serialize()); protected final ByteString validUserFourId = ByteString.copyFrom(validUserFourPresentation.getUuidCiphertext().serialize()); + protected final ByteString validUserFourPniId = ByteString.copyFrom(new ClientZkAuthOperations(AuthHelper.GROUPS_SERVER_KEY.getPublicParams()).createAuthCredentialPresentation(groupSecretParams, AuthHelper.VALID_USER_FOUR_PNI_AUTH_CREDENTIAL).getPniCiphertext().serialize()); protected final GroupsManager groupsManager = mock(GroupsManager.class); protected final Clock clock = mock(Clock.class); protected long currentTime; @@ -82,13 +86,13 @@ abstract class BaseGroupsControllerTest { .setAvatar(avatarFor(groupPublicParams.getGroupIdentifier().serialize())) .setVersion(0) .addMembers(Member.newBuilder() - .setUserId(ByteString.copyFrom(validUserPresentation.getUuidCiphertext().serialize())) + .setUserId(validUserId) .setProfileKey(ByteString.copyFrom(validUserPresentation.getProfileKeyCiphertext().serialize())) .setRole(Member.Role.ADMINISTRATOR) .setJoinedAtVersion(0) .build()) .addMembers(Member.newBuilder() - .setUserId(ByteString.copyFrom(validUserTwoPresentation.getUuidCiphertext().serialize())) + .setUserId(validUserTwoId) .setProfileKey(ByteString.copyFrom(validUserTwoPresentation.getProfileKeyCiphertext().serialize())) .setRole(Member.Role.DEFAULT) .setJoinedAtVersion(0) diff --git a/src/test/java/org/signal/storageservice/controllers/GroupsControllerPhoneNumberPrivacyTest.java b/src/test/java/org/signal/storageservice/controllers/GroupsControllerPhoneNumberPrivacyTest.java new file mode 100644 index 0000000..02b7afc --- /dev/null +++ b/src/test/java/org/signal/storageservice/controllers/GroupsControllerPhoneNumberPrivacyTest.java @@ -0,0 +1,47 @@ +package org.signal.storageservice.controllers; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; +import org.junit.jupiter.api.Test; +import org.signal.storageservice.providers.ProtocolBufferMediaType; +import org.signal.storageservice.storage.protos.groups.Group; +import org.signal.storageservice.storage.protos.groups.GroupChange; +import org.signal.storageservice.storage.protos.groups.Member; +import org.signal.storageservice.storage.protos.groups.MemberPendingProfileKey; +import org.signal.storageservice.util.AuthHelper; + +class GroupsControllerPhoneNumberPrivacyTest extends BaseGroupsControllerTest { + + @Test + void testRejectInvitationFromPni() throws Exception { + Group.Builder groupBuilder = Group.newBuilder(this.group) + .addMembersPendingProfileKey(MemberPendingProfileKey.newBuilder() + .setMember(Member.newBuilder() + .setUserId(validUserThreePniId) + .setRole(Member.Role.DEFAULT) + .setJoinedAtVersion(0) + .build()) + .setAddedByUserId(validUserId) + .setTimestamp(currentTime) + .build()); + + setupGroupsManagerBehaviors(groupBuilder.build()); + + GroupChange.Actions.Builder actionsBuilder = GroupChange.Actions.newBuilder() + .setVersion(1) + .addDeleteMembersPendingProfileKey(GroupChange.Actions.DeleteMemberPendingProfileKeyAction.newBuilder() + .setDeletedUserId(validUserThreePniId) + .build()); + + groupBuilder.clearMembersPendingProfileKey().setVersion(1); + + try (Response response = resources.getJerseyTest() + .target("/v1/groups/") + .request(ProtocolBufferMediaType.APPLICATION_PROTOBUF) + .header("Authorization", AuthHelper.getAuthHeader(groupSecretParams, AuthHelper.VALID_USER_THREE_PNI_AUTH_CREDENTIAL)) + .method("PATCH", Entity.entity(actionsBuilder.build().toByteArray(), ProtocolBufferMediaType.APPLICATION_PROTOBUF))) { + + verifyGroupModification(groupBuilder, actionsBuilder, 0, response, validUserThreePniId); + } + } +} diff --git a/src/test/java/org/signal/storageservice/util/AuthHelper.java b/src/test/java/org/signal/storageservice/util/AuthHelper.java index bfe978d..6a1f0ef 100644 --- a/src/test/java/org/signal/storageservice/util/AuthHelper.java +++ b/src/test/java/org/signal/storageservice/util/AuthHelper.java @@ -46,6 +46,7 @@ import org.signal.storageservice.auth.UserAuthenticator; public class AuthHelper { public static final String VALID_USER = UUID.randomUUID().toString(); + public static final UUID VALID_USER_PNI = UUID.randomUUID(); public static final byte[] VALID_USER_PROFILE_KEY = new byte[32]; public static final String VALID_PASSWORD = "foo"; @@ -55,10 +56,12 @@ public class AuthHelper { public static final String VALID_PASSWORD_TWO = "bar"; public static final String VALID_USER_THREE = UUID.randomUUID().toString(); + public static final UUID VALID_USER_THREE_PNI = UUID.randomUUID(); public static final byte[] VALID_USER_THREE_PROFILE_KEY = new byte[32]; public static final String VALID_PASSWORD_THREE = "baz"; public static final String VALID_USER_FOUR = UUID.randomUUID().toString(); + public static final UUID VALID_USER_FOUR_PNI = UUID.randomUUID(); public static final byte[] VALID_USER_FOUR_PROFILE_KEY = new byte[32]; public static final String VALID_PASSWORD_FOUR = "password"; @@ -69,10 +72,13 @@ public class AuthHelper { public static final ServerSecretParams GROUPS_SERVER_KEY = ServerSecretParams.generate(); public static final AuthCredential VALID_USER_AUTH_CREDENTIAL; + public static final AuthCredentialWithPni VALID_USER_PNI_AUTH_CREDENTIAL; public static final AuthCredential VALID_USER_TWO_AUTH_CREDENTIAL; public static final AuthCredentialWithPni VALID_USER_TWO_PNI_AUTH_CREDENTIAL; public static final AuthCredential VALID_USER_THREE_AUTH_CREDENTIAL; + public static final AuthCredentialWithPni VALID_USER_THREE_PNI_AUTH_CREDENTIAL; public static final AuthCredential VALID_USER_FOUR_AUTH_CREDENTIAL; + public static final AuthCredentialWithPni VALID_USER_FOUR_PNI_AUTH_CREDENTIAL; public static final ProfileKeyCredential VALID_USER_PROFILE_CREDENTIAL; public static final ProfileKeyCredential VALID_USER_TWO_PROFILE_CREDENTIAL; @@ -84,16 +90,22 @@ public class AuthHelper { int redemptionTime = Util.currentDaysSinceEpoch(); Instant redemptionInstant = Instant.EPOCH.plus(Duration.ofDays(redemptionTime)); AuthCredentialResponse validUserResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredential(UUID.fromString(VALID_USER ), redemptionTime); + AuthCredentialWithPniResponse validUserPniResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredentialWithPni(UUID.fromString(VALID_USER), VALID_USER_PNI, redemptionInstant); AuthCredentialResponse validUserTwoResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredential(UUID.fromString(VALID_USER_TWO), redemptionTime); AuthCredentialWithPniResponse validUserTwoPniResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredentialWithPni(UUID.fromString(VALID_USER_TWO), VALID_USER_TWO_PNI, redemptionInstant); AuthCredentialResponse validUserThreeResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredential(UUID.fromString(VALID_USER_THREE), redemptionTime); + AuthCredentialWithPniResponse validUserThreePniResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredentialWithPni(UUID.fromString(VALID_USER_THREE), VALID_USER_THREE_PNI, redemptionInstant); AuthCredentialResponse validUserFourResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredential(UUID.fromString(VALID_USER_FOUR), redemptionTime); + AuthCredentialWithPniResponse validUserFourPniResponse = new ServerZkAuthOperations(GROUPS_SERVER_KEY).issueAuthCredentialWithPni(UUID.fromString(VALID_USER_FOUR), VALID_USER_FOUR_PNI, redemptionInstant); VALID_USER_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredential(UUID.fromString(VALID_USER), redemptionTime, validUserResponse); + VALID_USER_PNI_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredentialWithPni(UUID.fromString(VALID_USER), VALID_USER_PNI, redemptionInstant.getEpochSecond(), validUserPniResponse); VALID_USER_TWO_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredential(UUID.fromString(VALID_USER_TWO), redemptionTime, validUserTwoResponse); VALID_USER_TWO_PNI_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredentialWithPni(UUID.fromString(VALID_USER_TWO), VALID_USER_TWO_PNI, redemptionInstant.getEpochSecond(), validUserTwoPniResponse); VALID_USER_THREE_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredential(UUID.fromString(VALID_USER_THREE), redemptionTime, validUserThreeResponse); + VALID_USER_THREE_PNI_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredentialWithPni(UUID.fromString(VALID_USER_THREE), VALID_USER_THREE_PNI, redemptionInstant.getEpochSecond(), validUserThreePniResponse); VALID_USER_FOUR_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredential(UUID.fromString(VALID_USER_FOUR), redemptionTime, validUserFourResponse); + VALID_USER_FOUR_PNI_AUTH_CREDENTIAL = new ClientZkAuthOperations(GROUPS_SERVER_KEY.getPublicParams()).receiveAuthCredentialWithPni(UUID.fromString(VALID_USER_FOUR), VALID_USER_FOUR_PNI, redemptionInstant.getEpochSecond(), validUserFourPniResponse); final SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(VALID_USER_PROFILE_KEY);