From f2ba9773f5d60abed6282037e879c8f7af44449b Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Mon, 27 Sep 2021 21:44:24 +0200 Subject: [PATCH] Use interactive console login in the example, print exceptions only once --- .../main/java/it.tdlight.example/Example.java | 2 +- example/src/main/resources/log4j2.xml | 4 +- .../it/tdlight/client/AuthenticationData.java | 77 +++---------- .../client/AuthenticationDataImpl.java | 69 ++++++++++++ ...ionStateWaitAuthenticationDataHandler.java | 12 +-- .../AuthorizationStateWaitCodeHandler.java | 7 +- ...rizationStateWaitEncryptionKeyHandler.java | 7 +- ...ateWaitOtherDeviceConfirmationHandler.java | 8 +- ...AuthorizationStateWaitPasswordHandler.java | 7 +- ...orizationStateWaitRegistrationHandler.java | 7 +- ...zationStateWaitTdlibParametersHandler.java | 7 +- .../ConsoleInteractiveAuthenticationData.java | 101 ++++++++++++++++++ .../tdlight/client/SimpleTelegramClient.java | 11 +- 13 files changed, 194 insertions(+), 125 deletions(-) create mode 100644 src/main/java/it/tdlight/client/AuthenticationDataImpl.java create mode 100644 src/main/java/it/tdlight/client/ConsoleInteractiveAuthenticationData.java diff --git a/example/src/main/java/it.tdlight.example/Example.java b/example/src/main/java/it.tdlight.example/Example.java index 706ca2e..f58da07 100644 --- a/example/src/main/java/it.tdlight.example/Example.java +++ b/example/src/main/java/it.tdlight.example/Example.java @@ -67,7 +67,7 @@ public final class Example { SimpleTelegramClient client = new SimpleTelegramClient(settings); // Configure the authentication info - AuthenticationData authenticationData = AuthenticationData.bot("124:1999"); + AuthenticationData authenticationData = AuthenticationData.consoleLogin(); // Add an example update handler that prints when the bot is started client.addUpdateHandler(UpdateAuthorizationState.class, update -> printStatus(update.authorizationState)); diff --git a/example/src/main/resources/log4j2.xml b/example/src/main/resources/log4j2.xml index ea9edbe..b1e9580 100644 --- a/example/src/main/resources/log4j2.xml +++ b/example/src/main/resources/log4j2.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://logging.apache.org/log4j/2.0/config https://raw.githubusercontent.com/apache/logging-log4j2/log4j-2.14.1/log4j-core/src/main/resources/Log4j-config.xsd" - status="ALL"> + status="INFO"> - + diff --git a/src/main/java/it/tdlight/client/AuthenticationData.java b/src/main/java/it/tdlight/client/AuthenticationData.java index dde3037..4230ba4 100644 --- a/src/main/java/it/tdlight/client/AuthenticationData.java +++ b/src/main/java/it/tdlight/client/AuthenticationData.java @@ -1,75 +1,22 @@ package it.tdlight.client; -import java.util.Objects; -import java.util.StringJoiner; +public interface AuthenticationData { -@SuppressWarnings("unused") -public final class AuthenticationData { - private final Long userPhoneNumber; - private final String botToken; + boolean isBot(); - private AuthenticationData(Long userPhoneNumber, String botToken) { - if ((userPhoneNumber == null) == (botToken == null)) { - throw new IllegalArgumentException("Please use either a bot token or a phone number"); - } - if (botToken != null) { - if (botToken.length() < 5 || botToken.length() > 200) { - throw new IllegalArgumentException("Bot token is invalid: " + botToken); - } - } - this.userPhoneNumber = userPhoneNumber; - this.botToken = botToken; + long getUserPhoneNumber(); + + String getBotToken(); + + static AuthenticationData user(long userPhoneNumber) { + return new AuthenticationDataImpl(userPhoneNumber, null); } - public static AuthenticationData user(long userPhoneNumber) { - return new AuthenticationData(userPhoneNumber, null); + static AuthenticationData bot(String botToken) { + return new AuthenticationDataImpl(null, botToken); } - public static AuthenticationData bot(String botToken) { - return new AuthenticationData(null, botToken); - } - - public boolean isBot() { - return botToken != null; - } - - public Long getUserPhoneNumber() { - if (userPhoneNumber == null) { - throw new UnsupportedOperationException("This is not a user"); - } - return userPhoneNumber; - } - - public String getBotToken() { - if (botToken == null) { - throw new UnsupportedOperationException("This is not a bot"); - } - return botToken; - } - - @Override - public String toString() { - if (userPhoneNumber != null) { - return "+" + userPhoneNumber; - } else { - return "\"" + botToken + "\""; - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AuthenticationData that = (AuthenticationData) o; - return Objects.equals(userPhoneNumber, that.userPhoneNumber) && Objects.equals(botToken, that.botToken); - } - - @Override - public int hashCode() { - return Objects.hash(userPhoneNumber, botToken); + static AuthenticationData consoleLogin() { + return new ConsoleInteractiveAuthenticationData(); } } diff --git a/src/main/java/it/tdlight/client/AuthenticationDataImpl.java b/src/main/java/it/tdlight/client/AuthenticationDataImpl.java new file mode 100644 index 0000000..efe3fd0 --- /dev/null +++ b/src/main/java/it/tdlight/client/AuthenticationDataImpl.java @@ -0,0 +1,69 @@ +package it.tdlight.client; + +import java.util.Objects; + +@SuppressWarnings("unused") +final class AuthenticationDataImpl implements AuthenticationData { + private final Long userPhoneNumber; + private final String botToken; + + AuthenticationDataImpl(Long userPhoneNumber, String botToken) { + if ((userPhoneNumber == null) == (botToken == null)) { + throw new IllegalArgumentException("Please use either a bot token or a phone number"); + } + if (botToken != null) { + if (botToken.length() < 5 || botToken.length() > 200) { + throw new IllegalArgumentException("Bot token is invalid: " + botToken); + } + } + this.userPhoneNumber = userPhoneNumber; + this.botToken = botToken; + } + + @Override + public boolean isBot() { + return botToken != null; + } + + @Override + public long getUserPhoneNumber() { + if (userPhoneNumber == null) { + throw new UnsupportedOperationException("This is not a user"); + } + return userPhoneNumber; + } + + @Override + public String getBotToken() { + if (botToken == null) { + throw new UnsupportedOperationException("This is not a bot"); + } + return botToken; + } + + @Override + public String toString() { + if (userPhoneNumber != null) { + return "+" + userPhoneNumber; + } else { + return "\"" + botToken + "\""; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AuthenticationDataImpl that = (AuthenticationDataImpl) o; + return Objects.equals(userPhoneNumber, that.userPhoneNumber) && Objects.equals(botToken, that.botToken); + } + + @Override + public int hashCode() { + return Objects.hash(userPhoneNumber, botToken); + } +} diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitAuthenticationDataHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitAuthenticationDataHandler.java index 76bd778..9c46b25 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitAuthenticationDataHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitAuthenticationDataHandler.java @@ -16,8 +16,6 @@ package it.tdlight.client; final class AuthorizationStateWaitAuthenticationDataHandler implements GenericUpdateHandler { - private static final Logger logger = LoggerFactory.getLogger(AuthorizationStateWaitAuthenticationDataHandler.class); - private final TelegramClient client; private final Authenticable authenticable; private final ExceptionHandler exceptionHandler; @@ -41,10 +39,7 @@ final class AuthorizationStateWaitAuthenticationDataHandler implements GenericUp if (ok.getConstructor() == Error.CONSTRUCTOR) { throw new TelegramError((Error) ok); } - }, ex -> { - logger.error("Failed to set TDLight phone number or bot token!", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } else { PhoneNumberAuthenticationSettings phoneSettings = new PhoneNumberAuthenticationSettings(false, false, false); @@ -54,10 +49,7 @@ final class AuthorizationStateWaitAuthenticationDataHandler implements GenericUp if (ok.getConstructor() == Error.CONSTRUCTOR) { throw new TelegramError((Error) ok); } - }, ex -> { - logger.error("Failed to set TDLight phone number!", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } } } diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitCodeHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitCodeHandler.java index 00f9864..ae05055 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitCodeHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitCodeHandler.java @@ -14,8 +14,6 @@ import org.slf4j.LoggerFactory; final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler { - private static final Logger logger = LoggerFactory.getLogger(AuthorizationStateWaitCodeHandler.class); - private final TelegramClient client; private final ClientInteraction clientInteraction; private final ExceptionHandler exceptionHandler; @@ -44,10 +42,7 @@ final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler { - logger.error("Failed to check authentication code", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } } } diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitEncryptionKeyHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitEncryptionKeyHandler.java index 8e08611..04588ac 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitEncryptionKeyHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitEncryptionKeyHandler.java @@ -14,8 +14,6 @@ import org.slf4j.LoggerFactory; final class AuthorizationStateWaitEncryptionKeyHandler implements GenericUpdateHandler { - private static final Logger logger = LoggerFactory.getLogger(AuthorizationStateWaitEncryptionKeyHandler.class); - private final TelegramClient client; private final ExceptionHandler exceptionHandler; @@ -31,10 +29,7 @@ final class AuthorizationStateWaitEncryptionKeyHandler implements GenericUpdateH if (ok.getConstructor() == Error.CONSTRUCTOR) { throw new TelegramError((Error) ok); } - }, ex -> { - logger.error("Failed to manage TDLight database encryption key!", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } } } diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitOtherDeviceConfirmationHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitOtherDeviceConfirmationHandler.java index 72c1c0b..b30c64f 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitOtherDeviceConfirmationHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitOtherDeviceConfirmationHandler.java @@ -8,16 +8,10 @@ import it.tdlight.jni.TdApi.UpdateAuthorizationState; final class AuthorizationStateWaitOtherDeviceConfirmationHandler implements GenericUpdateHandler { - private final TelegramClient client; private final ClientInteraction clientInteraction; - private final ExceptionHandler exceptionHandler; - public AuthorizationStateWaitOtherDeviceConfirmationHandler(TelegramClient client, - ClientInteraction clientInteraction, - ExceptionHandler exceptionHandler) { - this.client = client; + public AuthorizationStateWaitOtherDeviceConfirmationHandler(ClientInteraction clientInteraction) { this.clientInteraction = clientInteraction; - this.exceptionHandler = exceptionHandler; } @Override diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitPasswordHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitPasswordHandler.java index e26a9dc..1838bb0 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitPasswordHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitPasswordHandler.java @@ -14,8 +14,6 @@ import org.slf4j.LoggerFactory; final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandler { - private static final Logger logger = LoggerFactory.getLogger(AuthorizationStateWaitPasswordHandler.class); - private final TelegramClient client; private final ClientInteraction clientInteraction; private final ExceptionHandler exceptionHandler; @@ -43,10 +41,7 @@ final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandle if (ok.getConstructor() == Error.CONSTRUCTOR) { throw new TelegramError((Error) ok); } - }, ex -> { - logger.error("Failed to check authentication password", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } } } diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitRegistrationHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitRegistrationHandler.java index 64e7931..2391f80 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitRegistrationHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitRegistrationHandler.java @@ -12,8 +12,6 @@ import org.slf4j.LoggerFactory; final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHandler { - private static final Logger logger = LoggerFactory.getLogger(AuthorizationStateWaitRegistrationHandler.class); - private final TelegramClient client; private final ClientInteraction clientInteraction; private final ExceptionHandler exceptionHandler; @@ -55,10 +53,7 @@ final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHa if (ok.getConstructor() == Error.CONSTRUCTOR) { throw new TelegramError((Error) ok); } - }, ex -> { - logger.error("Failed to register user", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } } } diff --git a/src/main/java/it/tdlight/client/AuthorizationStateWaitTdlibParametersHandler.java b/src/main/java/it/tdlight/client/AuthorizationStateWaitTdlibParametersHandler.java index 21fcfa5..cd44927 100644 --- a/src/main/java/it/tdlight/client/AuthorizationStateWaitTdlibParametersHandler.java +++ b/src/main/java/it/tdlight/client/AuthorizationStateWaitTdlibParametersHandler.java @@ -12,8 +12,6 @@ import org.slf4j.LoggerFactory; final class AuthorizationStateWaitTdlibParametersHandler implements GenericUpdateHandler { - private static final Logger logger = LoggerFactory.getLogger(AuthorizationStateWaitEncryptionKeyHandler.class); - private final TelegramClient client; private final TDLibSettings settings; private final ExceptionHandler exceptionHandler; @@ -49,10 +47,7 @@ final class AuthorizationStateWaitTdlibParametersHandler implements GenericUpdat if (ok.getConstructor() == Error.CONSTRUCTOR) { throw new TelegramError((Error) ok); } - }, ex -> { - logger.error("Failed to set TDLight parameters!", ex); - exceptionHandler.onException(ex); - }); + }, exceptionHandler); } } } diff --git a/src/main/java/it/tdlight/client/ConsoleInteractiveAuthenticationData.java b/src/main/java/it/tdlight/client/ConsoleInteractiveAuthenticationData.java new file mode 100644 index 0000000..ffed0d8 --- /dev/null +++ b/src/main/java/it/tdlight/client/ConsoleInteractiveAuthenticationData.java @@ -0,0 +1,101 @@ +package it.tdlight.client; + +import it.tdlight.common.utils.ScannerUtils; +import java.util.Locale; +import java.util.stream.Collector; + +final class ConsoleInteractiveAuthenticationData implements AuthenticationData { + + private static final Object LOCK = new Object(); + + private boolean initialized = false; + private boolean isBot; + private String botToken; + private long phoneNumber; + + public ConsoleInteractiveAuthenticationData() { + + } + + public void askData() { + initializeIfNeeded(); + } + + @Override + public boolean isBot() { + initializeIfNeeded(); + return isBot; + } + + @Override + public long getUserPhoneNumber() { + initializeIfNeeded(); + if (isBot) { + throw new UnsupportedOperationException("This is not a user"); + } + return phoneNumber; + } + + @Override + public String getBotToken() { + initializeIfNeeded(); + if (!isBot) { + throw new UnsupportedOperationException("This is not a bot"); + } + return botToken; + } + + private void initializeIfNeeded() { + if (initialized) return; + + synchronized (LOCK) { + if (initialized) return; + + String choice; + + // Choose login type + Boolean useBotToken; + do { + choice = ScannerUtils + .askParameter("login", "Do you want to login using a bot [token] or a [phone] number? [token/phone]") + .trim() + .toLowerCase(Locale.ROOT); + if ("phone".equals(choice)) { + useBotToken = false; + } else if ("token".equals(choice)) { + useBotToken = true; + } else { + useBotToken = null; + } + } while (useBotToken == null); + + if (useBotToken) { + String token; + do { + token = ScannerUtils.askParameter("login", "Please type the bot token"); + } while (token.length() < 5 || !token.contains(":")); + + this.isBot = true; + this.phoneNumber = -1; + this.botToken = token; + } else { + String phoneNumber; + do { + phoneNumber = ScannerUtils.askParameter("login", "Please type your phone number"); + } while (phoneNumber.length() < 3); + + long phoneNumberLong = Long.parseLong(phoneNumber.chars().filter(Character::isDigit).boxed().collect(Collector.of( + StringBuilder::new, + StringBuilder::append, + StringBuilder::append, + StringBuilder::toString))); + + this.isBot = false; + this.phoneNumber = phoneNumberLong; + this.botToken = null; + } + + initialized = true; + } + } +} diff --git a/src/main/java/it/tdlight/client/SimpleTelegramClient.java b/src/main/java/it/tdlight/client/SimpleTelegramClient.java index 3df695a..9d8e5a2 100644 --- a/src/main/java/it/tdlight/client/SimpleTelegramClient.java +++ b/src/main/java/it/tdlight/client/SimpleTelegramClient.java @@ -10,24 +10,16 @@ import it.tdlight.common.internal.CommonClientManager; import it.tdlight.common.utils.CantLoadLibrary; import it.tdlight.common.utils.LibraryVersion; import it.tdlight.jni.TdApi; -import it.tdlight.jni.TdApi.Chat; import it.tdlight.jni.TdApi.Error; import it.tdlight.jni.TdApi.Function; -import it.tdlight.jni.TdApi.Message; -import it.tdlight.jni.TdApi.MessageText; -import it.tdlight.jni.TdApi.UpdateNewMessage; import it.tdlight.jni.TdApi.User; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Files; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.Set; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,8 +75,7 @@ public final class SimpleTelegramClient implements Authenticable { new AuthorizationStateWaitPasswordHandler(client, new SimpleTelegramClientInteraction(), this::handleDefaultException)); this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, - new AuthorizationStateWaitOtherDeviceConfirmationHandler(client, new SimpleTelegramClientInteraction(), - this::handleDefaultException)); + new AuthorizationStateWaitOtherDeviceConfirmationHandler(new SimpleTelegramClientInteraction())); this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitCodeHandler(client, new SimpleTelegramClientInteraction(), this::handleDefaultException));