Handle handshake rejections on invalid token, reuse not expired tokens

This commit is contained in:
Kai S. K. Engelbart 2020-09-19 13:33:18 +02:00
parent f21d077522
commit 3e594c1fbd
Signed by: kske
GPG Key ID: 8BEB13EC5DF7EF13
2 changed files with 26 additions and 8 deletions

View File

@ -93,8 +93,9 @@ public final class Startup extends Application {
logger.info("Attempting authentication with token..."); logger.info("Attempting authentication with token...");
localDB.initializeUserStorage(); localDB.initializeUserStorage();
localDB.loadUserData(); localDB.loadUserData();
performHandshake(LoginCredentials.loginWithToken(localDB.getUser().getName(), localDB.getAuthToken(), VERSION, localDB.getLastSync())); if (!performHandshake(
// TODO: handle unsuccessful handshake LoginCredentials.loginWithToken(localDB.getUser().getName(), localDB.getAuthToken(), VERSION, localDB.getLastSync())))
sceneContext.load(SceneInfo.LOGIN_SCENE);
} else { } else {
// Load login scene // Load login scene
@ -106,9 +107,10 @@ public final class Startup extends Application {
* Tries to perform a Handshake with the server. * Tries to perform a Handshake with the server.
* *
* @param credentials the credentials to use for the handshake * @param credentials the credentials to use for the handshake
* @return whether the handshake was successful or offline mode could be entered
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
public static void performHandshake(LoginCredentials credentials) { public static boolean performHandshake(LoginCredentials credentials) {
final var cacheMap = new CacheMap(); final var cacheMap = new CacheMap();
cacheMap.put(Message.class, new Cache<Message>()); cacheMap.put(Message.class, new Cache<Message>());
cacheMap.put(GroupMessage.class, new Cache<GroupMessage>()); cacheMap.put(GroupMessage.class, new Cache<GroupMessage>());
@ -120,10 +122,13 @@ public final class Startup extends Application {
if (client.isOnline()) { if (client.isOnline()) {
loadChatScene(); loadChatScene();
client.initReceiver(localDB, cacheMap); client.initReceiver(localDB, cacheMap);
return true;
} else {
return false;
} }
} catch (IOException | InterruptedException | TimeoutException e) { } catch (IOException | InterruptedException | TimeoutException e) {
logger.log(Level.INFO, "Could not connect to server. Entering offline mode..."); logger.log(Level.INFO, "Could not connect to server. Entering offline mode...");
attemptOfflineMode(credentials.getIdentifier()); return attemptOfflineMode(credentials.getIdentifier());
} }
} }
@ -132,9 +137,10 @@ public final class Startup extends Application {
* for a given user. * for a given user.
* *
* @param identifier the identifier of the user - currently his username * @param identifier the identifier of the user - currently his username
* @return whether the offline mode could be entered
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
public static void attemptOfflineMode(String identifier) { public static boolean attemptOfflineMode(String identifier) {
try { try {
// Try entering offline mode // Try entering offline mode
localDB.loadUsers(); localDB.loadUsers();
@ -142,10 +148,12 @@ public final class Startup extends Application {
if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown"); if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown");
client.setSender(clientUser); client.setSender(clientUser);
loadChatScene(); loadChatScene();
return true;
} catch (final Exception e) { } catch (final Exception e) {
new Alert(AlertType.ERROR, "Client error: " + e).showAndWait(); new Alert(AlertType.ERROR, "Client error: " + e).showAndWait();
logger.log(Level.SEVERE, "Offline mode could not be loaded: ", e); logger.log(Level.SEVERE, "Offline mode could not be loaded: ", e);
System.exit(1); System.exit(1);
return false;
} }
} }

View File

@ -122,10 +122,20 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
user.setStatus(ONLINE); user.setStatus(ONLINE);
UserStatusChangeProcessor.updateUserStatus(user); UserStatusChangeProcessor.updateUserStatus(user);
// Generate a new token if requested // Process token request
if (credentials.requestToken()) { if (credentials.requestToken()) {
String token = AuthTokenGenerator.nextToken(); String token;
user.setAuthToken(token);
if (user.getAuthToken() != null && user.getAuthTokenExpiration().isAfter(Instant.now())) {
// Reuse existing token and delay expiration date
token = user.getAuthToken();
} else {
// Generate new token
token = AuthTokenGenerator.nextToken();
user.setAuthToken(token);
}
user.setAuthTokenExpiration(Instant.now().plus(ServerConfig.getInstance().getAuthTokenExpiration().longValue(), ChronoUnit.DAYS)); user.setAuthTokenExpiration(Instant.now().plus(ServerConfig.getInstance().getAuthTokenExpiration().longValue(), ChronoUnit.DAYS));
persistenceManager.updateContact(user); persistenceManager.updateContact(user);
writeProxy.write(socketID, new NewAuthToken(token)); writeProxy.write(socketID, new NewAuthToken(token));