mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-1176: Validate new password set due to expiration. Allow errors dialogs during login process.
This commit is contained in:
@@ -26,6 +26,7 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||||
import org.glyptodon.guacamole.GuacamoleException;
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
import org.glyptodon.guacamole.form.Field;
|
import org.glyptodon.guacamole.form.Field;
|
||||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||||
@@ -121,6 +122,14 @@ public class UserContextService {
|
|||||||
throw new GuacamoleInsufficientCredentialsException("Password expired", EXPIRED_PASSWORD);
|
throw new GuacamoleInsufficientCredentialsException("Password expired", EXPIRED_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New password must be different from old password
|
||||||
|
if (newPassword.equals(credentials.getPassword()))
|
||||||
|
throw new GuacamoleClientException("The new password must be different from the expired password.");
|
||||||
|
|
||||||
|
// New password must not be blank
|
||||||
|
if (newPassword.isEmpty())
|
||||||
|
throw new GuacamoleClientException("The new password may not be blank.");
|
||||||
|
|
||||||
// STUB: Change password if new password given
|
// STUB: Change password if new password given
|
||||||
logger.info("Resetting expired password of user \"{}\".", user.getIdentifier());
|
logger.info("Resetting expired password of user \"{}\".", user.getIdentifier());
|
||||||
|
|
||||||
|
@@ -64,6 +64,26 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
|
|||||||
var $route = $injector.get('$route');
|
var $route = $injector.get('$route');
|
||||||
var authenticationService = $injector.get('authenticationService');
|
var authenticationService = $injector.get('authenticationService');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An action to be provided along with the object assigned to
|
||||||
|
* $scope.loginStatus which closes the currently-shown status dialog.
|
||||||
|
*/
|
||||||
|
var ACKNOWLEDGE_ACTION = {
|
||||||
|
name : "LOGIN.ACTION_ACKNOWLEDGE",
|
||||||
|
// Handle action
|
||||||
|
callback : function acknowledgeCallback() {
|
||||||
|
$scope.loginStatus = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently-visible notification describing login status, or false
|
||||||
|
* if no notification should be shown.
|
||||||
|
*
|
||||||
|
* @type Notification|Boolean|Object
|
||||||
|
*/
|
||||||
|
$scope.loginStatus = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether an error occurred during login.
|
* Whether an error occurred during login.
|
||||||
*
|
*
|
||||||
@@ -110,12 +130,15 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
|
|||||||
*/
|
*/
|
||||||
$scope.login = function login() {
|
$scope.login = function login() {
|
||||||
|
|
||||||
|
// Start with cleared status
|
||||||
|
$scope.loginError = false;
|
||||||
|
$scope.loginStatus = false;
|
||||||
|
|
||||||
// Attempt login once existing session is destroyed
|
// Attempt login once existing session is destroyed
|
||||||
authenticationService.authenticate($scope.enteredValues)
|
authenticationService.authenticate($scope.enteredValues)
|
||||||
|
|
||||||
// Clear and reload upon success
|
// Clear and reload upon success
|
||||||
.then(function loginSuccessful() {
|
.then(function loginSuccessful() {
|
||||||
$scope.loginError = false;
|
|
||||||
$scope.enteredValues = {};
|
$scope.enteredValues = {};
|
||||||
$route.reload();
|
$route.reload();
|
||||||
})
|
})
|
||||||
@@ -123,13 +146,24 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
|
|||||||
// Reset upon failure
|
// Reset upon failure
|
||||||
['catch'](function loginFailed(error) {
|
['catch'](function loginFailed(error) {
|
||||||
|
|
||||||
// Flag generic error for invalid login
|
|
||||||
if (error.type === Error.Type.INVALID_CREDENTIALS)
|
|
||||||
$scope.loginError = true;
|
|
||||||
|
|
||||||
// Clear out passwords if the credentials were rejected for any reason
|
// Clear out passwords if the credentials were rejected for any reason
|
||||||
if (error.type !== Error.Type.INSUFFICIENT_CREDENTIALS) {
|
if (error.type !== Error.Type.INSUFFICIENT_CREDENTIALS) {
|
||||||
angular.forEach($scope.form, function clearEnteredValueIfPassword(field) {
|
|
||||||
|
// Flag generic error for invalid login
|
||||||
|
if (error.type === Error.Type.INVALID_CREDENTIALS)
|
||||||
|
$scope.loginError = true;
|
||||||
|
|
||||||
|
// Display error if anything else goes wrong
|
||||||
|
else
|
||||||
|
$scope.loginStatus = {
|
||||||
|
'className' : 'error',
|
||||||
|
'title' : 'LOGIN.DIALOG_HEADER_ERROR',
|
||||||
|
'text' : error.message,
|
||||||
|
'actions' : [ ACKNOWLEDGE_ACTION ]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clear all visible password fields
|
||||||
|
angular.forEach($scope.remainingFields, function clearEnteredValueIfPassword(field) {
|
||||||
|
|
||||||
// Remove entered value only if field is a password field
|
// Remove entered value only if field is a password field
|
||||||
if (field.type === Field.Type.PASSWORD)
|
if (field.type === Field.Type.PASSWORD)
|
||||||
|
@@ -49,4 +49,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Login-specific status/error dialog -->
|
||||||
|
<div ng-class="{shown: loginStatus}" class="status-outer">
|
||||||
|
<div class="status-middle">
|
||||||
|
<guac-notification notification="loginStatus"></guac-notification>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -143,7 +143,10 @@
|
|||||||
|
|
||||||
"LOGIN": {
|
"LOGIN": {
|
||||||
|
|
||||||
"ACTION_LOGIN" : "@:APP.ACTION_LOGIN",
|
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
||||||
|
"ACTION_LOGIN" : "@:APP.ACTION_LOGIN",
|
||||||
|
|
||||||
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"ERROR_INVALID_LOGIN" : "Invalid Login",
|
"ERROR_INVALID_LOGIN" : "Invalid Login",
|
||||||
|
|
||||||
@@ -161,7 +164,7 @@
|
|||||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection",
|
||||||
"DIALOG_HEADER_ERROR" : "Error",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"FIELD_HEADER_LOCATION" : "Location:",
|
"FIELD_HEADER_LOCATION" : "Location:",
|
||||||
"FIELD_HEADER_NAME" : "Name:",
|
"FIELD_HEADER_NAME" : "Name:",
|
||||||
@@ -194,7 +197,7 @@
|
|||||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection Group",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete Connection Group",
|
||||||
"DIALOG_HEADER_ERROR" : "Error",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"FIELD_HEADER_LOCATION" : "Location:",
|
"FIELD_HEADER_LOCATION" : "Location:",
|
||||||
"FIELD_HEADER_NAME" : "Name:",
|
"FIELD_HEADER_NAME" : "Name:",
|
||||||
@@ -216,8 +219,8 @@
|
|||||||
"ACTION_DELETE" : "@:APP.ACTION_DELETE",
|
"ACTION_DELETE" : "@:APP.ACTION_DELETE",
|
||||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete User",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete User",
|
||||||
"DIALOG_HEADER_ERROR" : "Error",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
||||||
|
|
||||||
@@ -414,7 +417,7 @@
|
|||||||
"ACTION_NEW_CONNECTION" : "New Connection",
|
"ACTION_NEW_CONNECTION" : "New Connection",
|
||||||
"ACTION_NEW_CONNECTION_GROUP" : "New Group",
|
"ACTION_NEW_CONNECTION_GROUP" : "New Group",
|
||||||
|
|
||||||
"DIALOG_HEADER_ERROR" : "Error",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"HELP_CONNECTIONS" : "Click or tap on a connection below to manage that connection. Depending on your access level, connections can be added and deleted, and their properties (protocol, hostname, port, etc.) can be changed.",
|
"HELP_CONNECTIONS" : "Click or tap on a connection below to manage that connection. Depending on your access level, connections can be added and deleted, and their properties (protocol, hostname, port, etc.) can be changed.",
|
||||||
|
|
||||||
@@ -469,7 +472,7 @@
|
|||||||
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
||||||
"ACTION_NEW_USER" : "New User",
|
"ACTION_NEW_USER" : "New User",
|
||||||
|
|
||||||
"DIALOG_HEADER_ERROR" : "Error",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"HELP_USERS" : "Click or tap on a user below to manage that user. Depending on your access level, users can be added and deleted, and their passwords can be changed.",
|
"HELP_USERS" : "Click or tap on a user below to manage that user. Depending on your access level, users can be added and deleted, and their passwords can be changed.",
|
||||||
|
|
||||||
@@ -484,7 +487,7 @@
|
|||||||
"ACTION_DELETE" : "Kill Sessions",
|
"ACTION_DELETE" : "Kill Sessions",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Kill Sessions",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Kill Sessions",
|
||||||
"DIALOG_HEADER_ERROR" : "Error",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"FIELD_PLACEHOLDER_FILTER" : "Filter",
|
"FIELD_PLACEHOLDER_FILTER" : "Filter",
|
||||||
|
|
||||||
|
@@ -143,7 +143,10 @@
|
|||||||
|
|
||||||
"LOGIN": {
|
"LOGIN": {
|
||||||
|
|
||||||
"ACTION_LOGIN" : "@:APP.ACTION_LOGIN",
|
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
||||||
|
"ACTION_LOGIN" : "@:APP.ACTION_LOGIN",
|
||||||
|
|
||||||
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"ERROR_INVALID_LOGIN" : "Неверные данные для входа",
|
"ERROR_INVALID_LOGIN" : "Неверные данные для входа",
|
||||||
|
|
||||||
@@ -161,7 +164,7 @@
|
|||||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Удалить подключение",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Удалить подключение",
|
||||||
"DIALOG_HEADER_ERROR" : "Ошибка",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"FIELD_HEADER_LOCATION" : "Размещение:",
|
"FIELD_HEADER_LOCATION" : "Размещение:",
|
||||||
"FIELD_HEADER_NAME" : "Название:",
|
"FIELD_HEADER_NAME" : "Название:",
|
||||||
@@ -194,7 +197,7 @@
|
|||||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Удалить группу подключений",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Удалить группу подключений",
|
||||||
"DIALOG_HEADER_ERROR" : "Ошибка",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"FIELD_HEADER_LOCATION" : "Размещение:",
|
"FIELD_HEADER_LOCATION" : "Размещение:",
|
||||||
"FIELD_HEADER_NAME" : "Название:",
|
"FIELD_HEADER_NAME" : "Название:",
|
||||||
@@ -216,8 +219,8 @@
|
|||||||
"ACTION_DELETE" : "@:APP.ACTION_DELETE",
|
"ACTION_DELETE" : "@:APP.ACTION_DELETE",
|
||||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Удалить пользователя",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Удалить пользователя",
|
||||||
"DIALOG_HEADER_ERROR" : "Ошибка",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
||||||
|
|
||||||
@@ -393,7 +396,7 @@
|
|||||||
"ACTION_NEW_CONNECTION" : "Новое подключение",
|
"ACTION_NEW_CONNECTION" : "Новое подключение",
|
||||||
"ACTION_NEW_CONNECTION_GROUP" : "Новая группа",
|
"ACTION_NEW_CONNECTION_GROUP" : "Новая группа",
|
||||||
|
|
||||||
"DIALOG_HEADER_ERROR" : "Ошибка",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"HELP_CONNECTIONS" : "Нажмите на подключение, чтобы управлять им. В зависимости от прав доступа возможно добавление и удаление подключений, а также изменение их свойств (протокол, название сервера, порт и пр.).",
|
"HELP_CONNECTIONS" : "Нажмите на подключение, чтобы управлять им. В зависимости от прав доступа возможно добавление и удаление подключений, а также изменение их свойств (протокол, название сервера, порт и пр.).",
|
||||||
|
|
||||||
@@ -409,7 +412,7 @@
|
|||||||
"ACTION_CANCEL" : "@:APP.ACTION_CANCEL",
|
"ACTION_CANCEL" : "@:APP.ACTION_CANCEL",
|
||||||
"ACTION_UPDATE_PASSWORD" : "@:APP.ACTION_UPDATE_PASSWORD",
|
"ACTION_UPDATE_PASSWORD" : "@:APP.ACTION_UPDATE_PASSWORD",
|
||||||
|
|
||||||
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"ERROR_PASSWORD_BLANK" : "Пароль не может быть пустым.",
|
"ERROR_PASSWORD_BLANK" : "Пароль не может быть пустым.",
|
||||||
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
||||||
@@ -448,7 +451,7 @@
|
|||||||
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
||||||
"ACTION_NEW_USER" : "Новый пользователь",
|
"ACTION_NEW_USER" : "Новый пользователь",
|
||||||
|
|
||||||
"DIALOG_HEADER_ERROR" : "Ошибка",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"HELP_USERS" : "Нажмите на пользователя, чтобы управлять им. В зависимости от прав доступа возможно добавление и удаление пользователей, а также изменение паролей.",
|
"HELP_USERS" : "Нажмите на пользователя, чтобы управлять им. В зависимости от прав доступа возможно добавление и удаление пользователей, а также изменение паролей.",
|
||||||
|
|
||||||
@@ -463,7 +466,7 @@
|
|||||||
"ACTION_DELETE" : "Завершить сессии",
|
"ACTION_DELETE" : "Завершить сессии",
|
||||||
|
|
||||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Завершение сессий",
|
"DIALOG_HEADER_CONFIRM_DELETE" : "Завершение сессий",
|
||||||
"DIALOG_HEADER_ERROR" : "Ошибка",
|
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||||
|
|
||||||
"FIELD_PLACEHOLDER_FILTER" : "Фильтр",
|
"FIELD_PLACEHOLDER_FILTER" : "Фильтр",
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user