Skip to content

Commit

Permalink
Merge 1.5.0 changes back to master.
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-jumper committed Jan 11, 2023
2 parents 9f176ed + 28ae0a9 commit 0614861
Show file tree
Hide file tree
Showing 17 changed files with 585 additions and 10 deletions.
49 changes: 49 additions & 0 deletions guacamole-common-js/src/main/webapp/modules/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,21 @@ Guacamole.Client = function(tunnel) {
* A status object which describes the error.
*/
this.onerror = null;

/**
* Fired when an arbitrary message is received from the tunnel that should
* be processed by the client.
*
* @event
* @param {!number} msgcode
* A status code sent by the remote server that indicates the nature of
* the message that is being sent to the client.
*
* @param {string[]} args
* An array of arguments to be processed with the message sent to the
* client.
*/
this.onmsg = null;

/**
* Fired when a audio stream is created. The stream provided to this event
Expand Down Expand Up @@ -1427,6 +1442,12 @@ Guacamole.Client = function(tunnel) {
}

},

"msg" : function(parameters) {

if (guac_client.onmsg) guac_client.onmsg(parseInt(parameters[0]), parameters.slice(1));

},

"name": function(parameters) {
if (guac_client.onname) guac_client.onname(parameters[0]);
Expand Down Expand Up @@ -1954,3 +1975,31 @@ Guacamole.Client.DefaultTransferFunction = {
}

};

/**
* A list of possible messages that can be sent by the server for processing
* by the client.
*
* @type {!Object.<string, number>}
*/
Guacamole.Client.Message = {

/**
* A client message that indicates that a user has joined an existing
* connection. This message expects a single additional argument - the
* name of the user who has joined the connection.
*
* @type {!number}
*/
"USER_JOINED": 0x0001,

/**
* A client message that indicates that a user has left an existing
* connection. This message expects a single additional argument - the
* name of the user who has left the connection.
*
* @type {!number}
*/
"USER_LEFT": 0x0002

};
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,14 @@ public ConfiguredGuacamoleSocket(GuacamoleSocket socket,
if (GuacamoleProtocolCapability.TIMEZONE_HANDSHAKE.isSupported(protocolVersion)) {
String timezone = info.getTimezone();
if (timezone != null)
writer.writeInstruction(new GuacamoleInstruction("timezone", info.getTimezone()));
writer.writeInstruction(new GuacamoleInstruction("timezone", timezone));
}

// Send client name, if supported and available
if (GuacamoleProtocolCapability.NAME_HANDSHAKE.isSupported(protocolVersion)) {
String name = info.getName();
if (name != null)
writer.writeInstruction(new GuacamoleInstruction("name", name));
}

// Send args
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,22 @@ public class GuacamoleClientInformation {
/**
* The list of audio mimetypes reported by the client to be supported.
*/
private final List<String> audioMimetypes = new ArrayList<String>();
private final List<String> audioMimetypes = new ArrayList<>();

/**
* The list of video mimetypes reported by the client to be supported.
*/
private final List<String> videoMimetypes = new ArrayList<String>();
private final List<String> videoMimetypes = new ArrayList<>();

/**
* The list of image mimetypes reported by the client to be supported.
*/
private final List<String> imageMimetypes = new ArrayList<String>();
private final List<String> imageMimetypes = new ArrayList<>();

/**
* The name of the user reported by the client.
*/
private String name;

/**
* The timezone reported by the client.
Expand Down Expand Up @@ -150,6 +155,17 @@ public List<String> getImageMimetypes() {
return imageMimetypes;
}

/**
* Returns the name of the Guacamole user as reported by the client, or null
* if the user name is not set.
*
* @return
* A string value of the human-readable name reported by the client.
*/
public String getName() {
return name;
}

/**
* Return the timezone as reported by the client, or null if the timezone
* is not set. Valid timezones are specified in IANA zone key format,
Expand All @@ -162,6 +178,16 @@ public String getTimezone() {
return timezone;
}

/**
* Set the human-readable name of the user associated with this client.
*
* @param name
* The human-readable name of the user associated with this client.
*/
public void setName(String name) {
this.name = name;
}

/**
* Set the string value of the timezone, or null if the timezone will not
* be provided by the client. Valid timezones are specified in IANA zone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ public enum GuacamoleProtocolCapability {
*/
ARBITRARY_HANDSHAKE_ORDER(GuacamoleProtocolVersion.VERSION_1_1_0),

/**
* Support for the "msg" instruction. The "msg" instruction allows the
* server to send messages to the client. Support for this instruction was
* introduced in {@link GuacamoleProtocolVersion#VERSION_1_5_0}.
*/
MSG_INSTRUCTION(GuacamoleProtocolVersion.VERSION_1_5_0),

/**
* Support for the "name" handshake instruction, allowing clients to send
* the name of the Guacamole user to be passed to guacd and associated with
* connections. Support for this instruction was introduced in
* {@link GuacamoleProtocolVersion#VERSION_1_5_0}.
*/
NAME_HANDSHAKE(GuacamoleProtocolVersion.VERSION_1_5_0),

/**
* Negotiation of Guacamole protocol version between client and server
* during the protocol handshake. The ability to negotiate protocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,20 @@ public class GuacamoleProtocolVersion {
*/
public static final GuacamoleProtocolVersion VERSION_1_3_0 = new GuacamoleProtocolVersion(1, 3, 0);

/**
* Protocol version 1.5.0, which introduces the "msg" instruction, allowing
* the server to send message notifications that will be displayed on the
* client. The version also adds support for the "name" handshake
* instruction, allowing guacd to store the name of the user who is
* accessing the connection.
*/
public static final GuacamoleProtocolVersion VERSION_1_5_0 = new GuacamoleProtocolVersion(1, 5, 0);

/**
* The most recent version of the Guacamole protocol at the time this
* version of GuacamoleProtocolVersion was built.
*/
public static final GuacamoleProtocolVersion LATEST = VERSION_1_3_0;
public static final GuacamoleProtocolVersion LATEST = VERSION_1_5_0;

/**
* A regular expression that matches the VERSION_X_Y_Z pattern, where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,24 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
ManagedClient.uploadFile($scope.filesystemMenuContents.client, files[i], $scope.filesystemMenuContents);

};

/**
* Determines whether the attached client group has any associated client
* messages to display.
*
* @returns {Boolean}
* true if there are messages to display; otherwise false.
*/
$scope.hasMessages = function hasMessages() {

// No client group means no messages
if (!$scope.clientGroup)
return false;

// Otherwise, find messages within the clients in the group.
return _.findIndex($scope.clientGroup.clients, ManagedClient.hasMessages) !== -1;

};

/**
* Determines whether the attached client group has any associated file
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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.
*/

/**
* Directive which displays a message for the client.
*/
angular.module('client').directive('guacClientMessage', [function guacClientMessage() {

return {
restrict: 'E',
replace: true,
scope: {

/**
* The message to display to the client.
*
* @type {!ManagedClientMessage}
*/
message : '='

},

templateUrl: 'app/client/templates/guacClientMessage.html',

controller: ['$scope', '$injector', '$element',
function guacClientMessageController($scope, $injector, $element) {

// Required types
const ManagedClientMessage = $injector.get('ManagedClientMessage');

// Required services
var translationStringService = $injector.get('translationStringService');

/**
* Uses the msgcode to retrieve the correct translation key for
* the client message.
*
* @returns {string}
*/
$scope.getMessageKey = function getMessageKey() {

let msgString = "DEFAULT";
if (Object.values(Guacamole.Client.Message).includes($scope.message.msgcode))
msgString = Object.keys(Guacamole.Client.Message).find(key => Guacamole.Client.Message[key] === $scope.message.msgcode);

return "CLIENT.MESSAGE_" + translationStringService.canonicalize(msgString);
};

/**
* Returns a set of key/value object pairs that represent the
* arguments provided as part of the message in the form
* "ARGS_0 = value". Guacamole's translation system relies on
* the arguments being available in this format in order to be able
* to handle substituting values for an arbitrary list of arguments.
*
* @returns {Object}
*/
$scope.getMessageArgs = function getMessageArgs() {
return $scope.message.args.reduce(
function(acc, value, index) {
acc[`ARGS_${index}`] = value;
return acc;
},
{}
);
};

}]

};
}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.
*/

/**
* Directive which displays all client messages.
*/
angular.module('client').directive('guacMessageDialog', [function guacMessageDialog() {

return {
restrict: 'E',
replace: true,
scope: {

/**
* The client group whose messages should be managed by this
* directive.
*
* @type ManagedClientGroup
*/
clientGroup : '='

},

templateUrl: 'app/client/templates/guacMessageDialog.html',
controller: ['$scope', '$injector', function guacMessageDialogController($scope, $injector) {

// Required types
const ManagedClient = $injector.get('ManagedClient');
const ManagedClientGroup = $injector.get('ManagedClientGroup');

/**
* Removes all messages.
*/
$scope.clearAllMessages = function clearAllMessages() {

// Nothing to clear if no client group attached
if (!$scope.clientGroup)
return;

// Remove each client's messages
$scope.clientGroup.clients.forEach(client => {
client.messages = [];
});

};

/**
* @borrows ManagedClientGroup.hasMultipleClients
*/
$scope.hasMultipleClients = ManagedClientGroup.hasMultipleClients;

/**
* @borrows ManagedClient.hasMessages
*/
$scope.hasMessages = ManagedClient.hasMessages;

}]

};
}]);
Loading

0 comments on commit 0614861

Please sign in to comment.