diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connectable.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connectable.java new file mode 100644 index 000000000..6ce62c916 --- /dev/null +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connectable.java @@ -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; + +} diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java index 63e60a328..6fac0809f 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Connection.java @@ -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 diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java index a99978759..21a1e8de6 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionGroup.java @@ -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 getConnectionDirectory() - throws GuacamoleException; + public Set 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 getConnectionGroupDirectory() - throws GuacamoleException; + + public Set 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; - } diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Directory.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Directory.java index b241c017e..4dbb60ce9 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Directory.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/Directory.java @@ -122,16 +122,4 @@ public interface Directory { */ 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 directory) - throws GuacamoleException; - } diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java index deba2cb7d..c38d9a90f 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/UserContext.java @@ -54,6 +54,34 @@ public interface UserContext { */ Directory 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 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 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 diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnectionGroup.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnectionGroup.java index 6f4cb1051..eb197d01a 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnectionGroup.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleConnectionGroup.java @@ -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 connectionDirectory; + private final Set connectionIdentifiers; /** - * Underlying connection group directory, containing all connections within - * this group. + * The identifiers of all connection groups in this group. */ - private final Directory connectionGroupDirectory; + private final Set 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 connectionDirectory, - Directory connectionGroupDirectory) { + Collection connectionIdentifiers, + Collection 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(connectionIdentifiers); + this.connectionGroupIdentifiers = new HashSet(connectionGroupIdentifiers); } - - @Override - public Directory getConnectionDirectory() - throws GuacamoleException { - return connectionDirectory; - } @Override - public Directory getConnectionGroupDirectory() - throws GuacamoleException { - return connectionGroupDirectory; + public Set getConnectionIdentifiers() { + return connectionIdentifiers; + } + + @Override + public Set getConnectionGroupIdentifiers() { + return connectionGroupIdentifiers; } @Override diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleDirectory.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleDirectory.java index 570fe2bcd..caee07e2a 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleDirectory.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleDirectory.java @@ -138,10 +138,4 @@ public class SimpleDirectory implements Directory { throw new GuacamoleSecurityException("Permission denied."); } - @Override - public void move(String identifier, Directory directory) - throws GuacamoleException { - throw new GuacamoleSecurityException("Permission denied."); - } - } diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUser.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUser.java index 873c59062..fa0899fa2 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUser.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUser.java @@ -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 permissions, + Collection 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 configs, - Collection groups) { + Collection connectionIdentifiers, + Collection 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); } diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java index 032fc0dd4..8ee7e84c1 100644 --- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java +++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/simple/SimpleUserContext.java @@ -62,10 +62,21 @@ public class SimpleUserContext implements UserContext { private final Directory 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 connectionGroupDirectory; + + /** + * The Directory with access to all connections within the root group + * associated with this UserContext. + */ + private final Directory 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 configs) { + Collection connectionIdentifiers = new ArrayList(configs.size()); + Collection connectionGroupIdentifiers = Collections.singleton(ROOT_IDENTIFIER); + // Produce collection of connections from given configs Collection connections = new ArrayList(configs.size()); for (Map.Entry 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 getConnectionDirectory() + throws GuacamoleException { + return connectionDirectory; + } + + @Override + public Directory getConnectionGroupDirectory() + throws GuacamoleException { + return connectionGroupDirectory; + } + @Override public ConnectionGroup getRootConnectionGroup() throws GuacamoleException { - return connectionGroup; + return rootGroup; } } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java index 8c1679236..b0ba6ee39 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java @@ -210,11 +210,9 @@ public class TunnelRequestService { // Connection identifiers case CONNECTION: { - UserContext context = session.getUserContext(); - // Get connection directory - Directory directory = - context.getRootConnectionGroup().getConnectionDirectory(); + UserContext context = session.getUserContext(); + Directory directory = context.getConnectionDirectory(); // Get authorized connection Connection connection = directory.get(id); @@ -232,11 +230,9 @@ public class TunnelRequestService { // Connection group identifiers case CONNECTION_GROUP: { - UserContext context = session.getUserContext(); - // Get connection group directory - Directory directory = - context.getRootConnectionGroup().getConnectionGroupDirectory(); + UserContext context = session.getUserContext(); + Directory directory = context.getConnectionGroupDirectory(); // Get authorized connection group ConnectionGroup group = directory.get(id); diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/ObjectRetrievalService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/ObjectRetrievalService.java index fb7356604..c72040493 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/ObjectRetrievalService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/ObjectRetrievalService.java @@ -89,9 +89,8 @@ public class ObjectRetrievalService { public Connection retrieveConnection(UserContext userContext, String identifier) throws GuacamoleException { - // Get root directory - ConnectionGroup rootGroup = userContext.getRootConnectionGroup(); - Directory directory = rootGroup.getConnectionDirectory(); + // Get connection directory + Directory directory = userContext.getConnectionDirectory(); // Pull specified connection Connection connection = directory.get(identifier); @@ -125,14 +124,12 @@ public class ObjectRetrievalService { public ConnectionGroup retrieveConnectionGroup(UserContext userContext, String identifier) throws GuacamoleException { - ConnectionGroup rootGroup = userContext.getRootConnectionGroup(); - - // Use root group if identifier is null (or the standard root identifier) + // Use root group if identifier is the standard root identifier if (identifier != null && identifier.equals(APIConnectionGroup.ROOT_IDENTIFIER)) - return rootGroup; + return userContext.getRootConnectionGroup(); // Pull specified connection group otherwise - Directory directory = rootGroup.getConnectionGroupDirectory(); + Directory directory = userContext.getConnectionGroupDirectory(); ConnectionGroup connectionGroup = directory.get(identifier); if (connectionGroup == null) diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java index 5e1eb7368..8c827c11c 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java @@ -210,9 +210,7 @@ public class ConnectionRESTService { UserContext userContext = authenticationService.getUserContext(authToken); // Get the connection directory - ConnectionGroup rootGroup = userContext.getRootConnectionGroup(); - Directory connectionDirectory = - rootGroup.getConnectionDirectory(); + Directory connectionDirectory = userContext.getConnectionDirectory(); // Delete the specified connection connectionDirectory.remove(connectionID); @@ -247,12 +245,8 @@ public class ConnectionRESTService { if (connection == null) throw new GuacamoleClientException("Connection JSON must be submitted when creating connections."); - // Retrieve parent group - String parentID = connection.getParentIdentifier(); - ConnectionGroup parentConnectionGroup = retrievalService.retrieveConnectionGroup(userContext, parentID); - // Add the new connection - Directory connectionDirectory = parentConnectionGroup.getConnectionDirectory(); + Directory connectionDirectory = userContext.getConnectionDirectory(); connectionDirectory.add(new APIConnectionWrapper(connection)); // Return the new connection identifier @@ -291,9 +285,7 @@ public class ConnectionRESTService { throw new GuacamoleClientException("Connection JSON must be submitted when updating connections."); // Get the connection directory - ConnectionGroup rootGroup = userContext.getRootConnectionGroup(); - Directory connectionDirectory = - rootGroup.getConnectionDirectory(); + Directory connectionDirectory = userContext.getConnectionDirectory(); // Retrieve connection to update Connection existingConnection = retrievalService.retrieveConnection(userContext, connectionID); @@ -308,15 +300,6 @@ public class ConnectionRESTService { existingConnection.setName(connection.getName()); connectionDirectory.update(existingConnection); - // Get old and new parents - String oldParentIdentifier = existingConnection.getParentIdentifier(); - ConnectionGroup updatedParentGroup = retrievalService.retrieveConnectionGroup(userContext, connection.getParentIdentifier()); - - // Update connection parent, if changed - if ( (oldParentIdentifier != null && !oldParentIdentifier.equals(updatedParentGroup.getIdentifier())) - || (oldParentIdentifier == null && updatedParentGroup.getIdentifier() != null)) - connectionDirectory.move(connectionID, updatedParentGroup.getConnectionDirectory()); - } } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java index 24128bb56..a726ca169 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java @@ -22,6 +22,7 @@ package org.glyptodon.guacamole.net.basic.rest.connectiongroup; +import java.util.Set; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.GuacamoleSocket; import org.glyptodon.guacamole.net.auth.Connection; @@ -92,12 +93,12 @@ public class APIConnectionGroupWrapper implements ConnectionGroup { } @Override - public Directory getConnectionDirectory() throws GuacamoleException { + public Set getConnectionIdentifiers() { throw new UnsupportedOperationException("Operation not supported."); } @Override - public Directory getConnectionGroupDirectory() throws GuacamoleException { + public Set getConnectionGroupIdentifiers() { throw new UnsupportedOperationException("Operation not supported."); } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java index cab7a3550..abb686ec2 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java @@ -137,7 +137,7 @@ public class ConnectionGroupRESTService { // Retrieve the requested tree, filtering by the given permissions ConnectionGroup treeRoot = retrievalService.retrieveConnectionGroup(userContext, connectionGroupID); - ConnectionGroupTree tree = new ConnectionGroupTree(treeRoot, permissions); + ConnectionGroupTree tree = new ConnectionGroupTree(userContext, treeRoot, permissions); // Return tree as a connection group return tree.getRootAPIConnectionGroup(); @@ -166,9 +166,7 @@ public class ConnectionGroupRESTService { UserContext userContext = authenticationService.getUserContext(authToken); // Get the connection group directory - ConnectionGroup rootGroup = userContext.getRootConnectionGroup(); - Directory connectionGroupDirectory = - rootGroup.getConnectionGroupDirectory(); + Directory connectionGroupDirectory = userContext.getConnectionGroupDirectory(); // Delete the connection group connectionGroupDirectory.remove(connectionGroupID); @@ -205,12 +203,8 @@ public class ConnectionGroupRESTService { if (connectionGroup == null) throw new GuacamoleClientException("Connection group JSON must be submitted when creating connections groups."); - // Retrieve parent group - String parentID = connectionGroup.getParentIdentifier(); - ConnectionGroup parentConnectionGroup = retrievalService.retrieveConnectionGroup(userContext, parentID); - // Add the new connection group - Directory connectionGroupDirectory = parentConnectionGroup.getConnectionGroupDirectory(); + Directory connectionGroupDirectory = userContext.getConnectionGroupDirectory(); connectionGroupDirectory.add(new APIConnectionGroupWrapper(connectionGroup)); // Return the new connection group identifier @@ -250,9 +244,7 @@ public class ConnectionGroupRESTService { throw new GuacamoleClientException("Connection group JSON must be submitted when updating connection groups."); // Get the connection group directory - ConnectionGroup rootGroup = userContext.getRootConnectionGroup(); - Directory connectionGroupDirectory = - rootGroup.getConnectionGroupDirectory(); + Directory connectionGroupDirectory = userContext.getConnectionGroupDirectory(); // Retrieve connection group to update ConnectionGroup existingConnectionGroup = connectionGroupDirectory.get(connectionGroupID); @@ -262,15 +254,6 @@ public class ConnectionGroupRESTService { existingConnectionGroup.setType(connectionGroup.getType()); connectionGroupDirectory.update(existingConnectionGroup); - // Get old and new parents - String oldParentIdentifier = existingConnectionGroup.getParentIdentifier(); - ConnectionGroup updatedParentGroup = retrievalService.retrieveConnectionGroup(userContext, connectionGroup.getParentIdentifier()); - - // Update connection group parent, if changed - if ( (oldParentIdentifier != null && !oldParentIdentifier.equals(updatedParentGroup.getIdentifier())) - || (oldParentIdentifier == null && updatedParentGroup.getIdentifier() != null)) - connectionGroupDirectory.move(connectionGroupID, updatedParentGroup.getConnectionGroupDirectory()); - } } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupTree.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupTree.java index f20bea7a1..5d801525c 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupTree.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupTree.java @@ -31,6 +31,7 @@ import java.util.Map; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.auth.Connection; import org.glyptodon.guacamole.net.auth.ConnectionGroup; +import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.net.auth.permission.ObjectPermission; import org.glyptodon.guacamole.net.basic.rest.connection.APIConnection; import org.slf4j.Logger; @@ -48,11 +49,11 @@ public class ConnectionGroupTree { * Logger for this class. */ private static final Logger logger = LoggerFactory.getLogger(ConnectionGroupTree.class); - + /** - * The root connection group. + * The context of the user obtaining this tree. */ - private final ConnectionGroup root; + private final UserContext userContext; /** * The root connection group as an APIConnectionGroup. @@ -174,19 +175,19 @@ public class ConnectionGroupTree { // Build lists of identifiers for retrieval for (ConnectionGroup parent : parents) { - childConnectionIdentifiers.addAll(parent.getConnectionDirectory().getIdentifiers()); - childConnectionGroupIdentifiers.addAll(parent.getConnectionGroupDirectory().getIdentifiers()); + childConnectionIdentifiers.addAll(parent.getConnectionIdentifiers()); + childConnectionGroupIdentifiers.addAll(parent.getConnectionGroupIdentifiers()); } // Retrieve child connections if (!childConnectionIdentifiers.isEmpty()) { - Collection childConnections = root.getConnectionDirectory().getAll(childConnectionIdentifiers); + Collection childConnections = userContext.getConnectionDirectory().getAll(childConnectionIdentifiers); addConnections(childConnections); } // Retrieve child connection groups if (!childConnectionGroupIdentifiers.isEmpty()) { - Collection childConnectionGroups = root.getConnectionGroupDirectory().getAll(childConnectionGroupIdentifiers); + Collection childConnectionGroups = userContext.getConnectionGroupDirectory().getAll(childConnectionGroupIdentifiers); addConnectionGroups(childConnectionGroups); addDescendants(childConnectionGroups); } @@ -197,6 +198,9 @@ public class ConnectionGroupTree { * Creates a new connection group tree using the given connection group as * the tree root. * + * @param userContext + * The context of the user obtaining the connection group tree. + * * @param root * The connection group to use as the root of this connection group * tree. @@ -211,11 +215,12 @@ public class ConnectionGroupTree { * If an error occurs while retrieving the tree of connection groups * and their descendants. */ - public ConnectionGroupTree(ConnectionGroup root, + public ConnectionGroupTree(UserContext userContext, ConnectionGroup root, List permissions) throws GuacamoleException { + this.userContext = userContext; + // Store root of tree - this.root = root; this.rootAPIGroup = new APIConnectionGroup(root); retrievedGroups.put(root.getIdentifier(), this.rootAPIGroup);