mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 17:13:21 +00:00 
			
		
		
		
	GUAC-1100: Move connection and connection group directories to root level only.
This commit is contained in:
		| @@ -0,0 +1,54 @@ | ||||
| /* | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.auth; | ||||
|  | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleSocket; | ||||
| import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; | ||||
|  | ||||
| /** | ||||
|  * An object which Guacamole can connect to. | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public interface Connectable { | ||||
|  | ||||
|     /** | ||||
|      * Establishes a connection to guacd using the information associated with | ||||
|      * this object. The connection will be provided the given client | ||||
|      * information. | ||||
|      * | ||||
|      * @param info | ||||
|      *     Information associated with the connecting client. | ||||
|      * | ||||
|      * @return | ||||
|      *     A fully-established GuacamoleSocket. | ||||
|      * | ||||
|      * @throws GuacamoleException | ||||
|      *     If an error occurs while connecting to guacd, or if permission to | ||||
|      *     connect is denied. | ||||
|      */ | ||||
|     public GuacamoleSocket connect(GuacamoleClientInformation info) | ||||
|             throws GuacamoleException; | ||||
|  | ||||
| } | ||||
| @@ -24,8 +24,6 @@ package org.glyptodon.guacamole.net.auth; | ||||
|  | ||||
| import java.util.List; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleSocket; | ||||
| import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; | ||||
| import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; | ||||
|  | ||||
| /** | ||||
| @@ -36,7 +34,7 @@ import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public interface Connection extends Identifiable { | ||||
| public interface Connection extends Identifiable, Connectable { | ||||
|  | ||||
|     /** | ||||
|      * Returns the name assigned to this Connection. | ||||
| @@ -86,21 +84,6 @@ public interface Connection extends Identifiable { | ||||
|      */ | ||||
|     public void setConfiguration(GuacamoleConfiguration config); | ||||
|  | ||||
|     /** | ||||
|      * Establishes a connection to guacd using the GuacamoleConfiguration | ||||
|      * associated with this Connection, and returns the resulting, connected | ||||
|      * GuacamoleSocket. The GuacamoleSocket will be pre-configured and will | ||||
|      * already have passed the handshake stage. | ||||
|      * | ||||
|      * @param info Information associated with the connecting client. | ||||
|      * @return A fully-established GuacamoleSocket. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while connecting to guacd, | ||||
|      *                            or if permission to connect is denied. | ||||
|      */ | ||||
|     public GuacamoleSocket connect(GuacamoleClientInformation info) | ||||
|             throws GuacamoleException; | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of ConnectionRecords representing the usage history | ||||
|      * of this Connection, including any active users. ConnectionRecords | ||||
|   | ||||
| @@ -22,9 +22,7 @@ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.auth; | ||||
|  | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleSocket; | ||||
| import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * Represents a connection group, which can contain both other connection groups | ||||
| @@ -32,7 +30,7 @@ import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; | ||||
|  * | ||||
|  * @author James Muehlner | ||||
|  */ | ||||
| public interface ConnectionGroup extends Identifiable { | ||||
| public interface ConnectionGroup extends Identifiable, Connectable { | ||||
|    | ||||
|     /** | ||||
|      * All legal types of connection group. | ||||
| @@ -102,45 +100,24 @@ public interface ConnectionGroup extends Identifiable { | ||||
|     public Type getType(); | ||||
|  | ||||
|     /** | ||||
|      * Retrieves a Directory which can be used to view and manipulate | ||||
|      * connections and their configurations, but only as allowed by the | ||||
|      * permissions given to the user. | ||||
|      * Returns the identifiers of all readable connections that are children | ||||
|      * of this connection group. | ||||
|      * | ||||
|      * @return A Directory whose operations are bound by the permissions of  | ||||
|      *         the user. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while creating the | ||||
|      *                            Directory. | ||||
|      * @return | ||||
|      *     The set of identifiers of all readable connections that are children | ||||
|      *     of this connection group. | ||||
|      */ | ||||
|     Directory<Connection> getConnectionDirectory() | ||||
|             throws GuacamoleException; | ||||
|     public Set<String> getConnectionIdentifiers(); | ||||
|  | ||||
|     /** | ||||
|      * Retrieves a Directory which can be used to view and manipulate | ||||
|      * connection groups and their members, but only as allowed by the | ||||
|      * permissions given to the user. | ||||
|      * Returns the identifiers of all readable connection groups that are | ||||
|      * children of this connection group. | ||||
|      * | ||||
|      * @return A Directory whose operations are bound by the permissions of | ||||
|      *         the user. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while creating the | ||||
|      *                            Directory. | ||||
|      * @return | ||||
|      *     The set of identifiers of all readable connection groups that are | ||||
|      *     children of this connection group. | ||||
|      */ | ||||
|     Directory<ConnectionGroup> getConnectionGroupDirectory() | ||||
|             throws GuacamoleException; | ||||
|  | ||||
|     public Set<String> getConnectionGroupIdentifiers(); | ||||
|      | ||||
|     /** | ||||
|      * Establishes a connection to guacd using a connection chosen from among | ||||
|      * the connections in this ConnectionGroup, and returns the resulting,  | ||||
|      * connected GuacamoleSocket. | ||||
|      * | ||||
|      * @param info Information associated with the connecting client. | ||||
|      * @return A fully-established GuacamoleSocket. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while connecting to guacd, | ||||
|      *                            or if permission to connect is denied. | ||||
|      */ | ||||
|     public GuacamoleSocket connect(GuacamoleClientInformation info) | ||||
|             throws GuacamoleException; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -122,16 +122,4 @@ public interface Directory<ObjectType> { | ||||
|      */ | ||||
|     void remove(String identifier) throws GuacamoleException; | ||||
|  | ||||
|     /** | ||||
|      * Moves the object with the given identifier to the given directory. | ||||
|      * | ||||
|      * @param identifier The identifier of the object to remove. | ||||
|      * @param directory The directory to move the object to. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while moving the object, | ||||
|      *                            or if moving object is not allowed. | ||||
|      */ | ||||
|     void move(String identifier, Directory<ObjectType> directory)  | ||||
|             throws GuacamoleException; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -54,6 +54,34 @@ public interface UserContext { | ||||
|      */ | ||||
|     Directory<User> getUserDirectory() throws GuacamoleException; | ||||
|  | ||||
|     /** | ||||
|      * Retrieves a Directory which can be used to view and manipulate | ||||
|      * connections and their configurations, but only as allowed by the | ||||
|      * permissions given to the user. | ||||
|      * | ||||
|      * @return A Directory whose operations are bound by the permissions of  | ||||
|      *         the user. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while creating the | ||||
|      *                            Directory. | ||||
|      */ | ||||
|     Directory<Connection> getConnectionDirectory() | ||||
|             throws GuacamoleException; | ||||
|  | ||||
|     /** | ||||
|      * Retrieves a Directory which can be used to view and manipulate | ||||
|      * connection groups and their members, but only as allowed by the | ||||
|      * permissions given to the user. | ||||
|      * | ||||
|      * @return A Directory whose operations are bound by the permissions of | ||||
|      *         the user. | ||||
|      * | ||||
|      * @throws GuacamoleException If an error occurs while creating the | ||||
|      *                            Directory. | ||||
|      */ | ||||
|     Directory<ConnectionGroup> getConnectionGroupDirectory() | ||||
|             throws GuacamoleException; | ||||
|  | ||||
|     /** | ||||
|      * Retrieves a connection group which can be used to view and manipulate | ||||
|      * connections, but only as allowed by the permissions given to the user of  | ||||
|   | ||||
| @@ -22,18 +22,19 @@ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.auth.simple; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.HashSet; | ||||
| import java.util.Set; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.GuacamoleSecurityException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleSocket; | ||||
| import org.glyptodon.guacamole.net.auth.AbstractConnectionGroup; | ||||
| 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.protocol.GuacamoleClientInformation; | ||||
|  | ||||
| /** | ||||
|  * An extremely simple read-only implementation of a ConnectionGroup which | ||||
|  * returns the connection and connection group directories it was constructed | ||||
|  * returns the connection and connection group identifiers it was constructed | ||||
|  * with. Load balancing across this connection group is not allowed. | ||||
|  *  | ||||
|  * @author James Muehlner | ||||
| @@ -41,31 +42,34 @@ import org.glyptodon.guacamole.protocol.GuacamoleClientInformation; | ||||
| public class SimpleConnectionGroup extends AbstractConnectionGroup { | ||||
|  | ||||
|     /** | ||||
|      * Underlying connection directory, containing all connections within this | ||||
|      * group. | ||||
|      * The identifiers of all connections in this group. | ||||
|      */ | ||||
|     private final Directory<Connection> connectionDirectory; | ||||
|     private final Set<String> connectionIdentifiers; | ||||
|  | ||||
|     /** | ||||
|      * Underlying connection group directory, containing all connections within | ||||
|      * this group. | ||||
|      * The identifiers of all connection groups in this group. | ||||
|      */ | ||||
|     private final Directory<ConnectionGroup> connectionGroupDirectory; | ||||
|     private final Set<String> connectionGroupIdentifiers; | ||||
|      | ||||
|     /** | ||||
|      * Creates a new SimpleConnectionGroup having the given name and identifier | ||||
|      * which will expose the given directories as its contents. | ||||
|      * which will expose the given contents. | ||||
|      *  | ||||
|      * @param name The name to associate with this connection. | ||||
|      * @param identifier The identifier to associate with this connection. | ||||
|      * @param connectionDirectory The connection directory to expose when | ||||
|      *                            requested. | ||||
|      * @param connectionGroupDirectory The connection group directory to expose | ||||
|      *                                 when requested. | ||||
|      * @param name | ||||
|      *     The name to associate with this connection group. | ||||
|      * | ||||
|      * @param identifier | ||||
|      *     The identifier to associate with this connection group. | ||||
|      * | ||||
|      * @param connectionIdentifiers | ||||
|      *     The connection identifiers to expose when requested. | ||||
|      * | ||||
|      * @param connectionGroupIdentifiers | ||||
|      *     The connection group identifiers to expose when requested. | ||||
|      */ | ||||
|     public SimpleConnectionGroup(String name, String identifier, | ||||
|             Directory<Connection> connectionDirectory,  | ||||
|             Directory<ConnectionGroup> connectionGroupDirectory) { | ||||
|             Collection<String> connectionIdentifiers,  | ||||
|             Collection<String> connectionGroupIdentifiers) { | ||||
|  | ||||
|         // Set name | ||||
|         setName(name); | ||||
| @@ -76,22 +80,20 @@ public class SimpleConnectionGroup extends AbstractConnectionGroup { | ||||
|         // Set group type | ||||
|         setType(ConnectionGroup.Type.ORGANIZATIONAL); | ||||
|  | ||||
|         // Assign directories | ||||
|         this.connectionDirectory = connectionDirectory; | ||||
|         this.connectionGroupDirectory = connectionGroupDirectory; | ||||
|         // Populate contents | ||||
|         this.connectionIdentifiers = new HashSet<String>(connectionIdentifiers); | ||||
|         this.connectionGroupIdentifiers = new HashSet<String>(connectionGroupIdentifiers); | ||||
|  | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public Directory<Connection> getConnectionDirectory()  | ||||
|             throws GuacamoleException { | ||||
|         return connectionDirectory; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Directory<ConnectionGroup> getConnectionGroupDirectory()  | ||||
|             throws GuacamoleException { | ||||
|         return connectionGroupDirectory; | ||||
|     public Set<String> getConnectionIdentifiers() { | ||||
|         return connectionIdentifiers; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Set<String> getConnectionGroupIdentifiers() { | ||||
|         return connectionGroupIdentifiers; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -138,10 +138,4 @@ public class SimpleDirectory<ObjectType> implements Directory<ObjectType> { | ||||
|         throw new GuacamoleSecurityException("Permission denied."); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void move(String identifier, Directory<ObjectType> directory) | ||||
|             throws GuacamoleException { | ||||
|         throw new GuacamoleSecurityException("Permission denied."); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -24,15 +24,12 @@ package org.glyptodon.guacamole.net.auth.simple; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.HashSet; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.auth.AbstractUser; | ||||
| import org.glyptodon.guacamole.net.auth.ConnectionGroup; | ||||
| import org.glyptodon.guacamole.net.auth.permission.ObjectPermission; | ||||
| import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; | ||||
| import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; | ||||
| import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; | ||||
|  | ||||
| /** | ||||
|  * An extremely basic User implementation. | ||||
| @@ -60,46 +57,52 @@ public class SimpleUser extends AbstractUser { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a new SimpleUser having the given username. | ||||
|      * Adds a new READ permission to the given set of permissions for each of | ||||
|      * the given identifiers. | ||||
|      * | ||||
|      * @param username The username to assign to this SimpleUser. | ||||
|      * @param configs All configurations this user has read access to. | ||||
|      * @param groups All groups this user has read access to. | ||||
|      * @param permissions | ||||
|      *     The set of permissions to add READ permissions to. | ||||
|      * | ||||
|      * @param identifiers | ||||
|      *     The identifiers which should each have a corresponding READ | ||||
|      *     permission added to the given set. | ||||
|      */ | ||||
|     private void addReadPermissions(Set<ObjectPermission> permissions, | ||||
|             Collection<String> identifiers) { | ||||
|  | ||||
|         // Add a READ permission to the set for each identifier given | ||||
|         for (String identifier : identifiers) { | ||||
|             permissions.add(new ObjectPermission ( | ||||
|                 ObjectPermission.Type.READ, | ||||
|                 identifier | ||||
|             )); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Creates a new SimpleUser having the given username and READ access to | ||||
|      * the connections and groups having the given identifiers. | ||||
|      * | ||||
|      * @param username | ||||
|      *     The username to assign to this SimpleUser. | ||||
|      * @param connectionIdentifiers | ||||
|      *     The identifiers of all connections this user has READ access to. | ||||
|      * | ||||
|      * @param connectionGroupIdentifiers | ||||
|      *     The identifiers of all connection groups this user has READ access | ||||
|      *     to. | ||||
|      */ | ||||
|     public SimpleUser(String username, | ||||
|             Map<String, GuacamoleConfiguration> configs, | ||||
|             Collection<ConnectionGroup> groups) { | ||||
|             Collection<String> connectionIdentifiers, | ||||
|             Collection<String> connectionGroupIdentifiers) { | ||||
|  | ||||
|         // Set username | ||||
|         setIdentifier(username); | ||||
|  | ||||
|         // Add connection permissions | ||||
|         for (String identifier : configs.keySet()) { | ||||
|  | ||||
|             // Create permission | ||||
|             ObjectPermission permission = new ObjectPermission( | ||||
|                 ObjectPermission.Type.READ, | ||||
|                 identifier | ||||
|             ); | ||||
|  | ||||
|             // Add to set | ||||
|             connectionPermissions.add(permission); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Add group permissions | ||||
|         for (ConnectionGroup group : groups) { | ||||
|  | ||||
|             // Create permission | ||||
|             ObjectPermission permission = new ObjectPermission( | ||||
|                 ObjectPermission.Type.READ, | ||||
|                 group.getIdentifier() | ||||
|             ); | ||||
|  | ||||
|             // Add to set | ||||
|             connectionGroupPermissions.add(permission); | ||||
|  | ||||
|         } | ||||
|         // Add permissions | ||||
|         addReadPermissions(connectionPermissions,      connectionIdentifiers); | ||||
|         addReadPermissions(connectionGroupPermissions, connectionGroupIdentifiers); | ||||
|  | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -62,10 +62,21 @@ public class SimpleUserContext implements UserContext { | ||||
|     private final Directory<User> userDirectory; | ||||
|  | ||||
|     /** | ||||
|      * The ConnectionGroup with access only to those Connections that the User | ||||
|      * associated with this UserContext has access to. | ||||
|      * The Directory with access only to the root group associated with this | ||||
|      * UserContext. | ||||
|      */ | ||||
|     private final ConnectionGroup connectionGroup; | ||||
|     private final Directory<ConnectionGroup> connectionGroupDirectory; | ||||
|  | ||||
|     /** | ||||
|      * The Directory with access to all connections within the root group | ||||
|      * associated with this UserContext. | ||||
|      */ | ||||
|     private final Directory<Connection> connectionDirectory; | ||||
|  | ||||
|     /** | ||||
|      * The root connection group. | ||||
|      */ | ||||
|     private final ConnectionGroup rootGroup; | ||||
|  | ||||
|     /** | ||||
|      * Creates a new SimpleUserContext which provides access to only those | ||||
| @@ -90,6 +101,9 @@ public class SimpleUserContext implements UserContext { | ||||
|      */ | ||||
|     public SimpleUserContext(String username, Map<String, GuacamoleConfiguration> configs) { | ||||
|  | ||||
|         Collection<String> connectionIdentifiers = new ArrayList<String>(configs.size()); | ||||
|         Collection<String> connectionGroupIdentifiers = Collections.singleton(ROOT_IDENTIFIER); | ||||
|          | ||||
|         // Produce collection of connections from given configs | ||||
|         Collection<Connection> connections = new ArrayList<Connection>(configs.size()); | ||||
|         for (Map.Entry<String, GuacamoleConfiguration> configEntry : configs.entrySet()) { | ||||
| @@ -103,20 +117,25 @@ public class SimpleUserContext implements UserContext { | ||||
|             connection.setParentIdentifier(ROOT_IDENTIFIER); | ||||
|             connections.add(connection); | ||||
|  | ||||
|             // Add identifier to overall set of identifiers | ||||
|             connectionIdentifiers.add(identifier); | ||||
|              | ||||
|         } | ||||
|          | ||||
|         // Add root group that contains only configurations | ||||
|         this.connectionGroup = new SimpleConnectionGroup( | ||||
|                 ROOT_IDENTIFIER, ROOT_IDENTIFIER, | ||||
|                 new SimpleConnectionDirectory(connections), | ||||
|                 new SimpleConnectionGroupDirectory(Collections.EMPTY_LIST)); | ||||
|         // Add root group that contains only the given configurations | ||||
|         this.rootGroup = new SimpleConnectionGroup( | ||||
|             ROOT_IDENTIFIER, ROOT_IDENTIFIER, | ||||
|             connectionIdentifiers, Collections.EMPTY_LIST | ||||
|         ); | ||||
|  | ||||
|         // Build new user from credentials, giving the user an arbitrary name | ||||
|         this.self = new SimpleUser(username, | ||||
|                 configs, Collections.singleton(connectionGroup)); | ||||
|         // Build new user from credentials | ||||
|         this.self = new SimpleUser(username, connectionIdentifiers, | ||||
|                 connectionGroupIdentifiers); | ||||
|  | ||||
|         // Create user directory for new user | ||||
|         // Create directories for new user | ||||
|         this.userDirectory = new SimpleUserDirectory(self); | ||||
|         this.connectionDirectory = new SimpleConnectionDirectory(connections); | ||||
|         this.connectionGroupDirectory = new SimpleConnectionGroupDirectory(Collections.singleton(this.rootGroup)); | ||||
|          | ||||
|     } | ||||
|  | ||||
| @@ -131,9 +150,21 @@ public class SimpleUserContext implements UserContext { | ||||
|         return userDirectory; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Directory<Connection> getConnectionDirectory() | ||||
|             throws GuacamoleException { | ||||
|         return connectionDirectory; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Directory<ConnectionGroup> getConnectionGroupDirectory() | ||||
|             throws GuacamoleException { | ||||
|         return connectionGroupDirectory; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ConnectionGroup getRootConnectionGroup() throws GuacamoleException { | ||||
|         return connectionGroup; | ||||
|         return rootGroup; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user