]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/SignalDependencies.java
Use Java 17
[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.UptimeSleepTimer;
22 import org.whispersystems.signalservice.api.websocket.WebSocketFactory;
23 import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
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 DynamicCredentialsProvider 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 public SignalDependencies(
56 final ServiceEnvironmentConfig serviceEnvironmentConfig,
57 final String userAgent,
58 final DynamicCredentialsProvider 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 SignalServiceAccountManager getAccountManager() {
72 return getOrCreate(() -> accountManager,
73 () -> accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
74 credentialsProvider,
75 userAgent,
76 getGroupsV2Operations(),
77 ServiceConfig.AUTOMATIC_NETWORK_RETRY));
78 }
79
80 public GroupsV2Api getGroupsV2Api() {
81 return getOrCreate(() -> groupsV2Api, () -> groupsV2Api = getAccountManager().getGroupsV2Api());
82 }
83
84 public GroupsV2Operations getGroupsV2Operations() {
85 return getOrCreate(() -> groupsV2Operations,
86 () -> groupsV2Operations = capabilities.isGv2() ? new GroupsV2Operations(ClientZkOperations.create(
87 serviceEnvironmentConfig.getSignalServiceConfiguration())) : null);
88 }
89
90 private ClientZkOperations getClientZkOperations() {
91 return getOrCreate(() -> clientZkOperations,
92 () -> clientZkOperations = capabilities.isGv2()
93 ? ClientZkOperations.create(serviceEnvironmentConfig.getSignalServiceConfiguration())
94 : null);
95 }
96
97 private ClientZkProfileOperations getClientZkProfileOperations() {
98 final var clientZkOperations = getClientZkOperations();
99 return clientZkOperations == null ? null : clientZkOperations.getProfileOperations();
100 }
101
102 public SignalWebSocket getSignalWebSocket() {
103 return getOrCreate(() -> signalWebSocket, () -> {
104 final var timer = new UptimeSleepTimer();
105 final var healthMonitor = new SignalWebSocketHealthMonitor(timer);
106 final var webSocketFactory = new WebSocketFactory() {
107 @Override
108 public WebSocketConnection createWebSocket() {
109 return new WebSocketConnection("normal",
110 serviceEnvironmentConfig.getSignalServiceConfiguration(),
111 Optional.of(credentialsProvider),
112 userAgent,
113 healthMonitor);
114 }
115
116 @Override
117 public WebSocketConnection createUnidentifiedWebSocket() {
118 return new WebSocketConnection("unidentified",
119 serviceEnvironmentConfig.getSignalServiceConfiguration(),
120 Optional.absent(),
121 userAgent,
122 healthMonitor);
123 }
124 };
125 signalWebSocket = new SignalWebSocket(webSocketFactory);
126 healthMonitor.monitor(signalWebSocket);
127 });
128 }
129
130 public SignalServiceMessageReceiver getMessageReceiver() {
131 return getOrCreate(() -> messageReceiver,
132 () -> messageReceiver = new SignalServiceMessageReceiver(serviceEnvironmentConfig.getSignalServiceConfiguration(),
133 credentialsProvider,
134 userAgent,
135 getClientZkProfileOperations(),
136 ServiceConfig.AUTOMATIC_NETWORK_RETRY));
137 }
138
139 public SignalServiceMessageSender getMessageSender() {
140 return getOrCreate(() -> messageSender,
141 () -> messageSender = new SignalServiceMessageSender(serviceEnvironmentConfig.getSignalServiceConfiguration(),
142 credentialsProvider,
143 dataStore,
144 sessionLock,
145 userAgent,
146 getSignalWebSocket(),
147 Optional.absent(),
148 getClientZkProfileOperations(),
149 executor,
150 ServiceConfig.MAX_ENVELOPE_SIZE,
151 ServiceConfig.AUTOMATIC_NETWORK_RETRY));
152 }
153
154 public KeyBackupService getKeyBackupService() {
155 return getOrCreate(() -> keyBackupService,
156 () -> keyBackupService = getAccountManager().getKeyBackupService(ServiceConfig.getIasKeyStore(),
157 serviceEnvironmentConfig.getKeyBackupConfig().getEnclaveName(),
158 serviceEnvironmentConfig.getKeyBackupConfig().getServiceId(),
159 serviceEnvironmentConfig.getKeyBackupConfig().getMrenclave(),
160 10));
161 }
162
163 public ProfileService getProfileService() {
164 return getOrCreate(() -> profileService,
165 () -> profileService = new ProfileService(getClientZkProfileOperations(),
166 getMessageReceiver(),
167 getSignalWebSocket()));
168 }
169
170 public SignalServiceCipher getCipher() {
171 return getOrCreate(() -> cipher, () -> {
172 final var certificateValidator = new CertificateValidator(serviceEnvironmentConfig.getUnidentifiedSenderTrustRoot());
173 final var address = new SignalServiceAddress(credentialsProvider.getUuid(), credentialsProvider.getE164());
174 cipher = new SignalServiceCipher(address, dataStore, sessionLock, certificateValidator);
175 });
176 }
177
178 private <T> T getOrCreate(Supplier<T> supplier, Callable creator) {
179 var value = supplier.get();
180 if (value != null) {
181 return value;
182 }
183
184 synchronized (LOCK) {
185 value = supplier.get();
186 if (value != null) {
187 return value;
188 }
189 creator.call();
190 return supplier.get();
191 }
192 }
193
194 private interface Callable {
195
196 void call();
197 }
198 }