diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObject.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObject.java index 0d15373c4..e13445bc7 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObject.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObject.java @@ -19,6 +19,11 @@ package org.apache.guacamole.auth.jdbc.base; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import org.apache.guacamole.net.auth.Attributes; import org.apache.guacamole.net.auth.Identifiable; /** @@ -31,7 +36,7 @@ import org.apache.guacamole.net.auth.Identifiable; * The type of model object that corresponds to this object. */ public abstract class ModeledDirectoryObject - extends ModeledObject implements Identifiable { + extends ModeledObject implements Identifiable, Attributes { @Override public String getIdentifier() { @@ -43,4 +48,54 @@ public abstract class ModeledDirectoryObject getModel().setIdentifier(identifier); } + /** + * Returns the names of all attributes explicitly supported by this object. + * Attributes named here have associated mappings within the backing model + * object, and thus should not be included in the arbitrary attribute + * storage. Any attributes set which do not match these names, such as those + * set via other extensions, will be added to arbitrary attribute storage. + * + * @return + * A read-only Set of the names of all attributes explicitly supported + * (mapped to a property of the backing model) by this object. + */ + public Set getSupportedAttributeNames() { + return Collections.emptySet(); + } + + @Override + public Map getAttributes() { + + // If no arbitrary attributes are defined, just return an empty map + Map arbitraryAttributes = getModel().getArbitraryAttributes(); + if (arbitraryAttributes == null) + return new HashMap(); + + // Otherwise include any defined arbitrary attributes + return new HashMap(arbitraryAttributes); + + } + + @Override + public void setAttributes(Map attributes) { + + // Get set of all supported attribute names + Set supportedAttributes = getSupportedAttributeNames(); + + // Initialize model with empty map if no such map is already present + Map arbitraryAttributes = getModel().getArbitraryAttributes(); + if (arbitraryAttributes == null) { + arbitraryAttributes = new HashMap(); + getModel().setArbitraryAttributes(arbitraryAttributes); + } + + // Store remaining attributes only if not directly mapped to model + for (Map.Entry attribute : attributes.entrySet()) { + String name = attribute.getKey(); + if (!supportedAttributes.contains(name)) + arbitraryAttributes.put(name, attribute.getValue()); + } + + } + } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectModel.java index 833c0d993..3841f6f3e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectModel.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectModel.java @@ -19,6 +19,8 @@ package org.apache.guacamole.auth.jdbc.base; +import java.util.Map; + /** * Object representation of a Guacamole object, such as a user or connection, * as represented in the database. @@ -34,7 +36,13 @@ public abstract class ObjectModel { * The unique identifier which identifies this object. */ private String identifier; - + + /** + * Map of all arbitrary attributes associated with this object but not + * directly mapped to a particular column. + */ + private Map arbitraryAttributes; + /** * Creates a new, empty object. */ @@ -82,4 +90,35 @@ public abstract class ObjectModel { this.objectID = objectID; } + /** + * Returns a map of attribute name/value pairs for all attributes associated + * with this model which do not have explicit mappings to actual model + * properties. All other attributes (those which are explicitly supported + * by the model) should instead be mapped to properties with corresponding + * and properly-typed columns. + * + * @return + * A map of attribute name/value pairs for all attributes associated + * with this model which do not otherwise have explicit mappings to + * properties. + */ + public Map getArbitraryAttributes() { + return arbitraryAttributes; + } + + /** + * Sets all arbitrary attribute name/value pairs associated with this + * model. The provided map should contain only attributes which are not + * explicitly supported by the model, as any explicitly-supported + * attributes should instead be mapped to corresponding properties. + * + * @param arbitraryAttributes + * A map of attribute name/value pairs for all attributes associated + * with this model which do not otherwise have explicit mappings to + * properties. + */ + public void setArbitraryAttributes(Map arbitraryAttributes) { + this.arbitraryAttributes = arbitraryAttributes; + } + } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java index eb392bc7b..660212cdc 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java @@ -25,7 +25,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -157,6 +157,21 @@ public class ModeledConnection extends ModeledChildDirectoryObject ATTRIBUTE_NAMES = + Collections.unmodifiableSet(new HashSet(Arrays.asList( + GUACD_HOSTNAME_NAME, + GUACD_PORT_NAME, + GUACD_ENCRYPTION_NAME, + MAX_CONNECTIONS_NAME, + MAX_CONNECTIONS_PER_USER_NAME, + CONNECTION_WEIGHT, + FAILOVER_ONLY_NAME + ))); + /** * The environment of the Guacamole server. */ @@ -253,10 +268,16 @@ public class ModeledConnection extends ModeledChildDirectoryObject getSupportedAttributeNames() { + return ATTRIBUTE_NAMES; + } + @Override public Map getAttributes() { - Map attributes = new HashMap(); + // Include any defined arbitrary attributes + Map attributes = super.getAttributes(); // Set connection limit attribute attributes.put(MAX_CONNECTIONS_NAME, NumericField.format(getModel().getMaxConnections())); @@ -305,6 +326,9 @@ public class ModeledConnection extends ModeledChildDirectoryObject attributes) { + // Set arbitrary attributes + super.setAttributes(attributes); + // Translate connection limit attribute try { getModel().setMaxConnections(NumericField.parse(attributes.get(MAX_CONNECTIONS_NAME))); } catch (NumberFormatException e) { diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java index 7e65c7f75..3aac52d59 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java @@ -23,7 +23,7 @@ import com.google.inject.Inject; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.guacamole.GuacamoleException; @@ -89,6 +89,17 @@ public class ModeledConnectionGroup extends ModeledChildDirectoryObject ATTRIBUTE_NAMES = + Collections.unmodifiableSet(new HashSet(Arrays.asList( + MAX_CONNECTIONS_NAME, + MAX_CONNECTIONS_PER_USER_NAME, + ENABLE_SESSION_AFFINITY + ))); + /** * The environment of the Guacamole server. */ @@ -156,10 +167,16 @@ public class ModeledConnectionGroup extends ModeledChildDirectoryObject getSupportedAttributeNames() { + return ATTRIBUTE_NAMES; + } + @Override public Map getAttributes() { - Map attributes = new HashMap(); + // Include any defined arbitrary attributes + Map attributes = super.getAttributes(); // Set connection limit attribute attributes.put(MAX_CONNECTIONS_NAME, NumericField.format(getModel().getMaxConnections())); @@ -177,6 +194,9 @@ public class ModeledConnectionGroup extends ModeledChildDirectoryObject attributes) { + // Set arbitrary attributes + super.setAttributes(attributes); + // Translate connection limit attribute try { getModel().setMaxConnections(NumericField.parse(attributes.get(MAX_CONNECTIONS_NAME))); } catch (NumberFormatException e) { diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java index 19c70bb7e..1acbd790f 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java @@ -95,14 +95,4 @@ public class ModeledSharingProfile this.parameters = parameters; } - @Override - public Map getAttributes() { - return Collections.emptyMap(); - } - - @Override - public void setAttributes(Map attributes) { - // Do nothing - no attributes - } - } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index 5ffc458e5..b29565551 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -28,9 +28,10 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TimeZone; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObject; import org.apache.guacamole.auth.jdbc.security.PasswordEncryptionService; @@ -144,6 +145,25 @@ public class ModeledUser extends ModeledDirectoryObject implements Us ACCOUNT_RESTRICTIONS )); + /** + * The names of all attributes which are explicitly supported by this + * extension's User objects. + */ + public static final Set ATTRIBUTE_NAMES = + Collections.unmodifiableSet(new HashSet(Arrays.asList( + User.Attribute.FULL_NAME, + User.Attribute.EMAIL_ADDRESS, + User.Attribute.ORGANIZATION, + User.Attribute.ORGANIZATIONAL_ROLE, + DISABLED_ATTRIBUTE_NAME, + EXPIRED_ATTRIBUTE_NAME, + ACCESS_WINDOW_START_ATTRIBUTE_NAME, + ACCESS_WINDOW_END_ATTRIBUTE_NAME, + VALID_FROM_ATTRIBUTE_NAME, + VALID_UNTIL_ATTRIBUTE_NAME, + TIMEZONE_ATTRIBUTE_NAME + ))); + /** * Service for managing users. */ @@ -547,10 +567,16 @@ public class ModeledUser extends ModeledDirectoryObject implements Us } + @Override + public Set getSupportedAttributeNames() { + return ATTRIBUTE_NAMES; + } + @Override public Map getAttributes() { - Map attributes = new HashMap(); + // Include any defined arbitrary attributes + Map attributes = super.getAttributes(); // Always include unrestricted attributes putUnrestrictedAttributes(attributes); @@ -565,6 +591,9 @@ public class ModeledUser extends ModeledDirectoryObject implements Us @Override public void setAttributes(Map attributes) { + // Set arbitrary attributes + super.setAttributes(attributes); + // Always assign unrestricted attributes setUnrestrictedAttributes(attributes);