mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-96: Restrict submitted attributes to those explicitly declared by the UserContext.
This commit is contained in:
@@ -22,6 +22,7 @@ package org.apache.guacamole.rest.activeconnection;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.GuacamoleUnsupportedException;
|
||||
import org.apache.guacamole.net.auth.ActiveConnection;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
|
||||
/**
|
||||
@@ -30,7 +31,7 @@ import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
* toExternalObject() is implemented here.
|
||||
*/
|
||||
public class ActiveConnectionObjectTranslator
|
||||
implements DirectoryObjectTranslator<ActiveConnection, APIActiveConnection> {
|
||||
extends DirectoryObjectTranslator<ActiveConnection, APIActiveConnection> {
|
||||
|
||||
@Override
|
||||
public APIActiveConnection toExternalObject(ActiveConnection object)
|
||||
@@ -56,4 +57,10 @@ public class ActiveConnectionObjectTranslator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterExternalObject(UserContext context,
|
||||
APIActiveConnection object) throws GuacamoleException {
|
||||
// Nothing to filter on ActiveConnections (no attributes)
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -89,7 +89,7 @@ public class ActiveConnectionResource
|
||||
@Assisted Directory<ActiveConnection> directory,
|
||||
@Assisted ActiveConnection activeConnection,
|
||||
DirectoryObjectTranslator<ActiveConnection, APIActiveConnection> translator) {
|
||||
super(directory, activeConnection, translator);
|
||||
super(userContext, directory, activeConnection, translator);
|
||||
this.userContext = userContext;
|
||||
this.activeConnection = activeConnection;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ package org.apache.guacamole.rest.connection;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.Connection;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||
import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
|
||||
@@ -29,7 +30,7 @@ import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
* objects.
|
||||
*/
|
||||
public class ConnectionObjectTranslator
|
||||
implements DirectoryObjectTranslator<Connection, APIConnection> {
|
||||
extends DirectoryObjectTranslator<Connection, APIConnection> {
|
||||
|
||||
@Override
|
||||
public APIConnection toExternalObject(Connection object)
|
||||
@@ -59,4 +60,14 @@ public class ConnectionObjectTranslator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterExternalObject(UserContext userContext,
|
||||
APIConnection object) throws GuacamoleException {
|
||||
|
||||
// Filter object attributes by defined schema
|
||||
object.setAttributes(filterAttributes(
|
||||
userContext.getConnectionAttributes(), object.getAttributes()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -100,7 +100,7 @@ public class ConnectionResource extends DirectoryObjectResource<Connection, APIC
|
||||
@Assisted Directory<Connection> directory,
|
||||
@Assisted Connection connection,
|
||||
DirectoryObjectTranslator<Connection, APIConnection> translator) {
|
||||
super(directory, connection, translator);
|
||||
super(userContext, directory, connection, translator);
|
||||
this.userContext = userContext;
|
||||
this.connection = connection;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ package org.apache.guacamole.rest.connectiongroup;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.ConnectionGroup;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
* APIConnectionGroup objects.
|
||||
*/
|
||||
public class ConnectionGroupObjectTranslator
|
||||
implements DirectoryObjectTranslator<ConnectionGroup, APIConnectionGroup> {
|
||||
extends DirectoryObjectTranslator<ConnectionGroup, APIConnectionGroup> {
|
||||
|
||||
@Override
|
||||
public APIConnectionGroup toExternalObject(ConnectionGroup object)
|
||||
@@ -53,4 +54,15 @@ public class ConnectionGroupObjectTranslator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterExternalObject(UserContext userContext,
|
||||
APIConnectionGroup object) throws GuacamoleException {
|
||||
|
||||
// Filter object attributes by defined schema
|
||||
object.setAttributes(filterAttributes(
|
||||
userContext.getConnectionGroupAttributes(),
|
||||
object.getAttributes()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ public class ConnectionGroupResource
|
||||
@Assisted Directory<ConnectionGroup> directory,
|
||||
@Assisted ConnectionGroup connectionGroup,
|
||||
DirectoryObjectTranslator<ConnectionGroup, APIConnectionGroup> translator) {
|
||||
super(directory, connectionGroup, translator);
|
||||
super(userContext, directory, connectionGroup, translator);
|
||||
this.userContext = userContext;
|
||||
this.connectionGroup = connectionGroup;
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ import org.apache.guacamole.GuacamoleClientException;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.Directory;
|
||||
import org.apache.guacamole.net.auth.Identifiable;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
* A REST resource which abstracts the operations available on an existing
|
||||
@@ -50,6 +51,12 @@ import org.apache.guacamole.net.auth.Identifiable;
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public abstract class DirectoryObjectResource<InternalType extends Identifiable, ExternalType> {
|
||||
|
||||
/**
|
||||
* The UserContext associated with the Directory containing the object
|
||||
* represented by this DirectoryObjectResource.
|
||||
*/
|
||||
private final UserContext userContext;
|
||||
|
||||
/**
|
||||
* The Directory which contains the object represented by this
|
||||
* DirectoryObjectResource.
|
||||
@@ -71,6 +78,9 @@ public abstract class DirectoryObjectResource<InternalType extends Identifiable,
|
||||
* Creates a new DirectoryObjectResource which exposes the operations
|
||||
* available for the given object.
|
||||
*
|
||||
* @param userContext
|
||||
* The UserContext associated with the given Directory.
|
||||
*
|
||||
* @param directory
|
||||
* The Directory which contains the given object.
|
||||
*
|
||||
@@ -81,8 +91,10 @@ public abstract class DirectoryObjectResource<InternalType extends Identifiable,
|
||||
* A DirectoryObjectTranslator implementation which handles the type of
|
||||
* object given.
|
||||
*/
|
||||
public DirectoryObjectResource(Directory<InternalType> directory, InternalType object,
|
||||
public DirectoryObjectResource(UserContext userContext,
|
||||
Directory<InternalType> directory, InternalType object,
|
||||
DirectoryObjectTranslator<InternalType, ExternalType> translator) {
|
||||
this.userContext = userContext;
|
||||
this.directory = directory;
|
||||
this.object = object;
|
||||
this.translator = translator;
|
||||
@@ -121,6 +133,9 @@ public abstract class DirectoryObjectResource<InternalType extends Identifiable,
|
||||
if (modifiedObject == null)
|
||||
throw new GuacamoleClientException("Data must be submitted when updating objects.");
|
||||
|
||||
// Filter/sanitize object contents
|
||||
translator.filterExternalObject(userContext, modifiedObject);
|
||||
|
||||
// Perform update
|
||||
translator.applyExternalChanges(object, modifiedObject);
|
||||
directory.update(object);
|
||||
|
@@ -19,8 +19,14 @@
|
||||
|
||||
package org.apache.guacamole.rest.directory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.form.Field;
|
||||
import org.apache.guacamole.form.Form;
|
||||
import org.apache.guacamole.net.auth.Identifiable;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
* Provides bidirectional conversion between REST-specific objects and the
|
||||
@@ -35,7 +41,7 @@ import org.apache.guacamole.net.auth.Identifiable;
|
||||
* deserialized as JSON) between REST clients and resource implementations
|
||||
* when representing the InternalType.
|
||||
*/
|
||||
public interface DirectoryObjectTranslator<InternalType extends Identifiable, ExternalType> {
|
||||
public abstract class DirectoryObjectTranslator<InternalType extends Identifiable, ExternalType> {
|
||||
|
||||
/**
|
||||
* Converts the given object to an object which is intended to be used in
|
||||
@@ -51,7 +57,7 @@ public interface DirectoryObjectTranslator<InternalType extends Identifiable, Ex
|
||||
* @throws GuacamoleException
|
||||
* If the provided object cannot be converted for any reason.
|
||||
*/
|
||||
ExternalType toExternalObject(InternalType object)
|
||||
public abstract ExternalType toExternalObject(InternalType object)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
@@ -69,7 +75,7 @@ public interface DirectoryObjectTranslator<InternalType extends Identifiable, Ex
|
||||
* @throws GuacamoleException
|
||||
* If the provided object cannot be converted for any reason.
|
||||
*/
|
||||
InternalType toInternalObject(ExternalType object)
|
||||
public abstract InternalType toInternalObject(ExternalType object)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
@@ -87,7 +93,67 @@ public interface DirectoryObjectTranslator<InternalType extends Identifiable, Ex
|
||||
* @throws GuacamoleException
|
||||
* If the provided modifications cannot be applied for any reason.
|
||||
*/
|
||||
void applyExternalChanges(InternalType existingObject, ExternalType object)
|
||||
throws GuacamoleException;
|
||||
public abstract void applyExternalChanges(InternalType existingObject,
|
||||
ExternalType object) throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Applies filtering to the contents of the given external object which
|
||||
* came from an untrusted source. Implementations MUST sanitize the
|
||||
* contents of the external object as necessary to guarantee that the
|
||||
* object conforms to declared schema, such as the attributes declared for
|
||||
* each object type at the UserContext level.
|
||||
*
|
||||
* @param userContext
|
||||
* The UserContext associated with the object being filtered.
|
||||
*
|
||||
* @param object
|
||||
* The object to modify such that it strictly conforms to the declared
|
||||
* schema.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the object cannot be filtered due to an error.
|
||||
*/
|
||||
public abstract void filterExternalObject(UserContext userContext,
|
||||
ExternalType object) throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Filters the given map of attribute name/value pairs, producing a new
|
||||
* map containing only attributes defined as fields within the given schema.
|
||||
*
|
||||
* @param schema
|
||||
* The schema whose fields should be used to filter the given map of
|
||||
* attributes.
|
||||
*
|
||||
* @param attributes
|
||||
* The map of attribute name/value pairs to filter.
|
||||
*
|
||||
* @return
|
||||
* A new map containing only the attributes defined as fields within
|
||||
* the given schema.
|
||||
*/
|
||||
public Map<String, String> filterAttributes(Collection<Form> schema,
|
||||
Map<String, String> attributes) {
|
||||
|
||||
Map<String, String> filtered = new HashMap<String, String>();
|
||||
|
||||
// Grab all attribute value strictly for defined fields
|
||||
for (Form form : schema) {
|
||||
for (Field field : form.getFields()) {
|
||||
|
||||
// Pull the associated attribute value from given map
|
||||
String attributeName = field.getName();
|
||||
String attributeValue = attributes.get(attributeName);
|
||||
|
||||
// Include attribute value within filtered map only if
|
||||
// (1) defined and (2) present within provided map
|
||||
if (attributeValue != null)
|
||||
filtered.put(attributeName, attributeValue);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -222,6 +222,9 @@ public abstract class DirectoryResource<InternalType extends Identifiable, Exter
|
||||
if (object == null)
|
||||
throw new GuacamoleClientException("Data must be submitted when creating objects.");
|
||||
|
||||
// Filter/sanitize object contents
|
||||
translator.filterExternalObject(userContext, object);
|
||||
|
||||
// Create the new object within the directory
|
||||
directory.add(translator.toInternalObject(object));
|
||||
|
||||
|
@@ -21,6 +21,7 @@ package org.apache.guacamole.rest.sharingprofile;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.SharingProfile;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
* APISharingProfile objects.
|
||||
*/
|
||||
public class SharingProfileObjectTranslator
|
||||
implements DirectoryObjectTranslator<SharingProfile, APISharingProfile> {
|
||||
extends DirectoryObjectTranslator<SharingProfile, APISharingProfile> {
|
||||
|
||||
@Override
|
||||
public APISharingProfile toExternalObject(SharingProfile object)
|
||||
@@ -53,4 +54,15 @@ public class SharingProfileObjectTranslator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterExternalObject(UserContext userContext,
|
||||
APISharingProfile object) throws GuacamoleException {
|
||||
|
||||
// Filter object attributes by defined schema
|
||||
object.setAttributes(filterAttributes(
|
||||
userContext.getSharingProfileAttributes(),
|
||||
object.getAttributes()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@ public class SharingProfileResource
|
||||
@Assisted Directory<SharingProfile> directory,
|
||||
@Assisted SharingProfile sharingProfile,
|
||||
DirectoryObjectTranslator<SharingProfile, APISharingProfile> translator) {
|
||||
super(directory, sharingProfile, translator);
|
||||
super(userContext, directory, sharingProfile, translator);
|
||||
this.userContext = userContext;
|
||||
this.sharingProfile = sharingProfile;
|
||||
}
|
||||
|
@@ -21,13 +21,14 @@ package org.apache.guacamole.rest.user;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.User;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
|
||||
/**
|
||||
* Translator which converts between User objects and APIUser objects.
|
||||
*/
|
||||
public class UserObjectTranslator
|
||||
implements DirectoryObjectTranslator<User, APIUser> {
|
||||
extends DirectoryObjectTranslator<User, APIUser> {
|
||||
|
||||
@Override
|
||||
public APIUser toExternalObject(User object)
|
||||
@@ -54,4 +55,14 @@ public class UserObjectTranslator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterExternalObject(UserContext userContext, APIUser object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Filter object attributes by defined schema
|
||||
object.setAttributes(filterAttributes(userContext.getUserAttributes(),
|
||||
object.getAttributes()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -92,7 +92,7 @@ public class UserResource
|
||||
@Assisted Directory<User> directory,
|
||||
@Assisted User user,
|
||||
DirectoryObjectTranslator<User, APIUser> translator) {
|
||||
super(directory, user, translator);
|
||||
super(userContext, directory, user, translator);
|
||||
this.userContext = userContext;
|
||||
this.directory = directory;
|
||||
this.user = user;
|
||||
|
Reference in New Issue
Block a user