mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-926: Grant permissions to all users / groups.
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/* global _ */
|
||||
|
||||
/**
|
||||
* The controller for the connection import page.
|
||||
*/
|
||||
@@ -24,14 +26,21 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
||||
function importConnectionsController($scope, $injector) {
|
||||
|
||||
// Required services
|
||||
const $q = $injector.get('$q');
|
||||
const $routeParams = $injector.get('$routeParams');
|
||||
const connectionParseService = $injector.get('connectionParseService');
|
||||
const connectionService = $injector.get('connectionService');
|
||||
const permissionService = $injector.get('permissionService');
|
||||
const userService = $injector.get('userService');
|
||||
const userGroupService = $injector.get('userGroupService');
|
||||
|
||||
// Required types
|
||||
const DirectoryPatch = $injector.get('DirectoryPatch');
|
||||
const ParseError = $injector.get('ParseError');
|
||||
const PermissionSet = $injector.get('PermissionSet');
|
||||
const TranslatableMessage = $injector.get('TranslatableMessage');
|
||||
const User = $injector.get('User');
|
||||
const UserGroup = $injector.get('UserGroup');
|
||||
|
||||
/**
|
||||
* Given a successful response to an import PATCH request, make another
|
||||
@@ -56,10 +65,133 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
||||
|
||||
.then(deletionResponse =>
|
||||
console.log("Deletion response", deletionResponse))
|
||||
.catch(handleParseError);
|
||||
.catch(handleError);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all users and user groups mentioned in the import file that don't
|
||||
* already exist in the current data source.
|
||||
*
|
||||
* @param {ParseResult} parseResult
|
||||
* The result of parsing the user-supplied import file.
|
||||
*
|
||||
* @return {Object}
|
||||
* An object containing the results of the calls to create the users
|
||||
* and groups.
|
||||
*/
|
||||
function createUsersAndGroups(parseResult) {
|
||||
|
||||
const dataSource = $routeParams.dataSource;
|
||||
|
||||
return $q.all({
|
||||
existingUsers : userService.getUsers(dataSource),
|
||||
existingGroups : userGroupService.getUserGroups(dataSource)
|
||||
}).then(({existingUsers, existingGroups}) => {
|
||||
|
||||
const userPatches = Object.keys(parseResult.users)
|
||||
|
||||
// Filter out any existing users
|
||||
.filter(identifier => !existingUsers[identifier])
|
||||
|
||||
// A patch to create each new user
|
||||
.map(username => new DirectoryPatch({
|
||||
op: 'add',
|
||||
path: '/',
|
||||
value: new User({ username })
|
||||
}));
|
||||
|
||||
const groupPatches = Object.keys(parseResult.groups)
|
||||
|
||||
// Filter out any existing groups
|
||||
.filter(identifier => !existingGroups[identifier])
|
||||
|
||||
// A patch to create each new user group
|
||||
.map(identifier => new DirectoryPatch({
|
||||
op: 'add',
|
||||
path: '/',
|
||||
value: new UserGroup({ identifier })
|
||||
}));
|
||||
|
||||
return $q.all({
|
||||
createdUsers: userService.patchUsers(dataSource, userPatches),
|
||||
createdGroups: userGroupService.patchUserGroups(dataSource, groupPatches)
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant read permissions for each user and group in the supplied parse
|
||||
* result to each connection in their connection list. Note that there will
|
||||
* be a seperate request for each user and group.
|
||||
*
|
||||
* @param {ParseResult} parseResult
|
||||
* The result of successfully parsing a user-supplied import file.
|
||||
*
|
||||
* @param {Object} response
|
||||
* The response from the PATCH API request.
|
||||
*
|
||||
* @returns {Promise.<Object>}
|
||||
* A promise that will resolve with the result of every permission
|
||||
* granting request.
|
||||
*/
|
||||
function grantConnectionPermissions(parseResult, response) {
|
||||
|
||||
const dataSource = $routeParams.dataSource;
|
||||
|
||||
// All connection grant requests, one per user/group
|
||||
const userRequests = {};
|
||||
const groupRequests = {};
|
||||
|
||||
// Create a PermissionSet granting access to all connections at
|
||||
// the provided indices within the provided parse result
|
||||
const createPermissionSet = indices =>
|
||||
new PermissionSet({ connectionPermissions: indices.reduce(
|
||||
(permissions, index) => {
|
||||
const connectionId = response.patches[index].identifier;
|
||||
permissions[connectionId] = [
|
||||
PermissionSet.ObjectPermissionType.READ];
|
||||
return permissions;
|
||||
}, {}) });
|
||||
|
||||
// Now that we've created all the users, grant access to each
|
||||
_.forEach(parseResult.users, (connectionIndices, identifier) =>
|
||||
|
||||
// Grant the permissions - note the group flag is `false`
|
||||
userRequests[identifier] = permissionService.patchPermissions(
|
||||
dataSource, identifier,
|
||||
|
||||
// Create the permissions to these connections for this user
|
||||
createPermissionSet(connectionIndices),
|
||||
|
||||
// Do not remove any permissions
|
||||
new PermissionSet(),
|
||||
|
||||
// This call is not for a group
|
||||
false));
|
||||
|
||||
// Now that we've created all the groups, grant access to each
|
||||
_.forEach(parseResult.groups, (connectionIndices, identifier) =>
|
||||
|
||||
// Grant the permissions - note the group flag is `true`
|
||||
groupRequests[identifier] = permissionService.patchPermissions(
|
||||
dataSource, identifier,
|
||||
|
||||
// Create the permissions to these connections for this user
|
||||
createPermissionSet(connectionIndices),
|
||||
|
||||
// Do not remove any permissions
|
||||
new PermissionSet(),
|
||||
|
||||
// This call is for a group
|
||||
true));
|
||||
|
||||
// Return the result from all the permission granting calls
|
||||
return $q.all({ ...userRequests, ...groupRequests });
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a successfully parsed import file, creating any specified
|
||||
* connections, creating and granting permissions to any specified users
|
||||
@@ -78,19 +210,32 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
||||
*
|
||||
*/
|
||||
function handleParseSuccess(parseResult) {
|
||||
connectionService.patchConnections(
|
||||
$routeParams.dataSource, parseResult.patches)
|
||||
|
||||
.then(response => {
|
||||
console.log("Creation Response", response);
|
||||
|
||||
// TODON'T: Delete connections so we can test over and over
|
||||
cleanUpConnections(response);
|
||||
const dataSource = $routeParams.dataSource;
|
||||
|
||||
console.log("parseResult", parseResult);
|
||||
|
||||
// First, attempt to create the connections
|
||||
connectionService.patchConnections(dataSource, parseResult.patches)
|
||||
.then(response => {
|
||||
|
||||
// If connection creation is successful, create users and groups
|
||||
createUsersAndGroups(parseResult).then(() => {
|
||||
|
||||
grantConnectionPermissions(parseResult, response).then(results => {
|
||||
console.log("permission requests", results);
|
||||
|
||||
// TODON'T: Delete connections so we can test over and over
|
||||
cleanUpConnections(response);
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Set any caught error message to the scope for display
|
||||
const handleParseError = error => {
|
||||
const handleError = error => {
|
||||
console.error(error);
|
||||
$scope.error = error;
|
||||
}
|
||||
@@ -150,7 +295,7 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
||||
.then(handleParseSuccess)
|
||||
|
||||
// Display any error found while parsing the file
|
||||
.catch(handleParseError);
|
||||
.catch(handleError);
|
||||
}
|
||||
|
||||
$scope.upload = function() {
|
||||
|
@@ -199,9 +199,9 @@ angular.module('import').factory('connectionParseService',
|
||||
}
|
||||
|
||||
return getGroupTransformer().then(groupTransformer =>
|
||||
connectionData.reduce((parseResult, data) => {
|
||||
connectionData.reduce((parseResult, data, index) => {
|
||||
|
||||
const { patches, users, groups, allUsers, allGroups } = parseResult;
|
||||
const { patches, users, groups } = parseResult;
|
||||
|
||||
// Run the array data through each provided transform
|
||||
let connectionObject = data;
|
||||
@@ -223,15 +223,33 @@ angular.module('import').factory('connectionParseService',
|
||||
connectionErrors.push(error);
|
||||
}
|
||||
|
||||
// Add the user and group identifiers for this connection
|
||||
// The users and user groups that should be granted access
|
||||
const connectionUsers = connectionObject.users || [];
|
||||
const connectionGroups = connectionObject.groups || [];
|
||||
users.push(connectionUsers);
|
||||
groups.push(connectionGroups);
|
||||
|
||||
// Add all user and user group identifiers to the overall sets
|
||||
connectionUsers.forEach(identifier => allUsers[identifier] = true);
|
||||
connectionGroups.forEach(identifier => allGroups[identifier] = true);
|
||||
// Add this connection index to the list for each user
|
||||
connectionUsers.forEach(identifier => {
|
||||
|
||||
// If there's an existing list, add the index to that
|
||||
if (users[identifier])
|
||||
users[identifier].push(index);
|
||||
|
||||
// Otherwise, create a new list with just this index
|
||||
else
|
||||
users[identifier] = [index];
|
||||
});
|
||||
|
||||
// Add this connection index to the list for each group
|
||||
connectionGroups.forEach(identifier => {
|
||||
|
||||
// If there's an existing list, add the index to that
|
||||
if (groups[identifier])
|
||||
groups[identifier].push(index);
|
||||
|
||||
// Otherwise, create a new list with just this index
|
||||
else
|
||||
groups[identifier] = [index];
|
||||
});
|
||||
|
||||
// Translate to a full-fledged Connection
|
||||
const connection = new Connection(connectionObject);
|
||||
|
@@ -48,28 +48,13 @@ angular.module('import').factory('ParseResult', [function defineParseResult() {
|
||||
this.patches = template.patches || [];
|
||||
|
||||
/**
|
||||
* A list of user identifiers that should be granted read access to the
|
||||
* the corresponding connection (at the same array index).
|
||||
* An object whose keys are the user identifiers of users specified
|
||||
* in the batch import. and the keys are an array of indices of
|
||||
* connections to which those users should be granted access.
|
||||
*
|
||||
* @type {String[]}
|
||||
* @type {Object.<String, Integer[]>}
|
||||
*/
|
||||
this.users = template.users || [];
|
||||
|
||||
/**
|
||||
* A list of user group identifiers that should be granted read access
|
||||
* to the corresponding connection (at the same array index).
|
||||
*
|
||||
* @type {String[]}
|
||||
*/
|
||||
this.groups = template.groups || [];
|
||||
|
||||
/**
|
||||
* An object whose keys are the user identifiers of every user specified
|
||||
* in the batch import. i.e. a set of all user identifiers.
|
||||
*
|
||||
* @type {Object.<String, Boolean>}
|
||||
*/
|
||||
this.allUsers = template.allUsers || {};
|
||||
this.users = template.users || {};
|
||||
|
||||
/**
|
||||
* An object whose keys are the user group identifiers of every user
|
||||
@@ -78,7 +63,7 @@ angular.module('import').factory('ParseResult', [function defineParseResult() {
|
||||
*
|
||||
* @type {Object.<String, Boolean>}
|
||||
*/
|
||||
this.allGroups = template.allGroups || {};
|
||||
this.groups = template.users || {};
|
||||
|
||||
/**
|
||||
* An array of errors encountered while parsing the corresponding
|
||||
|
@@ -190,6 +190,39 @@ angular.module('rest').factory('userGroupService', ['$injector',
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes a request to the REST API to apply a supplied list of user group
|
||||
* patches, returning a promise that can be used for processing the results
|
||||
* of the call.
|
||||
*
|
||||
* This operation is atomic - if any errors are encountered during the
|
||||
* connection patching process, the entire request will fail, and no
|
||||
* changes will be persisted.
|
||||
*
|
||||
* @param {DirectoryPatch.<UserGroup>[]} patches
|
||||
* An array of patches to apply.
|
||||
*
|
||||
* @returns {Promise}
|
||||
* A promise for the HTTP call which will succeed if and only if the
|
||||
* patch operation is successful.
|
||||
*/
|
||||
service.patchUserGroups = function patchUserGroups(dataSource, patches) {
|
||||
|
||||
// Make the PATCH request
|
||||
return authenticationService.request({
|
||||
method : 'PATCH',
|
||||
url : 'api/session/data/' + encodeURIComponent(dataSource) + '/userGroups',
|
||||
data : patches
|
||||
})
|
||||
|
||||
// Clear the cache
|
||||
.then(function userGroupsPatched(patchResponse){
|
||||
cacheService.users.removeAll();
|
||||
return patchResponse;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return service;
|
||||
|
||||
}]);
|
||||
|
@@ -235,6 +235,39 @@ angular.module('rest').factory('userService', ['$injector',
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes a request to the REST API to apply a supplied list of user patches,
|
||||
* returning a promise that can be used for processing the results of the
|
||||
* call.
|
||||
*
|
||||
* This operation is atomic - if any errors are encountered during the
|
||||
* connection patching process, the entire request will fail, and no
|
||||
* changes will be persisted.
|
||||
*
|
||||
* @param {DirectoryPatch.<User>[]} patches
|
||||
* An array of patches to apply.
|
||||
*
|
||||
* @returns {Promise}
|
||||
* A promise for the HTTP call which will succeed if and only if the
|
||||
* patch operation is successful.
|
||||
*/
|
||||
service.patchUsers = function patchUsers(dataSource, patches) {
|
||||
|
||||
// Make the PATCH request
|
||||
return authenticationService.request({
|
||||
method : 'PATCH',
|
||||
url : 'api/session/data/' + encodeURIComponent(dataSource) + '/users',
|
||||
data : patches
|
||||
})
|
||||
|
||||
// Clear the cache
|
||||
.then(function usersPatched(patchResponse){
|
||||
cacheService.users.removeAll();
|
||||
return patchResponse;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return service;
|
||||
|
||||
|
Reference in New Issue
Block a user