mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUAC-801 Created password update dialog on home screen, grant self READ and UPDATE permission to users upon creation, and added sql update script to grant self READ and UPDATE permissions for users in pre-existing databases.
This commit is contained in:
@@ -34,6 +34,7 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
var authenticationService = $injector.get("authenticationService");
|
||||
var connectionGroupService = $injector.get("connectionGroupService");
|
||||
var permissionService = $injector.get("permissionService");
|
||||
var userService = $injector.get("userService");
|
||||
|
||||
/**
|
||||
* The root connection group, or null if the connection group hierarchy has
|
||||
@@ -52,6 +53,37 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
*/
|
||||
$scope.canManageGuacamole = null;
|
||||
|
||||
/**
|
||||
* Whether the current user has sufficient permissions to change
|
||||
* his/her own password. If permissions have not yet been loaded, this will
|
||||
* be null.
|
||||
*
|
||||
* @type Boolean
|
||||
*/
|
||||
$scope.canChangePassword = null;
|
||||
|
||||
/**
|
||||
* Whether the password edit dialog should be shown.
|
||||
*
|
||||
* @type Boolean
|
||||
*/
|
||||
$scope.showPasswordDialog = false;
|
||||
|
||||
/**
|
||||
* The new password for the user.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
$scope.password = null;
|
||||
|
||||
/**
|
||||
* The password match for the user. The update password action will fail if
|
||||
* $scope.password !== $scope.passwordMatch.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
$scope.passwordMatch = null;
|
||||
|
||||
/**
|
||||
* Returns whether critical data has completed being loaded.
|
||||
*
|
||||
@@ -62,7 +94,8 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
$scope.isLoaded = function isLoaded() {
|
||||
|
||||
return $scope.rootConnectionGroup !== null
|
||||
&& $scope.canManageGuacamole !== null;
|
||||
&& $scope.canManageGuacamole !== null
|
||||
&& $scope.canChangePassword !== null;
|
||||
|
||||
};
|
||||
|
||||
@@ -71,13 +104,24 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
.success(function rootGroupRetrieved(rootConnectionGroup) {
|
||||
$scope.rootConnectionGroup = rootConnectionGroup;
|
||||
});
|
||||
|
||||
// Identifier of the current user
|
||||
var currentUserID = authenticationService.getCurrentUserID();
|
||||
|
||||
// Retrieve current permissions
|
||||
permissionService.getPermissions(authenticationService.getCurrentUserID())
|
||||
permissionService.getPermissions(currentUserID)
|
||||
.success(function permissionsRetrieved(permissions) {
|
||||
|
||||
// Determine whether the current user can change his/her own password
|
||||
$scope.canChangePassword =
|
||||
PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, currentUserID)
|
||||
&& PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.READ, currentUserID);
|
||||
|
||||
// Ignore permission to update root group
|
||||
PermissionSet.removeConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, ConnectionGroup.ROOT_IDENTIFIER);
|
||||
|
||||
// Ignore permission to update self
|
||||
PermissionSet.removeUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, currentUserID);
|
||||
|
||||
// Determine whether the current user needs access to the management UI
|
||||
$scope.canManageGuacamole =
|
||||
@@ -105,4 +149,68 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* closes the currently-shown status dialog.
|
||||
*/
|
||||
var ACKNOWLEDGE_ACTION = {
|
||||
name : "MANAGE_USER.ACTION_ACKNOWLEDGE",
|
||||
// Handle action
|
||||
callback : function acknowledgeCallback() {
|
||||
$scope.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the password update dialog.
|
||||
*/
|
||||
$scope.showPasswordUpdate = function showPasswordUpdate() {
|
||||
|
||||
// Show the dialog
|
||||
$scope.showPasswordDialog = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the password update dialog.
|
||||
*/
|
||||
$scope.closePasswordUpdate = function closePasswordUpdate() {
|
||||
|
||||
// Clear the password fields and close the dialog
|
||||
$scope.password = null;
|
||||
$scope.passwordMatch = null;
|
||||
$scope.showPasswordDialog = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the current user's password to the password currently set within
|
||||
* the password change dialog.
|
||||
*/
|
||||
$scope.updatePassword = function updatePassword() {
|
||||
|
||||
// Verify passwords match
|
||||
if ($scope.passwordMatch !== $scope.password) {
|
||||
$scope.showStatus({
|
||||
'className' : 'error',
|
||||
'title' : 'HOME.DIALOG_HEADER_ERROR',
|
||||
'text' : 'HOME.ERROR_PASSWORD_MISMATCH',
|
||||
'actions' : [ ACKNOWLEDGE_ACTION ]
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the user with the new password
|
||||
userService.saveUser({
|
||||
username: currentUserID,
|
||||
password: $scope.password
|
||||
});
|
||||
|
||||
$scope.closePasswordUpdate();
|
||||
|
||||
// Indicate that the password has been changed
|
||||
$scope.showStatus({
|
||||
'text' : 'HOME.PASSWORD_CHANGED',
|
||||
'actions' : [ ACKNOWLEDGE_ACTION ]
|
||||
});
|
||||
};
|
||||
|
||||
}]);
|
||||
|
@@ -69,3 +69,13 @@ div.recent-connections div.connection {
|
||||
max-width: 75%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.password-dialog {
|
||||
position: absolute;
|
||||
background: white;
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
margin: 1em;
|
||||
width: 5in;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
@@ -25,6 +25,31 @@
|
||||
<div class="connection-list-ui">
|
||||
|
||||
<div class="logout-panel">
|
||||
<a class="change-password button" ng-click="showPasswordUpdate()" ng-show="canChangePassword">{{'HOME.ACTION_CHANGE_PASSWORD' | translate}}</a>
|
||||
<div class="password-dialog" ng-show="showPasswordDialog">
|
||||
<!-- Password editor -->
|
||||
<div class="section">
|
||||
<table class="properties">
|
||||
<tr>
|
||||
<th>{{'HOME.FIELD_HEADER_PASSWORD' | translate}}</th>
|
||||
|
||||
<td><input ng-model="password" type="password" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{'HOME.FIELD_HEADER_PASSWORD_AGAIN' | translate}}</th>
|
||||
|
||||
<td><input ng-model="passwordMatch" type="password" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Form action buttons -->
|
||||
<div class="action-buttons">
|
||||
<button ng-click="updatePassword()">{{'HOME.ACTION_SAVE' | translate}}</button>
|
||||
<button ng-click="closePasswordUpdate()">{{'HOME.ACTION_CANCEL' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="manage button" ng-show="canManageGuacamole" href="#/manage">{{'HOME.ACTION_MANAGE' | translate}}</a>
|
||||
<a class="logout button" ng-click="logout()">{{'HOME.ACTION_LOGOUT' | translate}}</a>
|
||||
</div>
|
||||
|
@@ -73,7 +73,7 @@ button.danger:active, a.button.danger:active {
|
||||
background: #932;
|
||||
}
|
||||
|
||||
.button.logout, .button.manage, .button.back, .button.home {
|
||||
.button.logout, .button.manage, .button.back, .button.home, .button.change-password {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1em;
|
||||
background-position: 0.5em 0.45em;
|
||||
@@ -95,3 +95,7 @@ button.danger:active, a.button.danger:active {
|
||||
.button.home {
|
||||
background-image: url('images/action-icons/guac-home.png');
|
||||
}
|
||||
|
||||
.button.change-password {
|
||||
background-image: url('images/action-icons/guac-key.png');
|
||||
}
|
||||
|
BIN
guacamole/src/main/webapp/images/action-icons/guac-key.png
Normal file
BIN
guacamole/src/main/webapp/images/action-icons/guac-key.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 702 B |
@@ -2,16 +2,24 @@
|
||||
|
||||
"APP" : {
|
||||
|
||||
"ACTION_ACKNOWLEDGE" : "OK",
|
||||
"ACTION_CANCEL" : "Cancel",
|
||||
"ACTION_CLONE" : "Clone",
|
||||
"ACTION_DELETE" : "Delete",
|
||||
"ACTION_LOGIN" : "Login",
|
||||
"ACTION_LOGOUT" : "Logout",
|
||||
"ACTION_MANAGE" : "Manage",
|
||||
"ACTION_NAVIGATE_BACK" : "Back",
|
||||
"ACTION_NAVIGATE_HOME" : "Home",
|
||||
"ACTION_SAVE" : "Save",
|
||||
"ACTION_ACKNOWLEDGE" : "OK",
|
||||
"ACTION_CANCEL" : "Cancel",
|
||||
"ACTION_CHANGE_PASSWORD" : "Change Password",
|
||||
"ACTION_CLONE" : "Clone",
|
||||
"ACTION_DELETE" : "Delete",
|
||||
"ACTION_LOGIN" : "Login",
|
||||
"ACTION_LOGOUT" : "Logout",
|
||||
"ACTION_MANAGE" : "Manage",
|
||||
"ACTION_NAVIGATE_BACK" : "Back",
|
||||
"ACTION_NAVIGATE_HOME" : "Home",
|
||||
"ACTION_SAVE" : "Save",
|
||||
|
||||
"DIALOG_HEADER_ERROR" : "Error",
|
||||
|
||||
"ERROR_PASSWORD_MISMATCH" : "The provided passwords do not match.",
|
||||
|
||||
"FIELD_HEADER_PASSWORD" : "Password:",
|
||||
"FIELD_HEADER_PASSWORD_AGAIN" : "Re-enter Password:",
|
||||
|
||||
"INFO_ACTIVE_USER_COUNT" : "Currently in use by {USERS} {USERS, plural, one{user} other{users}}.",
|
||||
|
||||
@@ -106,12 +114,25 @@
|
||||
|
||||
"HOME" : {
|
||||
|
||||
"ACTION_LOGOUT" : "@:APP.ACTION_LOGOUT",
|
||||
"ACTION_MANAGE" : "@:APP.ACTION_MANAGE",
|
||||
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
|
||||
"ACTION_CANCEL" : "@:APP.ACTION_CANCEL",
|
||||
"ACTION_CHANGE_PASSWORD" : "@:APP.ACTION_CHANGE_PASSWORD",
|
||||
"ACTION_LOGOUT" : "@:APP.ACTION_LOGOUT",
|
||||
"ACTION_MANAGE" : "@:APP.ACTION_MANAGE",
|
||||
"ACTION_SAVE" : "@:APP.ACTION_SAVE",
|
||||
|
||||
"DIALOG_HEADER_ERROR" : "@:APP.DIALOG_HEADER_ERROR",
|
||||
|
||||
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
||||
|
||||
"FIELD_HEADER_PASSWORD" : "@:APP.FIELD_HEADER_PASSWORD",
|
||||
"FIELD_HEADER_PASSWORD_AGAIN" : "@:APP.FIELD_HEADER_PASSWORD_AGAIN",
|
||||
|
||||
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
|
||||
|
||||
"INFO_NO_RECENT_CONNECTIONS" : "No recent connections.",
|
||||
|
||||
"PASSWORD_CHANGED" : "Password changed.",
|
||||
|
||||
"SECTION_HEADER_ALL_CONNECTIONS" : "All Connections",
|
||||
"SECTION_HEADER_RECENT_CONNECTIONS" : "Recent Connections"
|
||||
@@ -224,14 +245,14 @@
|
||||
"DIALOG_HEADER_CONFIRM_DELETE" : "Delete User",
|
||||
"DIALOG_HEADER_ERROR" : "Error",
|
||||
|
||||
"ERROR_PASSWORD_MISMATCH" : "The provided passwords do not match.",
|
||||
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
|
||||
|
||||
"FIELD_HEADER_ADMINISTER_SYSTEM" : "Administer system:",
|
||||
"FIELD_HEADER_CREATE_NEW_USERS" : "Create new users:",
|
||||
"FIELD_HEADER_CREATE_NEW_CONNECTIONS" : "Create new connections:",
|
||||
"FIELD_HEADER_CREATE_NEW_CONNECTION_GROUPS" : "Create new connection groups:",
|
||||
"FIELD_HEADER_PASSWORD" : "Password:",
|
||||
"FIELD_HEADER_PASSWORD_AGAIN" : "Re-enter Password:",
|
||||
"FIELD_HEADER_PASSWORD" : "@:APP.FIELD_HEADER_PASSWORD",
|
||||
"FIELD_HEADER_PASSWORD_AGAIN" : "@:APP.FIELD_HEADER_PASSWORD_AGAIN",
|
||||
"FIELD_HEADER_USERNAME" : "Username:",
|
||||
|
||||
"SECTION_HEADER_CONNECTIONS" : "Connections",
|
||||
|
Reference in New Issue
Block a user