Add email authentication phase

This commit is contained in:
Andrea Cavalli 2023-11-05 17:50:49 +01:00
parent 8338b52b50
commit 7a6b0c6d41
8 changed files with 273 additions and 35 deletions

View File

@ -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<UpdateAuthorizationState> {
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);
}
}

View File

@ -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<TdApi.UpdateAuthorizationState> {
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);
}
}

View File

@ -0,0 +1,6 @@
package it.tdlight.client;
public enum EmailAddressResetState {
AVAILABLE,
PENDING
}

View File

@ -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
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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 <R extends TdApi.Object> CompletableFuture<R> send(TdApi.Function<R> function) {
CompletableFuture<Void> future = new CompletableFuture<>();
if (shouldWaitForReadiness(function)) {

View File

@ -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<TdApi.Update> {
private static final Logger LOG = LoggerFactory.getLogger(TemporaryMessageHandler.class);
private final ConcurrentMap<TemporaryMessageURL, CompletableFuture<Message>> temporaryMessages;
private final ConcurrentMap<TemporaryMessageURL, CompletableFuture<TdApi.Message>> temporaryMessages;
public TemporaryMessageHandler(ConcurrentMap<TemporaryMessageURL, CompletableFuture<Message>> temporaryMessages) {
public TemporaryMessageHandler(ConcurrentMap<TemporaryMessageURL, CompletableFuture<TdApi.Message>> 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<TdApi.Update> {
}
}
private void onUpdateSuccess(UpdateMessageSendSucceeded updateMessageSendSucceeded) {
private void onUpdateSuccess(TdApi.UpdateMessageSendSucceeded updateMessageSendSucceeded) {
TemporaryMessageURL tempUrl
= new TemporaryMessageURL(updateMessageSendSucceeded.message.chatId, updateMessageSendSucceeded.oldMessageId);
CompletableFuture<TdApi.Message> future = temporaryMessages.remove(tempUrl);
@ -41,14 +37,14 @@ class TemporaryMessageHandler implements GenericUpdateHandler<TdApi.Update> {
}
}
private void onUpdateFailed(UpdateMessageSendFailed updateMessageSendFailed) {
private void onUpdateFailed(TdApi.UpdateMessageSendFailed updateMessageSendFailed) {
TemporaryMessageURL tempUrl
= new TemporaryMessageURL(updateMessageSendFailed.message.chatId, updateMessageSendFailed.oldMessageId);
CompletableFuture<TdApi.Message> 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));
}
}