Added ability to change user status

This commit is contained in:
2020-10-07 23:43:30 +02:00
parent f2eb89d469
commit 637ad9f61f
11 changed files with 81 additions and 81 deletions

View File

@ -22,14 +22,14 @@ public final class ConnectionManager implements ISocketIdListener {
*
* @since Envoy Server Standalone v0.1-alpha
*/
private Set<Long> pendingSockets = new HashSet<>();
private final Set<Long> pendingSockets = new HashSet<>();
/**
* Contains all socket IDs that have acquired a user ID as keys to these IDs.
*
* @since Envoy Server Standalone v0.1-alpha
*/
private Map<Long, Long> sockets = new HashMap<>();
private final Map<Long, Long> sockets = new HashMap<>();
private static ConnectionManager connectionManager = new ConnectionManager();
@ -44,11 +44,11 @@ public final class ConnectionManager implements ISocketIdListener {
@Override
public void socketCancelled(long socketID) {
if (!pendingSockets.remove(socketID)) {
// Notify contacts of this users offline-going
envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
user.setStatus(UserStatus.OFFLINE);
final envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
user.setLastSeen(Instant.now());
UserStatusChangeProcessor.updateUserStatus(user);
UserStatusChangeProcessor.updateUserStatus(user, UserStatus.OFFLINE);
// Remove the socket
sockets.entrySet().removeIf(e -> e.getValue() == socketID);

View File

@ -46,42 +46,40 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
// Acquire a user object (or reject the handshake if that's impossible)
User user = null;
if (!credentials.isRegistration()) {
try {
user = persistenceManager.getUserByName(credentials.getIdentifier());
if (!credentials.isRegistration()) try {
user = persistenceManager.getUserByName(credentials.getIdentifier());
// Check if the user is already online
if (connectionManager.isOnline(user.getID())) {
logger.warning(user + " is already online!");
writeProxy.write(socketID, new HandshakeRejection(INTERNAL_ERROR));
return;
}
// Authenticate with password or token
if (credentials.usesToken()) {
// Check the token
if (user.getAuthToken() == null || user.getAuthTokenExpiration().isBefore(Instant.now())
|| !user.getAuthToken().equals(credentials.getPassword())) {
logger.info(user + " tried to use an invalid token.");
writeProxy.write(socketID, new HandshakeRejection(INVALID_TOKEN));
return;
}
} else {
// Check the password hash
if (!PasswordUtil.validate(credentials.getPassword(), user.getPasswordHash())) {
logger.info(user + " has entered the wrong password.");
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
return;
}
}
} catch (NoResultException e) {
logger.info("The requested user does not exist.");
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
// Check if the user is already online
if (connectionManager.isOnline(user.getID())) {
logger.warning(user + " is already online!");
writeProxy.write(socketID, new HandshakeRejection(INTERNAL_ERROR));
return;
}
} else {
// Authenticate with password or token
if (credentials.usesToken()) {
// Check the token
if (user.getAuthToken() == null || user.getAuthTokenExpiration().isBefore(Instant.now())
|| !user.getAuthToken().equals(credentials.getPassword())) {
logger.info(user + " tried to use an invalid token.");
writeProxy.write(socketID, new HandshakeRejection(INVALID_TOKEN));
return;
}
} else
// Check the password hash
if (!PasswordUtil.validate(credentials.getPassword(), user.getPasswordHash())) {
logger.info(user + " has entered the wrong password.");
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
return;
}
} catch (final NoResultException e) {
logger.info("The requested user does not exist.");
writeProxy.write(socketID, new HandshakeRejection(WRONG_PASSWORD_OR_USER));
return;
}
else {
// Validate user name
if (!Bounds.isValidContactName(credentials.getIdentifier())) {
@ -98,7 +96,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
logger.info("The requested user already exists.");
writeProxy.write(socketID, new HandshakeRejection(USERNAME_TAKEN));
return;
} catch (NoResultException e) {
} catch (final NoResultException e) {
// Creation of a new user
user = new User();
user.setName(credentials.getIdentifier());
@ -115,18 +113,17 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
connectionManager.registerUser(user.getID(), socketID);
// Change status and notify contacts about it
user.setStatus(ONLINE);
UserStatusChangeProcessor.updateUserStatus(user);
UserStatusChangeProcessor.updateUserStatus(user, ONLINE);
// Process token request
if (credentials.requestToken()) {
String token;
if (user.getAuthToken() != null && user.getAuthTokenExpiration().isAfter(Instant.now())) {
if (user.getAuthToken() != null && user.getAuthTokenExpiration().isAfter(Instant.now()))
// Reuse existing token and delay expiration date
token = user.getAuthToken();
} else {
else {
// Generate new token
token = AuthTokenGenerator.nextToken();
@ -141,13 +138,13 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
pendingMessages.removeIf(GroupMessage.class::isInstance);
logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "...");
for (var msg : pendingMessages) {
for (final var msg : pendingMessages) {
final var msgCommon = msg.toCommon();
if (msg.getCreationDate().isAfter(credentials.getLastSync())) {
if (msg.getCreationDate().isAfter(credentials.getLastSync()))
// Sync without side effects
writeProxy.write(socketID, msgCommon);
} else if (msg.getStatus() == SENT) {
else if (msg.getStatus() == SENT) {
// Send the message
writeProxy.write(socketID, msgCommon);
@ -162,10 +159,10 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
} else writeProxy.write(socketID, new MessageStatusChange(msgCommon));
}
List<GroupMessage> pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync());
final List<GroupMessage> pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync());
logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "...");
for (var gmsg : pendingGroupMessages) {
for (final var gmsg : pendingGroupMessages) {
final var gmsgCommon = gmsg.toCommon();
// Deliver the message to the user if he hasn't received it yet
@ -189,20 +186,18 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
}
PersistenceManager.getInstance().updateMessage(gmsg);
} else {
} else
// Just send the message without updating if it was received in the past
writeProxy.write(socketID, gmsgCommon);
}
} else {
// Sending group message status changes
if (gmsg.getStatus() == SENT && gmsg.getLastStatusChangeDate().isAfter(gmsg.getCreationDate())
|| gmsg.getStatus() == RECEIVED && gmsg.getLastStatusChangeDate().isAfter(gmsg.getReceivedDate())) {
|| gmsg.getStatus() == RECEIVED && gmsg.getLastStatusChangeDate().isAfter(gmsg.getReceivedDate()))
gmsg.getMemberMessageStatus()
.forEach((memberID, memberStatus) -> writeProxy.write(socketID,
new GroupMessageStatusChange(gmsg.getID(), memberStatus, gmsg.getLastStatusChangeDate(), memberID)));
}
// Deliver just a status change instead of the whole message
if (gmsg.getStatus() == RECEIVED && user.getLastSeen().isBefore(gmsg.getReceivedDate())

View File

@ -28,18 +28,20 @@ public final class UserStatusChangeProcessor implements ObjectProcessor<UserStat
logger.warning("Received an unnecessary UserStatusChange");
return;
}
updateUserStatus(input);
updateUserStatus(persistenceManager.getUserByID(input.getID()), input.get());
}
/**
* Sets the {@link UserStatus} for a given user. Both offline contacts and
* currently online contacts are notified.
*
* @param user the {@link UserStatusChange} that signals the change
* @param user the user whose status has changed
* @param newStatus the new status of that user
* @since Envoy Server Standalone v0.1-alpha
*/
public static void updateUserStatus(User user) {
public static void updateUserStatus(User user, UserStatus newStatus) {
user.setStatus(newStatus);
// Handling for newly logged in clients
persistenceManager.updateContact(user);
@ -48,12 +50,6 @@ public final class UserStatusChangeProcessor implements ObjectProcessor<UserStat
writeProxy.writeToOnlineContacts(user.getContacts(), new UserStatusChange(user.getID(), user.getStatus()));
}
/**
* @param evt the {@link UserStatusChange}
* @since Envoy Server Standalone v0.1-alpha
*/
public static void updateUserStatus(UserStatusChange evt) { updateUserStatus(persistenceManager.getUserByID(evt.getID())); }
/**
* This method is only called by the LoginCredentialProcessor because every
* user needs to login (open a socket) before changing his status.