You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/02/01 18:32:49 UTC
[06/10] guacamole-client git commit: GUACAMOLE-96: Add base support
within JDBC auth for storage of arbitrary attributes from other extensions.
GUACAMOLE-96: Add base support within JDBC auth for storage of arbitrary attributes from other extensions.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/b6de402c
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/b6de402c
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/b6de402c
Branch: refs/heads/master
Commit: b6de402c0c1fbcaa2d6e95ebbc99baef9165bbe9
Parents: a3cee15
Author: Michael Jumper <mj...@apache.org>
Authored: Wed Nov 22 12:29:58 2017 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed Jan 31 15:26:16 2018 -0800
----------------------------------------------------------------------
.../auth/jdbc/base/ArbitraryAttributeMap.java | 162 +++++++++++++++++++
.../auth/jdbc/base/ArbitraryAttributeModel.java | 104 ++++++++++++
.../auth/jdbc/base/ModeledDirectoryObject.java | 33 ++--
.../jdbc/base/ModeledDirectoryObjectMapper.java | 25 ++-
.../base/ModeledDirectoryObjectService.java | 12 ++
.../guacamole/auth/jdbc/base/ObjectModel.java | 49 ++++--
6 files changed, 354 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b6de402c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeMap.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeMap.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeMap.java
new file mode 100644
index 0000000..e2cb438
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeMap.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.jdbc.base;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Map of arbitrary attribute name/value pairs which can alternatively be
+ * exposed as a collection of model objects.
+ */
+public class ArbitraryAttributeMap extends HashMap<String, String> {
+
+ /**
+ * Creates a new ArbitraryAttributeMap containing the name/value pairs
+ * within the given collection of model objects.
+ *
+ * @param models
+ * The model objects of all attributes which should be stored in the
+ * new map as name/value pairs.
+ *
+ * @return
+ * A new ArbitraryAttributeMap containing the name/value pairs within
+ * the given collection of model objects.
+ */
+ public static ArbitraryAttributeMap fromModelCollection(Collection<ArbitraryAttributeModel> models) {
+
+ // Add all name/value pairs from the given collection to the map
+ ArbitraryAttributeMap map = new ArbitraryAttributeMap();
+ for (ArbitraryAttributeModel model : models)
+ map.put(model.getName(), model.getValue());
+
+ return map;
+
+ }
+
+ /**
+ * Returns a collection of model objects which mirrors the contents of this
+ * ArbitraryAttributeMap. Each name/value pair within the map is reflected
+ * by a corresponding model object within the returned collection. Removing
+ * a model object from the collection removes the corresponding name/value
+ * pair from the map. Adding a new model object to the collection adds a
+ * corresponding name/value pair to the map. Changes to a model object
+ * within the collection are NOT reflected on the map, however.
+ *
+ * @return
+ * A collection of model objects which mirrors the contents of this
+ * ArbitraryAttributeMap.
+ */
+ public Collection<ArbitraryAttributeModel> toModelCollection() {
+ return new AbstractCollection<ArbitraryAttributeModel>() {
+
+ @Override
+ public void clear() {
+ ArbitraryAttributeMap.this.clear();
+ }
+
+ @Override
+ public boolean remove(Object o) {
+
+ // The Collection view of an ArbitraryAttributeMap can contain
+ // only ArbitraryAttributeModel objects
+ if (!(o instanceof ArbitraryAttributeModel))
+ return false;
+
+ // The attribute should be removed only if the value matches
+ ArbitraryAttributeModel model = (ArbitraryAttributeModel) o;
+ return ArbitraryAttributeMap.this.remove(model.getName(),
+ model.getValue());
+
+ }
+
+ @Override
+ public boolean add(ArbitraryAttributeModel e) {
+
+ String newValue = e.getValue();
+ String oldValue = put(e.getName(), newValue);
+
+ // If null value is being added, collection changed only if
+ // old value was non-null
+ if (newValue == null)
+ return oldValue != null;
+
+ // Collection changed if value changed
+ return !newValue.equals(oldValue);
+
+ }
+
+ @Override
+ public boolean contains(Object o) {
+
+ // The Collection view of an ArbitraryAttributeMap can contain
+ // only ArbitraryAttributeModel objects
+ if (!(o instanceof ArbitraryAttributeModel))
+ return false;
+
+ // No need to check the value of the attribute if the attribute
+ // is not even present
+ ArbitraryAttributeModel model = (ArbitraryAttributeModel) o;
+ String value = get(model.getName());
+ if (value == null)
+ return false;
+
+ // The name/value pair is present only if the value matches
+ return value.equals(model.getValue());
+
+ }
+
+ @Override
+ public Iterator<ArbitraryAttributeModel> iterator() {
+
+ // Get iterator over all string name/value entries
+ final Iterator<Entry<String, String>> iterator = entrySet().iterator();
+
+ // Dynamically translate each string name/value entry into a
+ // corresponding attribute model object as iteration continues
+ return new Iterator<ArbitraryAttributeModel>() {
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public ArbitraryAttributeModel next() {
+ Entry<String, String> entry = iterator.next();
+ return new ArbitraryAttributeModel(entry.getKey(),
+ entry.getValue());
+ }
+
+ };
+
+ }
+
+ @Override
+ public int size() {
+ return ArbitraryAttributeMap.this.size();
+ }
+
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b6de402c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeModel.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeModel.java
new file mode 100644
index 0000000..b064b54
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeModel.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.jdbc.base;
+
+/**
+ * A single attribute name/value pair belonging to a object which implements
+ * the Attributes interface, such as a Connection or User. Attributes stored
+ * as raw name/value pairs are the attributes which are given to the database
+ * authentication extension for storage by other extensions. Attributes which
+ * are directly supported by the database authentication extension have defined
+ * columns and properties with proper types, constraints, etc.
+ */
+public class ArbitraryAttributeModel {
+
+ /**
+ * The name of the attribute.
+ */
+ private String name;
+
+ /**
+ * The value the attribute is set to.
+ */
+ private String value;
+
+ /**
+ * Creates a new ArbitraryAttributeModel with its name and value both set
+ * to null.
+ */
+ public ArbitraryAttributeModel() {
+ }
+
+ /**
+ * Creates a new ArbitraryAttributeModel with its name and value
+ * initialized to the given values.
+ *
+ * @param name
+ * The name of the attribute.
+ *
+ * @param value
+ * The value the attribute is set to.
+ */
+ public ArbitraryAttributeModel(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Returns the name of this attribute.
+ *
+ * @return
+ * The name of this attribute.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of this attribute.
+ *
+ * @param name
+ * The name of this attribute.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the value of this attribute.
+ *
+ * @return
+ * The value of this attribute.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of this attribute.
+ *
+ * @param value
+ * The value of this attribute.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b6de402c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObject.java
----------------------------------------------------------------------
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 e13445b..ddeda92 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
@@ -65,35 +65,32 @@ public abstract class ModeledDirectoryObject<ModelType extends ObjectModel>
@Override
public Map<String, String> getAttributes() {
-
- // If no arbitrary attributes are defined, just return an empty map
- Map<String, String> arbitraryAttributes = getModel().getArbitraryAttributes();
- if (arbitraryAttributes == null)
- return new HashMap<String, String>();
-
- // Otherwise include any defined arbitrary attributes
- return new HashMap<String, String>(arbitraryAttributes);
-
+ return new HashMap<String, String>(getModel().getArbitraryAttributeMap());
}
@Override
public void setAttributes(Map<String, String> attributes) {
+ ArbitraryAttributeMap arbitraryAttributes = getModel().getArbitraryAttributeMap();
+
// Get set of all supported attribute names
Set<String> supportedAttributes = getSupportedAttributeNames();
- // Initialize model with empty map if no such map is already present
- Map<String, String> arbitraryAttributes = getModel().getArbitraryAttributes();
- if (arbitraryAttributes == null) {
- arbitraryAttributes = new HashMap<String, String>();
- getModel().setArbitraryAttributes(arbitraryAttributes);
- }
-
// Store remaining attributes only if not directly mapped to model
for (Map.Entry<String, String> attribute : attributes.entrySet()) {
+
String name = attribute.getKey();
- if (!supportedAttributes.contains(name))
- arbitraryAttributes.put(name, attribute.getValue());
+ String value = attribute.getValue();
+
+ // Handle null attributes as explicit removal of that attribute,
+ // as the underlying model cannot store null attribute values
+ if (!supportedAttributes.contains(name)) {
+ if (value == null)
+ arbitraryAttributes.remove(name);
+ else
+ arbitraryAttributes.put(name, value);
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b6de402c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java
index ebd95d9..4431e8f 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java
@@ -132,5 +132,28 @@ public interface ModeledDirectoryObjectMapper<ModelType> {
* The number of rows updated.
*/
int update(@Param("object") ModelType object);
-
+
+ /**
+ * Deletes any arbitrary attributes currently associated with the given
+ * object in the database.
+ *
+ * @param object
+ * The object whose arbitrary attributes should be deleted.
+ *
+ * @return
+ * The number of rows deleted.
+ */
+ int deleteAttributes(@Param("object") ModelType object);
+
+ /**
+ * Inserts all arbitrary attributes associated with the given object.
+ *
+ * @param object
+ * The object whose arbitrary attributes should be inserted.
+ *
+ * @return
+ * The number of rows inserted.
+ */
+ int insertAttributes(@Param("object") ModelType object);
+
}
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b6de402c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java
index 2c1402e..21508c4 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java
@@ -32,6 +32,7 @@ import org.apache.guacamole.auth.jdbc.user.UserModel;
import org.apache.guacamole.net.auth.Identifiable;
import org.apache.guacamole.net.auth.permission.ObjectPermission;
import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
+import org.mybatis.guice.transactional.Transactional;
/**
* Service which provides convenience methods for creating, retrieving, and
@@ -446,6 +447,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
}
@Override
+ @Transactional
public InternalType createObject(ModeledAuthenticatedUser user, ExternalType object)
throws GuacamoleException {
@@ -461,6 +463,10 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
// Add implicit permissions
getPermissionMapper().insert(getImplicitPermissions(user, model));
+ // Add any arbitrary attributes
+ if (model.hasArbitraryAttributes())
+ getObjectMapper().insertAttributes(model);
+
return getObjectInstance(user, model);
}
@@ -477,6 +483,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
}
@Override
+ @Transactional
public void updateObject(ModeledAuthenticatedUser user, InternalType object)
throws GuacamoleException {
@@ -486,6 +493,11 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
// Update object
getObjectMapper().update(model);
+ // Replace any existing arbitrary attributes
+ getObjectMapper().deleteAttributes(model);
+ if (model.hasArbitraryAttributes())
+ getObjectMapper().insertAttributes(model);
+
}
@Override
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b6de402c/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectModel.java
----------------------------------------------------------------------
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 3841f6f..c3052b1 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,7 +19,7 @@
package org.apache.guacamole.auth.jdbc.base;
-import java.util.Map;
+import java.util.Collection;
/**
* Object representation of a Guacamole object, such as a user or connection,
@@ -41,7 +41,8 @@ public abstract class ObjectModel {
* Map of all arbitrary attributes associated with this object but not
* directly mapped to a particular column.
*/
- private Map<String, String> arbitraryAttributes;
+ private ArbitraryAttributeMap arbitraryAttributes =
+ new ArbitraryAttributeMap();
/**
* Creates a new, empty object.
@@ -102,23 +103,47 @@ public abstract class ObjectModel {
* with this model which do not otherwise have explicit mappings to
* properties.
*/
- public Map<String, String> getArbitraryAttributes() {
+ public ArbitraryAttributeMap getArbitraryAttributeMap() {
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.
+ * Returns whether at least one arbitrary attribute name/value pair has
+ * been associated with this object.
+ *
+ * @return
+ * true if this object has at least one arbitrary attribute set, false
+ * otherwise.
+ */
+ public boolean hasArbitraryAttributes() {
+ return !arbitraryAttributes.isEmpty();
+ }
+
+ /**
+ * Returns a Collection view of the equivalent attribute model objects
+ * which make up the map of arbitrary attribute name/value pairs returned
+ * by getArbitraryAttributeMap(). Additions and removals on the returned
+ * Collection directly affect the attribute map.
+ *
+ * @return
+ * A Collection view of the map returned by
+ * getArbitraryAttributeMap().
+ */
+ public Collection<ArbitraryAttributeModel> getArbitraryAttributes() {
+ return arbitraryAttributes.toModelCollection();
+ }
+
+ /**
+ * Replaces all arbitrary attributes associated with this object with the
+ * attribute name/value pairs within the given collection of model objects.
*
* @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.
+ * The Collection of model objects containing the attribute name/value
+ * pairs which should replace all currently-stored arbitrary attributes,
+ * if any.
*/
- public void setArbitraryAttributes(Map<String, String> arbitraryAttributes) {
- this.arbitraryAttributes = arbitraryAttributes;
+ public void setArbitraryAttributes(Collection<ArbitraryAttributeModel> arbitraryAttributes) {
+ this.arbitraryAttributes = ArbitraryAttributeMap.fromModelCollection(arbitraryAttributes);
}
}