mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-09 06:31:22 +00:00
GUACAMOLE-926: Merge batch import corrections to file type detection, YAML value handling, and YAML example.
This commit is contained in:
@@ -26,6 +26,15 @@
|
|||||||
*/
|
*/
|
||||||
const CSV_MIME_TYPE = 'text/csv';
|
const CSV_MIME_TYPE = 'text/csv';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fallback regular expression for CSV filenames, if no MIME type is provided
|
||||||
|
* by the browser. Any file that matches this regex will be considered to be a
|
||||||
|
* CSV file.
|
||||||
|
*
|
||||||
|
* @type RegExp
|
||||||
|
*/
|
||||||
|
const CSV_FILENAME_REGEX = /\.csv$/i;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The allowed MIME type for JSON files.
|
* The allowed MIME type for JSON files.
|
||||||
*
|
*
|
||||||
@@ -33,6 +42,15 @@ const CSV_MIME_TYPE = 'text/csv';
|
|||||||
*/
|
*/
|
||||||
const JSON_MIME_TYPE = 'application/json';
|
const JSON_MIME_TYPE = 'application/json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fallback regular expression for JSON filenames, if no MIME type is provided
|
||||||
|
* by the browser. Any file that matches this regex will be considered to be a
|
||||||
|
* JSON file.
|
||||||
|
*
|
||||||
|
* @type RegExp
|
||||||
|
*/
|
||||||
|
const JSON_FILENAME_REGEX = /\.json$/i;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The allowed MIME types for YAML files.
|
* The allowed MIME types for YAML files.
|
||||||
* NOTE: There is no registered MIME type for YAML files. This may result in a
|
* NOTE: There is no registered MIME type for YAML files. This may result in a
|
||||||
@@ -50,6 +68,15 @@ const YAML_MIME_TYPES = [
|
|||||||
'application/yml'
|
'application/yml'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fallback regular expression for YAML filenames, if no MIME type is provided
|
||||||
|
* by the browser. Any file that matches this regex will be considered to be a
|
||||||
|
* YAML file.
|
||||||
|
*
|
||||||
|
* @type RegExp
|
||||||
|
*/
|
||||||
|
const YAML_FILENAME_REGEX = /\.ya?ml$/i;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Possible signatures for zip files (which include most modern Microsoft office
|
* Possible signatures for zip files (which include most modern Microsoft office
|
||||||
* documents - most notable excel). If any file, regardless of extension, has
|
* documents - most notable excel). If any file, regardless of extension, has
|
||||||
@@ -564,12 +591,46 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
|||||||
// There should only ever be a single file in the array
|
// There should only ever be a single file in the array
|
||||||
const file = files[0];
|
const file = files[0];
|
||||||
|
|
||||||
// The MIME type of the provided file
|
// The name and MIME type of the file as provided by the browser
|
||||||
const mimeType = file.type;
|
let fileName = file.name;
|
||||||
|
let mimeType = file.type;
|
||||||
|
|
||||||
|
// If no MIME type was provided by the browser at all, use REGEXes as a
|
||||||
|
// fallback to try to determine the file type. NOTE: Windows 10/11 are
|
||||||
|
// known to do this with YAML files.
|
||||||
|
if (!_.trim(mimeType).length) {
|
||||||
|
|
||||||
|
// If the file name matches what we'd expect for a CSV file, set the
|
||||||
|
// CSV MIME type and move on
|
||||||
|
if (CSV_FILENAME_REGEX.test(fileName))
|
||||||
|
mimeType = CSV_MIME_TYPE;
|
||||||
|
|
||||||
|
// If the file name matches what we'd expect for a JSON file, set
|
||||||
|
// the JSON MIME type and move on
|
||||||
|
else if (JSON_FILENAME_REGEX.test(fileName))
|
||||||
|
mimeType = JSON_MIME_TYPE;
|
||||||
|
|
||||||
|
// If the file name matches what we'd expect for a JSON file, set
|
||||||
|
// one of the allowed YAML MIME types and move on
|
||||||
|
else if (YAML_FILENAME_REGEX.test(fileName))
|
||||||
|
mimeType = YAML_MIME_TYPES[0];
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
// If none of the REGEXes pass, there's nothing more to be tried
|
||||||
|
handleError(new ParseError({
|
||||||
|
message: "Unknown type for file: " + fileName,
|
||||||
|
key: 'IMPORT.ERROR_DETECTED_INVALID_TYPE'
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the mimetype is one of the supported types,
|
// Check if the mimetype is one of the supported types,
|
||||||
// e.g. "application/json" or "text/csv"
|
// e.g. "application/json" or "text/csv"
|
||||||
if (LEGAL_MIME_TYPES.indexOf(mimeType) < 0) {
|
else if (LEGAL_MIME_TYPES.indexOf(mimeType) < 0) {
|
||||||
|
|
||||||
// If the provided file is not one of the supported types,
|
// If the provided file is not one of the supported types,
|
||||||
// display an error and abort processing
|
// display an error and abort processing
|
||||||
@@ -582,7 +643,9 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.fileName = file.name;
|
// Save the name and type to the scope
|
||||||
|
$scope.fileName = fileName;
|
||||||
|
$scope.mimeType = mimeType;
|
||||||
|
|
||||||
// Initialize upload state
|
// Initialize upload state
|
||||||
$scope.aborted = false;
|
$scope.aborted = false;
|
||||||
@@ -590,9 +653,6 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
|||||||
$scope.processing = false;
|
$scope.processing = false;
|
||||||
$scope.uploadStarted = true;
|
$scope.uploadStarted = true;
|
||||||
|
|
||||||
// Save the MIME type to the scope
|
|
||||||
$scope.mimeType = file.type;
|
|
||||||
|
|
||||||
// Save the file to the scope when ready
|
// Save the file to the scope when ready
|
||||||
$scope.fileReader = new FileReader();
|
$scope.fileReader = new FileReader();
|
||||||
$scope.fileReader.onloadend = (e => {
|
$scope.fileReader.onloadend = (e => {
|
||||||
|
@@ -477,9 +477,17 @@ angular.module('import').factory('connectionParseService',
|
|||||||
|
|
||||||
_.forEach(connection.parameters, (value, name) => {
|
_.forEach(connection.parameters, (value, name) => {
|
||||||
|
|
||||||
|
// An explicit null value for a parameter is valid - do not
|
||||||
|
// process it further
|
||||||
|
if (value === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// All non-null connection parameters must be strings.
|
||||||
|
const stringValue = String(value);
|
||||||
|
|
||||||
// Convert the provided value to the format that would match
|
// Convert the provided value to the format that would match
|
||||||
// the lookup object format
|
// the lookup object format
|
||||||
const comparisonValue = value.toLowerCase().trim();
|
const comparisonValue = stringValue.toLowerCase().trim();
|
||||||
|
|
||||||
// The validated / corrected option value for this connection
|
// The validated / corrected option value for this connection
|
||||||
// parameter, if any
|
// parameter, if any
|
||||||
@@ -491,6 +499,22 @@ angular.module('import').factory('connectionParseService',
|
|||||||
if (validOptionValue)
|
if (validOptionValue)
|
||||||
connection.parameters[name] = validOptionValue;
|
connection.parameters[name] = validOptionValue;
|
||||||
|
|
||||||
|
// Even if no option is found, the value must be a string
|
||||||
|
else
|
||||||
|
connection.parameters[name] = stringValue;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
_.forEach(connection.attributes, (value, name) => {
|
||||||
|
|
||||||
|
// An explicit null value for an attribute is valid - do not
|
||||||
|
// process it further
|
||||||
|
if (value === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// All non-null connection attributes must be strings
|
||||||
|
connection.attributes[name] = String(value);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
|
@@ -244,7 +244,7 @@
|
|||||||
"HELP_UPLOAD_DROP_TITLE" : "Drop a File Here",
|
"HELP_UPLOAD_DROP_TITLE" : "Drop a File Here",
|
||||||
"HELP_UPLOAD_FILE_TYPES" : "CSV, JSON, or YAML",
|
"HELP_UPLOAD_FILE_TYPES" : "CSV, JSON, or YAML",
|
||||||
"HELP_YAML_DESCRIPTION" : "A connection import YAML file is a list of connection objects with exactly the same structure as the JSON format.",
|
"HELP_YAML_DESCRIPTION" : "A connection import YAML file is a list of connection objects with exactly the same structure as the JSON format.",
|
||||||
"HELP_YAML_EXAMPLE" : "---\n - name: conn1\n protocol: vnc\n parameters:\n username: alice\n password: pass1\n hostname: conn1.web.com\n group: ROOT\n users:\n - guac user 1\n - guac user 2\n groups:\n - Connection 1 Users\n attributes:\n guacd-encryption: none\n - name: conn2\n protocol: rdp\n parameters:\n username: bob\n password: pass2\n hostname: conn2.web.com\n group: ROOT/Parent Group\n users:\n - guac user 1\n attributes:\n guacd-encryption: none\n - name: conn3\n protocol: ssh\n parameters:\n username: carol\n password: pass3\n hostname: conn3.web.com\n group: ROOT/Parent Group/Child Group\n users:\n - guac user 2\n - guac user 3\n - name: conn4\n protocol: kubernetes",
|
"HELP_YAML_EXAMPLE" : "---\n - name: conn1\n protocol: vnc\n parameters:\n username: alice\n password: pass1\n hostname: conn1.web.com\n group: ROOT\n users:\n - guac user 1\n - guac user 2\n groups:\n - Connection 1 Users\n attributes:\n guacd-encryption: none\n - name: conn2\n protocol: rdp\n parameters:\n username: bob\n password: pass2\n hostname: conn2.web.com\n group: ROOT/Parent Group\n users:\n - guac user 1\n attributes:\n guacd-encryption: none\n - name: conn3\n protocol: ssh\n parameters:\n username: carol\n password: pass3\n hostname: conn3.web.com\n group: ROOT/Parent Group/Child Group\n users:\n - guac user 2\n - guac user 3\n - name: conn4\n protocol: kubernetes",
|
||||||
|
|
||||||
"INFO_CONNECTIONS_IMPORTED_SUCCESS" : "{NUMBER} {NUMBER, plural, one{connection} other{connections}} imported successfully.",
|
"INFO_CONNECTIONS_IMPORTED_SUCCESS" : "{NUMBER} {NUMBER, plural, one{connection} other{connections}} imported successfully.",
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user