From 7a6b0c6d414362b20086068f7ed3d24dd717ed4c Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Sun, 5 Nov 2023 17:50:49 +0100 Subject: [PATCH] Add email authentication phase --- ...orizationStateWaitEmailAddressHandler.java | 49 ++++++++++++ ...uthorizationStateWaitEmailCodeHandler.java | 50 ++++++++++++ .../client/EmailAddressResetState.java | 6 ++ .../it/tdlight/client/InputParameter.java | 9 ++- .../client/ParameterInfoEmailAddress.java | 50 ++++++++++++ .../client/ParameterInfoEmailCode.java | 78 +++++++++++++++++++ .../tdlight/client/SimpleTelegramClient.java | 50 ++++++------ .../client/TemporaryMessageHandler.java | 16 ++-- 8 files changed, 273 insertions(+), 35 deletions(-) create mode 100644 tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailAddressHandler.java create mode 100644 tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailCodeHandler.java create mode 100644 tdlight-java/src/main/java/it/tdlight/client/EmailAddressResetState.java create mode 100644 tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailAddress.java create mode 100644 tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailCode.java diff --git a/tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailAddressHandler.java b/tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailAddressHandler.java new file mode 100644 index 0000000..c0efeac --- /dev/null +++ b/tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailAddressHandler.java @@ -0,0 +1,49 @@ +package it.tdlight.client; + +import it.tdlight.ExceptionHandler; +import it.tdlight.TelegramClient; +import it.tdlight.jni.TdApi; +import it.tdlight.jni.TdApi.AuthorizationStateWaitEmailAddress; +import it.tdlight.jni.TdApi.CheckAuthenticationCode; +import it.tdlight.jni.TdApi.CheckAuthenticationEmailCode; +import it.tdlight.jni.TdApi.SetAuthenticationEmailAddress; +import it.tdlight.jni.TdApi.UpdateAuthorizationState; + +final class AuthorizationStateWaitEmailAddressHandler implements GenericUpdateHandler { + + private final TelegramClient client; + private final ClientInteraction clientInteraction; + private final ExceptionHandler exceptionHandler; + + public AuthorizationStateWaitEmailAddressHandler(TelegramClient client, + ClientInteraction clientInteraction, + ExceptionHandler exceptionHandler) { + this.client = client; + this.clientInteraction = clientInteraction; + this.exceptionHandler = exceptionHandler; + } + + @Override + public void onUpdate(UpdateAuthorizationState update) { + if (update.authorizationState.getConstructor() == AuthorizationStateWaitEmailAddress.CONSTRUCTOR) { + AuthorizationStateWaitEmailAddress authorizationState = (AuthorizationStateWaitEmailAddress) update.authorizationState; + ParameterInfo parameterInfo = new ParameterInfoEmailAddress(authorizationState.allowAppleId, authorizationState.allowGoogleId); + clientInteraction.onParameterRequest(InputParameter.ASK_EMAIL_ADDRESS, parameterInfo).whenComplete((emailAddress, ex) -> { + if (ex != null) { + exceptionHandler.onException(ex); + return; + } + sendEmailAddress(emailAddress); + }); + } + } + + private void sendEmailAddress(String emailAddress) { + SetAuthenticationEmailAddress response = new SetAuthenticationEmailAddress(emailAddress); + client.send(response, ok -> { + if (ok.getConstructor() == TdApi.Error.CONSTRUCTOR) { + throw new TelegramError((TdApi.Error) ok); + } + }, exceptionHandler); + } +} diff --git a/tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailCodeHandler.java b/tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailCodeHandler.java new file mode 100644 index 0000000..8c3fd8c --- /dev/null +++ b/tdlight-java/src/main/java/it/tdlight/client/AuthorizationStateWaitEmailCodeHandler.java @@ -0,0 +1,50 @@ +package it.tdlight.client; + +import it.tdlight.ExceptionHandler; +import it.tdlight.TelegramClient; +import it.tdlight.jni.TdApi; +import java.util.Locale; + +final class AuthorizationStateWaitEmailCodeHandler implements GenericUpdateHandler { + + private final TelegramClient client; + private final ClientInteraction clientInteraction; + private final ExceptionHandler exceptionHandler; + + public AuthorizationStateWaitEmailCodeHandler(TelegramClient client, + ClientInteraction clientInteraction, + ExceptionHandler exceptionHandler) { + this.client = client; + this.clientInteraction = clientInteraction; + this.exceptionHandler = exceptionHandler; + } + + @Override + public void onUpdate(TdApi.UpdateAuthorizationState update) { + if (update.authorizationState.getConstructor() == TdApi.AuthorizationStateWaitEmailCode.CONSTRUCTOR) { + TdApi.AuthorizationStateWaitEmailCode authorizationState = (TdApi.AuthorizationStateWaitEmailCode) update.authorizationState; + ParameterInfo parameterInfo = new ParameterInfoEmailCode(authorizationState.allowAppleId, + authorizationState.allowGoogleId, + authorizationState.codeInfo.emailAddressPattern, + authorizationState.codeInfo.length, + EmailAddressResetState.valueOf(authorizationState.emailAddressResetState.getClass().getSimpleName().substring("EmailAddressResetState".length()).toUpperCase(Locale.ROOT)) + ); + clientInteraction.onParameterRequest(InputParameter.ASK_EMAIL_CODE, parameterInfo).whenComplete((emailAddress, ex) -> { + if (ex != null) { + exceptionHandler.onException(ex); + return; + } + sendEmailCode(emailAddress); + }); + } + } + + private void sendEmailCode(String code) { + TdApi.CheckAuthenticationEmailCode response = new TdApi.CheckAuthenticationEmailCode(new TdApi.EmailAddressAuthenticationCode(code)); + client.send(response, ok -> { + if (ok.getConstructor() == TdApi.Error.CONSTRUCTOR) { + throw new TelegramError((TdApi.Error) ok); + } + }, exceptionHandler); + } +} diff --git a/tdlight-java/src/main/java/it/tdlight/client/EmailAddressResetState.java b/tdlight-java/src/main/java/it/tdlight/client/EmailAddressResetState.java new file mode 100644 index 0000000..4d115c3 --- /dev/null +++ b/tdlight-java/src/main/java/it/tdlight/client/EmailAddressResetState.java @@ -0,0 +1,6 @@ +package it.tdlight.client; + +public enum EmailAddressResetState { + AVAILABLE, + PENDING +} diff --git a/tdlight-java/src/main/java/it/tdlight/client/InputParameter.java b/tdlight-java/src/main/java/it/tdlight/client/InputParameter.java index 1ed8b9b..e2c2822 100644 --- a/tdlight-java/src/main/java/it/tdlight/client/InputParameter.java +++ b/tdlight-java/src/main/java/it/tdlight/client/InputParameter.java @@ -1,5 +1,12 @@ package it.tdlight.client; public enum InputParameter { - ASK_FIRST_NAME, ASK_LAST_NAME, ASK_CODE, ASK_PASSWORD, NOTIFY_LINK, TERMS_OF_SERVICE + ASK_FIRST_NAME, + ASK_LAST_NAME, + ASK_CODE, + ASK_PASSWORD, + NOTIFY_LINK, + TERMS_OF_SERVICE, + ASK_EMAIL_ADDRESS, + ASK_EMAIL_CODE } diff --git a/tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailAddress.java b/tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailAddress.java new file mode 100644 index 0000000..7183840 --- /dev/null +++ b/tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailAddress.java @@ -0,0 +1,50 @@ +package it.tdlight.client; + +import it.tdlight.jni.TdApi.AuthenticationCodeType; +import java.util.Objects; +import java.util.StringJoiner; + +public final class ParameterInfoEmailAddress implements ParameterInfo { + + private final boolean allowGoogleId; + private final boolean allowAppleId; + + public ParameterInfoEmailAddress(boolean allowGoogleId, + boolean allowAppleId) { + this.allowGoogleId = allowGoogleId; + this.allowAppleId = allowAppleId; + } + + public boolean isAllowGoogleId() { + return allowGoogleId; + } + + public boolean isAllowAppleId() { + return allowAppleId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ParameterInfoEmailAddress that = (ParameterInfoEmailAddress) o; + return allowGoogleId == that.allowGoogleId && allowAppleId == that.allowAppleId; + } + + @Override + public int hashCode() { + return Objects.hash(allowGoogleId, allowAppleId); + } + + @Override + public String toString() { + return new StringJoiner(", ", ParameterInfoEmailAddress.class.getSimpleName() + "[", "]") + .add("allowGoogleId='" + allowGoogleId + "'") + .add("allowAppleId=" + allowAppleId) + .toString(); + } +} diff --git a/tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailCode.java b/tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailCode.java new file mode 100644 index 0000000..d012cd6 --- /dev/null +++ b/tdlight-java/src/main/java/it/tdlight/client/ParameterInfoEmailCode.java @@ -0,0 +1,78 @@ +package it.tdlight.client; + +import it.tdlight.jni.TdApi.EmailAddressAuthenticationCodeInfo; +import it.tdlight.jni.TdApi.EmailAddressResetStateAvailable; +import it.tdlight.jni.TdApi.EmailAddressResetStatePending; +import java.util.Objects; +import java.util.StringJoiner; + +public final class ParameterInfoEmailCode implements ParameterInfo { + + private final boolean allowGoogleId; + private final boolean allowAppleId; + private final String emailAddressPattern; + private final int emailLength; + private final EmailAddressResetState emailAddressResetState; + + public ParameterInfoEmailCode(boolean allowGoogleId, + boolean allowAppleId, + String emailAddressPattern, + int emailLength, + EmailAddressResetState emailAddressResetState) { + this.allowGoogleId = allowGoogleId; + this.allowAppleId = allowAppleId; + this.emailAddressPattern = emailAddressPattern; + this.emailLength = emailLength; + this.emailAddressResetState = emailAddressResetState; + } + + public boolean isAllowGoogleId() { + return allowGoogleId; + } + + public boolean isAllowAppleId() { + return allowAppleId; + } + + public String getEmailAddressPattern() { + return emailAddressPattern; + } + + public int getEmailLength() { + return emailLength; + } + + public EmailAddressResetState getEmailAddressResetState() { + return emailAddressResetState; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ParameterInfoEmailCode that = (ParameterInfoEmailCode) o; + return allowGoogleId == that.allowGoogleId && allowAppleId == that.allowAppleId && emailLength == that.emailLength + && Objects.equals(emailAddressPattern, that.emailAddressPattern) + && emailAddressResetState == that.emailAddressResetState; + } + + @Override + public int hashCode() { + return Objects.hash(allowGoogleId, allowAppleId, emailAddressPattern, emailLength, emailAddressResetState); + } + + @Override + public String toString() { + return new StringJoiner(", ", ParameterInfoEmailCode.class.getSimpleName() + "[", "]") + .add("allowGoogleId=" + allowGoogleId) + .add("allowAppleId=" + allowAppleId) + .add("emailAddressPattern='" + emailAddressPattern + "'") + .add("emailLength=" + emailLength) + .add("emailAddressResetState=" + emailAddressResetState) + .toString(); + } +} diff --git a/tdlight-java/src/main/java/it/tdlight/client/SimpleTelegramClient.java b/tdlight-java/src/main/java/it/tdlight/client/SimpleTelegramClient.java index c090c4c..dd5e324 100644 --- a/tdlight-java/src/main/java/it/tdlight/client/SimpleTelegramClient.java +++ b/tdlight-java/src/main/java/it/tdlight/client/SimpleTelegramClient.java @@ -92,30 +92,33 @@ public final class SimpleTelegramClient implements Authenticable, MutableTelegra this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitAuthenticationDataHandler(client, this, this::handleDefaultException) ); - this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, - new AuthorizationStateWaitRegistrationHandler(client, - new SimpleTelegramClientInteraction(), + var updateHandlerInteraction = new SimpleTelegramClientInteraction(); + this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitRegistrationHandler(client, + updateHandlerInteraction, + this::handleDefaultException + )); + this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitPasswordHandler(client, + updateHandlerInteraction, + this::handleDefaultException + )); + this.addUpdateHandler( + TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitOtherDeviceConfirmationHandler( + updateHandlerInteraction, this::handleDefaultException - ) - ); - this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, - new AuthorizationStateWaitPasswordHandler(client, - new SimpleTelegramClientInteraction(), - this::handleDefaultException - ) - ); - this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, - new AuthorizationStateWaitOtherDeviceConfirmationHandler(new SimpleTelegramClientInteraction(), - this::handleDefaultException - ) - ); - this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, - new AuthorizationStateWaitCodeHandler(client, - new SimpleTelegramClientInteraction(), - getTestCode(authenticationData), - this::handleDefaultException - ) - ); + )); + this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitCodeHandler(client, + updateHandlerInteraction, + getTestCode(authenticationData), + this::handleDefaultException + )); + this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitEmailAddressHandler(client, + updateHandlerInteraction, + this::handleDefaultException + )); + this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitEmailCodeHandler(client, + updateHandlerInteraction, + this::handleDefaultException + )); this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitReady(this::onReady)); this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitForExit(this::onCloseUpdate)); this.mainChatsLoader = new AuthorizationStateReadyLoadChats(client, new ChatListMain()); @@ -353,7 +356,6 @@ public final class SimpleTelegramClient implements Authenticable, MutableTelegra * @param function The request to TDLib. * @throws NullPointerException if function is null. */ - @SuppressWarnings("unchecked") public CompletableFuture send(TdApi.Function function) { CompletableFuture future = new CompletableFuture<>(); if (shouldWaitForReadiness(function)) { diff --git a/tdlight-java/src/main/java/it/tdlight/client/TemporaryMessageHandler.java b/tdlight-java/src/main/java/it/tdlight/client/TemporaryMessageHandler.java index cbc11e5..f3bbe5e 100644 --- a/tdlight-java/src/main/java/it/tdlight/client/TemporaryMessageHandler.java +++ b/tdlight-java/src/main/java/it/tdlight/client/TemporaryMessageHandler.java @@ -1,10 +1,6 @@ package it.tdlight.client; import it.tdlight.jni.TdApi; -import it.tdlight.jni.TdApi.Message; -import it.tdlight.jni.TdApi.Update; -import it.tdlight.jni.TdApi.UpdateMessageSendFailed; -import it.tdlight.jni.TdApi.UpdateMessageSendSucceeded; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.CompletableFuture; @@ -14,14 +10,14 @@ class TemporaryMessageHandler implements GenericUpdateHandler { private static final Logger LOG = LoggerFactory.getLogger(TemporaryMessageHandler.class); - private final ConcurrentMap> temporaryMessages; + private final ConcurrentMap> temporaryMessages; - public TemporaryMessageHandler(ConcurrentMap> temporaryMessages) { + public TemporaryMessageHandler(ConcurrentMap> temporaryMessages) { this.temporaryMessages = temporaryMessages; } @Override - public void onUpdate(Update update) { + public void onUpdate(TdApi.Update update) { switch (update.getConstructor()) { case TdApi.UpdateMessageSendSucceeded.CONSTRUCTOR: onUpdateSuccess(((TdApi.UpdateMessageSendSucceeded) update)); break; @@ -30,7 +26,7 @@ class TemporaryMessageHandler implements GenericUpdateHandler { } } - private void onUpdateSuccess(UpdateMessageSendSucceeded updateMessageSendSucceeded) { + private void onUpdateSuccess(TdApi.UpdateMessageSendSucceeded updateMessageSendSucceeded) { TemporaryMessageURL tempUrl = new TemporaryMessageURL(updateMessageSendSucceeded.message.chatId, updateMessageSendSucceeded.oldMessageId); CompletableFuture future = temporaryMessages.remove(tempUrl); @@ -41,14 +37,14 @@ class TemporaryMessageHandler implements GenericUpdateHandler { } } - private void onUpdateFailed(UpdateMessageSendFailed updateMessageSendFailed) { + private void onUpdateFailed(TdApi.UpdateMessageSendFailed updateMessageSendFailed) { TemporaryMessageURL tempUrl = new TemporaryMessageURL(updateMessageSendFailed.message.chatId, updateMessageSendFailed.oldMessageId); CompletableFuture future = temporaryMessages.remove(tempUrl); if (future == null) { logNotHandled(tempUrl); } else { - TdApi.Error error = new TdApi.Error(updateMessageSendFailed.errorCode, updateMessageSendFailed.errorMessage); + TdApi.Error error = updateMessageSendFailed.error; future.completeExceptionally(new TelegramError(error)); } }