Added logging and fixed some security concerns

This commit is contained in:
delvh 2020-08-01 14:57:08 +02:00
parent 0d77fbf831
commit 56bb00cd32
5 changed files with 41 additions and 12 deletions

View File

@ -4,6 +4,8 @@ import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Arrays;
import java.util.logging.Level;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -22,6 +24,7 @@ import envoy.client.ui.SceneContext;
import envoy.data.User; import envoy.data.User;
import envoy.event.*; import envoy.event.*;
import envoy.util.Bounds; import envoy.util.Bounds;
import envoy.util.EnvoyLog;
/** /**
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
@ -33,8 +36,8 @@ import envoy.util.Bounds;
*/ */
public class UserSettingsPane extends SettingsPane { public class UserSettingsPane extends SettingsPane {
private boolean profilePicChanged, usernameChanged, passwordChanged, validPassword; private boolean profilePicChanged, usernameChanged, validPassword;
private byte[] currentImageBytes; private byte[] currentImageBytes, originalImageBytes;
private String newUsername, newPassword = ""; private String newUsername, newPassword = "";
/** /**
@ -52,12 +55,14 @@ public class UserSettingsPane extends SettingsPane {
// TODO: display current profile pic // TODO: display current profile pic
final var profilePic = new ImageView(IconUtil.loadIcon("envoy_logo", 50)); final var profilePic = new ImageView(IconUtil.loadIcon("envoy_logo", 50));
profilePic.setCursor(Cursor.HAND); profilePic.setCursor(Cursor.HAND);
profilePic.setFitWidth(50);
profilePic.setFitHeight(50);
profilePic.setOnMouseClicked(e -> { profilePic.setOnMouseClicked(e -> {
final var pictureChooser = new FileChooser(); final var pictureChooser = new FileChooser();
pictureChooser.setTitle("Select a new picture"); pictureChooser.setTitle("Select a new picture");
pictureChooser.setInitialDirectory(new File(System.getProperty("user.home"))); pictureChooser.setInitialDirectory(new File(System.getProperty("user.home")));
pictureChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("Pictures", "*.png", "*.jpg", "*.bmp", "*.gif")); pictureChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Pictures", "*.png", "*.jpg", "*.bmp", "*.gif"));
final var file = pictureChooser.showOpenDialog(sceneContext.getStage()); final var file = pictureChooser.showOpenDialog(sceneContext.getStage());
@ -134,25 +139,38 @@ public class UserSettingsPane extends SettingsPane {
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
private void save(long userID, String oldPassword) { private void save(long userID, String oldPassword) {
final var eventbus = EventBus.getInstance(); final var eventBus = EventBus.getInstance();
final var logger = EnvoyLog.getLogger(UserSettingsPane.class);
// The profile pic was changed // The profile pic was changed
if (profilePicChanged) eventbus.dispatch(new SendEvent(new ProfilePicChange(currentImageBytes, userID))); if (profilePicChanged && !Arrays.equals(currentImageBytes, originalImageBytes)) {
final var profilePicChangeEvent = new ProfilePicChange(currentImageBytes, userID);
eventBus.dispatch(profilePicChangeEvent);
eventBus.dispatch(new SendEvent(profilePicChangeEvent));
logger.log(Level.INFO, "The user just changed his profile pic.");
}
// The username was changed // The username was changed
final var validContactName = Bounds.isValidContactName(newUsername); final var validContactName = Bounds.isValidContactName(newUsername);
if (usernameChanged && validContactName) eventbus.dispatch(new SendEvent(new NameChange(userID, newUsername))); if (usernameChanged && validContactName) {
else if (!validContactName) { final var nameChangeEvent = new NameChange(userID, newUsername);
eventBus.dispatch(new SendEvent(nameChangeEvent));
eventBus.dispatch(nameChangeEvent);
logger.log(Level.INFO, "The user just changed his name to " + newUsername + ".");
} else if (!validContactName) {
final var alert = new Alert(AlertType.ERROR); final var alert = new Alert(AlertType.ERROR);
alert.setTitle("Invalid username"); alert.setTitle("Invalid username");
alert.setContentText("The entered username does not conform with the naming limitations: " + Bounds.CONTACT_NAME_PATTERN); alert.setContentText("The entered username does not conform with the naming limitations: " + Bounds.CONTACT_NAME_PATTERN);
alert.showAndWait(); alert.showAndWait();
logger.log(Level.INFO, "An invalid username was requested.");
return; return;
} }
// The password was changed // The password was changed
if (passwordChanged && validPassword) eventbus.dispatch(new SendEvent(new PasswordChangeRequest(newPassword, oldPassword, userID))); if (validPassword) {
else if (!(validPassword || newPassword.isBlank())) { eventBus.dispatch(new SendEvent(new PasswordChangeRequest(newPassword, oldPassword, userID)));
logger.log(Level.INFO, "The user just tried to change his password!");
} else if (!(validPassword || newPassword.isBlank())) {
final var alert = new Alert(AlertType.ERROR); final var alert = new Alert(AlertType.ERROR);
alert.setTitle("Unequal Password"); alert.setTitle("Unequal Password");
alert.setContentText("Repeated password is unequal to the chosen new password"); alert.setContentText("Repeated password is unequal to the chosen new password");

View File

@ -41,4 +41,7 @@ public class PasswordChangeRequest extends Event<String> {
* @since Envoy Common v0.2-beta * @since Envoy Common v0.2-beta
*/ */
public String getOldPassword() { return oldPassword; } public String getOldPassword() { return oldPassword; }
@Override
public String toString() { return "PasswordChangeRequest[id=" + id + "]"; }
} }

View File

@ -71,7 +71,9 @@ public class Startup {
new UserSearchProcessor(), new UserSearchProcessor(),
new ContactOperationProcessor(), new ContactOperationProcessor(),
new IsTypingProcessor(), new IsTypingProcessor(),
new NameChangeProcessor()))); new NameChangeProcessor(),
new ProfilePicChangeProcessor(),
new PasswordChangeRequestProcessor())));
// Initialize the current message ID // Initialize the current message ID
final PersistenceManager persistenceManager = PersistenceManager.getInstance(); final PersistenceManager persistenceManager = PersistenceManager.getInstance();

View File

@ -18,7 +18,7 @@ import javax.persistence.*;
*/ */
@Entity @Entity
@Table(name = "contacts") @Table(name = "contacts", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }) })
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Contact { public abstract class Contact {

View File

@ -1,12 +1,14 @@
package envoy.server.processors; package envoy.server.processors;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Level;
import envoy.event.PasswordChangeRequest; import envoy.event.PasswordChangeRequest;
import envoy.event.PasswordChangeResult; import envoy.event.PasswordChangeResult;
import envoy.server.data.PersistenceManager; import envoy.server.data.PersistenceManager;
import envoy.server.net.ObjectWriteProxy; import envoy.server.net.ObjectWriteProxy;
import envoy.server.util.PasswordUtil; import envoy.server.util.PasswordUtil;
import envoy.util.EnvoyLog;
/** /**
* Project: <strong>envoy-server-standalone</strong><br> * Project: <strong>envoy-server-standalone</strong><br>
@ -22,8 +24,12 @@ public class PasswordChangeRequestProcessor implements ObjectProcessor<PasswordC
public void process(PasswordChangeRequest event, long socketID, ObjectWriteProxy writeProxy) throws IOException { public void process(PasswordChangeRequest event, long socketID, ObjectWriteProxy writeProxy) throws IOException {
final var persistenceManager = PersistenceManager.getInstance(); final var persistenceManager = PersistenceManager.getInstance();
final var user = persistenceManager.getUserByID(event.getID()); final var user = persistenceManager.getUserByID(event.getID());
final var logger = EnvoyLog.getLogger(PasswordChangeRequestProcessor.class);
final var correctAuthentication = PasswordUtil.validate(event.getOldPassword(), user.getPasswordHash()); final var correctAuthentication = PasswordUtil.validate(event.getOldPassword(), user.getPasswordHash());
if (correctAuthentication) user.setPasswordHash(PasswordUtil.hash(event.get())); if (correctAuthentication) {
user.setPasswordHash(PasswordUtil.hash(event.get()));
logger.log(Level.INFO, user + " changed his password");
} else logger.log(Level.INFO, user + " tried changing his password but provided insufficient authentication");
writeProxy.write(socketID, new PasswordChangeResult(correctAuthentication)); writeProxy.write(socketID, new PasswordChangeResult(correctAuthentication));
} }
} }