/* * Copyright (C) 2013 Glyptodon LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /** * Main Guacamole web service namespace. * @namespace */ var GuacamoleService = GuacamoleService || {}; /** * An arbitary Guacamole connection group, having the given type, ID and name. * * @constructor * @param {Number} type The type of this connection group - either ORGANIZATIONAL * or BALANCING. * @param {String} id An arbitrary ID, likely assigned by the auth provider. * @param {String} name The human-readable name of this group. */ GuacamoleService.ConnectionGroup = function(type, id, name) { /** * The type of this connection group. * @type Number */ this.type = type; /** * The unique ID of this connection group. * @type String */ this.id = id; /** * The human-readable name associated with this connection group. * @type String */ this.name = name; /** * The parent connection group of this group. If this group is the root * group, this will be null. * * @type GuacamoleService.ConnectionGroup */ this.parent = null; /** * All connection groups contained within this group. * @type GuacamoleService.ConnectionGroup[] */ this.groups = []; /** * All connections contained within this group. * @type GuacamoleService.Connection[] */ this.connections = []; }; /** * Set of all possible types for ConnectionGroups. */ GuacamoleService.ConnectionGroup.Type = { /** * Organizational groups exist solely to hold connections or other groups, * and provide no other semantics. * * @type Number */ "ORGANIZATIONAL" : 0, /** * Balancing groups act as connections. Users that have READ permission on * balancing groups can use the group as if it were a connection, and that * group will choose an appropriate connection within itself for that user * to use. * * @type Number */ "BALANCING" : 1 }; /** * An arbitrary Guacamole connection, consisting of an ID/protocol pair. * * @constructor * @param {String} protocol The protocol used by this connection. * @param {String} id The ID associated with this connection. * @param {String} name The human-readable name associated with this connection. */ GuacamoleService.Connection = function(protocol, id, name) { /** * Reference to this connection. */ var guac_connection = this; /** * The parent connection group of this connection. * @type GuacamoleService.ConnectionGroup */ this.parent = null; /** * The protocol associated with this connection. */ this.protocol = protocol; /** * The ID associated with this connection. */ this.id = id; /** * All parameters associated with this connection, if available. */ this.parameters = {}; /** * The name of this connection. This name is arbitrary and local to the * group containing the connection. * * @type String */ this.name = name; /** * An array of GuacamoleService.Connection.Record listing the usage * history of this connection. */ this.history = []; /** * Returns the number of active users of this connection (which may be * multiple instances under the same user) by walking the history records. * * @return {Number} The number of active users of this connection. */ this.currentUsage = function() { // Number of users of this connection var usage = 0; // Walk history counting active entries for (var i=0; i} * An object mapping the names of all available protocols to * their corresponding details. */ "list" : function() { // Construct request URL var list_url = "api/protocol" + "?token=" + GuacamoleService.Auth.current().authToken; // Get permission list var xhr = new XMLHttpRequest(); xhr.open("GET", list_url, false); xhr.send(null); // Handle response GuacamoleService.handleResponse(xhr); return JSON.parse(xhr.responseText); } }; /** * Collection of service functions which deal with the clipboard state. Each * function makes an explicit HTTP query to the server, and parses the response. */ GuacamoleService.Clipboard = { "get" : function() { // Construct request URL var list_url = "api/clipboard" + "?token=" + GuacamoleService.Auth.current().authToken; // Get permission list var xhr = new XMLHttpRequest(); xhr.open("GET", list_url, false); xhr.send(null); // Handle response GuacamoleService.handleResponse(xhr); return xhr.responseText; } }; /** * Collection of service functions which deal with the session keep-alive. Each * function makes an explicit HTTP query to the server. In the case of the * keep-alive ping, no response is expected, and any received response is * ignored. */ GuacamoleService.KeepAlive = { "ping" : function() { // Construct request URL var ping_url = "api/keep-alive" + "?token=" + GuacamoleService.Auth.current().authToken; // Send keep-alive "ping" var xhr = new XMLHttpRequest(); xhr.open("GET", ping_url, true); xhr.send(null); } }; /** * Collection of service functions which deal with authentication. Note that, * unlike everything else here, not all functions in GuacamoleService.Auth * make explicit HTTP queries. */ GuacamoleService.Auth = { /** * Attempts to login the given user using the given password, throwing an * error if the process fails. The resulting token, if successful, is * automatically stored locally within a cookie called "GUAC_TOKEN". This * token can be later retrieved via GuacamoleService.current().authToken. * * @param {String} username The name of the user to login as. * @param {String} password The password to use to authenticate the user. */ "login" : function(username, password) { // Populate data with username and password var data = "username=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password) // Include query parameters in submission data if (GuacamoleRootUI.parameters) data += "&" + GuacamoleRootUI.parameters; // Log in var xhr = new XMLHttpRequest(); xhr.open("POST", "api/login", false); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.send(data); // Handle failures if (xhr.status !== 200) throw new Error("Invalid login"); // Store auth token in cookie var response = JSON.parse(xhr.responseText); document.cookie = "GUAC_AUTH=" + encodeURIComponent(JSON.stringify(response)); }, /** * Returns the current auth result received via login. This result will * contain, among other things, the authToken. * * @returns {Object} The result of the most recent login, if any. If no such * result exists, an empty object is returned. */ "current" : function() { var guacAuth = document.cookie.replace(/(?:(?:^|.*;\s*)GUAC_AUTH\s*\=\s*([^;]*).*$)|^.*$/, "$1"); if (!guacAuth) return {}; return JSON.parse(decodeURIComponent(guacAuth)); } };