diff --git a/client/src/main/java/envoy/client/ui/controller/LoginScene.java b/client/src/main/java/envoy/client/ui/controller/LoginScene.java index 506170e..71e3988 100644 --- a/client/src/main/java/envoy/client/ui/controller/LoginScene.java +++ b/client/src/main/java/envoy/client/ui/controller/LoginScene.java @@ -1,5 +1,6 @@ package envoy.client.ui.controller; +import java.time.Instant; import java.util.logging.*; import javafx.fxml.FXML; @@ -56,8 +57,8 @@ public final class LoginScene implements EventListener { private boolean registration = false; - private static final Logger logger = EnvoyLog.getLogger(LoginScene.class); - private static final ClientConfig config = ClientConfig.getInstance(); + private static final Logger logger = EnvoyLog.getLogger(LoginScene.class); + private static final ClientConfig config = ClientConfig.getInstance(); @FXML private void initialize() { @@ -74,16 +75,20 @@ public final class LoginScene implements EventListener { @FXML private void loginButtonPressed() { + final String user = userTextField.getText(), pass = passwordField.getText(), repeatPass = repeatPasswordField.getText(); // Prevent registration with unequal passwords - if (registration && !passwordField.getText().equals(repeatPasswordField.getText())) { + if (registration && !pass.equals(repeatPass)) { new Alert(AlertType.ERROR, "The entered password is unequal to the repeated one").showAndWait(); repeatPasswordField.clear(); - } else if (!Bounds.isValidContactName(userTextField.getText())) { + } else if (!Bounds.isValidContactName(user)) { new Alert(AlertType.ERROR, "The entered user name is not valid (" + Bounds.CONTACT_NAME_PATTERN + ")").showAndWait(); userTextField.clear(); - } else Startup.performHandshake(new LoginCredentials(userTextField.getText(), passwordField.getText(), registration, Startup.VERSION, - Startup.loadLastSync(userTextField.getText()))); + } else { + Instant lastSync = Startup.loadLastSync(userTextField.getText()); + Startup.performHandshake(registration ? LoginCredentials.registration(user, pass, Startup.VERSION, lastSync) + : LoginCredentials.login(user, pass, Startup.VERSION, lastSync)); + } } @FXML diff --git a/common/src/main/java/envoy/data/LoginCredentials.java b/common/src/main/java/envoy/data/LoginCredentials.java index 0bef595..40866ad 100644 --- a/common/src/main/java/envoy/data/LoginCredentials.java +++ b/common/src/main/java/envoy/data/LoginCredentials.java @@ -7,6 +7,9 @@ import java.time.Instant; * Contains a {@link User}'s login / registration information as well as the * client version. *

+ * If the authentication is performed with a token, the token is stored instead + * of the password. + *

* Project: envoy-common
* File: LoginCredentials.java
* Created: 29.12.2019
@@ -17,35 +20,68 @@ import java.time.Instant; public final class LoginCredentials implements Serializable { private final String identifier, password, clientVersion; - private final boolean registration; + private final boolean registration, token; private final Instant lastSync; private static final long serialVersionUID = 3; - /** - * Initializes login credentials for a handshake. - * - * @param identifier the identifier of the user - * @param password the password of the user - * @param registration signifies that these credentials are used for user - * registration instead of user login - * @param clientVersion the version of the client sending these credentials - * @param lastSync the time stamp of the last synchronization - * @since Envoy Common v0.2-beta - */ - public LoginCredentials(String identifier, String password, boolean registration, String clientVersion, Instant lastSync) { + private LoginCredentials(String identifier, String password, boolean registration, boolean token, String clientVersion, Instant lastSync) { this.identifier = identifier; this.password = password; this.registration = registration; + this.token = token; this.clientVersion = clientVersion; this.lastSync = lastSync; } + /** + * Creates login credentials for a regular login. + * + * @param identifier the identifier of the user + * @param password the password of the user + * @param clientVersion the version of the client sending these credentials + * @param lastSync the timestamp of the last synchronization + * @return the created login credentials + * @since Envoy Common v0.2-beta + */ + public static LoginCredentials login(String identifier, String password, String clientVersion, Instant lastSync) { + return new LoginCredentials(identifier, password, false, false, clientVersion, lastSync); + } + + /** + * Creates login credentials for a login with an authentication token. + * + * @param identifier the identifier of the user + * @param token the authentication token of the user + * @param clientVersion the version of the client sending these credentials + * @param lastSync the timestamp of the last synchronization + * @return the created login credentials + * @since Envoy Common v0.2-beta + */ + public static LoginCredentials loginWithToken(String identifier, String token, String clientVersion, Instant lastSync) { + return new LoginCredentials(identifier, token, false, true, clientVersion, lastSync); + } + + /** + * Creates login credentials for a registration. + * + * @param identifier the identifier of the user + * @param password the password of the user + * @param clientVersion the version of the client sending these credentials + * @param lastSync the timestamp of the last synchronization + * @return the created login credentials + * @since Envoy Common v0.2-beta + */ + public static LoginCredentials registration(String identifier, String password, String clientVersion, Instant lastSync) { + return new LoginCredentials(identifier, password, true, false, clientVersion, lastSync); + } + @Override public String toString() { - return String.format("LoginCredentials[identifier=%s,registration=%b,clientVersion=%s,lastSync=%s]", + return String.format("LoginCredentials[identifier=%s,registration=%b,token=%b,clientVersion=%s,lastSync=%s]", identifier, registration, + token, clientVersion, lastSync); } @@ -69,6 +105,13 @@ public final class LoginCredentials implements Serializable { */ public boolean isRegistration() { return registration; } + /** + * @return {@code true} if these credentials use an authentication token instead + * of a password + * @since Envoy Common v0.2-beta + */ + public boolean usesToken() { return token; } + /** * @return the version of the client sending these credentials * @since Envoy Common v0.1-beta diff --git a/server/src/main/java/envoy/server/data/User.java b/server/src/main/java/envoy/server/data/User.java index 7ff3548..341ebd4 100755 --- a/server/src/main/java/envoy/server/data/User.java +++ b/server/src/main/java/envoy/server/data/User.java @@ -40,7 +40,7 @@ public final class User extends Contact { /** * Named query retrieving a user by name (parameter {@code :name}). - * + * * @since Envoy Server Standalone v0.1-beta */ public static final String findByName = "User.findByName"; @@ -48,7 +48,7 @@ public final class User extends Contact { /** * Named query retrieving the contacts of a given user (parameter * {@code :user}). - * + * * @since Envoy Server Standalone v0.1-beta */ public static final String findContacts = "User.findContacts"; @@ -57,7 +57,7 @@ public final class User extends Contact { * Named query searching for users with a name like a search phrase (parameter * {@code :searchPhrase}) that are not in the contact list of a given user * (parameter {@code :context}). - * + * * @since Envoy Server Standalone v0.1-beta */ public static final String searchByName = "User.searchByName"; @@ -65,6 +65,12 @@ public final class User extends Contact { @Column(name = "password_hash") private String passwordHash; + @Column(name = "auth_token") + private String authToken; + + @Column(name = "auth_token_expiration") + private Instant authTokenExpiration; + @Column(name = "last_seen") private Instant lastSeen; @@ -90,6 +96,31 @@ public final class User extends Contact { */ public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; } + /** + * @return the authentication token + * @since Envoy Server v0.2-beta + */ + public String getAuthToken() { return authToken; } + + /** + * @param authToken the authentication token to set + * @since Envoy Server v0.2-beta + */ + public void setAuthToken(String authToken) { this.authToken = authToken; } + + /** + * @return the time at which the authentication token expires + * @since Envoy Server v0.2-beta + */ + public Instant getAuthTokenExpiration() { return authTokenExpiration; } + + /** + * @param authTokenExpiration the authentication token expiration timestamp to + * set + * @since Envoy Server v0.2-beta + */ + public void setAuthTokenExpiration(Instant authTokenExpiration) { this.authTokenExpiration = authTokenExpiration; } + /** * @return the last date the user has been online * @since Envoy Server Standalone v0.2-beta