From c21ee0f8301c8b3ec134be2bf9f9243b59e7c3c1 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 22 Mar 2023 14:08:22 -0700 Subject: [PATCH 1/2] GUACAMOLE-1756: Display login failures regardless of whether the interactive login form was used. --- .../app/index/controllers/indexController.js | 25 ++++++++++++++++ .../index/styles/automatic-login-rejected.css | 30 +++++++++++++++++++ guacamole/src/main/frontend/src/index.html | 14 +++++++++ 3 files changed, 69 insertions(+) create mode 100644 guacamole/src/main/frontend/src/app/index/styles/automatic-login-rejected.css diff --git a/guacamole/src/main/frontend/src/app/index/controllers/indexController.js b/guacamole/src/main/frontend/src/app/index/controllers/indexController.js index 52c9d5853..40cb9540d 100644 --- a/guacamole/src/main/frontend/src/app/index/controllers/indexController.js +++ b/guacamole/src/main/frontend/src/app/index/controllers/indexController.js @@ -35,6 +35,7 @@ angular.module('index').controller('indexController', ['$scope', '$injector', const SESSION_VALIDITY_RECHECK_INTERVAL = 15000; // Required types + const Error = $injector.get('Error'); const ManagedClientState = $injector.get('ManagedClientState'); // Required services @@ -110,6 +111,11 @@ angular.module('index').controller('indexController', ['$scope', '$injector', */ var ApplicationState = { + /** + * A non-interactive authentication attempt failed. + */ + AUTOMATIC_LOGIN_REJECTED : 'automaticLoginRejected', + /** * The application has fully loaded but is awaiting credentials from * the user before proceeding. @@ -323,6 +329,25 @@ angular.module('index').controller('indexController', ['$scope', '$injector', }); + // Alert user to authentication errors that occur in the absence of an + // interactive login form + $scope.$on('guacLoginFailed', function loginFailed(event, parameters, error) { + + // All errors related to an interactive login form are handled elsewhere + if ($scope.applicationState === ApplicationState.AWAITING_CREDENTIALS + || error.type === Error.Type.INSUFFICIENT_CREDENTIALS + || error.type === Error.Type.INVALID_CREDENTIALS) + return; + + $scope.applicationState = ApplicationState.AUTOMATIC_LOGIN_REJECTED; + $scope.page.title = 'APP.NAME'; + $scope.page.bodyClassName = ''; + + $scope.reAuthenticating = false; + $scope.fatalError = error; + + }); + // Replace absolutely all content with an error message if the page itself // cannot be displayed due to an error $scope.$on('guacFatalPageError', function fatalPageError(error) { diff --git a/guacamole/src/main/frontend/src/app/index/styles/automatic-login-rejected.css b/guacamole/src/main/frontend/src/app/index/styles/automatic-login-rejected.css new file mode 100644 index 000000000..d034f81f1 --- /dev/null +++ b/guacamole/src/main/frontend/src/app/index/styles/automatic-login-rejected.css @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.automatic-login-rejected-modal guac-modal { + background: white; + z-index: 20; +} + +.automatic-login-rejected-modal .notification { + display: inline-block; + max-width: 5in; + padding: 1em; + width: 100%; +} diff --git a/guacamole/src/main/frontend/src/index.html b/guacamole/src/main/frontend/src/index.html index 7f007eb55..fd6337872 100644 --- a/guacamole/src/main/frontend/src/index.html +++ b/guacamole/src/main/frontend/src/index.html @@ -64,6 +64,20 @@ + +
+ +
+

+

+ +

+
+
+
+ Date: Thu, 23 Mar 2023 00:16:32 -0700 Subject: [PATCH 2/2] GUACAMOLE-1756: Clean up assignment of application state. --- .../app/index/controllers/indexController.js | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/guacamole/src/main/frontend/src/app/index/controllers/indexController.js b/guacamole/src/main/frontend/src/app/index/controllers/indexController.js index 40cb9540d..2f472a6e2 100644 --- a/guacamole/src/main/frontend/src/app/index/controllers/indexController.js +++ b/guacamole/src/main/frontend/src/app/index/controllers/indexController.js @@ -284,6 +284,22 @@ angular.module('index').controller('indexController', ['$scope', '$injector', }, true); + /** + * Sets the current overall state of the client side of the + * application to the given value. Possible values are defined by + * {@link ApplicationState}. The title and class associated with the + * current page are automatically reset to the standard values applicable + * to the application as a whole (rather than any specific page). + * + * @param {!string} state + * The state to assign, as defined by {@link ApplicationState}. + */ + const setApplicationState = function setApplicationState(state) { + $scope.applicationState = state; + $scope.page.title = 'APP.NAME'; + $scope.page.bodyClassName = ''; + }; + /** * Navigates the user back to the root of the application (or reloads the * current route and controller if the user is already there), effectively @@ -306,9 +322,7 @@ angular.module('index').controller('indexController', ['$scope', '$injector', // Display login screen if a whole new set of credentials is needed $scope.$on('guacInvalidCredentials', function loginInvalid(event, parameters, error) { - $scope.applicationState = ApplicationState.AWAITING_CREDENTIALS; - $scope.page.title = 'APP.NAME'; - $scope.page.bodyClassName = ''; + setApplicationState(ApplicationState.AWAITING_CREDENTIALS); $scope.loginHelpText = null; $scope.acceptedCredentials = {}; @@ -319,9 +333,7 @@ angular.module('index').controller('indexController', ['$scope', '$injector', // Prompt for remaining credentials if provided credentials were not enough $scope.$on('guacInsufficientCredentials', function loginInsufficient(event, parameters, error) { - $scope.applicationState = ApplicationState.AWAITING_CREDENTIALS; - $scope.page.title = 'APP.NAME'; - $scope.page.bodyClassName = ''; + setApplicationState(ApplicationState.AWAITING_CREDENTIALS); $scope.loginHelpText = error.translatableMessage; $scope.acceptedCredentials = parameters; @@ -339,10 +351,7 @@ angular.module('index').controller('indexController', ['$scope', '$injector', || error.type === Error.Type.INVALID_CREDENTIALS) return; - $scope.applicationState = ApplicationState.AUTOMATIC_LOGIN_REJECTED; - $scope.page.title = 'APP.NAME'; - $scope.page.bodyClassName = ''; - + setApplicationState(ApplicationState.AUTOMATIC_LOGIN_REJECTED); $scope.reAuthenticating = false; $scope.fatalError = error; @@ -351,13 +360,8 @@ angular.module('index').controller('indexController', ['$scope', '$injector', // Replace absolutely all content with an error message if the page itself // cannot be displayed due to an error $scope.$on('guacFatalPageError', function fatalPageError(error) { - - $scope.applicationState = ApplicationState.FATAL_ERROR; - $scope.page.title = 'APP.NAME'; - $scope.page.bodyClassName = ''; - + setApplicationState(ApplicationState.FATAL_ERROR); $scope.fatalError = error; - }); // Replace the overall user interface with an informational message if the