GUAC-1100: Move connection and connection group directories to root level only.

This commit is contained in:
Michael Jumper
2015-02-23 12:42:47 -08:00
parent 220e33eca1
commit 6f61300cbc
15 changed files with 246 additions and 221 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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.");
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}