mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-926: Create users and groups; don't require them to exist beforehand.
This commit is contained in:
@@ -24,19 +24,73 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
|||||||
function importConnectionsController($scope, $injector) {
|
function importConnectionsController($scope, $injector) {
|
||||||
|
|
||||||
// Required services
|
// Required services
|
||||||
|
const $routeParams = $injector.get('$routeParams');
|
||||||
const connectionParseService = $injector.get('connectionParseService');
|
const connectionParseService = $injector.get('connectionParseService');
|
||||||
const connectionService = $injector.get('connectionService');
|
const connectionService = $injector.get('connectionService');
|
||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
|
const DirectoryPatch = $injector.get('DirectoryPatch');
|
||||||
const ParseError = $injector.get('ParseError');
|
const ParseError = $injector.get('ParseError');
|
||||||
const TranslatableMessage = $injector.get('TranslatableMessage');
|
const TranslatableMessage = $injector.get('TranslatableMessage');
|
||||||
|
|
||||||
function handleSuccess(data) {
|
/**
|
||||||
console.log("OMG SUCCESS: ", data)
|
* Given a successful response to an import PATCH request, make another
|
||||||
|
* request to delete every created connection in the provided request, i.e.
|
||||||
|
* clean up every connection that was created.
|
||||||
|
*
|
||||||
|
* @param {DirectoryPatchResponse} creationResponse
|
||||||
|
*/
|
||||||
|
function cleanUpConnections(creationResponse) {
|
||||||
|
|
||||||
|
// The patches to delete - one delete per initial creation
|
||||||
|
const deletionPatches = creationResponse.patches.map(patch =>
|
||||||
|
new DirectoryPatch({
|
||||||
|
op: 'remove',
|
||||||
|
path: '/' + patch.identifier
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log("Deletion Patches", deletionPatches);
|
||||||
|
|
||||||
|
connectionService.patchConnections(
|
||||||
|
$routeParams.dataSource, deletionPatches)
|
||||||
|
|
||||||
|
.then(deletionResponse =>
|
||||||
|
console.log("Deletion response", deletionResponse))
|
||||||
|
.catch(handleParseError);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a successfully parsed import file, creating any specified
|
||||||
|
* connections, creating and granting permissions to any specified users
|
||||||
|
* and user groups.
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* - Do batch import of connections
|
||||||
|
* - Create all users/groups not already present
|
||||||
|
* - Grant permissions to all users/groups as defined in the import file
|
||||||
|
* - On failure: Roll back everything (maybe ask the user first):
|
||||||
|
* - Attempt to delete all created connections
|
||||||
|
* - Attempt to delete any created users / groups
|
||||||
|
*
|
||||||
|
* @param {ParseResult} parseResult
|
||||||
|
* The result of parsing the user-supplied import file.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set any caught error message to the scope for display
|
// Set any caught error message to the scope for display
|
||||||
const handleError = error => {
|
const handleParseError = error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
$scope.error = error;
|
$scope.error = error;
|
||||||
}
|
}
|
||||||
@@ -44,14 +98,25 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
|||||||
// Clear the current error
|
// Clear the current error
|
||||||
const clearError = () => delete $scope.error;
|
const clearError = () => delete $scope.error;
|
||||||
|
|
||||||
function processData(type, data) {
|
/**
|
||||||
|
* Process the uploaded import file, importing the connections, granting
|
||||||
|
* connection permissions, or displaying errors to the user if there are
|
||||||
|
* problems with the provided file.
|
||||||
|
*
|
||||||
|
* @param {String} mimeType
|
||||||
|
* The MIME type of the uploaded data file.
|
||||||
|
*
|
||||||
|
* @param {String} data
|
||||||
|
* The raw string contents of the import file.
|
||||||
|
*/
|
||||||
|
function processData(mimeType, data) {
|
||||||
|
|
||||||
// The function that will process all the raw data and return a list of
|
// The function that will process all the raw data and return a list of
|
||||||
// patches to be submitted to the API
|
// patches to be submitted to the API
|
||||||
let processDataCallback;
|
let processDataCallback;
|
||||||
|
|
||||||
// Parse the data based on the provided mimetype
|
// Parse the data based on the provided mimetype
|
||||||
switch(type) {
|
switch(mimeType) {
|
||||||
|
|
||||||
case "application/json":
|
case "application/json":
|
||||||
case "text/json":
|
case "text/json":
|
||||||
@@ -82,10 +147,10 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
|||||||
processDataCallback(data)
|
processDataCallback(data)
|
||||||
|
|
||||||
// Send the data off to be imported if parsing is successful
|
// Send the data off to be imported if parsing is successful
|
||||||
.then(handleSuccess)
|
.then(handleParseSuccess)
|
||||||
|
|
||||||
// Display any error found while parsing the file
|
// Display any error found while parsing the file
|
||||||
.catch(handleError);
|
.catch(handleParseError);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.upload = function() {
|
$scope.upload = function() {
|
||||||
|
@@ -33,7 +33,7 @@ angular.module('import').factory('connectionCSVService',
|
|||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
const ParseError = $injector.get('ParseError');
|
const ParseError = $injector.get('ParseError');
|
||||||
const ProtoConnection = $injector.get('ProtoConnection');
|
const ImportConnection = $injector.get('ImportConnection');
|
||||||
const TranslatableMessage = $injector.get('TranslatableMessage');
|
const TranslatableMessage = $injector.get('TranslatableMessage');
|
||||||
|
|
||||||
// Required services
|
// Required services
|
||||||
@@ -154,7 +154,7 @@ angular.module('import').factory('connectionCSVService',
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a CSV header row, create and return a promise that will resolve to
|
* Given a CSV header row, create and return a promise that will resolve to
|
||||||
* a function that can take a CSV data row and return a ProtoConnection
|
* a function that can take a CSV data row and return a ImportConnection
|
||||||
* object. If an error occurs while parsing a particular row, the resolved
|
* object. If an error occurs while parsing a particular row, the resolved
|
||||||
* function will throw a ParseError describing the failure.
|
* function will throw a ParseError describing the failure.
|
||||||
*
|
*
|
||||||
@@ -185,7 +185,7 @@ angular.module('import').factory('connectionCSVService',
|
|||||||
*
|
*
|
||||||
* @returns {Promise.<Function.<String[], Object>>}
|
* @returns {Promise.<Function.<String[], Object>>}
|
||||||
* A promise that will resolve to a function that translates a CSV data
|
* A promise that will resolve to a function that translates a CSV data
|
||||||
* row (array of strings) to a ProtoConnection object.
|
* row (array of strings) to a ImportConnection object.
|
||||||
*/
|
*/
|
||||||
service.getCSVTransformer = function getCSVTransformer(headerRow) {
|
service.getCSVTransformer = function getCSVTransformer(headerRow) {
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ angular.module('import').factory('connectionCSVService',
|
|||||||
const parentIdentifier = (
|
const parentIdentifier = (
|
||||||
parentIdentifierGetter && parentIdentifierGetter(row));
|
parentIdentifierGetter && parentIdentifierGetter(row));
|
||||||
|
|
||||||
return new ProtoConnection({
|
return new ImportConnection({
|
||||||
|
|
||||||
// Fields that are not protocol-specific
|
// Fields that are not protocol-specific
|
||||||
...{
|
...{
|
||||||
|
@@ -42,82 +42,9 @@ angular.module('import').factory('connectionParseService',
|
|||||||
const schemaService = $injector.get('schemaService');
|
const schemaService = $injector.get('schemaService');
|
||||||
const connectionCSVService = $injector.get('connectionCSVService');
|
const connectionCSVService = $injector.get('connectionCSVService');
|
||||||
const connectionGroupService = $injector.get('connectionGroupService');
|
const connectionGroupService = $injector.get('connectionGroupService');
|
||||||
const userService = $injector.get('userService');
|
|
||||||
const userGroupService = $injector.get('userGroupService');
|
|
||||||
|
|
||||||
const service = {};
|
const service = {};
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves to an object whose keys are all valid identifiers in the current
|
|
||||||
* data source. The provided `requestFunction` should resolve to such an
|
|
||||||
* object when provided with the current data source.
|
|
||||||
*
|
|
||||||
* @param {Function.<String<Object.<String, *>>} requestFunction
|
|
||||||
* A function that, given a data source, will return a promise resolving
|
|
||||||
* to an object with keys that are unique identifiers for entities in
|
|
||||||
* that data source.
|
|
||||||
*
|
|
||||||
* @returns {Promise.<Function[String[], String[]>>}
|
|
||||||
* A promise that will resolve to an function that, given an array of
|
|
||||||
* identifiers, will return all identifiers that do not exist as keys in
|
|
||||||
* the object returned by `requestFunction`, i.e. all identifiers that
|
|
||||||
* do not exist in the current data source.
|
|
||||||
*/
|
|
||||||
function getIdentifierMap(requestFunction) {
|
|
||||||
|
|
||||||
// The current data source to which all the identifiers will belong
|
|
||||||
const dataSource = $routeParams.dataSource;
|
|
||||||
|
|
||||||
// Make the request and return the response, which should be an object
|
|
||||||
// whose keys are all valid identifiers for the current data source
|
|
||||||
return requestFunction(dataSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a promise that resolves to a function that takes an array of
|
|
||||||
* identifiers, returning a ParseError describing the invalid identifiers
|
|
||||||
* from the list. The provided `requestFunction` should resolve to such an
|
|
||||||
* object whose keys are all valid identifiers when provided with the
|
|
||||||
* current data source.
|
|
||||||
*
|
|
||||||
* @param {Function.<String<Object.<String, *>>} requestFunction
|
|
||||||
* A function that, given a data source, will return a promise resolving
|
|
||||||
* to an object with keys that are unique identifiers for entities in
|
|
||||||
* that data source.
|
|
||||||
*
|
|
||||||
* @returns {Promise.<Function.<String[], ParseError?>>}
|
|
||||||
* A promise that will resolve to a function to check the validity of
|
|
||||||
* each identifier in a provided array, returning a ParseError
|
|
||||||
* describing the problem if any are not valid.
|
|
||||||
*/
|
|
||||||
function getInvalidIdentifierErrorChecker(requestFunction) {
|
|
||||||
|
|
||||||
// Fetch all the valid user identifiers in the system, and
|
|
||||||
return getIdentifierMap(requestFunction).then(validIdentifiers =>
|
|
||||||
|
|
||||||
// The resolved function that takes a list of user group identifiers
|
|
||||||
allIdentifiers => {
|
|
||||||
|
|
||||||
// Filter to only include invalid identifiers
|
|
||||||
const invalidIdentifiers = _.filter(allIdentifiers,
|
|
||||||
identifier => !validIdentifiers[identifier]);
|
|
||||||
|
|
||||||
if (invalidIdentifiers.length) {
|
|
||||||
|
|
||||||
// Quote and comma-seperate for display
|
|
||||||
const identifierList = invalidIdentifiers.map(
|
|
||||||
identifier => '"' + identifier + '"').join(', ');
|
|
||||||
|
|
||||||
return new ParseError({
|
|
||||||
message: 'Invalid User Group Identifiers: ' + identifierList,
|
|
||||||
key: 'CONNECTION_IMPORT.ERROR_INVALID_USER_GROUP_IDENTIFIERS',
|
|
||||||
variables: { IDENTIFIER_LIST: identifierList }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform basic checks, common to all file types - namely that the parsed
|
* Perform basic checks, common to all file types - namely that the parsed
|
||||||
* data is an array, and contains at least one connection entry. Returns an
|
* data is an array, and contains at least one connection entry. Returns an
|
||||||
@@ -245,12 +172,12 @@ angular.module('import').factory('connectionParseService',
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a provided ProtoConnection array into a ParseResult. Any provided
|
* Convert a provided ImportConnection array into a ParseResult. Any provided
|
||||||
* transform functions will be run on each entry in `connectionData` before
|
* transform functions will be run on each entry in `connectionData` before
|
||||||
* any other processing is done.
|
* any other processing is done.
|
||||||
*
|
*
|
||||||
* @param {*[]} connectionData
|
* @param {*[]} connectionData
|
||||||
* An arbitrary array of data. This must evaluate to a ProtoConnection
|
* An arbitrary array of data. This must evaluate to a ImportConnection
|
||||||
* object after being run through all functions in `transformFunctions`.
|
* object after being run through all functions in `transformFunctions`.
|
||||||
*
|
*
|
||||||
* @param {Function[]} transformFunctions
|
* @param {Function[]} transformFunctions
|
||||||
@@ -271,21 +198,10 @@ angular.module('import').factory('connectionParseService',
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $q.all({
|
return getGroupTransformer().then(groupTransformer =>
|
||||||
groupTransformer : getGroupTransformer(),
|
connectionData.reduce((parseResult, data) => {
|
||||||
invalidUserIdErrorDetector : getInvalidIdentifierErrorChecker(
|
|
||||||
userService.getUsers),
|
|
||||||
invalidGroupIDErrorDetector : getInvalidIdentifierErrorChecker(
|
|
||||||
userGroupService.getUserGroups),
|
|
||||||
})
|
|
||||||
|
|
||||||
// Transform the rows from the CSV file to an array of API patches
|
const { patches, users, groups, allUsers, allGroups } = parseResult;
|
||||||
// and lists of user and group identifiers
|
|
||||||
.then(({groupTransformer,
|
|
||||||
invalidUserIdErrorDetector, invalidGroupIDErrorDetector}) =>
|
|
||||||
connectionData.reduce((parseResult, data) => {
|
|
||||||
|
|
||||||
const { patches, identifiers, users, groups } = parseResult;
|
|
||||||
|
|
||||||
// Run the array data through each provided transform
|
// Run the array data through each provided transform
|
||||||
let connectionObject = data;
|
let connectionObject = data;
|
||||||
@@ -307,14 +223,15 @@ angular.module('import').factory('connectionParseService',
|
|||||||
connectionErrors.push(error);
|
connectionErrors.push(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push any errors for invalid user or user group identifiers
|
|
||||||
const pushError = error => error && connectionErrors.push(error);
|
|
||||||
pushError(invalidUserIdErrorDetector(connectionObject.users));
|
|
||||||
pushError(invalidGroupIDErrorDetector(connectionObject.userGroups));
|
|
||||||
|
|
||||||
// Add the user and group identifiers for this connection
|
// Add the user and group identifiers for this connection
|
||||||
users.push(connectionObject.users);
|
const connectionUsers = connectionObject.users || [];
|
||||||
groups.push(connectionObject.groups);
|
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);
|
||||||
|
|
||||||
// Translate to a full-fledged Connection
|
// Translate to a full-fledged Connection
|
||||||
const connection = new Connection(connectionObject);
|
const connection = new Connection(connectionObject);
|
||||||
@@ -398,7 +315,18 @@ angular.module('import').factory('connectionParseService',
|
|||||||
service.parseYAML = function parseYAML(yamlData) {
|
service.parseYAML = function parseYAML(yamlData) {
|
||||||
|
|
||||||
// Parse from YAML into a javascript array
|
// Parse from YAML into a javascript array
|
||||||
const connectionData = parseYAMLData(yamlData);
|
try {
|
||||||
|
const connectionData = parseYAMLData(yamlData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the YAML parser throws an error, reject with that error. No
|
||||||
|
// translation key will be available here.
|
||||||
|
catch(error) {
|
||||||
|
console.error(error);
|
||||||
|
const deferred = $q.defer();
|
||||||
|
deferred.reject(new ParseError({ message: error.message }));
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
// Produce a ParseResult
|
// Produce a ParseResult
|
||||||
return parseConnectionData(connectionData);
|
return parseConnectionData(connectionData);
|
||||||
@@ -420,7 +348,18 @@ angular.module('import').factory('connectionParseService',
|
|||||||
service.parseJSON = function parseJSON(jsonData) {
|
service.parseJSON = function parseJSON(jsonData) {
|
||||||
|
|
||||||
// Parse from JSON into a javascript array
|
// Parse from JSON into a javascript array
|
||||||
const connectionData = JSON.parse(jsonData);
|
try {
|
||||||
|
const connectionData = JSON.parse(jsonData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the JSON parse attempt throws an error, reject with that error.
|
||||||
|
// No translation key will be available here.
|
||||||
|
catch(error) {
|
||||||
|
console.error(error);
|
||||||
|
const deferred = $q.defer();
|
||||||
|
deferred.reject(new ParseError({ message: error.message }));
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
// Produce a ParseResult
|
// Produce a ParseResult
|
||||||
return parseConnectionData(connectionData);
|
return parseConnectionData(connectionData);
|
||||||
|
@@ -18,21 +18,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service which defines the Connection class.
|
* Service which defines the ImportConnection class.
|
||||||
*/
|
*/
|
||||||
angular.module('import').factory('ProtoConnection', [
|
angular.module('import').factory('ImportConnection', [
|
||||||
function defineProtoConnection() {
|
function defineImportConnection() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a connection to be imported, as parsed from an
|
* A representation of a connection to be imported, as parsed from an
|
||||||
* user-supplied import file.
|
* user-supplied import file.
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Connection|Object} [template={}]
|
* @param {ImportConnection|Object} [template={}]
|
||||||
* The object whose properties should be copied within the new
|
* The object whose properties should be copied within the new
|
||||||
* Connection.
|
* Connection.
|
||||||
*/
|
*/
|
||||||
var ProtoConnection = function ProtoConnection(template) {
|
var ImportConnection = function ImportConnection(template) {
|
||||||
|
|
||||||
// Use empty object by default
|
// Use empty object by default
|
||||||
template = template || {};
|
template = template || {};
|
||||||
@@ -106,6 +106,6 @@ angular.module('import').factory('ProtoConnection', [
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return ProtoConnection;
|
return ImportConnection;
|
||||||
|
|
||||||
}]);
|
}]);
|
@@ -63,6 +63,23 @@ angular.module('import').factory('ParseResult', [function defineParseResult() {
|
|||||||
*/
|
*/
|
||||||
this.groups = template.groups || [];
|
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 || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object whose keys are the user group identifiers of every user
|
||||||
|
* group specified in the batch import. i.e. a set of all user group
|
||||||
|
* identifiers.
|
||||||
|
*
|
||||||
|
* @type {Object.<String, Boolean>}
|
||||||
|
*/
|
||||||
|
this.allGroups = template.allGroups || {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of errors encountered while parsing the corresponding
|
* An array of errors encountered while parsing the corresponding
|
||||||
* connection (at the same array index). Each connection should have a
|
* connection (at the same array index). Each connection should have a
|
||||||
|
@@ -158,7 +158,7 @@ angular.module('rest').factory('connectionService', ['$injector',
|
|||||||
/**
|
/**
|
||||||
* Makes a request to the REST API to apply a supplied list of connection
|
* Makes a request to the REST API to apply a supplied list of connection
|
||||||
* patches, returning a promise that can be used for processing the results
|
* patches, returning a promise that can be used for processing the results
|
||||||
* of the call.
|
* of the call.
|
||||||
*
|
*
|
||||||
* This operation is atomic - if any errors are encountered during the
|
* This operation is atomic - if any errors are encountered during the
|
||||||
* connection patching process, the entire request will fail, and no
|
* connection patching process, the entire request will fail, and no
|
||||||
@@ -181,13 +181,15 @@ angular.module('rest').factory('connectionService', ['$injector',
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Clear the cache
|
// Clear the cache
|
||||||
.then(function connectionsPatched(){
|
.then(function connectionsPatched(patchResponse){
|
||||||
cacheService.connections.removeAll();
|
cacheService.connections.removeAll();
|
||||||
|
|
||||||
// Clear users cache to force reload of permissions for any
|
// Clear users cache to force reload of permissions for any
|
||||||
// newly created or replaced connections
|
// newly created or replaced connections
|
||||||
cacheService.users.removeAll();
|
cacheService.users.removeAll();
|
||||||
|
|
||||||
|
return patchResponse;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -59,10 +59,9 @@ angular.module('rest').factory('DirectoryPatch', [function defineDirectoryPatch(
|
|||||||
this.path = template.path || '/';
|
this.path = template.path || '/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object being added or replaced, or the identifier of the object
|
* The object being added, or undefined if deleting.
|
||||||
* being removed.
|
|
||||||
*
|
*
|
||||||
* @type {DirectoryObject|String}
|
* @type {DirectoryObject}
|
||||||
*/
|
*/
|
||||||
this.value = template.value;
|
this.value = template.value;
|
||||||
|
|
||||||
@@ -78,11 +77,6 @@ angular.module('rest').factory('DirectoryPatch', [function defineDirectoryPatch(
|
|||||||
*/
|
*/
|
||||||
ADD : "add",
|
ADD : "add",
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the specified object from the relation.
|
|
||||||
*/
|
|
||||||
REPLACE : "replace",
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the specified object from the relation.
|
* Removes the specified object from the relation.
|
||||||
*/
|
*/
|
||||||
|
@@ -30,15 +30,11 @@ angular.module('rest').factory('DirectoryPatchOutcome', [
|
|||||||
* response. The error field is only meaningful for unsuccessful patches.
|
* response. The error field is only meaningful for unsuccessful patches.
|
||||||
* @constructor
|
* @constructor
|
||||||
*
|
*
|
||||||
* @template DirectoryObject
|
* @param {DirectoryPatchOutcome|Object} [template={}]
|
||||||
* The directory-based object type that this DirectoryPatchOutcome
|
|
||||||
* represents a patch outcome for.
|
|
||||||
*
|
|
||||||
* @param {DirectoryObject|Object} [template={}]
|
|
||||||
* The object whose properties should be copied within the new
|
* The object whose properties should be copied within the new
|
||||||
* DirectoryPatchOutcome.
|
* DirectoryPatchOutcome.
|
||||||
*/
|
*/
|
||||||
var DirectoryPatchOutcome = function DirectoryPatchOutcome(template) {
|
const DirectoryPatchOutcome = function DirectoryPatchOutcome(template) {
|
||||||
|
|
||||||
// Use empty object by default
|
// Use empty object by default
|
||||||
template = template || {};
|
template = template || {};
|
||||||
@@ -78,6 +74,6 @@ angular.module('rest').factory('DirectoryPatchOutcome', [
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return DirectoryPatch;
|
return DirectoryPatchOutcome;
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service which defines the DirectoryPatchResponse class.
|
||||||
|
*/
|
||||||
|
angular.module('rest').factory('DirectoryPatchResponse', [
|
||||||
|
function defineDirectoryPatchResponse() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object returned by a PATCH request to a directory REST API,
|
||||||
|
* representing the successful response to a patch request.
|
||||||
|
*
|
||||||
|
* @param {DirectoryPatchResponse|Object} [template={}]
|
||||||
|
* The object whose properties should be copied within the new
|
||||||
|
* DirectoryPatchResponse.
|
||||||
|
*/
|
||||||
|
const DirectoryPatchResponse = function DirectoryPatchResponse(template) {
|
||||||
|
|
||||||
|
// Use empty object by default
|
||||||
|
template = template || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An outcome for each patch in the corresponding patch request.
|
||||||
|
*
|
||||||
|
* @type {DirectoryPatchOutcome[]}
|
||||||
|
*/
|
||||||
|
this.patches = template.patches;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return DirectoryPatchResponse;
|
||||||
|
|
||||||
|
}]);
|
Reference in New Issue
Block a user