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