Implemented new checks in authorizationHandler for check if bot token, phone number, code or password are invalid

Added password hint in password authorization

Check if EasyClient has the authorization before send request

Optimized execute in EasyClient

Implemented close and open for logout from TDLib e re-login

Now client can execute auto, just set logoutAtShutdown to true in initializer

Fix https://github.com/ErnyTech/JTDLib/issues/5
This commit is contained in:
Ernesto Castellotti 2018-11-19 17:59:57 +01:00
parent f6887374db
commit f8e0f352c3
5 changed files with 96 additions and 22 deletions

View File

@ -29,6 +29,6 @@ public class BotClient extends EasyClient {
* @param botToken The bot token generated with t.me/BotFather * @param botToken The bot token generated with t.me/BotFather
*/ */
public BotClient(String botToken) { public BotClient(String botToken) {
super(easyClient -> easyClient.send(new TdApi.CheckAuthenticationBotToken(botToken))); super(easyClient -> easyClient.sendRaw(new TdApi.CheckAuthenticationBotToken(botToken)));
} }
} }

View File

@ -24,6 +24,8 @@ import it.ernytech.tdlib.utils.ReceiveCallback;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -36,17 +38,28 @@ public class EasyClient {
private ClientActor clientActor; private ClientActor clientActor;
private ConcurrentHashMap<Long, TdCallback> handlers = new ConcurrentHashMap<>(); private ConcurrentHashMap<Long, TdCallback> handlers = new ConcurrentHashMap<>();
private AtomicLong requestId = new AtomicLong(1); private AtomicLong requestId = new AtomicLong(1);
private ExecutorService executors = Executors.newFixedThreadPool(10);
protected volatile boolean haveAuthorization = false; protected volatile boolean haveAuthorization = false;
private volatile boolean haveClosed = false;
/** /**
* Creates a new EasyClient. * Creates a new EasyClient.
* @param authorizationHandler Callback to be implemented in the client to manage the authorization. * @param authorizationHandler Callback to be implemented in the client to manage the authorization.
*/ */
public EasyClient(AuthorizationHandler authorizationHandler) { public EasyClient(AuthorizationHandler authorizationHandler) {
Log.setVerbosityLevel(1);
this.authorizationHandler = authorizationHandler; this.authorizationHandler = authorizationHandler;
this.handlers.put(0L, new TdCallback(response -> {}, error -> {}, () -> {})); this.handlers.put(0L, new TdCallback(response -> {}, error -> {}, () -> {}));
this.clientActor = new ClientActor(new TdCallback(this::onResult, this::onError, this::onClosed)); open();
}
public EasyClient(AuthorizationHandler authorizationHandler, boolean logoutAtShutdown) {
this.authorizationHandler = authorizationHandler;
this.handlers.put(0L, new TdCallback(response -> {}, error -> {}, () -> {}));
open();
if (logoutAtShutdown) {
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
} }
/** /**
@ -56,7 +69,15 @@ public class EasyClient {
*/ */
public long send(TdApi.Function function) { public long send(TdApi.Function function) {
var requestId = this.requestId.getAndIncrement(); var requestId = this.requestId.getAndIncrement();
this.clientActor.request(new Request(requestId, function)); this.executors.execute(() -> {
while (true) {
if (this.haveAuthorization) {
break;
}
}
this.clientActor.request(new Request(requestId, function));
});
return requestId; return requestId;
} }
@ -67,12 +88,6 @@ public class EasyClient {
* @param errorCallback Interface of callback for receive incoming error response. * @param errorCallback Interface of callback for receive incoming error response.
*/ */
public void execute(TdApi.Function function, ReceiveCallback receiveCallback, ErrorCallback errorCallback) { public void execute(TdApi.Function function, ReceiveCallback receiveCallback, ErrorCallback errorCallback) {
while (true) {
if (haveAuthorization) {
break;
}
}
var requestId = send(function); var requestId = send(function);
this.handlers.put(requestId, new TdCallback(receiveCallback, errorCallback)); this.handlers.put(requestId, new TdCallback(receiveCallback, errorCallback));
} }
@ -170,6 +185,17 @@ public class EasyClient {
this.handlers.put(0L, new TdCallback(receiveCallback, errorCallback, closeCallback)); this.handlers.put(0L, new TdCallback(receiveCallback, errorCallback, closeCallback));
} }
public void close() {
send(new TdApi.LogOut());
this.executors.shutdown();
this.haveClosed = true;
}
public void open() {
Log.setVerbosityLevel(1);
inizializeClient();
}
/** /**
* Destroys the client and TDLib instance. * Destroys the client and TDLib instance.
*/ */
@ -179,8 +205,10 @@ public class EasyClient {
} }
private void onResult(Response response) { private void onResult(Response response) {
System.out.println(response.getObject());
if (response.getObject().getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) { if (response.getObject().getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) {
authorizationHandler((TdApi.UpdateAuthorizationState) response.getObject()); TdApi.UpdateAuthorizationState updateAuthorizationState = (TdApi.UpdateAuthorizationState) response.getObject();
authorizationHandler(updateAuthorizationState.authorizationState);
return; return;
} }
@ -199,6 +227,24 @@ public class EasyClient {
} }
private void onError(Response error) { private void onError(Response error) {
TdApi.Error tdError = (TdApi.Error) error.getObject();
if (tdError.message.equals("PHONE_CODE_INVALID")) {
authorizationHandler(new TdApi.AuthorizationStateWaitCode());
}
if (tdError.message.equals("PASSWORD_HASH_INVALID")) {
authorizationHandler(new TdApi.AuthorizationStateWaitPassword());
}
if (tdError.message.equals("PHONE_NUMBER_INVALID")) {
throw new IllegalArgumentException("Phone number is invalid!");
}
if (tdError.message.equals("ACCESS_TOKEN_INVALID")) {
throw new IllegalArgumentException("Bot token is invalid!");
}
if (error.getId() == 0) { if (error.getId() == 0) {
this.handlers.get(0L).getErrorCallback().onError(error); this.handlers.get(0L).getErrorCallback().onError(error);
} else { } else {
@ -216,12 +262,21 @@ public class EasyClient {
this.handlers.get(0L).getCloseCallback().onClosed(); this.handlers.get(0L).getCloseCallback().onClosed();
} }
private void inizializeClient() {
this.clientActor = new ClientActor(new TdCallback(this::onResult, this::onError, this::onClosed));
}
public void sendRaw(TdApi.Function function) {
var requestId = this.requestId.getAndIncrement();
this.clientActor.request(new Request(requestId, function));
}
/** /**
* Manages the authorization state updates. * Manages the authorization state updates.
* @param authorizationState The status of the authorization. * @param authorizationState The status of the authorization.
*/ */
protected void authorizationHandler(TdApi.UpdateAuthorizationState authorizationState) { protected void authorizationHandler(TdApi.AuthorizationState authorizationState) {
switch (authorizationState.authorizationState.getConstructor()) { switch (authorizationState.getConstructor()) {
case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR : { case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR : {
var parameters = new TdApi.TdlibParameters(); var parameters = new TdApi.TdlibParameters();
parameters.databaseDirectory = "tdlib"; parameters.databaseDirectory = "tdlib";
@ -234,12 +289,12 @@ public class EasyClient {
parameters.systemVersion = "TDBOT"; parameters.systemVersion = "TDBOT";
parameters.applicationVersion = "1.0"; parameters.applicationVersion = "1.0";
parameters.enableStorageOptimizer = true; parameters.enableStorageOptimizer = true;
send(new TdApi.SetTdlibParameters(parameters)); sendRaw(new TdApi.SetTdlibParameters(parameters));
break; break;
} }
case TdApi.AuthorizationStateWaitEncryptionKey.CONSTRUCTOR: { case TdApi.AuthorizationStateWaitEncryptionKey.CONSTRUCTOR: {
send(new TdApi.CheckDatabaseEncryptionKey()); sendRaw(new TdApi.CheckDatabaseEncryptionKey());
break; break;
} }
@ -251,15 +306,17 @@ public class EasyClient {
case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR: { case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR: {
var scanner = new Scanner(System.in); var scanner = new Scanner(System.in);
System.out.print("Insert your code: "); System.out.print("Insert your code: ");
send(new TdApi.CheckAuthenticationCode(scanner.nextLine(), "", "")); sendRaw(new TdApi.CheckAuthenticationCode(scanner.nextLine(), "", ""));
System.out.println(); System.out.println();
break; break;
} }
case TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR: { case TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR: {
var scanner = new Scanner(System.in); var scanner = new Scanner(System.in);
System.out.println("Password authorization");
System.out.println("Password hint: " + ((TdApi.AuthorizationStateWaitPassword) authorizationState).passwordHint);
System.out.print("Insert your password: "); System.out.print("Insert your password: ");
send(new TdApi.CheckAuthenticationPassword(scanner.nextLine())); sendRaw(new TdApi.CheckAuthenticationPassword(scanner.nextLine()));
System.out.println(); System.out.println();
break; break;
} }
@ -268,6 +325,27 @@ public class EasyClient {
this.haveAuthorization = true; this.haveAuthorization = true;
break; break;
} }
case TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR: {
this.haveAuthorization = false;
break;
}
case TdApi.AuthorizationStateClosing.CONSTRUCTOR: {
this.haveAuthorization = false;
break;
}
case TdApi.AuthorizationStateClosed.CONSTRUCTOR: {
if(this.haveClosed) {
this.destroyBotClient();
} else {
this.destroyBotClient();
inizializeClient();
}
break;
}
default: {
throw new IllegalStateException("Unsupported authorization state:\n" + authorizationState);
}
} }
} }
} }

View File

@ -29,6 +29,6 @@ public class UserClient extends EasyClient {
* @param phoneNumber The phone number of user. * @param phoneNumber The phone number of user.
*/ */
public UserClient(long phoneNumber) { public UserClient(long phoneNumber) {
super(easyClient -> easyClient.send(new TdApi.SetAuthenticationPhoneNumber(String.valueOf(phoneNumber), false, false))); super(easyClient -> easyClient.sendRaw(new TdApi.SetAuthenticationPhoneNumber(String.valueOf(phoneNumber), false, false)));
} }
} }

View File

@ -17,9 +17,7 @@
package it.ernytech.tdlib; package it.ernytech.tdlib;
import it.ernytech.tdlib.utils.CantLoadLibrary;
import it.ernytech.tdlib.utils.Init; import it.ernytech.tdlib.utils.Init;
import it.ernytech.tdlib.utils.MissingTdlibLibrary;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -17,9 +17,7 @@
package it.ernytech.tdlib; package it.ernytech.tdlib;
import it.ernytech.tdlib.utils.CantLoadLibrary;
import it.ernytech.tdlib.utils.Init; import it.ernytech.tdlib.utils.Init;
import it.ernytech.tdlib.utils.MissingTdlibLibrary;
import java.util.Objects; import java.util.Objects;