]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/dbus/DbusCommandHandler.java
6e7a6ee1be8d848e69b0a7dbd119e8da20c34987
[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.errors.UnknownMethod;
17 import org.freedesktop.dbus.exceptions.DBusException;
18 import org.freedesktop.dbus.exceptions.DBusExecutionException;
19
20 public class DbusCommandHandler {
21
22 public static void handleCommand(
23 final Command command,
24 final String account,
25 final DBusConnection dBusConn,
26 final CommandHandler commandHandler
27 ) throws CommandException, DBusException {
28 try {
29 if (command instanceof ProvisioningCommand c) {
30 if (account != null) {
31 throw new UserErrorException("You cannot specify a account (phone number) when linking");
32 }
33
34 handleProvisioningCommand(c, dBusConn, commandHandler);
35 return;
36 }
37
38 if (account == null && command instanceof MultiLocalCommand c) {
39 handleMultiLocalCommand(c, dBusConn, commandHandler);
40 return;
41 }
42 if (account != null && command instanceof RegistrationCommand c) {
43 handleRegistrationCommand(c, account, dBusConn, commandHandler);
44 return;
45 }
46 if (!(command instanceof LocalCommand localCommand)) {
47 throw new UserErrorException("Command only works in multi-account mode");
48 }
49
50 var accountObjectPath = account == null ? tryGetSingleAccountObjectPath(dBusConn) : null;
51 if (accountObjectPath == null) {
52 accountObjectPath = DbusConfig.getObjectPath(account);
53 }
54 handleLocalCommand(localCommand, accountObjectPath, dBusConn, commandHandler);
55 } catch (UnsupportedOperationException e) {
56 throw new UserErrorException("Command is not yet implemented via dbus", e);
57 } catch (DBusExecutionException e) {
58 throw new UnexpectedErrorException(e.getMessage(), e);
59 }
60 }
61
62 private static String tryGetSingleAccountObjectPath(final DBusConnection dBusConn) throws DBusException, CommandException {
63 var control = dBusConn.getRemoteObject(DbusConfig.getBusname(),
64 DbusConfig.getObjectPath(),
65 SignalControl.class);
66 try {
67 final var accounts = control.listAccounts();
68 if (accounts.isEmpty()) {
69 throw new UserErrorException("No local users found, you first need to register or link an account");
70 } else if (accounts.size() > 1) {
71 throw new UserErrorException(
72 "Multiple users found, you need to specify an account (phone number) with -a");
73 }
74
75 return accounts.get(0).getPath();
76 } catch (UnknownMethod e) {
77 // dbus daemon not running in multi-account mode
78 return null;
79 }
80 }
81
82 private static void handleMultiLocalCommand(
83 final MultiLocalCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler
84 ) throws CommandException, DBusException {
85 final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
86 DbusConfig.getObjectPath(),
87 SignalControl.class);
88 try (final var multiAccountManager = new DbusMultiAccountManagerImpl(signalControl, dBusConn)) {
89 commandHandler.handleMultiLocalCommand(c, multiAccountManager);
90 }
91 }
92
93 private static void handleLocalCommand(
94 final LocalCommand c,
95 String accountObjectPath,
96 final DBusConnection dBusConn,
97 final CommandHandler commandHandler
98 ) throws CommandException, DBusException {
99 var signal = dBusConn.getRemoteObject(DbusConfig.getBusname(), accountObjectPath, Signal.class);
100 try (final var manager = new DbusManagerImpl(signal, dBusConn)) {
101 commandHandler.handleLocalCommand(c, manager);
102 }
103 }
104
105 private static void handleRegistrationCommand(
106 final RegistrationCommand c,
107 String account,
108 final DBusConnection dBusConn,
109 final CommandHandler commandHandler
110
111 ) throws CommandException, DBusException {
112 final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
113 DbusConfig.getObjectPath(),
114 SignalControl.class);
115 try (final var registrationManager = new DbusRegistrationManagerImpl(account, signalControl, dBusConn)) {
116 commandHandler.handleRegistrationCommand(c, registrationManager);
117 }
118 }
119
120 private static void handleProvisioningCommand(
121 final ProvisioningCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler
122
123 ) throws CommandException, DBusException {
124 final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
125 DbusConfig.getObjectPath(),
126 SignalControl.class);
127 final var provisioningManager = new DbusProvisioningManagerImpl(signalControl, dBusConn);
128 commandHandler.handleProvisioningCommand(c, provisioningManager);
129 }
130 }