mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-30 02:50:39 +00:00
Reformat project
This commit is contained in:
parent
4f2261e86f
commit
591c0fe8a3
51 changed files with 579 additions and 335 deletions
28
src/main/java/org/asamk/signal/manager/GroupUtils.java
Normal file
28
src/main/java/org/asamk/signal/manager/GroupUtils.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package org.asamk.signal.manager;
|
||||
|
||||
import org.asamk.signal.storage.groups.GroupInfo;
|
||||
import org.asamk.signal.storage.groups.GroupInfoV1;
|
||||
import org.asamk.signal.storage.groups.GroupInfoV2;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
|
||||
|
||||
public class GroupUtils {
|
||||
|
||||
public static void setGroupContext(
|
||||
final SignalServiceDataMessage.Builder messageBuilder, final GroupInfo groupInfo
|
||||
) {
|
||||
if (groupInfo instanceof GroupInfoV1) {
|
||||
SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER)
|
||||
.withId(groupInfo.groupId)
|
||||
.build();
|
||||
messageBuilder.asGroupMessage(group);
|
||||
} else {
|
||||
final GroupInfoV2 groupInfoV2 = (GroupInfoV2) groupInfo;
|
||||
SignalServiceGroupV2 group = SignalServiceGroupV2.newBuilder(groupInfoV2.getMasterKey())
|
||||
.withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().getRevision())
|
||||
.build();
|
||||
messageBuilder.asGroupMessage(group);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,8 +30,7 @@ class SendReceiptAction implements HandleAction {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final SendReceiptAction that = (SendReceiptAction) o;
|
||||
return timestamp == that.timestamp &&
|
||||
address.equals(that.address);
|
||||
return timestamp == that.timestamp && address.equals(that.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,8 +110,7 @@ class SendGroupInfoRequestAction implements HandleAction {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final SendGroupInfoRequestAction that = (SendGroupInfoRequestAction) o;
|
||||
return address.equals(that.address) &&
|
||||
Arrays.equals(groupId, that.groupId);
|
||||
return address.equals(that.address) && Arrays.equals(groupId, that.groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -143,8 +141,7 @@ class SendGroupUpdateAction implements HandleAction {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final SendGroupUpdateAction that = (SendGroupUpdateAction) o;
|
||||
return address.equals(that.address) &&
|
||||
Arrays.equals(groupId, that.groupId);
|
||||
return address.equals(that.address) && Arrays.equals(groupId, that.groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -704,7 +704,7 @@ public class Manager implements Closeable {
|
|||
) throws IOException, GroupNotFoundException, NotAGroupMemberException {
|
||||
final GroupInfo g = getGroupForSending(groupId);
|
||||
|
||||
GroupHelper.setGroupContext(messageBuilder, g);
|
||||
GroupUtils.setGroupContext(messageBuilder, g);
|
||||
messageBuilder.withExpiration(g.getMessageExpirationTime());
|
||||
|
||||
return sendMessage(messageBuilder, g.getMembersWithout(account.getSelfAddress()));
|
||||
|
|
|
@ -7,11 +7,7 @@ public class PathConfig {
|
|||
private final String avatarsPath;
|
||||
|
||||
public static PathConfig createDefault(final String settingsPath) {
|
||||
return new PathConfig(
|
||||
settingsPath + "/data",
|
||||
settingsPath + "/attachments",
|
||||
settingsPath + "/avatars"
|
||||
);
|
||||
return new PathConfig(settingsPath + "/data", settingsPath + "/attachments", settingsPath + "/avatars");
|
||||
}
|
||||
|
||||
private PathConfig(final String dataPath, final String attachmentsPath, final String avatarsPath) {
|
||||
|
|
|
@ -70,12 +70,19 @@ public class ProvisioningManager {
|
|||
public String getDeviceLinkUri() throws TimeoutException, IOException {
|
||||
String deviceUuid = accountManager.getNewDeviceUuid();
|
||||
|
||||
return Utils.createDeviceLinkUri(new Utils.DeviceLinkInfo(deviceUuid, identityKey.getPublicKey().getPublicKey()));
|
||||
return Utils.createDeviceLinkUri(new Utils.DeviceLinkInfo(deviceUuid,
|
||||
identityKey.getPublicKey().getPublicKey()));
|
||||
}
|
||||
|
||||
public String finishDeviceLink(String deviceName) throws IOException, InvalidKeyException, TimeoutException, UserAlreadyExists {
|
||||
String signalingKey = KeyUtils.createSignalingKey();
|
||||
SignalServiceAccountManager.NewDeviceRegistrationReturn ret = accountManager.finishNewDeviceRegistration(identityKey, signalingKey, false, true, registrationId, deviceName);
|
||||
SignalServiceAccountManager.NewDeviceRegistrationReturn ret = accountManager.finishNewDeviceRegistration(
|
||||
identityKey,
|
||||
signalingKey,
|
||||
false,
|
||||
true,
|
||||
registrationId,
|
||||
deviceName);
|
||||
|
||||
String username = ret.getNumber();
|
||||
// TODO do this check before actually registering
|
||||
|
@ -96,7 +103,15 @@ public class ProvisioningManager {
|
|||
}
|
||||
}
|
||||
|
||||
try (SignalAccount account = SignalAccount.createLinkedAccount(pathConfig.getDataPath(), username, ret.getUuid(), password, ret.getDeviceId(), ret.getIdentity(), registrationId, signalingKey, profileKey)) {
|
||||
try (SignalAccount account = SignalAccount.createLinkedAccount(pathConfig.getDataPath(),
|
||||
username,
|
||||
ret.getUuid(),
|
||||
password,
|
||||
ret.getDeviceId(),
|
||||
ret.getIdentity(),
|
||||
registrationId,
|
||||
signalingKey,
|
||||
profileKey)) {
|
||||
account.save();
|
||||
|
||||
try (Manager m = new Manager(account, pathConfig, serviceConfiguration, userAgent)) {
|
||||
|
|
|
@ -61,26 +61,27 @@ public class ServiceConfig {
|
|||
}
|
||||
|
||||
public static SignalServiceConfiguration createDefaultServiceConfiguration(String userAgent) {
|
||||
final Interceptor userAgentInterceptor = chain ->
|
||||
chain.proceed(chain.request().newBuilder()
|
||||
.header("User-Agent", userAgent)
|
||||
.build());
|
||||
final Interceptor userAgentInterceptor = chain -> chain.proceed(chain.request()
|
||||
.newBuilder()
|
||||
.header("User-Agent", userAgent)
|
||||
.build());
|
||||
|
||||
final List<Interceptor> interceptors = Collections.singletonList(userAgentInterceptor);
|
||||
|
||||
return new SignalServiceConfiguration(
|
||||
new SignalServiceUrl[]{new SignalServiceUrl(URL, TRUST_STORE)},
|
||||
makeSignalCdnUrlMapFor(new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}),
|
||||
return new SignalServiceConfiguration(new SignalServiceUrl[]{new SignalServiceUrl(URL, TRUST_STORE)},
|
||||
makeSignalCdnUrlMapFor(new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)},
|
||||
new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}),
|
||||
new SignalContactDiscoveryUrl[0],
|
||||
new SignalKeyBackupServiceUrl[]{new SignalKeyBackupServiceUrl(SIGNAL_KEY_BACKUP_URL, TRUST_STORE)},
|
||||
new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)},
|
||||
interceptors,
|
||||
dns,
|
||||
zkGroupServerPublicParams
|
||||
);
|
||||
zkGroupServerPublicParams);
|
||||
}
|
||||
|
||||
private static Map<Integer, SignalCdnUrl[]> makeSignalCdnUrlMapFor(SignalCdnUrl[] cdn0Urls, SignalCdnUrl[] cdn2Urls) {
|
||||
private static Map<Integer, SignalCdnUrl[]> makeSignalCdnUrlMapFor(
|
||||
SignalCdnUrl[] cdn0Urls, SignalCdnUrl[] cdn2Urls
|
||||
) {
|
||||
return Map.of(0, cdn0Urls, 2, cdn2Urls);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,21 @@ class Utils {
|
|||
Optional<String> caption = Optional.absent();
|
||||
Optional<String> blurHash = Optional.absent();
|
||||
final Optional<ResumableUploadSpec> resumableUploadSpec = Optional.absent();
|
||||
return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, false, preview, 0, 0, uploadTimestamp, caption, blurHash, null, null, resumableUploadSpec);
|
||||
return new SignalServiceAttachmentStream(attachmentStream,
|
||||
mime,
|
||||
attachmentSize,
|
||||
Optional.of(attachmentFile.getName()),
|
||||
false,
|
||||
false,
|
||||
preview,
|
||||
0,
|
||||
0,
|
||||
uploadTimestamp,
|
||||
caption,
|
||||
blurHash,
|
||||
null,
|
||||
null,
|
||||
resumableUploadSpec);
|
||||
}
|
||||
|
||||
static StreamDetails createStreamDetailsFromFile(File file) throws IOException {
|
||||
|
@ -96,7 +110,8 @@ class Utils {
|
|||
|
||||
static CertificateValidator getCertificateValidator() {
|
||||
try {
|
||||
ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.decode(ServiceConfig.UNIDENTIFIED_SENDER_TRUST_ROOT), 0);
|
||||
ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.decode(ServiceConfig.UNIDENTIFIED_SENDER_TRUST_ROOT),
|
||||
0);
|
||||
return new CertificateValidator(unidentifiedSenderTrustRoot);
|
||||
} catch (InvalidKeyException | IOException e) {
|
||||
throw new AssertionError(e);
|
||||
|
@ -116,7 +131,11 @@ class Utils {
|
|||
}
|
||||
|
||||
static String createDeviceLinkUri(DeviceLinkInfo info) {
|
||||
return "tsdevice:/?uuid=" + URLEncoder.encode(info.deviceIdentifier, StandardCharsets.UTF_8) + "&pub_key=" + URLEncoder.encode(Base64.encodeBytesWithoutPadding(info.deviceKey.serialize()), StandardCharsets.UTF_8);
|
||||
return "tsdevice:/?uuid="
|
||||
+ URLEncoder.encode(info.deviceIdentifier, StandardCharsets.UTF_8)
|
||||
+ "&pub_key="
|
||||
+ URLEncoder.encode(Base64.encodeBytesWithoutPadding(info.deviceKey.serialize()),
|
||||
StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
static DeviceLinkInfo parseDeviceLinkUri(URI linkUri) throws IOException, InvalidKeyException {
|
||||
|
@ -180,7 +199,15 @@ class Utils {
|
|||
Optional<SignalServiceAddress> addressOptional = sourceUuid == null && source.isEmpty()
|
||||
? Optional.absent()
|
||||
: Optional.of(new SignalServiceAddress(sourceUuid, source));
|
||||
return new SignalServiceEnvelope(type, addressOptional, sourceDevice, timestamp, legacyMessage, content, serverReceivedTimestamp, serverDeliveredTimestamp, uuid);
|
||||
return new SignalServiceEnvelope(type,
|
||||
addressOptional,
|
||||
sourceDevice,
|
||||
timestamp,
|
||||
legacyMessage,
|
||||
content,
|
||||
serverReceivedTimestamp,
|
||||
serverDeliveredTimestamp,
|
||||
uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,13 +257,18 @@ class Utils {
|
|||
return outputFile;
|
||||
}
|
||||
|
||||
static String computeSafetyNumber(SignalServiceAddress ownAddress, IdentityKey ownIdentityKey, SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
|
||||
static String computeSafetyNumber(
|
||||
SignalServiceAddress ownAddress,
|
||||
IdentityKey ownIdentityKey,
|
||||
SignalServiceAddress theirAddress,
|
||||
IdentityKey theirIdentityKey
|
||||
) {
|
||||
int version;
|
||||
byte[] ownId;
|
||||
byte[] theirId;
|
||||
|
||||
if (ServiceConfig.capabilities.isUuid()
|
||||
&& ownAddress.getUuid().isPresent() && theirAddress.getUuid().isPresent()) {
|
||||
if (ServiceConfig.capabilities.isUuid() && ownAddress.getUuid().isPresent() && theirAddress.getUuid()
|
||||
.isPresent()) {
|
||||
// Version 2: UUID user
|
||||
version = 2;
|
||||
ownId = UuidUtil.toByteArray(ownAddress.getUuid().get());
|
||||
|
@ -251,7 +283,11 @@ class Utils {
|
|||
theirId = theirAddress.getNumber().get().getBytes();
|
||||
}
|
||||
|
||||
Fingerprint fingerprint = new NumericFingerprintGenerator(5200).createFor(version, ownId, ownIdentityKey, theirId, theirIdentityKey);
|
||||
Fingerprint fingerprint = new NumericFingerprintGenerator(5200).createFor(version,
|
||||
ownId,
|
||||
ownIdentityKey,
|
||||
theirId,
|
||||
theirIdentityKey);
|
||||
return fingerprint.getDisplayableFingerprint().getDisplayText();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
package org.asamk.signal.manager.helper;
|
||||
|
||||
import org.asamk.signal.storage.groups.GroupInfo;
|
||||
import org.asamk.signal.storage.groups.GroupInfoV1;
|
||||
import org.asamk.signal.storage.groups.GroupInfoV2;
|
||||
import org.signal.storageservice.protos.groups.Member;
|
||||
import org.signal.zkgroup.groups.GroupSecretParams;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -40,23 +34,6 @@ public class GroupHelper {
|
|||
this.groupsV2Operations = groupsV2Operations;
|
||||
}
|
||||
|
||||
public static void setGroupContext(
|
||||
final SignalServiceDataMessage.Builder messageBuilder, final GroupInfo groupInfo
|
||||
) {
|
||||
if (groupInfo instanceof GroupInfoV1) {
|
||||
SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER)
|
||||
.withId(groupInfo.groupId)
|
||||
.build();
|
||||
messageBuilder.asGroupMessage(group);
|
||||
} else {
|
||||
final GroupInfoV2 groupInfoV2 = (GroupInfoV2) groupInfo;
|
||||
SignalServiceGroupV2 group = SignalServiceGroupV2.newBuilder(groupInfoV2.getMasterKey())
|
||||
.withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().getRevision())
|
||||
.build();
|
||||
messageBuilder.asGroupMessage(group);
|
||||
}
|
||||
}
|
||||
|
||||
public GroupsV2Operations.NewGroup createGroupV2(
|
||||
String name, Collection<SignalServiceAddress> members, byte[] avatar
|
||||
) {
|
||||
|
|
|
@ -46,8 +46,7 @@ public final class ProfileHelper {
|
|||
}
|
||||
|
||||
public ProfileAndCredential retrieveProfileSync(
|
||||
SignalServiceAddress recipient,
|
||||
SignalServiceProfile.RequestType requestType
|
||||
SignalServiceAddress recipient, SignalServiceProfile.RequestType requestType
|
||||
) throws IOException {
|
||||
try {
|
||||
return retrieveProfile(recipient, requestType).get(10, TimeUnit.SECONDS);
|
||||
|
@ -65,28 +64,31 @@ public final class ProfileHelper {
|
|||
}
|
||||
|
||||
public ListenableFuture<ProfileAndCredential> retrieveProfile(
|
||||
SignalServiceAddress address,
|
||||
SignalServiceProfile.RequestType requestType
|
||||
SignalServiceAddress address, SignalServiceProfile.RequestType requestType
|
||||
) {
|
||||
Optional<UnidentifiedAccess> unidentifiedAccess = getUnidentifiedAccess(address);
|
||||
Optional<ProfileKey> profileKey = Optional.fromNullable(profileKeyProvider.getProfileKey(address));
|
||||
|
||||
if (unidentifiedAccess.isPresent()) {
|
||||
return new CascadingFuture<>(Arrays.asList(() -> getPipeRetrievalFuture(address, profileKey, unidentifiedAccess, requestType),
|
||||
return new CascadingFuture<>(Arrays.asList(() -> getPipeRetrievalFuture(address,
|
||||
profileKey,
|
||||
unidentifiedAccess,
|
||||
requestType),
|
||||
() -> getSocketRetrievalFuture(address, profileKey, unidentifiedAccess, requestType),
|
||||
() -> getPipeRetrievalFuture(address, profileKey, Optional.absent(), requestType),
|
||||
() -> getSocketRetrievalFuture(address, profileKey, Optional.absent(), requestType)),
|
||||
e -> !(e instanceof NotFoundException));
|
||||
} else {
|
||||
return new CascadingFuture<>(Arrays.asList(() -> getPipeRetrievalFuture(address, profileKey, Optional.absent(), requestType),
|
||||
() -> getSocketRetrievalFuture(address, profileKey, Optional.absent(), requestType)),
|
||||
return new CascadingFuture<>(Arrays.asList(() -> getPipeRetrievalFuture(address,
|
||||
profileKey,
|
||||
Optional.absent(),
|
||||
requestType), () -> getSocketRetrievalFuture(address, profileKey, Optional.absent(), requestType)),
|
||||
e -> !(e instanceof NotFoundException));
|
||||
}
|
||||
}
|
||||
|
||||
public String decryptName(
|
||||
ProfileKey profileKey,
|
||||
String encryptedName
|
||||
ProfileKey profileKey, String encryptedName
|
||||
) throws InvalidCiphertextException, IOException {
|
||||
if (encryptedName == null) {
|
||||
return null;
|
||||
|
|
|
@ -24,7 +24,12 @@ public class UnidentifiedAccessHelper {
|
|||
|
||||
private final UnidentifiedAccessSenderCertificateProvider senderCertificateProvider;
|
||||
|
||||
public UnidentifiedAccessHelper(final SelfProfileKeyProvider selfProfileKeyProvider, final ProfileKeyProvider profileKeyProvider, final ProfileProvider profileProvider, final UnidentifiedAccessSenderCertificateProvider senderCertificateProvider) {
|
||||
public UnidentifiedAccessHelper(
|
||||
final SelfProfileKeyProvider selfProfileKeyProvider,
|
||||
final ProfileKeyProvider profileKeyProvider,
|
||||
final ProfileProvider profileProvider,
|
||||
final UnidentifiedAccessSenderCertificateProvider senderCertificateProvider
|
||||
) {
|
||||
this.selfProfileKeyProvider = selfProfileKeyProvider;
|
||||
this.profileKeyProvider = profileKeyProvider;
|
||||
this.profileProvider = profileProvider;
|
||||
|
@ -62,19 +67,16 @@ public class UnidentifiedAccessHelper {
|
|||
}
|
||||
|
||||
try {
|
||||
return Optional.of(new UnidentifiedAccessPair(
|
||||
new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate),
|
||||
new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate)
|
||||
));
|
||||
return Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(selfUnidentifiedAccessKey,
|
||||
selfUnidentifiedAccessCertificate),
|
||||
new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate)));
|
||||
} catch (InvalidCertificateException e) {
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Optional<UnidentifiedAccessPair>> getAccessFor(Collection<SignalServiceAddress> recipients) {
|
||||
return recipients.stream()
|
||||
.map(this::getAccessFor)
|
||||
.collect(Collectors.toList());
|
||||
return recipients.stream().map(this::getAccessFor).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Optional<UnidentifiedAccessPair> getAccessFor(SignalServiceAddress recipient) {
|
||||
|
@ -82,15 +84,16 @@ public class UnidentifiedAccessHelper {
|
|||
byte[] selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey();
|
||||
byte[] selfUnidentifiedAccessCertificate = senderCertificateProvider.getSenderCertificate();
|
||||
|
||||
if (recipientUnidentifiedAccessKey == null || selfUnidentifiedAccessKey == null || selfUnidentifiedAccessCertificate == null) {
|
||||
if (recipientUnidentifiedAccessKey == null
|
||||
|| selfUnidentifiedAccessKey == null
|
||||
|| selfUnidentifiedAccessCertificate == null) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
try {
|
||||
return Optional.of(new UnidentifiedAccessPair(
|
||||
new UnidentifiedAccess(recipientUnidentifiedAccessKey, selfUnidentifiedAccessCertificate),
|
||||
new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate)
|
||||
));
|
||||
return Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(recipientUnidentifiedAccessKey,
|
||||
selfUnidentifiedAccessCertificate),
|
||||
new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate)));
|
||||
} catch (InvalidCertificateException e) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue