]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/dbus/DbusSignalControlImpl.java
Reduce use of printStackTrace
[signal-cli] / src / main / java / org / asamk / signal / dbus / DbusSignalControlImpl.java
1 package org.asamk.signal.dbus;
2
3 import org.asamk.SignalControl;
4 import org.asamk.signal.BaseConfig;
5 import org.asamk.signal.DbusConfig;
6 import org.asamk.signal.manager.Manager;
7 import org.asamk.signal.manager.MultiAccountManager;
8 import org.asamk.signal.manager.ProvisioningManager;
9 import org.asamk.signal.manager.RegistrationManager;
10 import org.asamk.signal.manager.api.CaptchaRequiredException;
11 import org.asamk.signal.manager.api.IncorrectPinException;
12 import org.asamk.signal.manager.api.NonNormalizedPhoneNumberException;
13 import org.asamk.signal.manager.api.PinLockedException;
14 import org.asamk.signal.manager.api.RateLimitException;
15 import org.asamk.signal.manager.api.UserAlreadyExistsException;
16 import org.freedesktop.dbus.DBusPath;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 import java.io.IOException;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.nio.channels.OverlappingFileLockException;
24 import java.util.List;
25 import java.util.concurrent.TimeoutException;
26
27 public class DbusSignalControlImpl implements org.asamk.SignalControl {
28
29 private final static Logger logger = LoggerFactory.getLogger(DbusSignalControlImpl.class);
30 private final MultiAccountManager c;
31
32 private final String objectPath;
33
34 public DbusSignalControlImpl(final MultiAccountManager c, final String objectPath) {
35 this.c = c;
36 this.objectPath = objectPath;
37 }
38
39 @Override
40 public boolean isRemote() {
41 return false;
42 }
43
44 @Override
45 public String getObjectPath() {
46 return objectPath;
47 }
48
49 @Override
50 public void register(
51 final String number, final boolean voiceVerification
52 ) throws Error.Failure, Error.InvalidNumber {
53 registerWithCaptcha(number, voiceVerification, null);
54 }
55
56 @Override
57 public void registerWithCaptcha(
58 final String number, final boolean voiceVerification, final String captcha
59 ) throws Error.Failure, Error.InvalidNumber {
60 if (!Manager.isValidNumber(number, null)) {
61 throw new SignalControl.Error.InvalidNumber(
62 "Invalid account (phone number), make sure you include the country code.");
63 }
64 try (final RegistrationManager registrationManager = c.getNewRegistrationManager(number)) {
65 registrationManager.register(voiceVerification, captcha);
66 } catch (RateLimitException e) {
67 String message = "Rate limit reached";
68 throw new SignalControl.Error.Failure(message);
69 } catch (CaptchaRequiredException e) {
70 String message = captcha == null ? "Captcha required for verification." : "Invalid captcha given.";
71 throw new SignalControl.Error.RequiresCaptcha(message);
72 } catch (NonNormalizedPhoneNumberException e) {
73 throw new Error.InvalidNumber(e.getMessage());
74 } catch (OverlappingFileLockException e) {
75 throw new SignalControl.Error.Failure("Account is already in use");
76 } catch (IOException e) {
77 throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage());
78 }
79 }
80
81 @Override
82 public void verify(final String number, final String verificationCode) throws Error.Failure, Error.InvalidNumber {
83 verifyWithPin(number, verificationCode, null);
84 }
85
86 @Override
87 public void verifyWithPin(
88 final String number, final String verificationCode, final String pin
89 ) throws Error.Failure, Error.InvalidNumber {
90 try (final RegistrationManager registrationManager = c.getNewRegistrationManager(number)) {
91 registrationManager.verifyAccount(verificationCode, pin);
92 } catch (OverlappingFileLockException e) {
93 throw new SignalControl.Error.Failure("Account is already in use");
94 } catch (IOException e) {
95 throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage());
96 } catch (PinLockedException e) {
97 throw new Error.Failure(
98 "Verification failed! This number is locked with a pin. Hours remaining until reset: "
99 + (e.getTimeRemaining() / 1000 / 60 / 60));
100 } catch (IncorrectPinException e) {
101 throw new Error.Failure("Verification failed! Invalid pin, tries remaining: " + e.getTriesRemaining());
102 }
103 }
104
105 @Override
106 public String link(final String newDeviceName) throws Error.Failure {
107 final URI deviceLinkUri;
108 try {
109 deviceLinkUri = c.getNewProvisioningDeviceLinkUri();
110 } catch (TimeoutException | IOException e) {
111 throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage());
112 }
113 Thread.ofPlatform().name("dbus-link").start(() -> {
114 final ProvisioningManager provisioningManager = c.getProvisioningManagerFor(deviceLinkUri);
115 try {
116 provisioningManager.finishDeviceLink(newDeviceName);
117 } catch (IOException | TimeoutException | UserAlreadyExistsException e) {
118 logger.warn("Failed to finish linking", e);
119 }
120 });
121 return deviceLinkUri.toString();
122 }
123
124 @Override
125 public String startLink() throws Error.Failure {
126 try {
127 final URI deviceLinkUri = c.getNewProvisioningDeviceLinkUri();
128 return deviceLinkUri.toString();
129 } catch (TimeoutException | IOException e) {
130 throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage());
131 }
132 }
133
134 @Override
135 public String finishLink(String deviceLinkUri, final String newDeviceName) throws Error.Failure {
136 try {
137 final var provisioningManager = c.getProvisioningManagerFor(new URI(deviceLinkUri));
138 return provisioningManager.finishDeviceLink(newDeviceName);
139 } catch (TimeoutException | IOException | UserAlreadyExistsException | URISyntaxException e) {
140 throw new SignalControl.Error.Failure(e.getClass().getSimpleName() + " " + e.getMessage());
141 }
142 }
143
144 @Override
145 public String version() {
146 return BaseConfig.PROJECT_VERSION;
147 }
148
149 @Override
150 public List<DBusPath> listAccounts() {
151 return c.getAccountNumbers().stream().map(u -> new DBusPath(DbusConfig.getObjectPath(u))).toList();
152 }
153
154 @Override
155 public DBusPath getAccount(final String number) {
156 return new DBusPath(DbusConfig.getObjectPath(number));
157 }
158 }