Integrate call links create/update/read apis.

This commit is contained in:
Alex Hart
2023-05-19 10:28:29 -03:00
committed by Nicholas Tinsley
parent 4d6d31d624
commit 5a38143987
60 changed files with 1986 additions and 191 deletions

View File

@@ -3,15 +3,26 @@ package org.thoughtcrime.securesms.groups;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.zkgroup.GenericServerPublicParams;
import org.signal.libsignal.zkgroup.GenericServerSecretParams;
import org.signal.libsignal.zkgroup.VerificationFailedException;
import org.signal.libsignal.zkgroup.auth.AuthCredentialWithPniResponse;
import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredential;
import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredentialPresentation;
import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredentialResponse;
import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams;
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException;
import org.whispersystems.signalservice.api.push.ServiceIds;
import java.io.IOException;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -33,10 +44,10 @@ public class GroupsV2Authorization {
{
final long today = currentDaySeconds();
Map<Long, AuthCredentialWithPniResponse> credentials = authCache.read();
GroupsV2Api.CredentialResponseMaps credentials = authCache.read();
try {
return getAuthorization(serviceIds, groupSecretParams, credentials, today);
return getAuthorization(serviceIds, groupSecretParams, credentials.getAuthCredentialWithPniResponseHashMap(), today);
} catch (NoCredentialForRedemptionTimeException e) {
Log.i(TAG, "Auth out of date, will update auth and try again");
authCache.clear();
@@ -50,13 +61,54 @@ public class GroupsV2Authorization {
authCache.write(credentials);
try {
return getAuthorization(serviceIds, groupSecretParams, credentials, today);
return getAuthorization(serviceIds, groupSecretParams, credentials.getAuthCredentialWithPniResponseHashMap(), today);
} catch (NoCredentialForRedemptionTimeException e) {
Log.w(TAG, "The credentials returned did not include the day requested");
throw new IOException("Failed to get credentials");
}
}
public CallLinkAuthCredentialPresentation getCallLinkAuthorizationForToday(@NonNull GenericServerPublicParams genericServerPublicParams,
@NonNull CallLinkSecretParams callLinkSecretParams)
throws IOException, VerificationFailedException
{
final long today = currentDaySeconds();
GroupsV2Api.CredentialResponseMaps credentials = authCache.read();
try {
return getCallLinkAuthCredentialPresentation(
genericServerPublicParams,
callLinkSecretParams,
credentials.getCallLinkAuthCredentialResponseHashMap(),
today
);
} catch (NoCredentialForRedemptionTimeException e) {
Log.i(TAG, "Auth out of date, will update auth and try again");
authCache.clear();
} catch (VerificationFailedException e) {
Log.w(TAG, "Verification failed, will update auth and try again", e);
authCache.clear();
}
Log.i(TAG, "Getting new auth credential responses");
credentials = groupsV2Api.getCredentials(today);
authCache.write(credentials);
try {
return getCallLinkAuthCredentialPresentation(
genericServerPublicParams,
callLinkSecretParams,
credentials.getCallLinkAuthCredentialResponseHashMap(),
today
);
} catch (NoCredentialForRedemptionTimeException e) {
Log.w(TAG, "The credentials returned did not include the day requested");
throw new IOException("Failed to get credentials");
}
}
public void clear() {
authCache.clear();
}
@@ -65,6 +117,32 @@ public class GroupsV2Authorization {
return TimeUnit.DAYS.toSeconds(TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()));
}
private CallLinkAuthCredentialPresentation getCallLinkAuthCredentialPresentation(GenericServerPublicParams genericServerPublicParams,
CallLinkSecretParams callLinkSecretParams,
Map<Long, CallLinkAuthCredentialResponse> credentials,
long todaySeconds)
throws NoCredentialForRedemptionTimeException, VerificationFailedException
{
CallLinkAuthCredentialResponse authCredentialResponse = credentials.get(todaySeconds);
if (authCredentialResponse == null) {
throw new NoCredentialForRedemptionTimeException();
}
CallLinkAuthCredential credential = authCredentialResponse.receive(
Recipient.self().requireServiceId().uuid(),
Instant.ofEpochSecond(todaySeconds),
genericServerPublicParams
);
return credential.present(
Recipient.self().requireServiceId().uuid(),
Instant.ofEpochSecond(todaySeconds),
genericServerPublicParams,
callLinkSecretParams
);
}
private GroupsV2AuthorizationString getAuthorization(ServiceIds serviceIds,
GroupSecretParams groupSecretParams,
Map<Long, AuthCredentialWithPniResponse> credentials,
@@ -84,8 +162,8 @@ public class GroupsV2Authorization {
void clear();
@NonNull Map<Long, AuthCredentialWithPniResponse> read();
@NonNull GroupsV2Api.CredentialResponseMaps read();
void write(@NonNull Map<Long, AuthCredentialWithPniResponse> values);
void write(@NonNull GroupsV2Api.CredentialResponseMaps values);
}
}

View File

@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.groups;
import androidx.annotation.NonNull;
import org.signal.libsignal.zkgroup.auth.AuthCredentialWithPniResponse;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
import java.util.Collections;
import java.util.HashMap;
@@ -10,8 +11,8 @@ import java.util.Map;
public final class GroupsV2AuthorizationMemoryValueCache implements GroupsV2Authorization.ValueCache {
private final GroupsV2Authorization.ValueCache inner;
private Map<Long, AuthCredentialWithPniResponse> values;
private final GroupsV2Authorization.ValueCache inner;
private GroupsV2Api.CredentialResponseMaps values;
public GroupsV2AuthorizationMemoryValueCache(@NonNull GroupsV2Authorization.ValueCache inner) {
this.inner = inner;
@@ -24,8 +25,8 @@ public final class GroupsV2AuthorizationMemoryValueCache implements GroupsV2Auth
}
@Override
public @NonNull synchronized Map<Long, AuthCredentialWithPniResponse> read() {
Map<Long, AuthCredentialWithPniResponse> map = values;
public @NonNull synchronized GroupsV2Api.CredentialResponseMaps read() {
GroupsV2Api.CredentialResponseMaps map = values;
if (map == null) {
map = inner.read();
@@ -36,8 +37,8 @@ public final class GroupsV2AuthorizationMemoryValueCache implements GroupsV2Auth
}
@Override
public synchronized void write(@NonNull Map<Long, AuthCredentialWithPniResponse> values) {
public synchronized void write(@NonNull GroupsV2Api.CredentialResponseMaps values) {
inner.write(values);
this.values = Collections.unmodifiableMap(new HashMap<>(values));
this.values = values.createUnmodifiableCopy();
}
}