mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-926: Fix styling, option semantics, and directory patch endpoint logging/handling.
This commit is contained in:
@@ -635,44 +635,5 @@ angular.module('import').controller('importConnectionsController', ['$scope', '$
|
||||
// Read all the data into memory
|
||||
$scope.fileReader.readAsBinaryString(file);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a modal with the given title and text keys.
|
||||
*
|
||||
* @param {String} titleKey
|
||||
* The translation key to use for the title of the modal.
|
||||
*
|
||||
* @param {String} contentKey
|
||||
* The translation key to use for the text contents of the modal.
|
||||
*/
|
||||
const showModal = (titleKey, contentKey) => guacNotification.showStatus({
|
||||
|
||||
// The provided modal contents
|
||||
title: titleKey,
|
||||
text: { key: contentKey },
|
||||
|
||||
// Add a button to hide the modal
|
||||
actions : [{
|
||||
name : 'IMPORT.ACTION_ACKNOWLEDGE',
|
||||
callback : () => guacNotification.showStatus(false)
|
||||
}]
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Display a modal with information about the existing connection
|
||||
* replacement option.
|
||||
*/
|
||||
$scope.showConnectionReplaceHelp = () => showModal(
|
||||
'IMPORT.HELP_REPLACE_CONNECTION_TITLE',
|
||||
'IMPORT.HELP_REPLACE_CONNECTION_CONTENT');
|
||||
|
||||
/**
|
||||
* Display a modal with information about the existing connection permission
|
||||
* replacement option.
|
||||
*/
|
||||
$scope.showPermissionReplaceHelp = () => showModal(
|
||||
'IMPORT.HELP_REPLACE_PERMISSION_TITLE',
|
||||
'IMPORT.HELP_REPLACE_PERMISSION_CONTENT');
|
||||
|
||||
|
||||
}]);
|
||||
|
@@ -312,7 +312,7 @@ angular.module('import').factory('connectionParseService',
|
||||
throw new ParseError({
|
||||
message: 'Duplicate connection in file: ' + path,
|
||||
key: 'IMPORT.ERROR_DUPLICATE_CONNECTION_IN_FILE',
|
||||
variables: { PATH: path }
|
||||
variables: { NAME: connection.name, PATH: group }
|
||||
});
|
||||
|
||||
// Mark the current path as already seen in the file
|
||||
@@ -326,12 +326,12 @@ angular.module('import').factory('connectionParseService',
|
||||
let identifier;
|
||||
|
||||
// If updates to existing connections are disallowed
|
||||
if (existingIdentifier && importConfig.replaceConnectionMode ===
|
||||
ConnectionImportConfig.ReplaceConnectionMode.REJECT)
|
||||
if (existingIdentifier && importConfig.existingConnectionMode ===
|
||||
ConnectionImportConfig.ExistingConnectionMode.REJECT)
|
||||
throw new ParseError({
|
||||
message: 'Rejecting update to existing connection: ' + path,
|
||||
key: 'IMPORT.ERROR_REJECT_UPDATE_CONNECTION',
|
||||
variables: { PATH: path }
|
||||
variables: { NAME: connection.name, PATH: group }
|
||||
});
|
||||
|
||||
// If the connection is being replaced, set the existing identifer
|
||||
@@ -430,7 +430,7 @@ angular.module('import').factory('connectionParseService',
|
||||
// The connection is being replaced, and permissions are only being
|
||||
// added, not replaced
|
||||
else if (importConfig.existingPermissionMode ===
|
||||
ConnectionImportConfig.ExistingPermissionMode.ADD)
|
||||
ConnectionImportConfig.ExistingPermissionMode.PRESERVE)
|
||||
|
||||
// Add a patch for replacing the connection
|
||||
patches.push(new DirectoryPatch({
|
||||
|
@@ -171,7 +171,7 @@
|
||||
.file-upload-container .import-config .help {
|
||||
|
||||
visibility: hidden;
|
||||
cursor: pointer;
|
||||
cursor: help;
|
||||
|
||||
}
|
||||
|
||||
|
@@ -41,22 +41,22 @@
|
||||
<ul class="import-config">
|
||||
<li>
|
||||
<input type="checkbox"
|
||||
id="replace-connections" ng-model="importConfig.replaceConnectionMode"
|
||||
id="existing-connection-mode" ng-model="importConfig.existingConnectionMode"
|
||||
ng-true-value="'REPLACE'" ng-false-value="'REJECT'" />
|
||||
<label for="replace-connections">
|
||||
{{'IMPORT.FIELD_HEADER_REPLACE_CONNECTIONS' | translate}}
|
||||
<label for="existing-connection-mode">
|
||||
{{'IMPORT.FIELD_HEADER_EXISTING_CONNECTION_MODE' | translate}}
|
||||
</label>
|
||||
<span ng-click="showConnectionReplaceHelp()" class="help"></span>
|
||||
<span ng-attr-title="{{'IMPORT.HELP_EXISTING_CONNECTION_MODE' | translate}}" class="help"></span>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox"
|
||||
id="replace-permissions" ng-model="importConfig.existingPermissionMode"
|
||||
id="existing-permission-mode" ng-model="importConfig.existingPermissionMode"
|
||||
ng-disabled="importConfig.replaceConnectionMode === 'REJECT'"
|
||||
ng-true-value="'REPLACE'" ng-false-value="'ADD'" />
|
||||
<label for="replace-permissions">
|
||||
{{'IMPORT.FIELD_HEADER_REPLACE_PERMISSIONS' | translate}}
|
||||
ng-true-value="'REPLACE'" ng-false-value="'PRESERVE'" />
|
||||
<label for="existing-permission-mode">
|
||||
{{'IMPORT.FIELD_HEADER_EXISTING_PERMISSION_MODE' | translate}}
|
||||
</label>
|
||||
<span ng-click="showPermissionReplaceHelp()" class="help"></span>
|
||||
<span ng-attr-title="{{'IMPORT.HELP_EXISTING_PERMISSION_MODE' | translate}}" class="help"></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@@ -40,10 +40,10 @@ angular.module('import').factory('ConnectionImportConfig', [
|
||||
/**
|
||||
* The mode for handling connections that match existing connections.
|
||||
*
|
||||
* @type ConnectionImportConfig.ReplaceConnectionMode
|
||||
* @type ConnectionImportConfig.ExistingConnectionMode
|
||||
*/
|
||||
this.replaceConnectionMode = template.replaceConnectionMode
|
||||
|| ConnectionImportConfig.ReplaceConnectionMode.REJECT;
|
||||
this.existingConnectionMode = template.existingConnectionMode
|
||||
|| ConnectionImportConfig.ExistingConnectionMode.REJECT;
|
||||
|
||||
/**
|
||||
* The mode for handling permissions on existing connections that are
|
||||
@@ -53,19 +53,19 @@ angular.module('import').factory('ConnectionImportConfig', [
|
||||
* @type ConnectionImportConfig.ExistingPermissionMode
|
||||
*/
|
||||
this.existingPermissionMode = template.existingPermissionMode
|
||||
|| ConnectionImportConfig.ExistingPermissionMode.ADD;
|
||||
|| ConnectionImportConfig.ExistingPermissionMode.PRESERVE;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Valid modes for the behavior of the importer when attempts are made to
|
||||
* update existing connections.
|
||||
* Valid modes for the behavior of the importer when an imported connection
|
||||
* already exists.
|
||||
*/
|
||||
ConnectionImportConfig.ReplaceConnectionMode = {
|
||||
ConnectionImportConfig.ExistingConnectionMode = {
|
||||
|
||||
/**
|
||||
* Any attempt to update existing connections will cause the entire
|
||||
* import to be rejected with an error.
|
||||
* Any Connection that has the same name and parent group as an existing
|
||||
* connection will cause the entire import to be rejected with an error.
|
||||
*/
|
||||
REJECT : "REJECT",
|
||||
|
||||
@@ -87,7 +87,7 @@ angular.module('import').factory('ConnectionImportConfig', [
|
||||
* added to the existing connection, without removing any existing
|
||||
* permissions.
|
||||
*/
|
||||
ADD : "ADD",
|
||||
PRESERVE : "PRESERVE",
|
||||
|
||||
/**
|
||||
* Any existing permissions will be removed, ensuring that only the
|
||||
|
@@ -80,7 +80,7 @@ angular.module('import').factory('ParseResult', [function defineParseResult() {
|
||||
/**
|
||||
* An array of errors encountered while parsing the corresponding
|
||||
* connection (at the same array index in the patches array). Each
|
||||
* connection should have a an array of errors. If empty, no errors
|
||||
* connection should have an array of errors. If empty, no errors
|
||||
* occurred for this connection.
|
||||
*
|
||||
* @type {ParseError[][]}
|
||||
|
@@ -1,64 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="svg10"
|
||||
sodipodi:docname="question.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs14" />
|
||||
<sodipodi:namedview
|
||||
id="namedview12"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="38.5625"
|
||||
inkscape:cy="31.0625"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1025"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g8" />
|
||||
<g
|
||||
style="stroke-width:1.04766"
|
||||
id="g8">
|
||||
<g
|
||||
style="font-style:normal;font-weight:400;font-size:142.558px;line-height:100%;font-family:Sans;letter-spacing:0;word-spacing:0;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3.20748px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="g6">
|
||||
<path
|
||||
d="m 169.301,354.693 c -60.57527,-41.3594 -30.28763,-20.6797 0,0 z m -0.627,90.839 c -60.15727,-101.91873 -30.07863,-50.95937 0,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:142.558px;line-height:100%;font-family:Roboto;-inkscape-font-specification:'Roboto Heavy';text-align:center;text-anchor:middle;fill:#000000;stroke-width:3.20748px"
|
||||
transform="matrix(0.3118,0,0,0.31173,-24.457,-91.229)"
|
||||
aria-label="!"
|
||||
id="path4"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
<path
|
||||
id="path2540"
|
||||
style="fill:#000000"
|
||||
d="M 32,0.75 A 31.25,31.25 0 0 0 0.75,32 31.25,31.25 0 0 0 32,63.25 31.25,31.25 0 0 0 63.25,32 31.25,31.25 0 0 0 32,0.75 Z m 0,5 A 26.25,26.25 0 0 1 58.25,32 26.25,26.25 0 0 1 32,58.25 26.25,26.25 0 0 1 5.75,32 26.25,26.25 0 0 1 32,5.75 Z" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="17.083984"
|
||||
y="52.78125"
|
||||
id="text4900"><tspan
|
||||
id="tspan4898"
|
||||
x="17.083984"
|
||||
y="52.78125"
|
||||
sodipodi:role="line"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:56px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">?</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><g style="stroke-width:1.04766"><g style="font-style:normal;font-weight:400;font-size:142.558px;line-height:100%;font-family:Sans;letter-spacing:0;word-spacing:0;fill:#000;fill-opacity:1;stroke:none;stroke-width:3.20748px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><path d="M169.301 354.693c-60.575-41.36-30.288-20.68 0 0zm-.627 90.839c-60.157-101.919-30.079-50.96 0 0z" aria-label="!" style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:142.558px;line-height:100%;font-family:Roboto;-inkscape-font-specification:"Roboto Heavy";text-align:center;text-anchor:middle;fill:#000;stroke-width:3.20748px" transform="matrix(.3118 0 0 .31173 -24.457 -91.229)"/></g><path d="M32 .75A31.25 31.25 0 0 0 .75 32 31.25 31.25 0 0 0 32 63.25 31.25 31.25 0 0 0 63.25 32 31.25 31.25 0 0 0 32 .75Zm0 5A26.25 26.25 0 0 1 58.25 32 26.25 26.25 0 0 1 32 58.25 26.25 26.25 0 0 1 5.75 32 26.25 26.25 0 0 1 32 5.75Z" style="fill:#000"/><g style="font-size:40px;line-height:1.25"><path d="M27.775 45.836h5.551v6.945h-5.55zm5.387-4.02H27.94v-4.21q0-2.762.766-4.54.766-1.777 3.227-4.129l2.46-2.433q1.56-1.45 2.243-2.734.71-1.286.71-2.625 0-2.434-1.804-3.938-1.777-1.504-4.73-1.504-2.16 0-4.622.957-2.433.957-5.085 2.79v-5.141q2.57-1.559 5.195-2.325 2.652-.765 5.469-.765 5.03 0 8.066 2.652 3.062 2.652 3.062 7 0 2.078-.984 3.965-.984 1.86-3.445 4.21l-2.406 2.352q-1.286 1.286-1.832 2.024-.52.71-.739 1.394-.164.575-.246 1.395-.082.82-.082 2.242z" aria-label="?" style="font-size:56px;-inkscape-font-specification:"sans-serif, Normal""/></g></g></svg>
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -204,7 +204,7 @@
|
||||
"ERROR_AMBIGUOUS_PARENT_GROUP" : "Both group and parentIdentifier may be not specified at the same time",
|
||||
"ERROR_ARRAY_REQUIRED" : "The provided file must contain a list of connections",
|
||||
"ERROR_DETECTED_INVALID_TYPE" : "Unsupported file type. Please make sure the file is valid CSV, JSON, or YAML.",
|
||||
"ERROR_DUPLICATE_CONNECTION_IN_FILE" : "Duplicate connection in file at \"{PATH}\"",
|
||||
"ERROR_DUPLICATE_CONNECTION_IN_FILE" : "Duplicated connection \"{NAME}\" at \"{PATH}\" in import file",
|
||||
"ERROR_DUPLICATE_CSV_HEADER" : "Duplicate CSV Header: {HEADER}",
|
||||
"ERROR_EMPTY_FILE" : "The provided file is empty",
|
||||
"ERROR_INVALID_CSV_HEADER" : "Invalid CSV Header \"{HEADER}\" is neither an attribute or parameter",
|
||||
@@ -215,31 +215,25 @@
|
||||
"ERROR_PARSE_FAILURE_CSV" : "Please make sure your file is valid CSV. Parsing failed with error \"{ERROR}\". ",
|
||||
"ERROR_PARSE_FAILURE_JSON" : "Please make sure your file is valid JSON. Parsing failed with error \"{ERROR}\". ",
|
||||
"ERROR_PARSE_FAILURE_YAML" : "Please make sure your file is valid YAML. Parsing failed with error \"{ERROR}\". ",
|
||||
"ERROR_REJECT_UPDATE_CONNECTION" : "Disallowed update to existing connection at \"{PATH}\"",
|
||||
"ERROR_REJECT_UPDATE_CONNECTION" : "Connection \"{NAME}\" already exists at \"{PATH}\"",
|
||||
"ERROR_REQUIRED_NAME" : "No connection name found in the provided file",
|
||||
"ERROR_REQUIRED_PROTOCOL" : "No connection protocol found in the provided file",
|
||||
|
||||
"FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER",
|
||||
|
||||
"FIELD_HEADER_REPLACE_CONNECTIONS" : "Replace/Update existing connections",
|
||||
"FIELD_HEADER_REPLACE_PERMISSIONS" : "Reset permissions",
|
||||
|
||||
"FIELD_OPTION_DUPLICATE_REPLACE" : "Replace duplicates",
|
||||
"FIELD_OPTION_DUPLICATE_IGNORE" : "Ignore duplicates",
|
||||
"FIELD_OPTION_DUPLICATE_ERROR" : "Disallow duplicates",
|
||||
"FIELD_HEADER_EXISTING_CONNECTION_MODE" : "Replace/Update existing connections",
|
||||
"FIELD_HEADER_EXISTING_PERMISSION_MODE" : "Reset permissions",
|
||||
|
||||
"HELP_CSV_DESCRIPTION" : "A connection import CSV file has one connection record per row. Each column will specify a connection field. At minimum the connection name and protocol must be specified.",
|
||||
"HELP_CSV_EXAMPLE" : "name,protocol,hostname,group,users,groups,guacd-encryption (attribute)\nconn1,vnc,conn1.web.com,ROOT,guac user 1;guac user 2,Connection 1 Users,none\nconn2,rdp,conn2.web.com,ROOT/Parent Group,guac user 1,,ssl\nconn3,ssh,conn3.web.com,ROOT/Parent Group/Child Group,guac user 2;guac user 3,,\nconn4,kubernetes,,,,,",
|
||||
"HELP_CSV_MORE_DETAILS" : "The CSV header for each row specifies the connection field. The connection group ID that the connection should be imported into may be directly specified with \"parentIdentifier\", or the path to the parent group may be specified using \"group\" as shown below. In most cases, there should be no conflict between fields, but if needed, an \" (attribute)\" or \" (parameter)\" suffix may be added to disambiguate. Lists of user or user group identifiers must be semicolon-separated.¹",
|
||||
"HELP_FILE_TYPE_DESCRIPTION" : "Three file types are supported for connection import: CSV, JSON, and YAML. The same data may be specified by each file type. This must include the connection name and protocol. Optionally, a connection group location, a list of users and/or user groups to grant access, connection parameters, or connection protocols may also be specified. Any users or user groups that do not exist in the current data source will be automatically created. Note that any existing connection permissions will not be removed for updated connections.",
|
||||
"HELP_FILE_TYPE_DESCRIPTION" : "Three file types are supported for connection import: CSV, JSON, and YAML. The same data may be specified by each file type. This must include the connection name and protocol. Optionally, a connection group location, a list of users and/or user groups to grant access, connection parameters, or connection protocols may also be specified. Any users or user groups that do not exist in the current data source will be automatically created. Note that any existing connection permissions will not be removed for updated connections, unless \"Reset permissions\" is checked.",
|
||||
"HELP_FILE_TYPE_HEADER" : "File Types",
|
||||
"HELP_JSON_DESCRIPTION" : "A connection import JSON file is a list of connection objects. At minimum the connection name and protocol must be specified in each connection object.",
|
||||
"HELP_JSON_EXAMPLE" : "[\n \\{\n \"name\": \"conn1\",\n \"protocol\": \"vnc\",\n \"parameters\": \\{ \"hostname\": \"conn1.web.com\" \\},\n \"parentIdentifier\": \"ROOT\",\n \"users\": [ \"guac user 1\", \"guac user 2\" ],\n \"groups\": [ \"Connection 1 Users\" ],\n \"attributes\": \\{ \"guacd-encryption\": \"none\" \\}\n \\},\n \\{\n \"name\": \"conn2\",\n \"protocol\": \"rdp\",\n \"parameters\": \\{ \"hostname\": \"conn2.web.com\" \\},\n \"group\": \"ROOT/Parent Group\",\n \"users\": [ \"guac user 1\" ],\n \"attributes\": \\{ \"guacd-encryption\": \"none\" \\}\n \\},\n \\{\n \"name\": \"conn3\",\n \"protocol\": \"ssh\",\n \"parameters\": \\{ \"hostname\": \"conn3.web.com\" \\},\n \"group\": \"ROOT/Parent Group/Child Group\",\n \"users\": [ \"guac user 2\", \"guac user 3\" ]\n \\},\n \\{\n \"name\": \"conn4\",\n \"protocol\": \"kubernetes\"\n \\}\n]",
|
||||
"HELP_JSON_MORE_DETAILS" : "The connection group ID that the connection should be imported into may be directly specified with a \"parentIdentifier\" field, or the path to the parent group may be specified using a \"group\" field as shown below. An array of user and user group identifiers to grant access to may be specified per connection.",
|
||||
"HELP_REPLACE_CONNECTION_TITLE" : "Replacing existing connections",
|
||||
"HELP_REPLACE_CONNECTION_CONTENT" : "Checking this box will allow existing connections to be updated, if an imported connection has the same name and parent group as an existing connection. If unchecked, attempts to update existing connections will be treated as an error.",
|
||||
"HELP_REPLACE_PERMISSION_TITLE" : "Replacing connection permissions",
|
||||
"HELP_REPLACE_PERMISSION_CONTENT" : "If replacement of existing connections is enabled, checking this box will allow full replacement of connection permissions. If checked, access permission will only be granted to users and groups specified in the import file for this connection. If unchecked, specified users and groups will be granted access in addition to any existing permissions.",
|
||||
"HELP_EXISTING_CONNECTION_MODE" : "Entirely replace/update existing connections if their names and parent connection groups match the values in the provided file. If unchecked, attempting to import a connection with the same name and parent connection group of an existing connection will be considered an error.",
|
||||
"HELP_EXISTING_PERMISSION_MODE" : "Fully reset the permissions granted for all connections in the provided file to the permissions specified in that file. If no permissions are specified, all relevant connection permissions will be revoked. If unchecked, existing permissions are preserved, and any permissions specified in the file will be added.",
|
||||
"HELP_SEMICOLON_FOOTNOTE" : "If present, semicolons can be escaped with a backslash, e.g. \"first\\\\;last\"",
|
||||
"HELP_UPLOAD_DROP_TITLE" : "Drop a File Here",
|
||||
"HELP_UPLOAD_FILE_TYPES" : "CSV, JSON, or YAML",
|
||||
|
@@ -421,6 +421,45 @@ public abstract class DirectoryResource<InternalType extends Identifiable, Exter
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and return the object having the given identifier from the
|
||||
* directory, throwing a GuacamoleResourceNotFoundException and firing a
|
||||
* directory GET failure event if no object exists with the given identifier
|
||||
* in the directory.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to retrieve from the directory.
|
||||
*
|
||||
* @return
|
||||
* The object from the directory with the provided identifier.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If no object with the provided identifier exists within the
|
||||
* directory, or if any other error occurs while attempting to retrieve
|
||||
* the object.
|
||||
*/
|
||||
@Nonnull
|
||||
private InternalType getObjectByIdentifier(String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Retrieve the object having the given identifier
|
||||
InternalType object;
|
||||
try {
|
||||
object = directory.get(identifier);
|
||||
if (object == null)
|
||||
throw new GuacamoleResourceNotFoundException(
|
||||
"Not found: \"" + identifier + "\"");
|
||||
}
|
||||
catch (GuacamoleException | RuntimeException | Error e) {
|
||||
fireDirectoryFailureEvent(
|
||||
DirectoryEvent.Operation.GET, identifier, null, e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Return the object; it is guaranteed to be non-null at this point
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the provided throwable is a known Guacamole-specific type, create and
|
||||
* return a APIPatchError with an error message extracted from the error.
|
||||
@@ -600,8 +639,10 @@ public abstract class DirectoryResource<InternalType extends Identifiable, Exter
|
||||
|
||||
try {
|
||||
|
||||
// Fetch the object to be updated
|
||||
original = directory.get(identifier);
|
||||
// Fetch the object to be updated. If no object is
|
||||
// found, a directory GET failure event will be
|
||||
// logged, and the update attempt will be aborted.
|
||||
original = getObjectByIdentifier(identifier);
|
||||
|
||||
// Apply the changes to the original object
|
||||
translator.applyExternalChanges(
|
||||
@@ -805,17 +846,10 @@ public abstract class DirectoryResource<InternalType extends Identifiable, Exter
|
||||
getObjectResource(@PathParam("identifier") String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Retrieve the object having the given identifier
|
||||
InternalType object;
|
||||
try {
|
||||
object = directory.get(identifier);
|
||||
if (object == null)
|
||||
throw new GuacamoleResourceNotFoundException("Not found: \"" + identifier + "\"");
|
||||
}
|
||||
catch (GuacamoleException | RuntimeException | Error e) {
|
||||
fireDirectoryFailureEvent(DirectoryEvent.Operation.GET, identifier, null, e);
|
||||
throw e;
|
||||
}
|
||||
// Fetch the object to be updated. If no object is found, a directory
|
||||
// GET failure event will be logged. If no exception is thrown, the
|
||||
// object is guaranteed to exist
|
||||
InternalType object = getObjectByIdentifier(identifier);
|
||||
|
||||
// Return a resource which provides access to the retrieved object
|
||||
DirectoryObjectResource<InternalType, ExternalType> resource = resourceFactory.create(authenticatedUser, userContext, directory, object);
|
||||
|
Reference in New Issue
Block a user