]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/SignalDependencies.java
Update libsignal-service-java
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / SignalDependencies.java
1 package org.asamk.signal.manager;
2
3 import org.asamk.signal.manager.config.ServiceConfig;
4 import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
5 import org.signal.libsignal.metadata.certificate.CertificateValidator;
6 import org.signal.zkgroup.profiles.ClientZkProfileOperations;
7 import org.whispersystems.libsignal.util.guava.Optional;
8 import org.whispersystems.signalservice.api.KeyBackupService;
9 import org.whispersystems.signalservice.api.SignalServiceAccountManager;
10 import org.whispersystems.signalservice.api.SignalServiceDataStore;
11 import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
12 import org.whispersystems.signalservice.api.SignalServiceMessageSender;
13 import org.whispersystems.signalservice.api.SignalSessionLock;
14 import org.whispersystems.signalservice.api.SignalWebSocket;
15 import org.whispersystems.signalservice.api.crypto.SignalServiceCipher;
16 import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
17 import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
18 import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
19 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
20 import org.whispersystems.signalservice.api.services.ProfileService;
21 import org.whispersystems.signalservice.api.util.CredentialsProvider;
22 import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
23 import org.whispersystems.signalservice.api.websocket.WebSocketFactory;
24 import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
25
26 import java.util.concurrent.ExecutorService;
27 import java.util.function.Supplier;
28
29 import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
30
31 public class SignalDependencies {
32
33 private final Object LOCK = new Object();
34
35 private final ServiceEnvironmentConfig serviceEnvironmentConfig;
36 private final String userAgent;
37 private final CredentialsProvider credentialsProvider;
38 private final SignalServiceDataStore dataStore;
39 private final ExecutorService executor;
40 private final SignalSessionLock sessionLock;
41
42 private SignalServiceAccountManager accountManager;
43 private GroupsV2Api groupsV2Api;
44 private GroupsV2Operations groupsV2Operations;
45 private ClientZkOperations clientZkOperations;
46
47 private SignalWebSocket signalWebSocket;
48 private SignalServiceMessageReceiver messageReceiver;
49 private SignalServiceMessageSender messageSender;
50
51 private KeyBackupService keyBackupService;
52 private ProfileService profileService;
53 private SignalServiceCipher cipher;
54
55 SignalDependencies(
56 final ServiceEnvironmentConfig serviceEnvironmentConfig,
57 final String userAgent,
58 final CredentialsProvider credentialsProvider,
59 final SignalServiceDataStore dataStore,
60 final ExecutorService executor,
61 final SignalSessionLock sessionLock
62 ) {
63 this.serviceEnvironmentConfig = serviceEnvironmentConfig;
64 this.userAgent = userAgent;
65 this.credentialsProvider = credentialsProvider;
66 this.dataStore = dataStore;
67 this.executor = executor;
68 this.sessionLock = sessionLock;
69 }
70
71 public void resetAfterAddressChange() {
72 this.messageSender = null;
73 this.cipher = null;
74 }
75
76 public ServiceEnvironmentConfig getServiceEnvironmentConfig() {
77 return serviceEnvironmentConfig;
78 }
79
80 public SignalServiceAccountManager getAccountManager() {
81 return getOrCreate(() -> accountManager,
82 () -> accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
83 credentialsProvider,
84 userAgent,
85 getGroupsV2Operations(),
86 ServiceConfig.AUTOMATIC_NETWORK_RETRY));
87 }
88
89 public SignalServiceAccountManager createUnauthenticatedAccountManager(String number, String password) {
90 return new SignalServiceAccountManager(getServiceEnvironmentConfig().getSignalServiceConfiguration(),
91 null,
92 number,
93 SignalServiceAddress.DEFAULT_DEVICE_ID,
94 password,
95 userAgent,
96 ServiceConfig.AUTOMATIC_NETWORK_RETRY);
97 }
98
99 public GroupsV2Api getGroupsV2Api() {
100 return getOrCreate(() -> groupsV2Api, () -> groupsV2Api = getAccountManager().getGroupsV2Api());
101 }
102
103 public GroupsV2Operations getGroupsV2Operations() {
104 return getOrCreate(() -> groupsV2Operations,
105 () -> groupsV2Operations = capabilities.isGv2() ? new GroupsV2Operations(ClientZkOperations.create(
106 serviceEnvironmentConfig.getSignalServiceConfiguration())) : null);
107 }
108
109 private ClientZkOperations getClientZkOperations() {
110 return getOrCreate(() -> clientZkOperations,
111 () -> clientZkOperations = capabilities.isGv2()
112 ? ClientZkOperations.create(serviceEnvironmentConfig.getSignalServiceConfiguration())
113 : null);
114 }
115
116 private ClientZkProfileOperations getClientZkProfileOperations() {
117 final var clientZkOperations = getClientZkOperations();
118 return clientZkOperations == null ? null : clientZkOperations.getProfileOperations();
119 }
120
121 public SignalWebSocket getSignalWebSocket() {
122 return getOrCreate(() -> signalWebSocket, () -> {
123 final var timer = new UptimeSleepTimer();
124 final var healthMonitor = new SignalWebSocketHealthMonitor(timer);
125 final var webSocketFactory = new WebSocketFactory() {
126 @Override
127 public WebSocketConnection createWebSocket() {
128 return new WebSocketConnection("normal",
129 serviceEnvironmentConfig.getSignalServiceConfiguration(),
130 Optional.of(credentialsProvider),
131 userAgent,
132 healthMonitor);
133 }
134
135 @Override
136 public WebSocketConnection createUnidentifiedWebSocket() {
137 return new WebSocketConnection("unidentified",
138 serviceEnvironmentConfig.getSignalServiceConfiguration(),
139 Optional.absent(),
140 userAgent,
141 healthMonitor);
142 }
143 };
144 signalWebSocket = new SignalWebSocket(webSocketFactory);
145 healthMonitor.monitor(signalWebSocket);
146 });
147 }
148
149 public SignalServiceMessageReceiver getMessageReceiver() {
150 return getOrCreate(() -> messageReceiver,
151 () -> messageReceiver = new SignalServiceMessageReceiver(serviceEnvironmentConfig.getSignalServiceConfiguration(),
152 credentialsProvider,
153 userAgent,
154 getClientZkProfileOperations(),
155 ServiceConfig.AUTOMATIC_NETWORK_RETRY));
156 }
157
158 public SignalServiceMessageSender getMessageSender() {
159 return getOrCreate(() -> messageSender,
160 () -> messageSender = new SignalServiceMessageSender(serviceEnvironmentConfig.getSignalServiceConfiguration(),
161 credentialsProvider,
162 dataStore,
163 sessionLock,
164 userAgent,
165 getSignalWebSocket(),
166 Optional.absent(),
167 getClientZkProfileOperations(),
168 executor,
169 ServiceConfig.MAX_ENVELOPE_SIZE,
170 ServiceConfig.AUTOMATIC_NETWORK_RETRY));
171 }
172
173 public KeyBackupService getKeyBackupService() {
174 return getOrCreate(() -> keyBackupService,
175 () -> keyBackupService = getAccountManager().getKeyBackupService(ServiceConfig.getIasKeyStore(),
176 serviceEnvironmentConfig.getKeyBackupConfig().getEnclaveName(),
177 serviceEnvironmentConfig.getKeyBackupConfig().getServiceId(),
178 serviceEnvironmentConfig.getKeyBackupConfig().getMrenclave(),
179 10));
180 }
181
182 public ProfileService getProfileService() {
183 return getOrCreate(() -> profileService,
184 () -> profileService = new ProfileService(getClientZkProfileOperations(),
185 getMessageReceiver(),
186 getSignalWebSocket()));
187 }
188
189 public SignalServiceCipher getCipher() {
190 return getOrCreate(() -> cipher, () -> {
191 final var certificateValidator = new CertificateValidator(serviceEnvironmentConfig.getUnidentifiedSenderTrustRoot());
192 final var address = new SignalServiceAddress(credentialsProvider.getAci(), credentialsProvider.getE164());
193 final var deviceId = credentialsProvider.getDeviceId();
194 cipher = new SignalServiceCipher(address, deviceId, dataStore.aci(), sessionLock, certificateValidator);
195 });
196 }
197
198 private <T> T getOrCreate(Supplier<T> supplier, Callable creator) {
199 var value = supplier.get();
200 if (value != null) {
201 return value;
202 }
203
204 synchronized (LOCK) {
205 value = supplier.get();
206 if (value != null) {
207 return value;
208 }
209 creator.call();
210 return supplier.get();
211 }
212 }
213
214 private interface Callable {
215
216 void call();
217 }
218 }