mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-586: Invoke REST service functions across multiple data sources using dataSourceService.apply().
This commit is contained in:
@@ -39,6 +39,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
|
||||
var $q = $injector.get('$q');
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
var connectionGroupService = $injector.get('connectionGroupService');
|
||||
var dataSourceService = $injector.get('dataSourceService');
|
||||
var guacNotification = $injector.get('guacNotification');
|
||||
var permissionService = $injector.get('permissionService');
|
||||
var schemaService = $injector.get('schemaService');
|
||||
@@ -326,63 +327,8 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
|
||||
$scope.attributes = attributes;
|
||||
});
|
||||
|
||||
/**
|
||||
* Retrieves all user objects having the given username from each of the
|
||||
* given data sources, returning a promise which resolves to a map of those
|
||||
* users by data source identifier. If any data source returns an error,
|
||||
* that data source is omitted from the results.
|
||||
*
|
||||
* @param {String[]} dataSources
|
||||
* The identifiers of the data sources to query.
|
||||
*
|
||||
* @param {String} username
|
||||
* The username of the user to retrieve from each of the given data
|
||||
* sources.
|
||||
*
|
||||
* @returns {Promise.<Object.<String, User>>}
|
||||
* A promise which resolves to a map of user objects by data source
|
||||
* identifier.
|
||||
*/
|
||||
var getUserAccounts = function getUserAccounts(dataSources, username) {
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
var userRequests = [];
|
||||
var accounts = {};
|
||||
|
||||
// Retrieve the requested user account from all data sources
|
||||
angular.forEach(dataSources, function retrieveUser(dataSource) {
|
||||
|
||||
// Add promise to list of pending requests
|
||||
var deferredUserRequest = $q.defer();
|
||||
userRequests.push(deferredUserRequest.promise);
|
||||
|
||||
// Retrieve user from data source
|
||||
userService.getUser(dataSource, username)
|
||||
.success(function userRetrieved(user) {
|
||||
accounts[dataSource] = user;
|
||||
deferredUserRequest.resolve();
|
||||
})
|
||||
|
||||
// Ignore any errors
|
||||
.error(function userRetrievalFailed() {
|
||||
deferredUserRequest.resolve();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Resolve when all requests are completed
|
||||
$q.all(userRequests)
|
||||
.then(function accountsRetrieved() {
|
||||
deferred.resolve(accounts);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
// Pull user data
|
||||
getUserAccounts(dataSources, username)
|
||||
dataSourceService.apply(userService.getUser, dataSources, username)
|
||||
.then(function usersReceived(users) {
|
||||
|
||||
// Get user for currently-selected data source
|
||||
@@ -427,7 +373,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
|
||||
});
|
||||
|
||||
// Retrieve all connections for which we have ADMINISTER permission
|
||||
connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, [PermissionSet.ObjectPermissionType.ADMINISTER])
|
||||
connectionGroupService.getConnectionGroupTree(dataSource, ConnectionGroup.ROOT_IDENTIFIER, [PermissionSet.ObjectPermissionType.ADMINISTER])
|
||||
.success(function connectionGroupReceived(rootGroup) {
|
||||
$scope.rootGroup = rootGroup;
|
||||
});
|
||||
|
@@ -34,8 +34,9 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
||||
// Get required services
|
||||
var $q = $injector.get('$q');
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
var connectionGroupService = $injector.get("connectionGroupService");
|
||||
var permissionService = $injector.get("permissionService");
|
||||
var connectionGroupService = $injector.get('connectionGroupService');
|
||||
var dataSourceService = $injector.get('dataSourceService');
|
||||
var permissionService = $injector.get('permissionService');
|
||||
|
||||
var service = {};
|
||||
|
||||
@@ -259,7 +260,8 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
||||
var deferred = $q.defer();
|
||||
|
||||
// Retrieve current permissions
|
||||
permissionService.getAllPermissions(
|
||||
dataSourceService.apply(
|
||||
permissionService.getPermissions,
|
||||
authenticationService.getAvailableDataSources(),
|
||||
authenticationService.getCurrentUsername()
|
||||
)
|
||||
@@ -346,7 +348,8 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
||||
});
|
||||
|
||||
// Retrieve current permissions
|
||||
permissionService.getAllPermissions(
|
||||
dataSourceService.apply(
|
||||
permissionService.getPermissions,
|
||||
authenticationService.getAvailableDataSources(),
|
||||
authenticationService.getCurrentUsername()
|
||||
)
|
||||
|
125
guacamole/src/main/webapp/app/rest/services/dataSourceService.js
Normal file
125
guacamole/src/main/webapp/app/rest/services/dataSourceService.js
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Service which contains all REST API response caches.
|
||||
*/
|
||||
angular.module('rest').factory('dataSourceService', ['$injector',
|
||||
function dataSourceService($injector) {
|
||||
|
||||
// Required services
|
||||
var $q = $injector.get('$q');
|
||||
|
||||
// Service containing all caches
|
||||
var service = {};
|
||||
|
||||
/**
|
||||
* Invokes the given function once for each of the given data sources,
|
||||
* passing that data source as the first argument to each invocation,
|
||||
* followed by any additional arguments passed to apply(). The results of
|
||||
* each invocation are aggregated into a map by data source identifier,
|
||||
* and handled through a single promise which is resolved or rejected
|
||||
* depending on the success/failure of each resulting REST call. Any error
|
||||
* results in rejection of the entire apply() operation, except 404 ("NOT
|
||||
* FOUND") errors, which are ignored.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* The function to call for each of the given data sources. The data
|
||||
* source identifier will be given as the first argument, followed by
|
||||
* the rest of the arguments given to apply(), in order. The function
|
||||
* must return a Promise which is resolved or rejected depending on the
|
||||
* result of the REST call.
|
||||
*
|
||||
* @param {String[]} dataSources
|
||||
* The array or data source identifiers against which the given
|
||||
* function should be called.
|
||||
*
|
||||
* @param {...*} args
|
||||
* Any additional arguments to pass to the given function each time it
|
||||
* is called.
|
||||
*
|
||||
* @returns {Promise.<Object.<String, *>>}
|
||||
* A Promise which resolves with a map of data source identifier to
|
||||
* corresponding result. The result will be the exact object or value
|
||||
* provided as the resolution to the Promise returned by calls to the
|
||||
* given function.
|
||||
*/
|
||||
service.apply = function apply(fn, dataSources) {
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
var requests = [];
|
||||
var results = {};
|
||||
|
||||
// Build array of arguments to pass to the given function
|
||||
var args = [];
|
||||
for (var i = 2; i < arguments.length; i++)
|
||||
args.push(arguments[i]);
|
||||
|
||||
// Retrieve the root group from all data sources
|
||||
angular.forEach(dataSources, function invokeAgainstDataSource(dataSource) {
|
||||
|
||||
// Add promise to list of pending requests
|
||||
var deferredRequest = $q.defer();
|
||||
requests.push(deferredRequest.promise);
|
||||
|
||||
// Retrieve root group from data source
|
||||
fn.apply(this, [dataSource].concat(args))
|
||||
|
||||
// Store result on success
|
||||
.then(function immediateRequestSucceeded(response) {
|
||||
results[dataSource] = response.data;
|
||||
deferredRequest.resolve();
|
||||
},
|
||||
|
||||
// Fail on any errors (except "NOT FOUND")
|
||||
function immediateRequestFailed(response) {
|
||||
|
||||
// Ignore "NOT FOUND" errors
|
||||
if (response.status === 404)
|
||||
deferredRequest.resolve();
|
||||
|
||||
// Explicitly abort for all other errors
|
||||
else
|
||||
deferredRequest.reject(response);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Resolve if all requests succeed
|
||||
$q.all(requests).then(function requestsSucceeded() {
|
||||
deferred.resolve(results);
|
||||
},
|
||||
|
||||
// Reject if at least one request fails
|
||||
function requestFailed(response) {
|
||||
deferred.reject(response);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
}]);
|
@@ -71,63 +71,6 @@ angular.module('rest').factory('permissionService', ['$injector',
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a promise which resolves with all permissions available to the
|
||||
* given user, as a map of all PermissionSet objects by the identifier of
|
||||
* their corresponding data source. All given data sources are queried. If
|
||||
* an error occurs while retrieving any PermissionSet, the promise will be
|
||||
* rejected.
|
||||
*
|
||||
* @param {String[]} dataSources
|
||||
* The unique identifier of the data sources containing the user whose
|
||||
* permissions should be retrieved. These identifiers corresponds to
|
||||
* AuthenticationProviders within the Guacamole web application.
|
||||
*
|
||||
* @param {String} username
|
||||
* The username of the user to retrieve the permissions for.
|
||||
*
|
||||
* @returns {Promise.<Object.<String, PermissionSet>>}
|
||||
* A promise which resolves with all permissions available to the
|
||||
* current user, as a map of app PermissionSet objects by the
|
||||
* identifier of their corresponding data source.
|
||||
*/
|
||||
service.getAllPermissions = function getAllPermissions(dataSources, username) {
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
var permissionSetRequests = [];
|
||||
var permissionSets = {};
|
||||
|
||||
// Retrieve all permissions from all data sources
|
||||
angular.forEach(dataSources, function retrievePermissions(dataSource) {
|
||||
permissionSetRequests.push(
|
||||
service.getPermissions(dataSource, username)
|
||||
.success(function permissionsRetrieved(permissions) {
|
||||
permissionSets[dataSource] = permissions;
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Resolve when all requests are completed
|
||||
$q.all(permissionSetRequests)
|
||||
.then(
|
||||
|
||||
// All requests completed successfully
|
||||
function allPermissionsRetrieved() {
|
||||
deferred.resolve(permissionSets);
|
||||
},
|
||||
|
||||
// At least one request failed
|
||||
function permissionRetrievalFailed(e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes a request to the REST API to add permissions for a given user,
|
||||
* returning a promise that can be used for processing the results of the
|
||||
|
@@ -78,65 +78,6 @@ angular.module('rest').factory('userService', ['$injector',
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a promise which resolves with all users accessible by the
|
||||
* current user, as a map of @link{User} arrays by the identifier of their
|
||||
* corresponding data source. All given data sources are queried. If an
|
||||
* error occurs while retrieving any user, the promise will be rejected.
|
||||
*
|
||||
* @param {String[]} dataSources
|
||||
* The unique identifier of the data sources containing the user to be
|
||||
* retrieved. These identifiers correspond to AuthenticationProviders
|
||||
* within the Guacamole web application.
|
||||
*
|
||||
* @param {String[]} [permissionTypes]
|
||||
* The set of permissions to filter with. A user must have one or more
|
||||
* of these permissions for a user to appear in the result.
|
||||
* If null, no filtering will be performed. Valid values are listed
|
||||
* within PermissionSet.ObjectType.
|
||||
*
|
||||
* @returns {Promise.<Object.<String, User[]>>}
|
||||
* A promise which resolves with all user objects available to the
|
||||
* current user, as a map of @link{User} arrays grouped by the
|
||||
* identifier of their corresponding data source.
|
||||
*/
|
||||
service.getAllUsers = function getAllUsers(dataSources, permissionTypes) {
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
var userRequests = [];
|
||||
var userArrays = {};
|
||||
|
||||
// Retrieve all users from all data sources
|
||||
angular.forEach(dataSources, function retrieveUsers(dataSource) {
|
||||
userRequests.push(
|
||||
service.getUsers(dataSource, permissionTypes)
|
||||
.success(function usersRetrieved(users) {
|
||||
userArrays[dataSource] = users;
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// Resolve when all requests are completed
|
||||
$q.all(userRequests)
|
||||
.then(
|
||||
|
||||
// All requests completed successfully
|
||||
function allUsersRetrieved() {
|
||||
deferred.resolve(userArrays);
|
||||
},
|
||||
|
||||
// At least one request failed
|
||||
function userRetrievalFailed(e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes a request to the REST API to get the user having the given
|
||||
* username, returning a promise that provides the corresponding
|
||||
|
@@ -43,6 +43,7 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
|
||||
// Required services
|
||||
var $location = $injector.get('$location');
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
var dataSourceService = $injector.get('dataSourceService');
|
||||
var guacNotification = $injector.get('guacNotification');
|
||||
var permissionService = $injector.get('permissionService');
|
||||
var userService = $injector.get('userService');
|
||||
@@ -193,7 +194,7 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
|
||||
};
|
||||
|
||||
// Retrieve current permissions
|
||||
permissionService.getAllPermissions(dataSources, currentUsername)
|
||||
dataSourceService.apply(permissionService.getPermissions, dataSources, currentUsername)
|
||||
.then(function permissionsRetrieved(permissions) {
|
||||
|
||||
// Store retrieved permissions
|
||||
@@ -206,7 +207,7 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
|
||||
});
|
||||
|
||||
// Retrieve all users for whom we have UPDATE or DELETE permission
|
||||
userService.getAllUsers(dataSources, [
|
||||
dataSourceService.apply(userService.getUsers, dataSources, [
|
||||
PermissionSet.ObjectPermissionType.UPDATE,
|
||||
PermissionSet.ObjectPermissionType.DELETE
|
||||
])
|
||||
|
Reference in New Issue
Block a user