mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Add CommandException to abstract cli return codes for errors
This commit is contained in:
parent
c6395b9f35
commit
221d937eec
47 changed files with 538 additions and 572 deletions
|
@ -14,6 +14,9 @@ import org.asamk.signal.commands.LocalCommand;
|
|||
import org.asamk.signal.commands.MultiLocalCommand;
|
||||
import org.asamk.signal.commands.ProvisioningCommand;
|
||||
import org.asamk.signal.commands.RegistrationCommand;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.NotRegisteredException;
|
||||
import org.asamk.signal.manager.ProvisioningManager;
|
||||
|
@ -29,9 +32,8 @@ import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class App {
|
||||
|
||||
|
@ -79,18 +81,16 @@ public class App {
|
|||
this.ns = ns;
|
||||
}
|
||||
|
||||
public int init() {
|
||||
public void init() throws CommandException {
|
||||
var commandKey = ns.getString("command");
|
||||
var command = Commands.getCommand(commandKey);
|
||||
if (command == null) {
|
||||
logger.error("Command not implemented!");
|
||||
return 1;
|
||||
throw new UserErrorException("Command not implemented!");
|
||||
}
|
||||
|
||||
OutputType outputType = ns.get("output");
|
||||
if (!command.getSupportedOutputTypes().contains(outputType)) {
|
||||
logger.error("Command doesn't support output type {}", outputType.toString());
|
||||
return 1;
|
||||
throw new UserErrorException("Command doesn't support output type " + outputType.toString());
|
||||
}
|
||||
|
||||
var username = ns.getString("username");
|
||||
|
@ -99,7 +99,8 @@ public class App {
|
|||
final boolean useDbusSystem = ns.getBoolean("dbus_system");
|
||||
if (useDbus || useDbusSystem) {
|
||||
// If username is null, it will connect to the default object path
|
||||
return initDbusClient(command, username, useDbusSystem);
|
||||
initDbusClient(command, username, useDbusSystem);
|
||||
return;
|
||||
}
|
||||
|
||||
final File dataPath;
|
||||
|
@ -118,111 +119,102 @@ public class App {
|
|||
}
|
||||
|
||||
if (!ServiceConfig.isSignalClientAvailable()) {
|
||||
logger.error("Missing required native library dependency: libsignal-client");
|
||||
return 1;
|
||||
throw new UserErrorException("Missing required native library dependency: libsignal-client");
|
||||
}
|
||||
|
||||
if (command instanceof ProvisioningCommand) {
|
||||
if (username != null) {
|
||||
System.err.println("You cannot specify a username (phone number) when linking");
|
||||
return 1;
|
||||
throw new UserErrorException("You cannot specify a username (phone number) when linking");
|
||||
}
|
||||
|
||||
return handleProvisioningCommand((ProvisioningCommand) command, dataPath, serviceEnvironment);
|
||||
handleProvisioningCommand((ProvisioningCommand) command, dataPath, serviceEnvironment);
|
||||
return;
|
||||
}
|
||||
|
||||
if (username == null) {
|
||||
var usernames = Manager.getAllLocalUsernames(dataPath);
|
||||
if (usernames.size() == 0) {
|
||||
System.err.println("No local users found, you first need to register or link an account");
|
||||
return 1;
|
||||
throw new UserErrorException("No local users found, you first need to register or link an account");
|
||||
}
|
||||
|
||||
if (command instanceof MultiLocalCommand) {
|
||||
return handleMultiLocalCommand((MultiLocalCommand) command, dataPath, serviceEnvironment, usernames);
|
||||
handleMultiLocalCommand((MultiLocalCommand) command, dataPath, serviceEnvironment, usernames);
|
||||
return;
|
||||
}
|
||||
|
||||
if (usernames.size() > 1) {
|
||||
System.err.println("Multiple users found, you need to specify a username (phone number) with -u");
|
||||
return 1;
|
||||
throw new UserErrorException(
|
||||
"Multiple users found, you need to specify a username (phone number) with -u");
|
||||
}
|
||||
|
||||
username = usernames.get(0);
|
||||
} else if (!PhoneNumberFormatter.isValidNumber(username, null)) {
|
||||
System.err.println("Invalid username (phone number), make sure you include the country code.");
|
||||
return 1;
|
||||
throw new UserErrorException("Invalid username (phone number), make sure you include the country code.");
|
||||
}
|
||||
|
||||
if (command instanceof RegistrationCommand) {
|
||||
return handleRegistrationCommand((RegistrationCommand) command, username, dataPath, serviceEnvironment);
|
||||
handleRegistrationCommand((RegistrationCommand) command, username, dataPath, serviceEnvironment);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(command instanceof LocalCommand)) {
|
||||
System.err.println("Command only works via dbus");
|
||||
return 1;
|
||||
throw new UserErrorException("Command only works via dbus");
|
||||
}
|
||||
|
||||
return handleLocalCommand((LocalCommand) command, username, dataPath, serviceEnvironment);
|
||||
handleLocalCommand((LocalCommand) command, username, dataPath, serviceEnvironment);
|
||||
}
|
||||
|
||||
private int handleProvisioningCommand(
|
||||
private void handleProvisioningCommand(
|
||||
final ProvisioningCommand command, final File dataPath, final ServiceEnvironment serviceEnvironment
|
||||
) {
|
||||
) throws CommandException {
|
||||
var pm = ProvisioningManager.init(dataPath, serviceEnvironment, BaseConfig.USER_AGENT);
|
||||
return command.handleCommand(ns, pm);
|
||||
command.handleCommand(ns, pm);
|
||||
}
|
||||
|
||||
private int handleRegistrationCommand(
|
||||
private void handleRegistrationCommand(
|
||||
final RegistrationCommand command,
|
||||
final String username,
|
||||
final File dataPath,
|
||||
final ServiceEnvironment serviceEnvironment
|
||||
) {
|
||||
) throws CommandException {
|
||||
final RegistrationManager manager;
|
||||
try {
|
||||
manager = RegistrationManager.init(username, dataPath, serviceEnvironment, BaseConfig.USER_AGENT);
|
||||
} catch (Throwable e) {
|
||||
logger.error("Error loading or creating state file: {}", e.getMessage());
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Error loading or creating state file: " + e.getMessage());
|
||||
}
|
||||
try (var m = manager) {
|
||||
return command.handleCommand(ns, m);
|
||||
command.handleCommand(ns, m);
|
||||
} catch (IOException e) {
|
||||
logger.error("Cleanup failed", e);
|
||||
return 2;
|
||||
logger.warn("Cleanup failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private int handleLocalCommand(
|
||||
private void handleLocalCommand(
|
||||
final LocalCommand command,
|
||||
final String username,
|
||||
final File dataPath,
|
||||
final ServiceEnvironment serviceEnvironment
|
||||
) {
|
||||
) throws CommandException {
|
||||
try (var m = loadManager(username, dataPath, serviceEnvironment)) {
|
||||
if (m == null) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return command.handleCommand(ns, m);
|
||||
command.handleCommand(ns, m);
|
||||
} catch (IOException e) {
|
||||
logger.error("Cleanup failed", e);
|
||||
return 2;
|
||||
logger.warn("Cleanup failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private int handleMultiLocalCommand(
|
||||
private void handleMultiLocalCommand(
|
||||
final MultiLocalCommand command,
|
||||
final File dataPath,
|
||||
final ServiceEnvironment serviceEnvironment,
|
||||
final List<String> usernames
|
||||
) {
|
||||
final var managers = usernames.stream()
|
||||
.map(u -> loadManager(u, dataPath, serviceEnvironment))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
) throws CommandException {
|
||||
final var managers = new ArrayList<Manager>();
|
||||
for (String u : usernames) {
|
||||
managers.add(loadManager(u, dataPath, serviceEnvironment));
|
||||
}
|
||||
|
||||
var result = command.handleCommand(ns, managers);
|
||||
command.handleCommand(ns, managers);
|
||||
|
||||
for (var m : managers) {
|
||||
try {
|
||||
|
@ -231,34 +223,32 @@ public class App {
|
|||
logger.warn("Cleanup failed", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Manager loadManager(
|
||||
final String username, final File dataPath, final ServiceEnvironment serviceEnvironment
|
||||
) {
|
||||
) throws CommandException {
|
||||
Manager manager;
|
||||
try {
|
||||
manager = Manager.init(username, dataPath, serviceEnvironment, BaseConfig.USER_AGENT);
|
||||
} catch (NotRegisteredException e) {
|
||||
logger.error("User " + username + " is not registered.");
|
||||
return null;
|
||||
throw new UserErrorException("User " + username + " is not registered.");
|
||||
} catch (Throwable e) {
|
||||
logger.error("Error loading state file for user " + username + ": {}", e.getMessage());
|
||||
return null;
|
||||
throw new UnexpectedErrorException("Error loading state file for user " + username + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
manager.checkAccountState();
|
||||
} catch (IOException e) {
|
||||
logger.error("Error while checking account " + username + ": {}", e.getMessage());
|
||||
return null;
|
||||
throw new UnexpectedErrorException("Error while checking account " + username + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
private int initDbusClient(final Command command, final String username, final boolean systemBus) {
|
||||
private void initDbusClient(
|
||||
final Command command, final String username, final boolean systemBus
|
||||
) throws CommandException {
|
||||
try {
|
||||
DBusConnection.DBusBusType busType;
|
||||
if (systemBus) {
|
||||
|
@ -271,22 +261,21 @@ public class App {
|
|||
DbusConfig.getObjectPath(username),
|
||||
Signal.class);
|
||||
|
||||
return handleCommand(command, ts, dBusConn);
|
||||
handleCommand(command, ts, dBusConn);
|
||||
}
|
||||
} catch (DBusException | IOException e) {
|
||||
logger.error("Dbus client failed", e);
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Dbus client failed");
|
||||
}
|
||||
}
|
||||
|
||||
private int handleCommand(Command command, Signal ts, DBusConnection dBusConn) {
|
||||
private void handleCommand(Command command, Signal ts, DBusConnection dBusConn) throws CommandException {
|
||||
if (command instanceof ExtendedDbusCommand) {
|
||||
return ((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn);
|
||||
((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn);
|
||||
} else if (command instanceof DbusCommand) {
|
||||
return ((DbusCommand) command).handleCommand(ns, ts);
|
||||
((DbusCommand) command).handleCommand(ns, ts);
|
||||
} else {
|
||||
System.err.println("Command is not yet implemented via dbus");
|
||||
return 1;
|
||||
throw new UserErrorException("Command is not yet implemented via dbus");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory;
|
|||
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class JsonReceiveMessageHandler implements Manager.ReceiveMessageHandler {
|
||||
|
@ -32,10 +31,7 @@ public class JsonReceiveMessageHandler implements Manager.ReceiveMessageHandler
|
|||
if (envelope != null) {
|
||||
object.put("envelope", new JsonMessageEnvelope(envelope, content, m));
|
||||
}
|
||||
try {
|
||||
|
||||
jsonWriter.write(object);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write json object: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ public class JsonWriter {
|
|||
objectMapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
|
||||
}
|
||||
|
||||
public void write(final Object object) throws IOException {
|
||||
public void write(final Object object) {
|
||||
try {
|
||||
try {
|
||||
objectMapper.writeValue(writer, object);
|
||||
} catch (JsonProcessingException e) {
|
||||
|
@ -35,5 +36,8 @@ public class JsonWriter {
|
|||
}
|
||||
writer.write(System.lineSeparator());
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ import net.sourceforge.argparse4j.impl.Arguments;
|
|||
import net.sourceforge.argparse4j.inf.ArgumentParserException;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.LibSignalLogger;
|
||||
import org.asamk.signal.util.SecurityProvider;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
@ -39,8 +44,14 @@ public class Main {
|
|||
|
||||
var ns = parser.parseArgsOrFail(args);
|
||||
|
||||
var res = new App(ns).init();
|
||||
System.exit(res);
|
||||
int status = 0;
|
||||
try {
|
||||
new App(ns).init();
|
||||
} catch (CommandException e) {
|
||||
System.err.println(e.getMessage());
|
||||
status = getStatusForError(e);
|
||||
}
|
||||
System.exit(status);
|
||||
}
|
||||
|
||||
private static void installSecurityProviderWorkaround() {
|
||||
|
@ -78,4 +89,18 @@ public class Main {
|
|||
System.setProperty("org.slf4j.simpleLogger.showDateTime", "false");
|
||||
}
|
||||
}
|
||||
|
||||
private static int getStatusForError(final CommandException e) {
|
||||
if (e instanceof UserErrorException) {
|
||||
return 1;
|
||||
} else if (e instanceof UnexpectedErrorException) {
|
||||
return 2;
|
||||
} else if (e instanceof IOErrorException) {
|
||||
return 3;
|
||||
} else if (e instanceof UntrustedKeyErrorException) {
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
package org.asamk.signal;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface PlainTextWriter {
|
||||
|
||||
void println(String format, Object... args) throws IOException;
|
||||
void println(String format, Object... args);
|
||||
|
||||
PlainTextWriter indentedWriter();
|
||||
|
||||
default void println() throws IOException {
|
||||
default void println() {
|
||||
println("");
|
||||
}
|
||||
|
||||
default void indent(final WriterConsumer subWriter) throws IOException {
|
||||
default void indent(final WriterConsumer subWriter) {
|
||||
subWriter.consume(indentedWriter());
|
||||
}
|
||||
|
||||
interface WriterConsumer {
|
||||
|
||||
void consume(PlainTextWriter writer) throws IOException;
|
||||
void consume(PlainTextWriter writer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,16 @@ public final class PlainTextWriterImpl implements PlainTextWriter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void println(String format, Object... args) throws IOException {
|
||||
public void println(String format, Object... args) {
|
||||
final var message = MessageFormatter.arrayFormat(format, args).getMessage();
|
||||
|
||||
try {
|
||||
writer.write(message);
|
||||
writer.write(System.lineSeparator());
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,8 +55,12 @@ public final class PlainTextWriterImpl implements PlainTextWriter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void println(final String format, final Object... args) throws IOException {
|
||||
public void println(final String format, final Object... args) {
|
||||
try {
|
||||
writer.write(spaces);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
plainTextWriter.println(format, args);
|
||||
}
|
||||
|
||||
|
|
|
@ -630,7 +630,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
|
|||
writer.println("- {}: {} (length: {})", formatContact(address), mention.getStart(), mention.getLength());
|
||||
}
|
||||
|
||||
private void printAttachment(PlainTextWriter writer, SignalServiceAttachment attachment) throws IOException {
|
||||
private void printAttachment(PlainTextWriter writer, SignalServiceAttachment attachment) {
|
||||
writer.println("Content-Type: {}", attachment.getContentType());
|
||||
writer.println("Type: {}", attachment.isPointer() ? "Pointer" : attachment.isStream() ? "Stream" : "<unknown>");
|
||||
if (attachment.isPointer()) {
|
||||
|
|
|
@ -3,7 +3,13 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -14,6 +20,8 @@ import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
|||
|
||||
public class AddDeviceCommand implements LocalCommand {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(AddDeviceCommand.class);
|
||||
|
||||
@Override
|
||||
public void attachToSubparser(final Subparser subparser) {
|
||||
subparser.addArgument("--uri")
|
||||
|
@ -22,19 +30,20 @@ public class AddDeviceCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
m.addDeviceLink(new URI(ns.getString("uri")));
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
} catch (InvalidKeyException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
return 2;
|
||||
logger.error("Add device link failed", e);
|
||||
throw new IOErrorException("Add device link failed");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new UserErrorException("Device link uri has invalid format: {}" + e.getMessage());
|
||||
} catch (InvalidKeyException e) {
|
||||
logger.error("Add device link failed", e);
|
||||
throw new UnexpectedErrorException("Add device link failed.");
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,14 @@ import org.asamk.signal.manager.Manager;
|
|||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||
import org.asamk.signal.util.Util;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
|
||||
public class BlockCommand implements LocalCommand {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(BlockCommand.class);
|
||||
|
||||
@Override
|
||||
public void attachToSubparser(final Subparser subparser) {
|
||||
subparser.addArgument("contact").help("Contact number").nargs("*");
|
||||
|
@ -19,12 +23,12 @@ public class BlockCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) {
|
||||
for (var contact_number : ns.<String>getList("contact")) {
|
||||
try {
|
||||
m.setContactBlocked(contact_number, true);
|
||||
} catch (InvalidNumberException e) {
|
||||
System.err.println(e.getMessage());
|
||||
logger.warn("Invalid number {}: {}", contact_number, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,11 +38,9 @@ public class BlockCommand implements LocalCommand {
|
|||
var groupId = Util.decodeGroupId(groupIdString);
|
||||
m.setGroupBlocked(groupId, true);
|
||||
} catch (GroupIdFormatException | GroupNotFoundException e) {
|
||||
System.err.println(e.getMessage());
|
||||
logger.warn("Invalid group id {}: {}", groupIdString, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import org.asamk.signal.DbusConfig;
|
|||
import org.asamk.signal.DbusReceiveMessageHandler;
|
||||
import org.asamk.signal.JsonDbusReceiveMessageHandler;
|
||||
import org.asamk.signal.OutputType;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.dbus.DbusSignalImpl;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
||||
|
@ -44,7 +46,7 @@ public class DaemonCommand implements MultiLocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
|
||||
|
||||
// TODO delete later when "json" variable is removed
|
||||
|
@ -71,15 +73,14 @@ public class DaemonCommand implements MultiLocalCommand {
|
|||
t.join();
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
return 0;
|
||||
} catch (DBusException | IOException e) {
|
||||
logger.error("Dbus command failed", e);
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Dbus command failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final List<Manager> managers) {
|
||||
public void handleCommand(final Namespace ns, final List<Manager> managers) throws CommandException {
|
||||
var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
|
||||
|
||||
// TODO delete later when "json" variable is removed
|
||||
|
@ -112,10 +113,9 @@ public class DaemonCommand implements MultiLocalCommand {
|
|||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} catch (DBusException | IOException e) {
|
||||
logger.error("Dbus command failed", e);
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Dbus command failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,14 +3,15 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.dbus.DbusSignalImpl;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
public interface DbusCommand extends LocalCommand {
|
||||
|
||||
int handleCommand(Namespace ns, Signal signal);
|
||||
void handleCommand(Namespace ns, Signal signal) throws CommandException;
|
||||
|
||||
default int handleCommand(final Namespace ns, final Manager m) {
|
||||
return handleCommand(ns, new DbusSignalImpl(m));
|
||||
default void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
handleCommand(ns, new DbusSignalImpl(m));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
||||
|
||||
public interface ExtendedDbusCommand extends Command {
|
||||
|
||||
int handleCommand(Namespace ns, Signal signal, DBusConnection dbusconnection);
|
||||
void handleCommand(Namespace ns, Signal signal, DBusConnection dbusconnection) throws CommandException;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import net.sourceforge.argparse4j.inf.Subparser;
|
|||
import org.asamk.signal.JsonWriter;
|
||||
import org.asamk.signal.OutputType;
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -36,7 +38,7 @@ public class GetUserStatusCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
// Setup the json object mapper
|
||||
var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
|
||||
|
||||
|
@ -50,8 +52,8 @@ public class GetUserStatusCommand implements LocalCommand {
|
|||
try {
|
||||
registered = m.areUsersRegistered(new HashSet<>(ns.getList("number")));
|
||||
} catch (IOException e) {
|
||||
System.err.println("Unable to check if users are registered");
|
||||
return 3;
|
||||
logger.debug("Failed to check registered users", e);
|
||||
throw new IOErrorException("Unable to check if users are registered");
|
||||
}
|
||||
|
||||
// Output
|
||||
|
@ -63,28 +65,16 @@ public class GetUserStatusCommand implements LocalCommand {
|
|||
.map(entry -> new JsonUserStatus(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
try {
|
||||
jsonWriter.write(jsonUserStatuses);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write json object: {}", e.getMessage());
|
||||
return 3;
|
||||
}
|
||||
} else {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
try {
|
||||
for (var entry : registered.entrySet()) {
|
||||
writer.println("{}: {}", entry.getKey(), entry.getValue());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static final class JsonUserStatus {
|
||||
|
||||
public String name;
|
||||
|
|
|
@ -4,46 +4,42 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
|
||||
import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.GroupPatchNotAcceptedException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleIOException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleTimestampAndSendMessageResults;
|
||||
|
||||
public class JoinGroupCommand implements LocalCommand {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(JoinGroupCommand.class);
|
||||
|
||||
@Override
|
||||
public void attachToSubparser(final Subparser subparser) {
|
||||
subparser.addArgument("--uri").required(true).help("Specify the uri with the group invitation link.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
final GroupInviteLinkUrl linkUrl;
|
||||
var uri = ns.getString("uri");
|
||||
try {
|
||||
linkUrl = GroupInviteLinkUrl.fromUri(uri);
|
||||
} catch (GroupInviteLinkUrl.InvalidGroupLinkException e) {
|
||||
System.err.println("Group link is invalid: " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Group link is invalid: " + e.getMessage());
|
||||
} catch (GroupInviteLinkUrl.UnknownGroupLinkVersionException e) {
|
||||
System.err.println("Group link was created with an incompatible version: " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Group link was created with an incompatible version: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (linkUrl == null) {
|
||||
System.err.println("Link is not a signal group invitation link");
|
||||
return 1;
|
||||
throw new UserErrorException("Link is not a signal group invitation link");
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -56,23 +52,18 @@ public class JoinGroupCommand implements LocalCommand {
|
|||
} else {
|
||||
writer.println("Joined group \"{}\"", newGroupId.toBase64());
|
||||
}
|
||||
return handleTimestampAndSendMessageResults(writer, 0, results.second());
|
||||
handleTimestampAndSendMessageResults(writer, 0, results.second());
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (GroupPatchNotAcceptedException e) {
|
||||
System.err.println("Failed to join group, maybe already a member");
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to join group, maybe already a member");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
handleIOException(e);
|
||||
return 3;
|
||||
throw new IOErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (GroupLinkNotActiveException e) {
|
||||
System.err.println("Group link is not valid: " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Group link is not valid: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.ProvisioningManager;
|
||||
import org.asamk.signal.manager.UserAlreadyExists;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -25,7 +29,7 @@ public class LinkCommand implements ProvisioningCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final ProvisioningManager m) {
|
||||
public void handleCommand(final Namespace ns, final ProvisioningManager m) throws CommandException {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
var deviceName = ns.getString("name");
|
||||
|
@ -37,25 +41,21 @@ public class LinkCommand implements ProvisioningCommand {
|
|||
var username = m.finishDeviceLink(deviceName);
|
||||
writer.println("Associated with: {}", username);
|
||||
} catch (TimeoutException e) {
|
||||
System.err.println("Link request timed out, please try again.");
|
||||
return 3;
|
||||
throw new UserErrorException("Link request timed out, please try again.");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Link request error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Link request error: " + e.getMessage());
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
return 2;
|
||||
logger.debug("Finish device link failed", e);
|
||||
throw new UnexpectedErrorException("Invalid key: " + e.getMessage());
|
||||
} catch (UserAlreadyExists e) {
|
||||
System.err.println("The user "
|
||||
throw new UserErrorException("The user "
|
||||
+ e.getUsername()
|
||||
+ " already exists\nDelete \""
|
||||
+ e.getFileName()
|
||||
+ "\" before trying again.");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ import net.sourceforge.argparse4j.inf.Subparser;
|
|||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ListContactsCommand implements LocalCommand {
|
||||
|
||||
@Override
|
||||
|
@ -15,18 +13,12 @@ public class ListContactsCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
var contacts = m.getContacts();
|
||||
try {
|
||||
for (var c : contacts) {
|
||||
writer.println("Number: {} Name: {} Blocked: {}", c.number, c.name, c.blocked);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,22 +4,37 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.util.DateUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class ListDevicesCommand implements LocalCommand {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ListDevicesCommand.class);
|
||||
|
||||
@Override
|
||||
public void attachToSubparser(final Subparser subparser) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
List<DeviceInfo> devices;
|
||||
try {
|
||||
var devices = m.getLinkedDevices();
|
||||
devices = m.getLinkedDevices();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Failed to get linked devices", e);
|
||||
throw new IOErrorException("Failed to get linked devices: " + e.getMessage());
|
||||
}
|
||||
|
||||
for (var d : devices) {
|
||||
writer.println("- Device {}{}:", d.getId(), (d.getId() == m.getDeviceId() ? " (this device)" : ""));
|
||||
writer.indent(w -> {
|
||||
|
@ -28,10 +43,5 @@ public class ListDevicesCommand implements LocalCommand {
|
|||
w.println("Last seen: {}", DateUtils.formatTimestamp(d.getLastSeen()));
|
||||
});
|
||||
}
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,13 @@ import org.asamk.signal.JsonWriter;
|
|||
import org.asamk.signal.OutputType;
|
||||
import org.asamk.signal.PlainTextWriter;
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -32,7 +32,7 @@ public class ListGroupsCommand implements LocalCommand {
|
|||
|
||||
private static void printGroupPlainText(
|
||||
PlainTextWriter writer, Manager m, GroupInfo group, boolean detailed
|
||||
) throws IOException {
|
||||
) {
|
||||
if (detailed) {
|
||||
final var groupInviteLink = group.getGroupInviteLink();
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class ListGroupsCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
if (ns.get("output") == OutputType.JSON) {
|
||||
final var jsonWriter = new JsonWriter(System.out);
|
||||
|
||||
|
@ -88,30 +88,16 @@ public class ListGroupsCommand implements LocalCommand {
|
|||
groupInviteLink == null ? null : groupInviteLink.getUrl()));
|
||||
}
|
||||
|
||||
try {
|
||||
jsonWriter.write(jsonGroups);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write json object: {}", e.getMessage());
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
boolean detailed = ns.getBoolean("detailed");
|
||||
try {
|
||||
for (var group : m.getGroups()) {
|
||||
printGroupPlainText(writer, m, group, detailed);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static final class JsonGroup {
|
||||
|
||||
public String id;
|
||||
|
|
|
@ -5,6 +5,8 @@ import net.sourceforge.argparse4j.inf.Subparser;
|
|||
|
||||
import org.asamk.signal.PlainTextWriter;
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.storage.protocol.IdentityInfo;
|
||||
import org.asamk.signal.util.Hex;
|
||||
|
@ -13,7 +15,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class ListIdentitiesCommand implements LocalCommand {
|
||||
|
||||
|
@ -21,16 +23,12 @@ public class ListIdentitiesCommand implements LocalCommand {
|
|||
|
||||
private static void printIdentityFingerprint(PlainTextWriter writer, Manager m, IdentityInfo theirId) {
|
||||
var digits = Util.formatSafetyNumber(m.computeSafetyNumber(theirId.getAddress(), theirId.getIdentityKey()));
|
||||
try {
|
||||
writer.println("{}: {} Added: {} Fingerprint: {} Safety Number: {}",
|
||||
theirId.getAddress().getNumber().orNull(),
|
||||
theirId.getTrustLevel(),
|
||||
theirId.getDateAdded(),
|
||||
Hex.toString(theirId.getFingerprint()),
|
||||
digits);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,24 +37,27 @@ public class ListIdentitiesCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
if (ns.get("number") == null) {
|
||||
var number = ns.getString("number");
|
||||
|
||||
if (number == null) {
|
||||
for (var identity : m.getIdentities()) {
|
||||
printIdentityFingerprint(writer, m, identity);
|
||||
}
|
||||
} else {
|
||||
var number = ns.getString("number");
|
||||
return;
|
||||
}
|
||||
|
||||
List<IdentityInfo> identities;
|
||||
try {
|
||||
var identities = m.getIdentities(number);
|
||||
identities = m.getIdentities(number);
|
||||
} catch (InvalidNumberException e) {
|
||||
throw new UserErrorException("Invalid number: " + e.getMessage());
|
||||
}
|
||||
|
||||
for (var id : identities) {
|
||||
printIdentityFingerprint(writer, m, id);
|
||||
}
|
||||
} catch (InvalidNumberException e) {
|
||||
System.err.println("Invalid number: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ package org.asamk.signal.commands;
|
|||
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
public interface LocalCommand extends Command {
|
||||
|
||||
int handleCommand(Namespace ns, Manager m);
|
||||
void handleCommand(Namespace ns, Manager m) throws CommandException;
|
||||
}
|
||||
|
|
|
@ -2,16 +2,17 @@ package org.asamk.signal.commands;
|
|||
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface MultiLocalCommand extends LocalCommand {
|
||||
|
||||
int handleCommand(Namespace ns, List<Manager> m);
|
||||
void handleCommand(Namespace ns, List<Manager> m) throws CommandException;
|
||||
|
||||
@Override
|
||||
default int handleCommand(final Namespace ns, final Manager m) {
|
||||
return handleCommand(ns, List.of(m));
|
||||
default void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
handleCommand(ns, List.of(m));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ package org.asamk.signal.commands;
|
|||
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.manager.ProvisioningManager;
|
||||
|
||||
public interface ProvisioningCommand extends Command {
|
||||
|
||||
int handleCommand(Namespace ns, ProvisioningManager m);
|
||||
void handleCommand(Namespace ns, ProvisioningManager m) throws CommandException;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,11 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.groups.GroupId;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||
|
@ -13,10 +17,6 @@ import org.asamk.signal.util.Util;
|
|||
import java.io.IOException;
|
||||
|
||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleGroupNotFoundException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleIOException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleNotAGroupMemberException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleTimestampAndSendMessageResults;
|
||||
|
||||
public class QuitGroupCommand implements LocalCommand {
|
||||
|
@ -27,28 +27,28 @@ public class QuitGroupCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
try {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
final var groupId = Util.decodeGroupId(ns.getString("group"));
|
||||
final GroupId groupId;
|
||||
try {
|
||||
groupId = Util.decodeGroupId(ns.getString("group"));
|
||||
} catch (GroupIdFormatException e) {
|
||||
throw new UserErrorException("Invalid group id:" + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
final var results = m.sendQuitGroupMessage(groupId);
|
||||
return handleTimestampAndSendMessageResults(writer, results.first(), results.second());
|
||||
handleTimestampAndSendMessageResults(writer, results.first(), results.second());
|
||||
} catch (IOException e) {
|
||||
handleIOException(e);
|
||||
return 3;
|
||||
throw new IOErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (GroupNotFoundException e) {
|
||||
handleGroupNotFoundException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to send to group: " + e.getMessage());
|
||||
} catch (NotAGroupMemberException e) {
|
||||
handleNotAGroupMemberException(e);
|
||||
return 1;
|
||||
} catch (GroupIdFormatException e) {
|
||||
handleGroupIdFormatException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to send to group: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@ import org.asamk.signal.JsonWriter;
|
|||
import org.asamk.signal.OutputType;
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.ReceiveMessageHandler;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.json.JsonMessageEnvelope;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.util.DateUtils;
|
||||
|
@ -48,7 +51,9 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
public int handleCommand(final Namespace ns, final Signal signal, DBusConnection dbusconnection) {
|
||||
public void handleCommand(
|
||||
final Namespace ns, final Signal signal, DBusConnection dbusconnection
|
||||
) throws CommandException {
|
||||
var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
|
||||
|
||||
// TODO delete later when "json" variable is removed
|
||||
|
@ -63,45 +68,31 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
dbusconnection.addSigHandler(Signal.MessageReceived.class, messageReceived -> {
|
||||
var envelope = new JsonMessageEnvelope(messageReceived);
|
||||
final var object = Map.of("envelope", envelope);
|
||||
try {
|
||||
jsonWriter.write(object);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write json object: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.ReceiptReceived.class, receiptReceived -> {
|
||||
var envelope = new JsonMessageEnvelope(receiptReceived);
|
||||
final var object = Map.of("envelope", envelope);
|
||||
try {
|
||||
jsonWriter.write(object);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write json object: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, syncReceived -> {
|
||||
var envelope = new JsonMessageEnvelope(syncReceived);
|
||||
final var object = Map.of("envelope", envelope);
|
||||
try {
|
||||
jsonWriter.write(object);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write json object: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
dbusconnection.addSigHandler(Signal.MessageReceived.class, messageReceived -> {
|
||||
try {
|
||||
writer.println("Envelope from: {}", messageReceived.getSender());
|
||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(messageReceived.getTimestamp()));
|
||||
writer.println("Body: {}", messageReceived.getMessage());
|
||||
if (messageReceived.getGroupId().length > 0) {
|
||||
writer.println("Group info:");
|
||||
writer.indentedWriter()
|
||||
.println("Id: {}",
|
||||
Base64.getEncoder().encodeToString(messageReceived.getGroupId()));
|
||||
.println("Id: {}", Base64.getEncoder().encodeToString(messageReceived.getGroupId()));
|
||||
}
|
||||
if (messageReceived.getAttachments().size() > 0) {
|
||||
writer.println("Attachments:");
|
||||
|
@ -110,22 +101,14 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
}
|
||||
}
|
||||
writer.println();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.ReceiptReceived.class, receiptReceived -> {
|
||||
try {
|
||||
writer.println("Receipt from: {}", receiptReceived.getSender());
|
||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(receiptReceived.getTimestamp()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, syncReceived -> {
|
||||
try {
|
||||
writer.println("Sync Envelope from: {} to: {}",
|
||||
syncReceived.getSource(),
|
||||
syncReceived.getDestination());
|
||||
|
@ -143,26 +126,23 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
}
|
||||
}
|
||||
writer.println();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (DBusException e) {
|
||||
e.printStackTrace();
|
||||
return 2;
|
||||
logger.error("Dbus client failed", e);
|
||||
throw new UnexpectedErrorException("Dbus client failed");
|
||||
}
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
return 0;
|
||||
} catch (InterruptedException ignored) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
|
||||
|
||||
// TODO delete later when "json" variable is removed
|
||||
|
@ -187,13 +167,11 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
returnOnTimeout,
|
||||
ignoreAttachments,
|
||||
handler);
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error while receiving messages: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Error while receiving messages: " + e.getMessage());
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import net.sourceforge.argparse4j.impl.Arguments;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.RegistrationManager;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.CaptchaRequiredException;
|
||||
|
||||
|
@ -21,26 +24,25 @@ public class RegisterCommand implements RegistrationCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final RegistrationManager m) {
|
||||
public void handleCommand(final Namespace ns, final RegistrationManager m) throws CommandException {
|
||||
final boolean voiceVerification = ns.getBoolean("voice");
|
||||
final var captcha = ns.getString("captcha");
|
||||
|
||||
try {
|
||||
m.register(voiceVerification, captcha);
|
||||
return 0;
|
||||
} catch (CaptchaRequiredException e) {
|
||||
String message;
|
||||
if (captcha == null) {
|
||||
System.err.println("Captcha required for verification, use --captcha CAPTCHA");
|
||||
System.err.println("To get the token, go to https://signalcaptchas.org/registration/generate.html");
|
||||
System.err.println("Check the developer tools (F12) console for a failed redirect to signalcaptcha://");
|
||||
System.err.println("Everything after signalcaptcha:// is the captcha token.");
|
||||
message = "Captcha required for verification, use --captcha CAPTCHA\n"
|
||||
+ "To get the token, go to https://signalcaptchas.org/registration/generate.html\n"
|
||||
+ "Check the developer tools (F12) console for a failed redirect to signalcaptcha://\n"
|
||||
+ "Everything after signalcaptcha:// is the captcha token.";
|
||||
} else {
|
||||
System.err.println("Invalid captcha given.");
|
||||
message = "Invalid captcha given.";
|
||||
}
|
||||
return 1;
|
||||
throw new UserErrorException(message);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Request verify error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Request verify error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ package org.asamk.signal.commands;
|
|||
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.manager.RegistrationManager;
|
||||
|
||||
public interface RegistrationCommand extends Command {
|
||||
|
||||
int handleCommand(Namespace ns, RegistrationManager m);
|
||||
void handleCommand(Namespace ns, RegistrationManager m) throws CommandException;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -18,14 +20,12 @@ public class RemoveDeviceCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
int deviceId = ns.getInt("deviceId");
|
||||
m.removeLinkedDevices(deviceId);
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
throw new IOErrorException("Error while removing device: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException;
|
||||
|
@ -16,16 +19,13 @@ public class RemovePinCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
m.setRegistrationLockPin(Optional.absent());
|
||||
return 0;
|
||||
} catch (UnauthenticatedResponseException e) {
|
||||
System.err.println("Remove pin error: " + e.getMessage());
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Remove pin failed with unauthenticated response: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.err.println("Remove pin error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Remove pin error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ import net.sourceforge.argparse4j.inf.Subparser;
|
|||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.util.IOUtils;
|
||||
import org.asamk.signal.util.Util;
|
||||
|
@ -19,7 +23,6 @@ import java.nio.charset.Charset;
|
|||
import java.util.List;
|
||||
|
||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
|
||||
|
||||
public class SendCommand implements DbusCommand {
|
||||
|
||||
|
@ -42,7 +45,7 @@ public class SendCommand implements DbusCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Signal signal) {
|
||||
public void handleCommand(final Namespace ns, final Signal signal) throws CommandException {
|
||||
final List<String> recipients = ns.getList("recipient");
|
||||
final var isEndSession = ns.getBoolean("endsession");
|
||||
final var groupIdString = ns.getString("group");
|
||||
|
@ -50,32 +53,27 @@ public class SendCommand implements DbusCommand {
|
|||
|
||||
final var noRecipients = recipients == null || recipients.isEmpty();
|
||||
if ((noRecipients && isEndSession) || (noRecipients && groupIdString == null && !isNoteToSelf)) {
|
||||
System.err.println("No recipients given");
|
||||
System.err.println("Aborting sending.");
|
||||
return 1;
|
||||
throw new UserErrorException("No recipients given");
|
||||
}
|
||||
if (!noRecipients && groupIdString != null) {
|
||||
System.err.println("You cannot specify recipients by phone number and groups at the same time");
|
||||
return 1;
|
||||
throw new UserErrorException("You cannot specify recipients by phone number and groups at the same time");
|
||||
}
|
||||
if (!noRecipients && isNoteToSelf) {
|
||||
System.err.println("You cannot specify recipients by phone number and not to self at the same time");
|
||||
return 1;
|
||||
throw new UserErrorException(
|
||||
"You cannot specify recipients by phone number and not to self at the same time");
|
||||
}
|
||||
|
||||
if (isEndSession) {
|
||||
try {
|
||||
signal.sendEndSessionMessage(recipients);
|
||||
return 0;
|
||||
return;
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (Signal.Error.UntrustedIdentity e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 4;
|
||||
throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +82,7 @@ public class SendCommand implements DbusCommand {
|
|||
try {
|
||||
messageText = IOUtils.readAll(System.in, Charset.defaultCharset());
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to read message from stdin: " + e.getMessage());
|
||||
System.err.println("Aborting sending.");
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to read message from stdin: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,23 +98,18 @@ public class SendCommand implements DbusCommand {
|
|||
try {
|
||||
groupId = Util.decodeGroupId(groupIdString).serialize();
|
||||
} catch (GroupIdFormatException e) {
|
||||
handleGroupIdFormatException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Invalid group id:" + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
var timestamp = signal.sendGroupMessage(messageText, attachments, groupId);
|
||||
writer.println("{}", timestamp);
|
||||
return 0;
|
||||
return;
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (DBusExecutionException e) {
|
||||
System.err.println("Failed to send group message: " + e.getMessage());
|
||||
return 2;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
throw new UnexpectedErrorException("Failed to send group message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,41 +117,29 @@ public class SendCommand implements DbusCommand {
|
|||
try {
|
||||
var timestamp = signal.sendNoteToSelfMessage(messageText, attachments);
|
||||
writer.println("{}", timestamp);
|
||||
return 0;
|
||||
return;
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (Signal.Error.UntrustedIdentity e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 4;
|
||||
throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
System.err.println("Failed to send note to self message: " + e.getMessage());
|
||||
return 2;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
throw new UnexpectedErrorException("Failed to send note to self message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var timestamp = signal.sendMessage(messageText, attachments, recipients);
|
||||
writer.println("{}", timestamp);
|
||||
return 0;
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (UnknownObject e) {
|
||||
System.err.println("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
|
||||
} catch (Signal.Error.UntrustedIdentity e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 4;
|
||||
throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 2;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
|
||||
|
@ -16,16 +19,13 @@ public class SendContactsCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
m.sendContacts();
|
||||
return 0;
|
||||
} catch (UntrustedIdentityException e) {
|
||||
System.err.println("SendContacts error: " + e.getMessage());
|
||||
return 2;
|
||||
throw new UntrustedKeyErrorException("SendContacts error: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.err.println("SendContacts error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("SendContacts error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,11 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.groups.GroupId;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||
|
@ -18,11 +22,6 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
|
||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleGroupNotFoundException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleIOException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleInvalidNumberException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleNotAGroupMemberException;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleTimestampAndSendMessageResults;
|
||||
|
||||
public class SendReactionCommand implements LocalCommand {
|
||||
|
@ -46,19 +45,16 @@ public class SendReactionCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
final List<String> recipients = ns.getList("recipient");
|
||||
final var groupIdString = ns.getString("group");
|
||||
|
||||
final var noRecipients = recipients == null || recipients.isEmpty();
|
||||
if (noRecipients && groupIdString == null) {
|
||||
System.err.println("No recipients given");
|
||||
System.err.println("Aborting sending.");
|
||||
return 1;
|
||||
throw new UserErrorException("No recipients given");
|
||||
}
|
||||
if (!noRecipients && groupIdString != null) {
|
||||
System.err.println("You cannot specify recipients by phone number and groups at the same time");
|
||||
return 1;
|
||||
throw new UserErrorException("You cannot specify recipients by phone number and groups at the same time");
|
||||
}
|
||||
|
||||
final var emoji = ns.getString("emoji");
|
||||
|
@ -66,35 +62,37 @@ public class SendReactionCommand implements LocalCommand {
|
|||
final var targetAuthor = ns.getString("target_author");
|
||||
final long targetTimestamp = ns.getLong("target_timestamp");
|
||||
|
||||
try {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
|
||||
final Pair<Long, List<SendMessageResult>> results;
|
||||
if (groupIdString != null) {
|
||||
var groupId = Util.decodeGroupId(groupIdString);
|
||||
|
||||
GroupId groupId = null;
|
||||
if (groupId != null) {
|
||||
try {
|
||||
groupId = Util.decodeGroupId(groupIdString);
|
||||
} catch (GroupIdFormatException e) {
|
||||
throw new UserErrorException("Invalid group id:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (groupId != null) {
|
||||
results = m.sendGroupMessageReaction(emoji, isRemove, targetAuthor, targetTimestamp, groupId);
|
||||
} else {
|
||||
results = m.sendMessageReaction(emoji, isRemove, targetAuthor, targetTimestamp, recipients);
|
||||
}
|
||||
return handleTimestampAndSendMessageResults(writer, results.first(), results.second());
|
||||
handleTimestampAndSendMessageResults(writer, results.first(), results.second());
|
||||
} catch (IOException e) {
|
||||
handleIOException(e);
|
||||
return 3;
|
||||
throw new IOErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (GroupNotFoundException e) {
|
||||
handleGroupNotFoundException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to send to group: " + e.getMessage());
|
||||
} catch (NotAGroupMemberException e) {
|
||||
handleNotAGroupMemberException(e);
|
||||
return 1;
|
||||
} catch (GroupIdFormatException e) {
|
||||
handleGroupIdFormatException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to send to group: " + e.getMessage());
|
||||
} catch (InvalidNumberException e) {
|
||||
handleInvalidNumberException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Invalid number: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException;
|
||||
|
@ -18,17 +21,14 @@ public class SetPinCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
var registrationLockPin = ns.getString("registrationLockPin");
|
||||
m.setRegistrationLockPin(Optional.of(registrationLockPin));
|
||||
return 0;
|
||||
} catch (UnauthenticatedResponseException e) {
|
||||
System.err.println("Set pin error: " + e.getMessage());
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Set pin error failed with unauthenticated response: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.err.println("Set pin error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Set pin error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@ import net.sourceforge.argparse4j.impl.Arguments;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.util.ErrorUtils;
|
||||
import org.asamk.signal.util.Hex;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
|
||||
|
@ -25,13 +26,12 @@ public class TrustCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
var number = ns.getString("number");
|
||||
if (ns.getBoolean("trust_all_known_keys")) {
|
||||
var res = m.trustIdentityAllKeys(number);
|
||||
if (!res) {
|
||||
System.err.println("Failed to set the trust for this number, make sure the number is correct.");
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to set the trust for this number, make sure the number is correct.");
|
||||
}
|
||||
} else {
|
||||
var safetyNumber = ns.getString("verified_safety_number");
|
||||
|
@ -42,46 +42,38 @@ public class TrustCommand implements LocalCommand {
|
|||
try {
|
||||
fingerprintBytes = Hex.toByteArray(safetyNumber.toLowerCase(Locale.ROOT));
|
||||
} catch (Exception e) {
|
||||
System.err.println(
|
||||
throw new UserErrorException(
|
||||
"Failed to parse the fingerprint, make sure the fingerprint is a correctly encoded hex string without additional characters.");
|
||||
return 1;
|
||||
}
|
||||
boolean res;
|
||||
try {
|
||||
res = m.trustIdentityVerified(number, fingerprintBytes);
|
||||
} catch (InvalidNumberException e) {
|
||||
ErrorUtils.handleInvalidNumberException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to parse recipient: " + e.getMessage());
|
||||
}
|
||||
if (!res) {
|
||||
System.err.println(
|
||||
throw new UserErrorException(
|
||||
"Failed to set the trust for the fingerprint of this number, make sure the number and the fingerprint are correct.");
|
||||
return 1;
|
||||
}
|
||||
} else if (safetyNumber.length() == 60) {
|
||||
boolean res;
|
||||
try {
|
||||
res = m.trustIdentityVerifiedSafetyNumber(number, safetyNumber);
|
||||
} catch (InvalidNumberException e) {
|
||||
ErrorUtils.handleInvalidNumberException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to parse recipient: " + e.getMessage());
|
||||
}
|
||||
if (!res) {
|
||||
System.err.println(
|
||||
throw new UserErrorException(
|
||||
"Failed to set the trust for the safety number of this phone number, make sure the phone number and the safety number are correct.");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
System.err.println(
|
||||
throw new UserErrorException(
|
||||
"Safety number has invalid format, either specify the old hex fingerprint or the new safety number");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
System.err.println(
|
||||
throw new UserErrorException(
|
||||
"You need to specify the fingerprint/safety number you have verified with -v SAFETY_NUMBER");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,19 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||
import org.asamk.signal.util.Util;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
|
||||
public class UnblockCommand implements LocalCommand {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(UnblockCommand.class);
|
||||
|
||||
@Override
|
||||
public void attachToSubparser(final Subparser subparser) {
|
||||
subparser.addArgument("contact").help("Contact number").nargs("*");
|
||||
|
@ -19,12 +24,12 @@ public class UnblockCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
for (var contact_number : ns.<String>getList("contact")) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
for (var contactNumber : ns.<String>getList("contact")) {
|
||||
try {
|
||||
m.setContactBlocked(contact_number, false);
|
||||
m.setContactBlocked(contactNumber, false);
|
||||
} catch (InvalidNumberException e) {
|
||||
System.err.println(e.getMessage());
|
||||
logger.warn("Invalid number: {}", contactNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,12 +38,12 @@ public class UnblockCommand implements LocalCommand {
|
|||
try {
|
||||
var groupId = Util.decodeGroupId(groupIdString);
|
||||
m.setGroupBlocked(groupId, false);
|
||||
} catch (GroupIdFormatException | GroupNotFoundException e) {
|
||||
System.err.println(e.getMessage());
|
||||
} catch (GroupIdFormatException e) {
|
||||
logger.warn("Invalid group id: {}", groupIdString);
|
||||
} catch (GroupNotFoundException e) {
|
||||
logger.warn("Unknown group id: {}", groupIdString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -15,13 +17,11 @@ public class UnregisterCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
m.unregister();
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
System.err.println("Unregister error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Unregister error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -15,13 +17,11 @@ public class UpdateAccountCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
try {
|
||||
m.updateAccountAttributes();
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
System.err.println("UpdateAccount error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("UpdateAccount error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
|
||||
|
@ -22,7 +25,7 @@ public class UpdateContactCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
var number = ns.getString("number");
|
||||
var name = ns.getString("name");
|
||||
|
||||
|
@ -34,13 +37,9 @@ public class UpdateContactCommand implements LocalCommand {
|
|||
m.setExpirationTimer(number, expiration);
|
||||
}
|
||||
} catch (InvalidNumberException e) {
|
||||
System.err.println("Invalid contact number: " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Invalid contact number: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.err.println("Update contact error: " + e.getMessage());
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
throw new IOErrorException("Update contact error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,19 +5,20 @@ import net.sourceforge.argparse4j.inf.Subparser;
|
|||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.util.Util;
|
||||
import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
||||
import static org.asamk.signal.util.ErrorUtils.handleGroupIdFormatException;
|
||||
|
||||
public class UpdateGroupCommand implements DbusCommand {
|
||||
|
||||
|
@ -32,15 +33,14 @@ public class UpdateGroupCommand implements DbusCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Signal signal) {
|
||||
public void handleCommand(final Namespace ns, final Signal signal) throws CommandException {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
byte[] groupId = null;
|
||||
if (ns.getString("group") != null) {
|
||||
try {
|
||||
groupId = Util.decodeGroupId(ns.getString("group")).serialize();
|
||||
} catch (GroupIdFormatException e) {
|
||||
handleGroupIdFormatException(e);
|
||||
return 1;
|
||||
throw new UserErrorException("Invalid group id:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
if (groupId == null) {
|
||||
|
@ -65,23 +65,15 @@ public class UpdateGroupCommand implements DbusCommand {
|
|||
try {
|
||||
var newGroupId = signal.updateGroup(groupId, groupName, groupMembers, groupAvatar);
|
||||
if (groupId.length != newGroupId.length) {
|
||||
try {
|
||||
writer.println("Creating new group \"{}\" …", Base64.getEncoder().encodeToString(newGroupId));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 3;
|
||||
writer.println("Created new group: \"{}\"", Base64.getEncoder().encodeToString(newGroupId));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} catch (AssertionError e) {
|
||||
handleAssertionError(e);
|
||||
return 1;
|
||||
throw e;
|
||||
} catch (Signal.Error.AttachmentInvalid e) {
|
||||
System.err.println("Failed to add avatar attachment for group\": " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Failed to add avatar attachment for group\": " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
return 2;
|
||||
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import net.sourceforge.argparse4j.impl.Arguments;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
|
@ -26,23 +28,21 @@ public class UpdateProfileCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
var name = ns.getString("name");
|
||||
var about = ns.getString("about");
|
||||
var aboutEmoji = ns.getString("about_emoji");
|
||||
var avatarPath = ns.getString("avatar");
|
||||
boolean removeAvatar = ns.getBoolean("remove_avatar");
|
||||
|
||||
try {
|
||||
Optional<File> avatarFile = removeAvatar
|
||||
? Optional.absent()
|
||||
: avatarPath == null ? null : Optional.of(new File(avatarPath));
|
||||
|
||||
try {
|
||||
m.setProfile(name, about, aboutEmoji, avatarFile);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Update profile error: " + e.getMessage());
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
throw new IOErrorException("Update profile error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.PlainTextWriterImpl;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.StickerPackInvalidException;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -23,19 +26,17 @@ public class UploadStickerPackCommand implements LocalCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final Manager m) {
|
||||
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
|
||||
final var writer = new PlainTextWriterImpl(System.out);
|
||||
try {
|
||||
var path = new File(ns.getString("path"));
|
||||
|
||||
try {
|
||||
var url = m.uploadStickerPack(path);
|
||||
writer.println("{}", url);
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
System.err.println("Upload error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Upload error: " + e.getMessage());
|
||||
} catch (StickerPackInvalidException e) {
|
||||
System.err.println("Invalid sticker pack: " + e.getMessage());
|
||||
return 1;
|
||||
throw new UserErrorException("Invalid sticker pack: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ package org.asamk.signal.commands;
|
|||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.RegistrationManager;
|
||||
import org.whispersystems.signalservice.api.KeyBackupServicePinException;
|
||||
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
|
||||
|
@ -19,26 +23,23 @@ public class VerifyCommand implements RegistrationCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int handleCommand(final Namespace ns, final RegistrationManager m) {
|
||||
try {
|
||||
public void handleCommand(final Namespace ns, final RegistrationManager m) throws CommandException {
|
||||
var verificationCode = ns.getString("verificationCode");
|
||||
var pin = ns.getString("pin");
|
||||
|
||||
try {
|
||||
m.verifyAccount(verificationCode, pin);
|
||||
return 0;
|
||||
} catch (LockedException e) {
|
||||
System.err.println("Verification failed! This number is locked with a pin. Hours remaining until reset: "
|
||||
+ (e.getTimeRemaining() / 1000 / 60 / 60));
|
||||
System.err.println("Use '--pin PIN_CODE' to specify the registration lock PIN");
|
||||
return 1;
|
||||
throw new UserErrorException(
|
||||
"Verification failed! This number is locked with a pin. Hours remaining until reset: "
|
||||
+ (e.getTimeRemaining() / 1000 / 60 / 60)
|
||||
+ "\nUse '--pin PIN_CODE' to specify the registration lock PIN");
|
||||
} catch (KeyBackupServicePinException e) {
|
||||
System.err.println("Verification failed! Invalid pin, tries remaining: " + e.getTriesRemaining());
|
||||
return 1;
|
||||
throw new UserErrorException("Verification failed! Invalid pin, tries remaining: " + e.getTriesRemaining());
|
||||
} catch (KeyBackupSystemNoDataException e) {
|
||||
System.err.println("Verification failed! No KBS data.");
|
||||
return 3;
|
||||
throw new UnexpectedErrorException("Verification failed! No KBS data.");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Verify error: " + e.getMessage());
|
||||
return 3;
|
||||
throw new IOErrorException("Verify error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.asamk.signal.commands.exceptions;
|
||||
|
||||
public class CommandException extends Exception {
|
||||
|
||||
public CommandException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.asamk.signal.commands.exceptions;
|
||||
|
||||
public final class IOErrorException extends CommandException {
|
||||
|
||||
public IOErrorException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.asamk.signal.commands.exceptions;
|
||||
|
||||
public final class UnexpectedErrorException extends CommandException {
|
||||
|
||||
public UnexpectedErrorException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.asamk.signal.commands.exceptions;
|
||||
|
||||
public final class UntrustedKeyErrorException extends CommandException {
|
||||
|
||||
public UntrustedKeyErrorException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.asamk.signal.commands.exceptions;
|
||||
|
||||
public final class UserErrorException extends CommandException {
|
||||
|
||||
public UserErrorException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -1,38 +1,34 @@
|
|||
package org.asamk.signal.util;
|
||||
|
||||
import org.asamk.signal.PlainTextWriter;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ErrorUtils {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ErrorUtils.class);
|
||||
|
||||
private ErrorUtils() {
|
||||
}
|
||||
|
||||
public static void handleAssertionError(AssertionError e) {
|
||||
System.err.println("Failed to send/receive message (Assertion): " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
System.err.println(
|
||||
"If you use an Oracle JRE please check if you have unlimited strength crypto enabled, see README");
|
||||
logger.warn("If you use an Oracle JRE please check if you have unlimited strength crypto enabled, see README");
|
||||
}
|
||||
|
||||
public static int handleTimestampAndSendMessageResults(
|
||||
PlainTextWriter writer,
|
||||
long timestamp,
|
||||
List<SendMessageResult> results
|
||||
) throws IOException {
|
||||
public static void handleTimestampAndSendMessageResults(
|
||||
PlainTextWriter writer, long timestamp, List<SendMessageResult> results
|
||||
) throws CommandException {
|
||||
if (timestamp != 0) {
|
||||
writer.println("{}", timestamp);
|
||||
}
|
||||
var errors = getErrorMessagesFromSendMessageResults(results);
|
||||
return handleSendMessageResultErrors(errors);
|
||||
handleSendMessageResultErrors(errors);
|
||||
}
|
||||
|
||||
public static List<String> getErrorMessagesFromSendMessageResults(List<SendMessageResult> results) {
|
||||
|
@ -58,39 +54,15 @@ public class ErrorUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static int handleSendMessageResultErrors(List<String> errors) {
|
||||
private static void handleSendMessageResultErrors(List<String> errors) throws CommandException {
|
||||
if (errors.size() == 0) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
System.err.println("Failed to send (some) messages:");
|
||||
var message = new StringBuilder();
|
||||
message.append("Failed to send (some) messages:\n");
|
||||
for (var error : errors) {
|
||||
System.err.println(error);
|
||||
message.append(error).append("\n");
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
public static void handleIOException(IOException e) {
|
||||
System.err.println("Failed to send message: " + e.getMessage());
|
||||
}
|
||||
|
||||
public static void handleGroupNotFoundException(GroupNotFoundException e) {
|
||||
System.err.println("Failed to send to group: " + e.getMessage());
|
||||
System.err.println("Aborting sending.");
|
||||
}
|
||||
|
||||
public static void handleNotAGroupMemberException(NotAGroupMemberException e) {
|
||||
System.err.println("Failed to send to group: " + e.getMessage());
|
||||
System.err.println("Update the group on another device to readd the user to this group.");
|
||||
System.err.println("Aborting sending.");
|
||||
}
|
||||
|
||||
public static void handleGroupIdFormatException(GroupIdFormatException e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.err.println("Aborting sending.");
|
||||
}
|
||||
|
||||
public static void handleInvalidNumberException(InvalidNumberException e) {
|
||||
System.err.println("Failed to parse recipient: " + e.getMessage());
|
||||
System.err.println("Aborting sending.");
|
||||
throw new IOErrorException(message.toString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue