mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-932: Add support for recursive query (and break JS).
This commit is contained in:
@@ -24,7 +24,6 @@ package org.glyptodon.guacamole.net.basic.rest;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.glyptodon.guacamole.net.basic.rest.connection.ConnectionService;
|
||||
import org.glyptodon.guacamole.net.basic.rest.connectiongroup.ConnectionGroupService;
|
||||
import org.glyptodon.guacamole.net.basic.rest.protocol.ProtocolRetrievalService;
|
||||
|
||||
/**
|
||||
@@ -40,7 +39,6 @@ public class RESTModule extends AbstractModule {
|
||||
|
||||
// Bind generic low-level services
|
||||
bind(ConnectionService.class);
|
||||
bind(ConnectionGroupService.class);
|
||||
bind(ProtocolRetrievalService.class);
|
||||
|
||||
}
|
||||
|
@@ -22,9 +22,11 @@
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.rest.connectiongroup;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup.Type;
|
||||
import org.glyptodon.guacamole.net.basic.rest.connection.APIConnection;
|
||||
|
||||
/**
|
||||
* A simple connection group to expose through the REST endpoints.
|
||||
@@ -58,6 +60,18 @@ public class APIConnectionGroup {
|
||||
* The type of this connection group.
|
||||
*/
|
||||
private Type type;
|
||||
|
||||
/**
|
||||
* All child connection groups. If children are not being queried, this may
|
||||
* be omitted.
|
||||
*/
|
||||
private Collection<APIConnectionGroup> childConnectionGroups;
|
||||
|
||||
/**
|
||||
* All child connections. If children are not being queried, this may be
|
||||
* omitted.
|
||||
*/
|
||||
private Collection<APIConnection> childConnections;
|
||||
|
||||
/**
|
||||
* Create an empty APIConnectionGroup.
|
||||
@@ -148,4 +162,52 @@ public class APIConnectionGroup {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of all child connection groups, or null if children
|
||||
* have not been queried.
|
||||
*
|
||||
* @return
|
||||
* A collection of all child connection groups, or null if children
|
||||
* have not been queried.
|
||||
*/
|
||||
public Collection<APIConnectionGroup> getChildConnectionGroups() {
|
||||
return childConnectionGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collection of all child connection groups to the given
|
||||
* collection, which may be null if children have not been queried.
|
||||
*
|
||||
* @param childConnectionGroups
|
||||
* The collection containing all child connection groups of this
|
||||
* connection group, or null if children have not been queried.
|
||||
*/
|
||||
public void setChildConnectionGroups(Collection<APIConnectionGroup> childConnectionGroups) {
|
||||
this.childConnectionGroups = childConnectionGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of all child connections, or null if children have
|
||||
* not been queried.
|
||||
*
|
||||
* @return
|
||||
* A collection of all child connections, or null if children have not
|
||||
* been queried.
|
||||
*/
|
||||
public Collection<APIConnection> getChildConnections() {
|
||||
return childConnections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collection of all child connections to the given collection,
|
||||
* which may be null if children have not been queried.
|
||||
*
|
||||
* @param childConnections
|
||||
* The collection containing all child connections of this connection
|
||||
* group, or null if children have not been queried.
|
||||
*/
|
||||
public void setChildConnections(Collection<APIConnection> childConnections) {
|
||||
this.childConnections = childConnections;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -23,7 +23,8 @@
|
||||
package org.glyptodon.guacamole.net.basic.rest.connectiongroup;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
@@ -37,12 +38,15 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure;
|
||||
import org.glyptodon.guacamole.net.basic.rest.HTTPException;
|
||||
import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService;
|
||||
import org.glyptodon.guacamole.net.basic.rest.connection.APIConnection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -68,55 +72,101 @@ public class ConnectionGroupRESTService {
|
||||
private AuthenticationService authenticationService;
|
||||
|
||||
/**
|
||||
* A service for managing the REST endpoint APIConnection objects.
|
||||
* Retrieves the given connection group from the user context, including
|
||||
* all descendant connections and groups if requested.
|
||||
*
|
||||
* @param userContext
|
||||
* The user context from which to retrieve the connection group.
|
||||
*
|
||||
* @param identifier
|
||||
* The unique identifier of the connection group to retrieve.
|
||||
*
|
||||
* @param includeDescendants
|
||||
* Whether the descendant connections and groups of the given
|
||||
* connection group should also be retrieved.
|
||||
*
|
||||
* @return
|
||||
* The requested connection group, or null if no such connection group
|
||||
* exists.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the requested connection group
|
||||
* or any of its descendants.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* The ID that will be guaranteed to refer to the root connection group.
|
||||
*/
|
||||
private static final String ROOT_CONNECTION_GROUP_ID = "ROOT";
|
||||
|
||||
/**
|
||||
* Gets a list of connection groups with the given ConnectionGroup parentID.
|
||||
* If no parentID is provided, returns the connection groups from the root group.
|
||||
*
|
||||
* @param authToken The authentication token that is used to authenticate
|
||||
* the user performing the operation.
|
||||
* @param parentID The ID of the ConnectionGroup the connection groups
|
||||
* belong to. If null, the root connection group will be used.
|
||||
* @return The connection list.
|
||||
* @throws GuacamoleException If a problem is encountered while listing connection groups.
|
||||
*/
|
||||
@GET
|
||||
@AuthProviderRESTExposure
|
||||
public List<APIConnectionGroup> getConnectionGroups(@QueryParam("token") String authToken, @QueryParam("parentID") String parentID)
|
||||
private APIConnectionGroup retrieveConnectionGroup(UserContext userContext,
|
||||
String identifier, boolean includeDescendants)
|
||||
throws GuacamoleException {
|
||||
|
||||
UserContext userContext = authenticationService.getUserContext(authToken);
|
||||
ConnectionGroup rootGroup = userContext.getRootConnectionGroup();
|
||||
|
||||
// If the parent connection group is passed in, try to find it.
|
||||
ConnectionGroup parentConnectionGroup;
|
||||
if (parentID == null)
|
||||
parentConnectionGroup = userContext.getRootConnectionGroup();
|
||||
ConnectionGroup connectionGroup;
|
||||
|
||||
// Use root group if requested
|
||||
if (identifier == null || identifier.equals(APIConnectionGroup.ROOT_IDENTIFIER))
|
||||
connectionGroup = rootGroup;
|
||||
|
||||
// Otherwise, query requested group using root group directory
|
||||
else {
|
||||
ConnectionGroup rootGroup = userContext.getRootConnectionGroup();
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory = rootGroup.getConnectionGroupDirectory();
|
||||
parentConnectionGroup = connectionGroupDirectory.get(parentID);
|
||||
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory =
|
||||
rootGroup.getConnectionGroupDirectory();
|
||||
|
||||
// Get the connection group from root directory
|
||||
connectionGroup = connectionGroupDirectory.get(identifier);
|
||||
if (connectionGroup == null)
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
if (parentConnectionGroup == null)
|
||||
throw new HTTPException(Status.NOT_FOUND, "No connection group found with the provided parentID.");
|
||||
// Wrap queried connection group
|
||||
APIConnectionGroup apiConnectionGroup = new APIConnectionGroup(connectionGroup);
|
||||
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory =
|
||||
parentConnectionGroup.getConnectionGroupDirectory();
|
||||
// Recursively query all descendants if necessary
|
||||
if (includeDescendants) {
|
||||
|
||||
// Query all child connections
|
||||
Collection<APIConnection> apiConnections = new ArrayList<APIConnection>();
|
||||
Directory<String, Connection> connectionDirectory = connectionGroup.getConnectionDirectory();
|
||||
|
||||
for (String childIdentifier : connectionDirectory.getIdentifiers()) {
|
||||
|
||||
// Pull current connection - silently ignore if connection was removed prior to read
|
||||
Connection childConnection = connectionDirectory.get(childIdentifier);
|
||||
if (childConnection == null)
|
||||
continue;
|
||||
|
||||
apiConnections.add(new APIConnection(childConnection));
|
||||
|
||||
}
|
||||
|
||||
// Associate child connections with current connection group
|
||||
apiConnectionGroup.setChildConnections(apiConnections);
|
||||
|
||||
// Query all child connection groups
|
||||
Collection<APIConnectionGroup> apiConnectionGroups = new ArrayList<APIConnectionGroup>();
|
||||
Directory<String, ConnectionGroup> groupDirectory = connectionGroup.getConnectionGroupDirectory();
|
||||
|
||||
for (String childIdentifier : groupDirectory.getIdentifiers()) {
|
||||
|
||||
// Pull current connection group - silently ignore if connection group was removed prior to read
|
||||
APIConnectionGroup childConnectionGroup = retrieveConnectionGroup(userContext, childIdentifier, true);
|
||||
if (childConnectionGroup == null)
|
||||
continue;
|
||||
|
||||
apiConnectionGroups.add(childConnectionGroup);
|
||||
|
||||
}
|
||||
|
||||
// Associate child groups with current connection group
|
||||
apiConnectionGroup.setChildConnectionGroups(apiConnectionGroups);
|
||||
|
||||
}
|
||||
|
||||
// Return the connectiion group
|
||||
return apiConnectionGroup;
|
||||
|
||||
// Return the converted connection group list
|
||||
return connectionGroupService.convertConnectionGroupList(connectionGroupDirectory);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an individual connection group.
|
||||
*
|
||||
@@ -133,27 +183,50 @@ public class ConnectionGroupRESTService {
|
||||
@PathParam("connectionGroupID") String connectionGroupID) throws GuacamoleException {
|
||||
|
||||
UserContext userContext = authenticationService.getUserContext(authToken);
|
||||
|
||||
// Get the connection group directory
|
||||
ConnectionGroup rootGroup = userContext.getRootConnectionGroup();
|
||||
|
||||
// Return the root group if it was asked for
|
||||
if (connectionGroupID != null && connectionGroupID.equals(ROOT_CONNECTION_GROUP_ID))
|
||||
return new APIConnectionGroup(rootGroup);
|
||||
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory =
|
||||
rootGroup.getConnectionGroupDirectory();
|
||||
|
||||
// Get the connection group
|
||||
ConnectionGroup connectionGroup = connectionGroupDirectory.get(connectionGroupID);
|
||||
// Retrieve requested connection group only
|
||||
APIConnectionGroup connectionGroup = retrieveConnectionGroup(userContext, connectionGroupID, false);
|
||||
if (connectionGroup == null)
|
||||
throw new HTTPException(Status.NOT_FOUND, "No ConnectionGroup found with the provided ID.");
|
||||
throw new GuacamoleResourceNotFoundException("No such connection group: \"" + connectionGroupID + "\"");
|
||||
|
||||
// Return the connectiion group
|
||||
return new APIConnectionGroup(connectionGroup);
|
||||
return connectionGroup;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an individual connection group and all children.
|
||||
*
|
||||
* @param authToken
|
||||
* The authentication token that is used to authenticate the user
|
||||
* performing the operation.
|
||||
*
|
||||
* @param connectionGroupID
|
||||
* The ID of the ConnectionGroup.
|
||||
*
|
||||
* @return
|
||||
* The connection group.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If a problem is encountered while retrieving the connection group or
|
||||
* its descendants.
|
||||
*/
|
||||
@GET
|
||||
@Path("/{connectionGroupID}/tree")
|
||||
@AuthProviderRESTExposure
|
||||
public APIConnectionGroup getConnectionGroupTree(@QueryParam("token") String authToken,
|
||||
@PathParam("connectionGroupID") String connectionGroupID) throws GuacamoleException {
|
||||
|
||||
UserContext userContext = authenticationService.getUserContext(authToken);
|
||||
|
||||
// Retrieve requested connection group and all descendants
|
||||
APIConnectionGroup connectionGroup = retrieveConnectionGroup(userContext, connectionGroupID, true);
|
||||
if (connectionGroup == null)
|
||||
throw new GuacamoleResourceNotFoundException("No such connection group: \"" + connectionGroupID + "\"");
|
||||
|
||||
return connectionGroup;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an individual connection group.
|
||||
*
|
||||
@@ -174,7 +247,7 @@ public class ConnectionGroupRESTService {
|
||||
ConnectionGroup rootGroup = userContext.getRootConnectionGroup();
|
||||
|
||||
// Use the root group if it was asked for
|
||||
if (connectionGroupID != null && connectionGroupID.equals(ROOT_CONNECTION_GROUP_ID))
|
||||
if (connectionGroupID != null && connectionGroupID.equals(APIConnectionGroup.ROOT_IDENTIFIER))
|
||||
connectionGroupID = rootGroup.getIdentifier();
|
||||
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory =
|
||||
@@ -263,7 +336,7 @@ public class ConnectionGroupRESTService {
|
||||
ConnectionGroup rootGroup = userContext.getRootConnectionGroup();
|
||||
|
||||
// Use the root group if it was asked for
|
||||
if (connectionGroupID != null && connectionGroupID.equals(ROOT_CONNECTION_GROUP_ID))
|
||||
if (connectionGroupID != null && connectionGroupID.equals(APIConnectionGroup.ROOT_IDENTIFIER))
|
||||
connectionGroupID = rootGroup.getIdentifier();
|
||||
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory =
|
||||
@@ -300,7 +373,7 @@ public class ConnectionGroupRESTService {
|
||||
ConnectionGroup rootGroup = userContext.getRootConnectionGroup();
|
||||
|
||||
// Use the root group if it was asked for
|
||||
if (connectionGroupID != null && connectionGroupID.equals(ROOT_CONNECTION_GROUP_ID))
|
||||
if (connectionGroupID != null && connectionGroupID.equals(APIConnectionGroup.ROOT_IDENTIFIER))
|
||||
connectionGroupID = rootGroup.getIdentifier();
|
||||
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory =
|
||||
|
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole.net.basic.rest.connectiongroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
|
||||
/**
|
||||
* A service for performing useful manipulations on REST ConnectionGroups.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ConnectionGroupService {
|
||||
|
||||
/**
|
||||
* Converts a ConnectionGroup directory to a list of APIConnectionGroup
|
||||
* objects for exposing with the REST endpoints.
|
||||
*
|
||||
* @param connectionGroupDirectory The ConnectionGroup Directory to convert for REST endpoint use.
|
||||
* @return A List of APIConnectionGroup objects for use with the REST endpoint.
|
||||
* @throws GuacamoleException If an error occurs while converting the
|
||||
* connection group directory.
|
||||
*/
|
||||
public List<APIConnectionGroup> convertConnectionGroupList(
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory) throws GuacamoleException {
|
||||
|
||||
List<APIConnectionGroup> restConnectionGroups = new ArrayList<APIConnectionGroup>();
|
||||
|
||||
for (String connectionGroupID : connectionGroupDirectory.getIdentifiers())
|
||||
restConnectionGroups.add(new APIConnectionGroup(connectionGroupDirectory.get(connectionGroupID)));
|
||||
|
||||
return restConnectionGroups;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -29,26 +29,26 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati
|
||||
var service = {};
|
||||
|
||||
/**
|
||||
* Makes a request to the REST API to get the list of connection groups,
|
||||
* returning a promise that provides an array of
|
||||
* @link{ConnectionGroup} objects if successful.
|
||||
* Makes a request to the REST API to get an individual connection group
|
||||
* and all descendants, returning a promise that provides the corresponding
|
||||
* @link{ConnectionGroup} if successful. Descendant groups and connections
|
||||
* will be stored as children of that connection group.
|
||||
*
|
||||
* @param {String} [parentID=ConnectionGroup.ROOT_IDENTIFIER]
|
||||
* The ID of the connection group whose child connection groups should
|
||||
* be returned. If not provided, the root connection group will be
|
||||
* used by default.
|
||||
* @param {String} [connectionGroupID=ConnectionGroup.ROOT_IDENTIFIER]
|
||||
* The ID of the connection group to retrieve. If not provided, the
|
||||
* root connection group will be retrieved by default.
|
||||
*
|
||||
* @returns {Promise.<ConnectionGroup[]>}
|
||||
* A promise which will resolve with an array of @link{ConnectionGroup}
|
||||
* objects upon success.
|
||||
* @returns {Promise.ConnectionGroup}
|
||||
* A promise which will resolve with a @link{ConnectionGroup} upon
|
||||
* success.
|
||||
*/
|
||||
service.getConnectionGroups = function getConnectionGroups(parentID) {
|
||||
service.getConnectionGroupTree = function getConnectionGroupTree(connectionGroupID) {
|
||||
|
||||
var parentIDParam = "";
|
||||
if (parentID)
|
||||
parentIDParam = "&parentID=" + parentID;
|
||||
// Use the root connection group ID if no ID is passed in
|
||||
connectionGroupID = connectionGroupID || ConnectionGroup.ROOT_IDENTIFIER;
|
||||
|
||||
return $http.get("api/connectionGroup?token=" + authenticationService.getCurrentToken() + parentIDParam);
|
||||
return $http.get("api/connectionGroup/" + connectionGroupID + "/tree?token=" + authenticationService.getCurrentToken());
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -70,6 +70,7 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati
|
||||
connectionGroupID = connectionGroupID || ConnectionGroup.ROOT_IDENTIFIER;
|
||||
|
||||
return $http.get("api/connectionGroup/" + connectionGroupID + "?token=" + authenticationService.getCurrentToken());
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -73,6 +73,24 @@ angular.module('rest').factory('ConnectionGroup', [function defineConnectionGrou
|
||||
*/
|
||||
this.type = template.type || ConnectionGroup.Type.ORGANIZATIONAL;
|
||||
|
||||
/**
|
||||
* An array of all child connections, if known. This property may be
|
||||
* null or undefined if children have not been queried, and thus the
|
||||
* child connections are unknown.
|
||||
*
|
||||
* @type Connection[]
|
||||
*/
|
||||
this.childConnections = template.childConnections;
|
||||
|
||||
/**
|
||||
* An array of all child connection groups, if known. This property may
|
||||
* be null or undefined if children have not been queried, and thus the
|
||||
* child connection groups are unknown.
|
||||
*
|
||||
* @type ConnectionGroup[]
|
||||
*/
|
||||
this.childConnectionGroups = template.childConnectionGroups;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user