in guacamole/src/main/frontend/src/app/import/services/connectionParseService.js [223:369]
function getTreeTransformer(importConfig) {
// A map of group path with connection name, to connection object, used
// for detecting duplicate connections within the import file itself
const connectionsInFile = {};
return getTreeLookups().then(treeLookups => connection => {
const { groupPathsByIdentifier, groupIdentifiersByPath,
connectionIdsByGroupAndName } = treeLookups;
const providedIdentifier = connection.parentIdentifier;
// The normalized group path for this connection, of the form
// "ROOT/parent/child"
let group;
// The identifier for the parent group of this connection
let parentIdentifier;
// The operator to apply for this connection
let op = DirectoryPatch.Operation.ADD;
// If both are specified, the parent group is ambigious
if (providedIdentifier && connection.group) {
connection.errors.push(new ParseError({
message: 'Only one of group or parentIdentifier can be set',
key: 'IMPORT.ERROR_AMBIGUOUS_PARENT_GROUP'
}));
return connection;
}
// If a parent group identifier is present, but not valid
else if (providedIdentifier
&& !groupPathsByIdentifier[providedIdentifier]) {
connection.errors.push(new ParseError({
message: 'No group with identifier: ' + providedIdentifier,
key: 'IMPORT.ERROR_INVALID_GROUP_IDENTIFIER',
variables: { IDENTIFIER: providedIdentifier }
}));
return connection;
}
// If the parent identifier is valid, use it to determine the path
else if (providedIdentifier) {
parentIdentifier = providedIdentifier;
group = groupPathsByIdentifier[providedIdentifier];
}
// If a user-supplied group path is provided, attempt to normalize
// and match it to an existing connection group
else if (connection.group) {
// The group path extracted from the user-provided connection,
// to be translated into an absolute path starting at the root
group = connection.group;
// If the provided group isn't a string, it can never be valid
if (typeof group !== 'string') {
connection.errors.push(new ParseError({
message: 'Invalid group type - must be a string',
key: 'IMPORT.ERROR_INVALID_GROUP_TYPE'
}));
return connection;
}
// Allow the group to start with a leading slash instead instead
// of explicitly requiring the root connection group
if (group.startsWith('/'))
group = ROOT_GROUP_IDENTIFIER + group;
// Allow groups to begin directly with the path under the root
else if (!group.startsWith(ROOT_GROUP_IDENTIFIER))
group = ROOT_GROUP_IDENTIFIER + '/' + group;
// Allow groups to end with a trailing slash
if (group.endsWith('/'))
group = group.slice(0, -1);
// Look up the parent identifier for the specified group path
parentIdentifier = groupPathsByIdentifier[group];
// If the group doesn't match anything in the tree
if (!parentIdentifier) {
connection.errors.push(new ParseError({
message: 'No group found named: ' + connection.group,
key: 'IMPORT.ERROR_INVALID_GROUP',
variables: { GROUP: connection.group }
}));
return connection;
}
}
// If no group is specified at all, default to the root group
else {
parentIdentifier = ROOT_GROUP_IDENTIFIER;
group = ROOT_GROUP_IDENTIFIER;
}
// The full path, of the form "ROOT/Child Group/Connection Name"
const path = group + '/' + connection.name;
// Error out if this is a duplicate of a connection already in the
// file
if (!!_.get(connectionsInFile, path))
connection.errors.push(new ParseError({
message: 'Duplicate connection in file: ' + path,
key: 'IMPORT.ERROR_DUPLICATE_CONNECTION_IN_FILE',
variables: { NAME: connection.name, PATH: group }
}));
// Mark the current path as already seen in the file
_.setWith(connectionsInFile, path, connection, Object);
// Check if this would be an update to an existing connection
const existingIdentifier = _.get(connectionIdsByGroupAndName,
[parentIdentifier, connection.name]);
// The default behavior is to create connections if no conflict
let importMode = ImportConnection.ImportMode.CREATE;
let identifier;
// If updates to existing connections are disallowed
if (existingIdentifier && importConfig.existingConnectionMode ===
ConnectionImportConfig.ExistingConnectionMode.REJECT)
connection.errors.push(new ParseError({
message: 'Rejecting update to existing connection: ' + path,
key: 'IMPORT.ERROR_REJECT_UPDATE_CONNECTION',
variables: { NAME: connection.name, PATH: group }
}));
// If the connection is being replaced, set the existing identifer
else if (existingIdentifier) {
identifier = existingIdentifier;
importMode = ImportConnection.ImportMode.REPLACE;
}
else
importMode = ImportConnection.ImportMode.CREATE;
// Set the import mode, normalized path, and validated identifier
return new ImportConnection({ ...connection,
importMode, group, identifier, parentIdentifier });
});
}