]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/dbus/DbusCommandHandler.java
Fix inspection issues
[signal-cli] / src / main / java / org / asamk / signal / dbus / DbusCommandHandler.java
1 package org.asamk.signal.dbus;
2
3 import org.asamk.Signal;
4 import org.asamk.SignalControl;
5 import org.asamk.signal.DbusConfig;
6 import org.asamk.signal.commands.Command;
7 import org.asamk.signal.commands.CommandHandler;
8 import org.asamk.signal.commands.LocalCommand;
9 import org.asamk.signal.commands.MultiLocalCommand;
10 import org.asamk.signal.commands.ProvisioningCommand;
11 import org.asamk.signal.commands.RegistrationCommand;
12 import org.asamk.signal.commands.exceptions.CommandException;
13 import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
14 import org.asamk.signal.commands.exceptions.UserErrorException;
15 import org.freedesktop.dbus.connections.impl.DBusConnection;
16 import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder;
17 import org.freedesktop.dbus.errors.ServiceUnknown;
18 import org.freedesktop.dbus.errors.UnknownMethod;
19 import org.freedesktop.dbus.exceptions.DBusException;
20 import org.freedesktop.dbus.exceptions.DBusExecutionException;
21
22 import java.io.IOException;
23
24 public class DbusCommandHandler {
25
26 public static void initDbusClient(
27 final Command command, final String account, final boolean systemBus, final CommandHandler commandHandler
28 ) throws CommandException {
29 try {
30 final var busType = systemBus ? DBusConnection.DBusBusType.SYSTEM : DBusConnection.DBusBusType.SESSION;
31 try (var dBusConn = DBusConnectionBuilder.forType(busType).build()) {
32 handleCommand(command, account, dBusConn, commandHandler);
33 }
34 } catch (ServiceUnknown e) {
35 throw new UserErrorException("signal-cli DBus daemon not running on "
36 + (systemBus ? "system" : "session")
37 + " bus: "
38 + e.getMessage(), e);
39 } catch (DBusExecutionException | DBusException | IOException e) {
40 throw new UnexpectedErrorException("Dbus client failed: " + e.getMessage(), e);
41 }
42 }
43
44 public static void handleCommand(
45 final Command command,
46 final String account,
47 final DBusConnection dBusConn,
48 final CommandHandler commandHandler
49 ) throws CommandException, DBusException {
50 try {
51 if (command instanceof ProvisioningCommand c) {
52 if (account != null) {
53 throw new UserErrorException("You cannot specify a account (phone number) when linking");
54 }
55
56 handleProvisioningCommand(c, dBusConn, commandHandler);
57 return;
58 }
59
60 if (account == null && command instanceof MultiLocalCommand c) {
61 handleMultiLocalCommand(c, dBusConn, commandHandler);
62 return;
63 }
64 if (account != null && command instanceof RegistrationCommand c) {
65 handleRegistrationCommand(c, account, dBusConn, commandHandler);
66 return;
67 }
68 if (!(command instanceof LocalCommand localCommand)) {
69 throw new UserErrorException("Command only works in multi-account mode");
70 }
71
72 var accountObjectPath = account == null ? tryGetSingleAccountObjectPath(dBusConn) : null;
73 if (accountObjectPath == null) {
74 accountObjectPath = DbusConfig.getObjectPath(account);
75 }
76 handleLocalCommand(localCommand, accountObjectPath, dBusConn, commandHandler);
77 } catch (UnsupportedOperationException e) {
78 throw new UserErrorException("Command is not yet implemented via dbus", e);
79 } catch (DBusExecutionException e) {
80 throw new UnexpectedErrorException(e.getMessage(), e);
81 }
82 }
83
84 private static String tryGetSingleAccountObjectPath(final DBusConnection dBusConn) throws DBusException, CommandException {
85 var control = dBusConn.getRemoteObject(DbusConfig.getBusname(),
86 DbusConfig.getObjectPath(),
87 SignalControl.class);
88 try {
89 final var accounts = control.listAccounts();
90 if (accounts.isEmpty()) {
91 throw new UserErrorException("No local users found, you first need to register or link an account");
92 } else if (accounts.size() > 1) {
93 throw new UserErrorException(
94 "Multiple users found, you need to specify an account (phone number) with -a");
95 }
96
97 return accounts.getFirst().getPath();
98 } catch (UnknownMethod e) {
99 // dbus daemon not running in multi-account mode
100 return null;
101 }
102 }
103
104 private static void handleMultiLocalCommand(
105 final MultiLocalCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler
106 ) throws CommandException, DBusException {
107 final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
108 DbusConfig.getObjectPath(),
109 SignalControl.class);
110 try (final var multiAccountManager = new DbusMultiAccountManagerImpl(signalControl, dBusConn)) {
111 commandHandler.handleMultiLocalCommand(c, multiAccountManager);
112 }
113 }
114
115 private static void handleLocalCommand(
116 final LocalCommand c,
117 String accountObjectPath,
118 final DBusConnection dBusConn,
119 final CommandHandler commandHandler
120 ) throws CommandException, DBusException {
121 var signal = dBusConn.getRemoteObject(DbusConfig.getBusname(), accountObjectPath, Signal.class);
122 try (final var manager = new DbusManagerImpl(signal, dBusConn)) {
123 commandHandler.handleLocalCommand(c, manager);
124 }
125 }
126
127 private static void handleRegistrationCommand(
128 final RegistrationCommand c,
129 String account,
130 final DBusConnection dBusConn,
131 final CommandHandler commandHandler
132
133 ) throws CommandException, DBusException {
134 final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
135 DbusConfig.getObjectPath(),
136 SignalControl.class);
137 try (final var registrationManager = new DbusRegistrationManagerImpl(account, signalControl, dBusConn)) {
138 commandHandler.handleRegistrationCommand(c, registrationManager);
139 }
140 }
141
142 private static void handleProvisioningCommand(
143 final ProvisioningCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler
144
145 ) throws CommandException, DBusException {
146 final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
147 DbusConfig.getObjectPath(),
148 SignalControl.class);
149 final var provisioningManager = new DbusProvisioningManagerImpl(signalControl, dBusConn);
150 commandHandler.handleProvisioningCommand(c, provisioningManager);
151 }
152 }