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