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