mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +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; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user