mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
439 lines
16 KiB
JavaScript
439 lines
16 KiB
JavaScript
/*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* The controller for editing users.
|
|
*/
|
|
angular.module('manage').controller('manageUserController', ['$scope', '$injector',
|
|
function manageUserController($scope, $injector) {
|
|
|
|
// Required types
|
|
var Error = $injector.get('Error');
|
|
var ManagementPermissions = $injector.get('ManagementPermissions');
|
|
var PermissionFlagSet = $injector.get('PermissionFlagSet');
|
|
var PermissionSet = $injector.get('PermissionSet');
|
|
var User = $injector.get('User');
|
|
|
|
// Required services
|
|
var $location = $injector.get('$location');
|
|
var $routeParams = $injector.get('$routeParams');
|
|
var $q = $injector.get('$q');
|
|
var authenticationService = $injector.get('authenticationService');
|
|
var dataSourceService = $injector.get('dataSourceService');
|
|
var permissionService = $injector.get('permissionService');
|
|
var requestService = $injector.get('requestService');
|
|
var schemaService = $injector.get('schemaService');
|
|
var userService = $injector.get('userService');
|
|
|
|
/**
|
|
* The identifiers of all data sources currently available to the
|
|
* authenticated user.
|
|
*
|
|
* @type String[]
|
|
*/
|
|
var dataSources = authenticationService.getAvailableDataSources();
|
|
|
|
/**
|
|
* The username of the current, authenticated user.
|
|
*
|
|
* @type String
|
|
*/
|
|
var currentUsername = authenticationService.getCurrentUsername();
|
|
|
|
/**
|
|
* The username of the original user from which this user is
|
|
* being cloned. Only valid if this is a new user.
|
|
*
|
|
* @type String
|
|
*/
|
|
var cloneSourceUsername = $location.search().clone;
|
|
|
|
/**
|
|
* The username of the user being edited. If a new user is
|
|
* being created, this will not be defined.
|
|
*
|
|
* @type String
|
|
*/
|
|
var username = $routeParams.id;
|
|
|
|
/**
|
|
* The unique identifier of the data source containing the user being
|
|
* edited.
|
|
*
|
|
* @type String
|
|
*/
|
|
$scope.dataSource = $routeParams.dataSource;
|
|
|
|
/**
|
|
* The string value representing the user currently being edited within the
|
|
* permission flag set. Note that his may not match the user's actual
|
|
* username - it is a marker that is (1) guaranteed to be associated with
|
|
* the current user's permissions in the permission set and (2) guaranteed
|
|
* not to collide with any user that does not represent the current user
|
|
* within the permission set.
|
|
*
|
|
* @type String
|
|
*/
|
|
$scope.selfUsername = '';
|
|
|
|
/**
|
|
* All user accounts associated with the same username as the account being
|
|
* created or edited, as a map of data source identifier to the User object
|
|
* within that data source.
|
|
*
|
|
* @type Object.<String, User>
|
|
*/
|
|
$scope.users = null;
|
|
|
|
/**
|
|
* The user being modified.
|
|
*
|
|
* @type User
|
|
*/
|
|
$scope.user = null;
|
|
|
|
/**
|
|
* All permissions associated with the user being modified.
|
|
*
|
|
* @type PermissionFlagSet
|
|
*/
|
|
$scope.permissionFlags = null;
|
|
|
|
/**
|
|
* The set of permissions that will be added to the user when the user is
|
|
* saved. Permissions will only be present in this set if they are
|
|
* manually added, and not later manually removed before saving.
|
|
*
|
|
* @type PermissionSet
|
|
*/
|
|
$scope.permissionsAdded = new PermissionSet();
|
|
|
|
/**
|
|
* The set of permissions that will be removed from the user when the user
|
|
* is saved. Permissions will only be present in this set if they are
|
|
* manually removed, and not later manually added before saving.
|
|
*
|
|
* @type PermissionSet
|
|
*/
|
|
$scope.permissionsRemoved = new PermissionSet();
|
|
|
|
/**
|
|
* For each applicable data source, the management-related actions that the
|
|
* current user may perform on the user account currently being created
|
|
* or modified, as a map of data source identifier to the
|
|
* {@link ManagementPermissions} object describing the actions available
|
|
* within that data source, or null if the current user's permissions have
|
|
* not yet been loaded.
|
|
*
|
|
* @type Object.<String, ManagementPermissions>
|
|
*/
|
|
$scope.managementPermissions = null;
|
|
|
|
/**
|
|
* All available user attributes. This is only the set of attribute
|
|
* definitions, organized as logical groupings of attributes, not attribute
|
|
* values.
|
|
*
|
|
* @type Form[]
|
|
*/
|
|
$scope.attributes = null;
|
|
|
|
/**
|
|
* Returns whether critical data has completed being loaded.
|
|
*
|
|
* @returns {Boolean}
|
|
* true if enough data has been loaded for the user interface to be
|
|
* useful, false otherwise.
|
|
*/
|
|
$scope.isLoaded = function isLoaded() {
|
|
|
|
return $scope.users !== null
|
|
&& $scope.permissionFlags !== null
|
|
&& $scope.managementPermissions !== null
|
|
&& $scope.attributes !== null;
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns whether the current user can edit the username of the user being
|
|
* edited within the given data source.
|
|
*
|
|
* @param {String} [dataSource]
|
|
* The identifier of the data source to check. If omitted, this will
|
|
* default to the currently-selected data source.
|
|
*
|
|
* @returns {Boolean}
|
|
* true if the current user can edit the username of the user being
|
|
* edited, false otherwise.
|
|
*/
|
|
$scope.canEditUsername = function canEditUsername(dataSource) {
|
|
return !username;
|
|
};
|
|
|
|
/**
|
|
* Loads the data associated with the user having the given username,
|
|
* preparing the interface for making modifications to that existing user.
|
|
*
|
|
* @param {String} dataSource
|
|
* The unique identifier of the data source containing the user to
|
|
* load.
|
|
*
|
|
* @param {String} username
|
|
* The username of the user to load.
|
|
*
|
|
* @returns {Promise}
|
|
* A promise which is resolved when the interface has been prepared for
|
|
* editing the given user.
|
|
*/
|
|
var loadExistingUser = function loadExistingUser(dataSource, username) {
|
|
return $q.all({
|
|
users : dataSourceService.apply(userService.getUser, dataSources, username),
|
|
permissions : permissionService.getPermissions(dataSource, username)
|
|
})
|
|
.then(function userDataRetrieved(values) {
|
|
|
|
$scope.users = values.users;
|
|
$scope.user = values.users[dataSource];
|
|
|
|
// Create skeleton user if user does not exist
|
|
if (!$scope.user)
|
|
$scope.user = new User({
|
|
'username' : username
|
|
});
|
|
|
|
// The current user will be associated with username of the existing
|
|
// user in the retrieved permission set
|
|
$scope.selfUsername = username;
|
|
$scope.permissionFlags = PermissionFlagSet.fromPermissionSet(values.permissions);
|
|
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Loads the data associated with the user having the given username,
|
|
* preparing the interface for cloning that existing user.
|
|
*
|
|
* @param {String} dataSource
|
|
* The unique identifier of the data source containing the user to
|
|
* be cloned.
|
|
*
|
|
* @param {String} username
|
|
* The username of the user being cloned.
|
|
*
|
|
* @returns {Promise}
|
|
* A promise which is resolved when the interface has been prepared for
|
|
* cloning the given user.
|
|
*/
|
|
var loadClonedUser = function loadClonedUser(dataSource, username) {
|
|
return $q.all({
|
|
users : dataSourceService.apply(userService.getUser, [dataSource], username),
|
|
permissions : permissionService.getPermissions(dataSource, username)
|
|
})
|
|
.then(function userDataRetrieved(values) {
|
|
|
|
$scope.users = {};
|
|
$scope.user = values.users[dataSource];
|
|
|
|
// The current user will be associated with cloneSourceUsername in the
|
|
// retrieved permission set
|
|
$scope.selfUsername = username;
|
|
$scope.permissionFlags = PermissionFlagSet.fromPermissionSet(values.permissions);
|
|
$scope.permissionsAdded = values.permissions;
|
|
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Loads skeleton user data, preparing the interface for creating a new
|
|
* user.
|
|
*
|
|
* @returns {Promise}
|
|
* A promise which is resolved when the interface has been prepared for
|
|
* creating a new user.
|
|
*/
|
|
var loadSkeletonUser = function loadSkeletonUser() {
|
|
|
|
// No users exist regardless of data source if there is no username
|
|
$scope.users = {};
|
|
|
|
// Use skeleton user object with no associated permissions
|
|
$scope.user = new User();
|
|
$scope.permissionFlags = new PermissionFlagSet();
|
|
|
|
// As no permissions are yet associated with the user, it is safe to
|
|
// use any non-empty username as a placeholder for self-referential
|
|
// permissions
|
|
$scope.selfUsername = 'SELF';
|
|
|
|
return $q.resolve();
|
|
|
|
};
|
|
|
|
/**
|
|
* Loads the data required for performing the management task requested
|
|
* through the route parameters given at load time, automatically preparing
|
|
* the interface for editing an existing user, cloning an existing user, or
|
|
* creating an entirely new user.
|
|
*
|
|
* @returns {Promise}
|
|
* A promise which is resolved when the interface has been prepared
|
|
* for performing the requested management task.
|
|
*/
|
|
var loadRequestedUser = function loadRequestedUser() {
|
|
|
|
// Pull user data and permissions if we are editing an existing user
|
|
if (username)
|
|
return loadExistingUser($scope.dataSource, username);
|
|
|
|
// If we are cloning an existing user, pull his/her data instead
|
|
if (cloneSourceUsername)
|
|
return loadClonedUser($scope.dataSource, cloneSourceUsername);
|
|
|
|
// If we are creating a new user, populate skeleton user data
|
|
return loadSkeletonUser();
|
|
|
|
};
|
|
|
|
// Populate interface with requested data
|
|
$q.all({
|
|
userData : loadRequestedUser(),
|
|
permissions : dataSourceService.apply(permissionService.getEffectivePermissions, dataSources, currentUsername),
|
|
attributes : schemaService.getUserAttributes($scope.dataSource)
|
|
})
|
|
.then(function dataReceived(values) {
|
|
|
|
$scope.attributes = values.attributes;
|
|
|
|
$scope.managementPermissions = {};
|
|
angular.forEach(dataSources, function addAccountPage(dataSource) {
|
|
|
|
// Determine whether data source contains this user
|
|
var exists = (dataSource in $scope.users);
|
|
|
|
// Calculate management actions available for this specific account
|
|
$scope.managementPermissions[dataSource] = ManagementPermissions.fromPermissionSet(
|
|
values.permissions[dataSource],
|
|
PermissionSet.SystemPermissionType.CREATE_USER,
|
|
PermissionSet.hasUserPermission,
|
|
exists ? username : null);
|
|
|
|
});
|
|
|
|
}, requestService.DIE);
|
|
|
|
/**
|
|
* Returns the URL for the page which manages the user account currently
|
|
* being edited under the given data source. The given data source need not
|
|
* be the same as the data source currently selected.
|
|
*
|
|
* @param {String} dataSource
|
|
* The unique identifier of the data source that the URL is being
|
|
* generated for.
|
|
*
|
|
* @returns {String}
|
|
* The URL for the page which manages the user account currently being
|
|
* edited under the given data source.
|
|
*/
|
|
$scope.getUserURL = function getUserURL(dataSource) {
|
|
return '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username || '');
|
|
};
|
|
|
|
/**
|
|
* Cancels all pending edits, returning to the main list of users.
|
|
*/
|
|
$scope.returnToUserList = function returnToUserList() {
|
|
$location.url('/settings/users');
|
|
};
|
|
|
|
/**
|
|
* Cancels all pending edits, opening an edit page for a new user
|
|
* which is prepopulated with the data from the user currently being edited.
|
|
*/
|
|
$scope.cloneUser = function cloneUser() {
|
|
$location.path('/manage/' + encodeURIComponent($scope.dataSource) + '/users').search('clone', username);
|
|
};
|
|
|
|
/**
|
|
* Saves the current user, creating a new user or updating the existing
|
|
* user depending on context, returning a promise which is resolved if the
|
|
* save operation succeeds and rejected if the save operation fails.
|
|
*
|
|
* @returns {Promise}
|
|
* A promise which is resolved if the save operation succeeds and is
|
|
* rejected with an {@link Error} if the save operation fails.
|
|
*/
|
|
$scope.saveUser = function saveUser() {
|
|
|
|
// Verify passwords match
|
|
if ($scope.passwordMatch !== $scope.user.password) {
|
|
return $q.reject(new Error({
|
|
translatableMessage : {
|
|
key : 'MANAGE_USER.ERROR_PASSWORD_MISMATCH'
|
|
}
|
|
}));
|
|
}
|
|
|
|
// Save or create the user, depending on whether the user exists
|
|
var saveUserPromise;
|
|
if ($scope.dataSource in $scope.users)
|
|
saveUserPromise = userService.saveUser($scope.dataSource, $scope.user);
|
|
else
|
|
saveUserPromise = userService.createUser($scope.dataSource, $scope.user);
|
|
|
|
return saveUserPromise.then(function savedUser() {
|
|
|
|
// Move permission flags if username differs from marker
|
|
if ($scope.selfUsername !== $scope.user.username) {
|
|
|
|
// Rename added permission
|
|
if ($scope.permissionsAdded.userPermissions[$scope.selfUsername]) {
|
|
$scope.permissionsAdded.userPermissions[$scope.user.username] = $scope.permissionsAdded.userPermissions[$scope.selfUsername];
|
|
delete $scope.permissionsAdded.userPermissions[$scope.selfUsername];
|
|
}
|
|
|
|
// Rename removed permission
|
|
if ($scope.permissionsRemoved.userPermissions[$scope.selfUsername]) {
|
|
$scope.permissionsRemoved.userPermissions[$scope.user.username] = $scope.permissionsRemoved.userPermissions[$scope.selfUsername];
|
|
delete $scope.permissionsRemoved.userPermissions[$scope.selfUsername];
|
|
}
|
|
|
|
}
|
|
|
|
// Upon success, save any changed permissions
|
|
return permissionService.patchPermissions($scope.dataSource, $scope.user.username,
|
|
$scope.permissionsAdded, $scope.permissionsRemoved);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
/**
|
|
* Deletes the current user, returning a promise which is resolved if the
|
|
* delete operation succeeds and rejected if the delete operation fails.
|
|
*
|
|
* @returns {Promise}
|
|
* A promise which is resolved if the delete operation succeeds and is
|
|
* rejected with an {@link Error} if the delete operation fails.
|
|
*/
|
|
$scope.deleteUser = function deleteUser() {
|
|
return userService.deleteUser($scope.dataSource, $scope.user);
|
|
};
|
|
|
|
}]);
|