mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-96: Merge allow extensions to voluntarily store each other's data.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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<ModelType extends ObjectModel>
|
||||
extends ModeledObject<ModelType> implements Identifiable {
|
||||
extends ModeledObject<ModelType> implements Identifiable, Attributes {
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
@@ -43,4 +48,51 @@ public abstract class ModeledDirectoryObject<ModelType extends ObjectModel>
|
||||
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<String> getSupportedAttributeNames() {
|
||||
return Collections.<String>emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
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();
|
||||
|
||||
// Store remaining attributes only if not directly mapped to model
|
||||
for (Map.Entry<String, String> attribute : attributes.entrySet()) {
|
||||
|
||||
String name = attribute.getKey();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
package org.apache.guacamole.auth.jdbc.base;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Object representation of a Guacamole object, such as a user or connection,
|
||||
* as represented in the database.
|
||||
@@ -34,7 +36,14 @@ 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 ArbitraryAttributeMap arbitraryAttributes =
|
||||
new ArbitraryAttributeMap();
|
||||
|
||||
/**
|
||||
* Creates a new, empty object.
|
||||
*/
|
||||
@@ -82,4 +91,59 @@ 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 ArbitraryAttributeMap getArbitraryAttributeMap() {
|
||||
return arbitraryAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* The Collection of model objects containing the attribute name/value
|
||||
* pairs which should replace all currently-stored arbitrary attributes,
|
||||
* if any.
|
||||
*/
|
||||
public void setArbitraryAttributes(Collection<ArbitraryAttributeModel> arbitraryAttributes) {
|
||||
this.arbitraryAttributes = ArbitraryAttributeMap.fromModelCollection(arbitraryAttributes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<ConnectionMod
|
||||
GUACD_PARAMETERS
|
||||
));
|
||||
|
||||
/**
|
||||
* The names of all attributes which are explicitly supported by this
|
||||
* extension's Connection objects.
|
||||
*/
|
||||
public static final Set<String> ATTRIBUTE_NAMES =
|
||||
Collections.unmodifiableSet(new HashSet<String>(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<ConnectionMod
|
||||
return tunnelService.getActiveConnections(this).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSupportedAttributeNames() {
|
||||
return ATTRIBUTE_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
// Include any defined arbitrary attributes
|
||||
Map<String, String> 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<ConnectionMod
|
||||
@Override
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
|
||||
// Set arbitrary attributes
|
||||
super.setAttributes(attributes);
|
||||
|
||||
// Translate connection limit attribute
|
||||
try { getModel().setMaxConnections(NumericField.parse(attributes.get(MAX_CONNECTIONS_NAME))); }
|
||||
catch (NumberFormatException e) {
|
||||
|
@@ -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<Connecti
|
||||
CONCURRENCY_LIMITS
|
||||
));
|
||||
|
||||
/**
|
||||
* The names of all attributes which are explicitly supported by this
|
||||
* extension's ConnectionGroup objects.
|
||||
*/
|
||||
public static final Set<String> ATTRIBUTE_NAMES =
|
||||
Collections.unmodifiableSet(new HashSet<String>(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<Connecti
|
||||
return getModel().getConnectionGroupIdentifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSupportedAttributeNames() {
|
||||
return ATTRIBUTE_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
// Include any defined arbitrary attributes
|
||||
Map<String, String> 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<Connecti
|
||||
@Override
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
|
||||
// Set arbitrary attributes
|
||||
super.setAttributes(attributes);
|
||||
|
||||
// Translate connection limit attribute
|
||||
try { getModel().setMaxConnections(NumericField.parse(attributes.get(MAX_CONNECTIONS_NAME))); }
|
||||
catch (NumberFormatException e) {
|
||||
|
@@ -95,14 +95,4 @@ public class ModeledSharingProfile
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
return Collections.<String, String>emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
// Do nothing - no attributes
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<UserModel> implements Us
|
||||
ACCOUNT_RESTRICTIONS
|
||||
));
|
||||
|
||||
/**
|
||||
* The names of all attributes which are explicitly supported by this
|
||||
* extension's User objects.
|
||||
*/
|
||||
public static final Set<String> ATTRIBUTE_NAMES =
|
||||
Collections.unmodifiableSet(new HashSet<String>(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<UserModel> implements Us
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSupportedAttributeNames() {
|
||||
return ATTRIBUTE_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
// Include any defined arbitrary attributes
|
||||
Map<String, String> attributes = super.getAttributes();
|
||||
|
||||
// Always include unrestricted attributes
|
||||
putUnrestrictedAttributes(attributes);
|
||||
@@ -565,6 +591,9 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
|
||||
@Override
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
|
||||
// Set arbitrary attributes
|
||||
super.setAttributes(attributes);
|
||||
|
||||
// Always assign unrestricted attributes
|
||||
setUnrestrictedAttributes(attributes);
|
||||
|
||||
|
@@ -185,6 +185,94 @@ CREATE TABLE guacamole_sharing_profile_parameter (
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary user attributes. Each attribute is simply a name/value
|
||||
-- pair associated with a user. Arbitrary attributes are defined by other
|
||||
-- extensions. Attributes defined by this extension will be mapped to
|
||||
-- properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_user_attribute (
|
||||
|
||||
`user_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (user_id, attribute_name),
|
||||
KEY `user_id` (`user_id`),
|
||||
|
||||
CONSTRAINT guacamole_user_attribute_ibfk_1
|
||||
FOREIGN KEY (user_id)
|
||||
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_attribute (
|
||||
|
||||
`connection_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_id, attribute_name),
|
||||
KEY `connection_id` (`connection_id`),
|
||||
|
||||
CONSTRAINT guacamole_connection_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_id)
|
||||
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection group attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection group. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_group_attribute (
|
||||
|
||||
`connection_group_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_group_id, attribute_name),
|
||||
KEY `connection_group_id` (`connection_group_id`),
|
||||
|
||||
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_group_id)
|
||||
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a sharing profile. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_sharing_profile_attribute (
|
||||
|
||||
`sharing_profile_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (sharing_profile_id, attribute_name),
|
||||
KEY `sharing_profile_id` (`sharing_profile_id`),
|
||||
|
||||
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
|
||||
FOREIGN KEY (sharing_profile_id)
|
||||
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of connection permissions. Each connection permission grants a user
|
||||
-- specific access to a connection.
|
||||
|
@@ -0,0 +1,106 @@
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
--
|
||||
-- Table of arbitrary user attributes. Each attribute is simply a name/value
|
||||
-- pair associated with a user. Arbitrary attributes are defined by other
|
||||
-- extensions. Attributes defined by this extension will be mapped to
|
||||
-- properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_user_attribute (
|
||||
|
||||
`user_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (user_id, attribute_name),
|
||||
KEY `user_id` (`user_id`),
|
||||
|
||||
CONSTRAINT guacamole_user_attribute_ibfk_1
|
||||
FOREIGN KEY (user_id)
|
||||
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_attribute (
|
||||
|
||||
`connection_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_id, attribute_name),
|
||||
KEY `connection_id` (`connection_id`),
|
||||
|
||||
CONSTRAINT guacamole_connection_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_id)
|
||||
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection group attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection group. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_group_attribute (
|
||||
|
||||
`connection_group_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_group_id, attribute_name),
|
||||
KEY `connection_group_id` (`connection_group_id`),
|
||||
|
||||
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_group_id)
|
||||
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a sharing profile. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_sharing_profile_attribute (
|
||||
|
||||
`sharing_profile_id` int(11) NOT NULL,
|
||||
`attribute_name` varchar(128) NOT NULL,
|
||||
`attribute_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (sharing_profile_id, attribute_name),
|
||||
KEY `sharing_profile_id` (`sharing_profile_id`),
|
||||
|
||||
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
|
||||
FOREIGN KEY (sharing_profile_id)
|
||||
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
@@ -47,6 +47,14 @@
|
||||
<result column="sharing_profile_id"/>
|
||||
</collection>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="connection_id" foreignColumn="connection_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all connection identifiers -->
|
||||
@@ -87,7 +95,7 @@
|
||||
|
||||
<!-- Select multiple connections by identifier -->
|
||||
<select id="select" resultMap="ConnectionResultMap"
|
||||
resultSets="connections,sharingProfiles">
|
||||
resultSets="connections,sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_connection.connection_id,
|
||||
@@ -119,11 +127,22 @@
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_attribute
|
||||
WHERE connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple connections by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="ConnectionResultMap"
|
||||
resultSets="connections,sharingProfiles">
|
||||
resultSets="connections,sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_connection.connection_id,
|
||||
@@ -161,6 +180,20 @@
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
guacamole_connection_attribute.connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_attribute
|
||||
JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection_attribute.connection_id
|
||||
WHERE guacamole_connection_attribute.connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single connection by name -->
|
||||
@@ -242,4 +275,25 @@
|
||||
WHERE connection_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with connection -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_connection_attribute
|
||||
WHERE connection_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for connection -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_connection_attribute (
|
||||
connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -48,6 +48,14 @@
|
||||
<result column="connection_id"/>
|
||||
</collection>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="connection_group_id" foreignColumn="connection_group_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all connection group identifiers -->
|
||||
@@ -88,7 +96,7 @@
|
||||
|
||||
<!-- Select multiple connection groups by identifier -->
|
||||
<select id="select" resultMap="ConnectionGroupResultMap"
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections">
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
connection_group_id,
|
||||
@@ -121,11 +129,22 @@
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_group_attribute
|
||||
WHERE connection_group_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple connection groups by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="ConnectionGroupResultMap"
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections">
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_connection_group.connection_group_id,
|
||||
@@ -167,6 +186,20 @@
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
guacamole_connection_group_attribute.connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_group_attribute
|
||||
JOIN guacamole_connection_group_permission ON guacamole_connection_group_permission.connection_group_id = guacamole_connection_group_attribute.connection_group_id
|
||||
WHERE guacamole_connection_group_attribute.connection_group_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single connection group by name -->
|
||||
@@ -229,4 +262,25 @@
|
||||
WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with connection group -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_connection_group_attribute
|
||||
WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for connection group -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_connection_group_attribute (
|
||||
connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -25,9 +25,20 @@
|
||||
|
||||
<!-- Result mapper for sharing profile objects -->
|
||||
<resultMap id="SharingProfileResultMap" type="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileModel">
|
||||
|
||||
<!-- Sharing profile properties -->
|
||||
<id column="sharing_profile_id" property="objectID" jdbcType="INTEGER"/>
|
||||
<result column="sharing_profile_name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="primary_connection_id" property="parentIdentifier" jdbcType="INTEGER"/>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="sharing_profile_id" foreignColumn="sharing_profile_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all sharing profile identifiers -->
|
||||
@@ -46,7 +57,8 @@
|
||||
</select>
|
||||
|
||||
<!-- Select multiple sharing profiles by identifier -->
|
||||
<select id="select" resultMap="SharingProfileResultMap">
|
||||
<select id="select" resultMap="SharingProfileResultMap"
|
||||
resultSets="sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
sharing_profile_id,
|
||||
@@ -57,12 +69,24 @@
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_sharing_profile_attribute
|
||||
WHERE sharing_profile_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple sharing profiles by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="SharingProfileResultMap">
|
||||
<select id="selectReadable" resultMap="SharingProfileResultMap"
|
||||
resultSets="sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_sharing_profile.sharing_profile_id,
|
||||
@@ -76,7 +100,21 @@
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
guacamole_sharing_profile_attribute.sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_sharing_profile_attribute
|
||||
JOIN guacamole_sharing_profile_permission ON guacamole_sharing_profile_permission.sharing_profile_id = guacamole_sharing_profile_attribute.sharing_profile_id
|
||||
WHERE guacamole_sharing_profile_attribute.sharing_profile_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
@@ -123,4 +161,25 @@
|
||||
WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with sharing profile -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_sharing_profile_attribute
|
||||
WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for sharing profile -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_sharing_profile_attribute (
|
||||
sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
@@ -25,6 +25,8 @@
|
||||
|
||||
<!-- Result mapper for user objects -->
|
||||
<resultMap id="UserResultMap" type="org.apache.guacamole.auth.jdbc.user.UserModel" >
|
||||
|
||||
<!-- User properties -->
|
||||
<id column="user_id" property="objectID" jdbcType="INTEGER"/>
|
||||
<result column="username" property="identifier" jdbcType="VARCHAR"/>
|
||||
<result column="password_hash" property="passwordHash" jdbcType="BINARY"/>
|
||||
@@ -42,6 +44,15 @@
|
||||
<result column="organization" property="organization" jdbcType="VARCHAR"/>
|
||||
<result column="organizational_role" property="organizationalRole" jdbcType="VARCHAR"/>
|
||||
<result column="last_active" property="lastActive" jdbcType="TIMESTAMP"/>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="user_id" foreignColumn="user_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all usernames -->
|
||||
@@ -61,7 +72,8 @@
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username -->
|
||||
<select id="select" resultMap="UserResultMap">
|
||||
<select id="select" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
@@ -88,12 +100,25 @@
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
GROUP BY guacamole_user.user_id
|
||||
GROUP BY guacamole_user.user_id;
|
||||
|
||||
SELECT
|
||||
guacamole_user_attribute.user_id,
|
||||
guacamole_user_attribute.attribute_name,
|
||||
guacamole_user_attribute.attribute_value
|
||||
FROM guacamole_user_attribute
|
||||
JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username only if readable -->
|
||||
<select id="selectReadable" resultMap="UserResultMap">
|
||||
<select id="selectReadable" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
@@ -123,12 +148,28 @@
|
||||
</foreach>
|
||||
AND guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
GROUP BY guacamole_user.user_id
|
||||
GROUP BY guacamole_user.user_id;
|
||||
|
||||
SELECT
|
||||
guacamole_user_attribute.user_id,
|
||||
guacamole_user_attribute.attribute_name,
|
||||
guacamole_user_attribute.attribute_value
|
||||
FROM guacamole_user_attribute
|
||||
JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id
|
||||
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single user by username -->
|
||||
<select id="selectOne" resultMap="UserResultMap">
|
||||
<select id="selectOne" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
@@ -152,7 +193,15 @@
|
||||
LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id
|
||||
WHERE
|
||||
guacamole_user.username = #{username,jdbcType=VARCHAR}
|
||||
GROUP BY guacamole_user.user_id
|
||||
GROUP BY guacamole_user.user_id;
|
||||
|
||||
SELECT
|
||||
guacamole_user_attribute.user_id,
|
||||
guacamole_user_attribute.attribute_name,
|
||||
guacamole_user_attribute.attribute_value
|
||||
FROM guacamole_user_attribute
|
||||
JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id
|
||||
WHERE username = #{username,jdbcType=VARCHAR};
|
||||
|
||||
</select>
|
||||
|
||||
@@ -223,4 +272,25 @@
|
||||
WHERE user_id = #{object.objectID,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
<!-- Delete attributes associated with user -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_user_attribute
|
||||
WHERE user_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for user -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_user_attribute (
|
||||
user_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -251,6 +251,102 @@ CREATE TABLE guacamole_sharing_profile_parameter (
|
||||
CREATE INDEX guacamole_sharing_profile_parameter_sharing_profile_id
|
||||
ON guacamole_sharing_profile_parameter(sharing_profile_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary user attributes. Each attribute is simply a name/value
|
||||
-- pair associated with a user. Arbitrary attributes are defined by other
|
||||
-- extensions. Attributes defined by this extension will be mapped to
|
||||
-- properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_user_attribute (
|
||||
|
||||
user_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (user_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_user_attribute_ibfk_1
|
||||
FOREIGN KEY (user_id)
|
||||
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_user_attribute_user_id
|
||||
ON guacamole_user_attribute(user_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_attribute (
|
||||
|
||||
connection_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_connection_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_id)
|
||||
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_connection_attribute_connection_id
|
||||
ON guacamole_connection_attribute(connection_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection group attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection group. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_group_attribute (
|
||||
|
||||
connection_group_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_group_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_group_id)
|
||||
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_connection_group_attribute_connection_group_id
|
||||
ON guacamole_connection_group_attribute(connection_group_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a sharing profile. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_sharing_profile_attribute (
|
||||
|
||||
sharing_profile_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (sharing_profile_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
|
||||
FOREIGN KEY (sharing_profile_id)
|
||||
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_sharing_profile_attribute_sharing_profile_id
|
||||
ON guacamole_sharing_profile_attribute(sharing_profile_id);
|
||||
|
||||
--
|
||||
-- Table of connection permissions. Each connection permission grants a user
|
||||
-- specific access to a connection.
|
||||
|
@@ -0,0 +1,114 @@
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
--
|
||||
-- Table of arbitrary user attributes. Each attribute is simply a name/value
|
||||
-- pair associated with a user. Arbitrary attributes are defined by other
|
||||
-- extensions. Attributes defined by this extension will be mapped to
|
||||
-- properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_user_attribute (
|
||||
|
||||
user_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (user_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_user_attribute_ibfk_1
|
||||
FOREIGN KEY (user_id)
|
||||
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_user_attribute_user_id
|
||||
ON guacamole_user_attribute(user_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_attribute (
|
||||
|
||||
connection_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_connection_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_id)
|
||||
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_connection_attribute_connection_id
|
||||
ON guacamole_connection_attribute(connection_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection group attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection group. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_connection_group_attribute (
|
||||
|
||||
connection_group_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_group_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
|
||||
FOREIGN KEY (connection_group_id)
|
||||
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_connection_group_attribute_connection_group_id
|
||||
ON guacamole_connection_group_attribute(connection_group_id);
|
||||
|
||||
--
|
||||
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a sharing profile. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_sharing_profile_attribute (
|
||||
|
||||
sharing_profile_id integer NOT NULL,
|
||||
attribute_name varchar(128) NOT NULL,
|
||||
attribute_value varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (sharing_profile_id, attribute_name),
|
||||
|
||||
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
|
||||
FOREIGN KEY (sharing_profile_id)
|
||||
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE INDEX guacamole_sharing_profile_attribute_sharing_profile_id
|
||||
ON guacamole_sharing_profile_attribute(sharing_profile_id);
|
@@ -47,6 +47,14 @@
|
||||
<result column="sharing_profile_id"/>
|
||||
</collection>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="connection_id" foreignColumn="connection_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all connection identifiers -->
|
||||
@@ -87,7 +95,7 @@
|
||||
|
||||
<!-- Select multiple connections by identifier -->
|
||||
<select id="select" resultMap="ConnectionResultMap"
|
||||
resultSets="connections,sharingProfiles">
|
||||
resultSets="connections,sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_connection.connection_id,
|
||||
@@ -119,11 +127,22 @@
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_attribute
|
||||
WHERE connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple connections by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="ConnectionResultMap"
|
||||
resultSets="connections,sharingProfiles">
|
||||
resultSets="connections,sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_connection.connection_id,
|
||||
@@ -161,6 +180,20 @@
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
guacamole_connection_attribute.connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_attribute
|
||||
JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection_attribute.connection_id
|
||||
WHERE guacamole_connection_attribute.connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single connection by name -->
|
||||
@@ -242,4 +275,25 @@
|
||||
WHERE connection_id = #{object.objectID,jdbcType=INTEGER}::integer
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with connection -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_connection_attribute
|
||||
WHERE connection_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for connection -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_connection_attribute (
|
||||
connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -48,6 +48,14 @@
|
||||
<result column="connection_id"/>
|
||||
</collection>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="connection_group_id" foreignColumn="connection_group_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all connection group identifiers -->
|
||||
@@ -88,7 +96,7 @@
|
||||
|
||||
<!-- Select multiple connection groups by identifier -->
|
||||
<select id="select" resultMap="ConnectionGroupResultMap"
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections">
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
connection_group_id,
|
||||
@@ -121,11 +129,22 @@
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_group_attribute
|
||||
WHERE connection_group_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple connection groups by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="ConnectionGroupResultMap"
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections">
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_connection_group.connection_group_id,
|
||||
@@ -167,6 +186,20 @@
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
guacamole_connection_group_attribute.connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_connection_group_attribute
|
||||
JOIN guacamole_connection_group_permission ON guacamole_connection_group_permission.connection_group_id = guacamole_connection_group_attribute.connection_group_id
|
||||
WHERE guacamole_connection_group_attribute.connection_group_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single connection group by name -->
|
||||
@@ -229,4 +262,25 @@
|
||||
WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER}::integer
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with connection group -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_connection_group_attribute
|
||||
WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for connection group -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_connection_group_attribute (
|
||||
connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -25,9 +25,20 @@
|
||||
|
||||
<!-- Result mapper for sharing profile objects -->
|
||||
<resultMap id="SharingProfileResultMap" type="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileModel">
|
||||
|
||||
<!-- Sharing profile properties -->
|
||||
<id column="sharing_profile_id" property="objectID" jdbcType="INTEGER"/>
|
||||
<result column="sharing_profile_name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="primary_connection_id" property="parentIdentifier" jdbcType="INTEGER"/>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="sharing_profile_id" foreignColumn="sharing_profile_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all sharing profile identifiers -->
|
||||
@@ -46,7 +57,8 @@
|
||||
</select>
|
||||
|
||||
<!-- Select multiple sharing profiles by identifier -->
|
||||
<select id="select" resultMap="SharingProfileResultMap">
|
||||
<select id="select" resultMap="SharingProfileResultMap"
|
||||
resultSets="sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
sharing_profile_id,
|
||||
@@ -57,12 +69,24 @@
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_sharing_profile_attribute
|
||||
WHERE sharing_profile_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple sharing profiles by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="SharingProfileResultMap">
|
||||
<select id="selectReadable" resultMap="SharingProfileResultMap"
|
||||
resultSets="sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_sharing_profile.sharing_profile_id,
|
||||
@@ -76,7 +100,21 @@
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
guacamole_sharing_profile_attribute.sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM guacamole_sharing_profile_attribute
|
||||
JOIN guacamole_sharing_profile_permission ON guacamole_sharing_profile_permission.sharing_profile_id = guacamole_sharing_profile_attribute.sharing_profile_id
|
||||
WHERE guacamole_sharing_profile_attribute.sharing_profile_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}::integer
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
@@ -123,4 +161,25 @@
|
||||
WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER}::integer
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with sharing profile -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_sharing_profile_attribute
|
||||
WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for sharing profile -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_sharing_profile_attribute (
|
||||
sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
@@ -25,6 +25,8 @@
|
||||
|
||||
<!-- Result mapper for user objects -->
|
||||
<resultMap id="UserResultMap" type="org.apache.guacamole.auth.jdbc.user.UserModel" >
|
||||
|
||||
<!-- User properties -->
|
||||
<id column="user_id" property="objectID" jdbcType="INTEGER"/>
|
||||
<result column="username" property="identifier" jdbcType="VARCHAR"/>
|
||||
<result column="password_hash" property="passwordHash" jdbcType="BINARY"/>
|
||||
@@ -42,6 +44,15 @@
|
||||
<result column="organization" property="organization" jdbcType="VARCHAR"/>
|
||||
<result column="organizational_role" property="organizationalRole" jdbcType="VARCHAR"/>
|
||||
<result column="last_active" property="lastActive" jdbcType="TIMESTAMP"/>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="user_id" foreignColumn="user_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all usernames -->
|
||||
@@ -61,7 +72,8 @@
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username -->
|
||||
<select id="select" resultMap="UserResultMap">
|
||||
<select id="select" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
@@ -88,12 +100,25 @@
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
GROUP BY guacamole_user.user_id
|
||||
GROUP BY guacamole_user.user_id;
|
||||
|
||||
SELECT
|
||||
guacamole_user_attribute.user_id,
|
||||
guacamole_user_attribute.attribute_name,
|
||||
guacamole_user_attribute.attribute_value
|
||||
FROM guacamole_user_attribute
|
||||
JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username only if readable -->
|
||||
<select id="selectReadable" resultMap="UserResultMap">
|
||||
<select id="selectReadable" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
@@ -123,12 +148,28 @@
|
||||
</foreach>
|
||||
AND guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
GROUP BY guacamole_user.user_id
|
||||
GROUP BY guacamole_user.user_id;
|
||||
|
||||
SELECT
|
||||
guacamole_user_attribute.user_id,
|
||||
guacamole_user_attribute.attribute_name,
|
||||
guacamole_user_attribute.attribute_value
|
||||
FROM guacamole_user_attribute
|
||||
JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id
|
||||
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single user by username -->
|
||||
<select id="selectOne" resultMap="UserResultMap">
|
||||
<select id="selectOne" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
@@ -152,7 +193,15 @@
|
||||
LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id
|
||||
WHERE
|
||||
guacamole_user.username = #{username,jdbcType=VARCHAR}
|
||||
GROUP BY guacamole_user.user_id
|
||||
GROUP BY guacamole_user.user_id;
|
||||
|
||||
SELECT
|
||||
guacamole_user_attribute.user_id,
|
||||
guacamole_user_attribute.attribute_name,
|
||||
guacamole_user_attribute.attribute_value
|
||||
FROM guacamole_user_attribute
|
||||
JOIN guacamole_user ON guacamole_user.user_id = guacamole_user_attribute.user_id
|
||||
WHERE username = #{username,jdbcType=VARCHAR};
|
||||
|
||||
</select>
|
||||
|
||||
@@ -223,4 +272,25 @@
|
||||
WHERE user_id = #{object.objectID,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with user -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM guacamole_user_attribute
|
||||
WHERE user_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for user -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO guacamole_user_attribute (
|
||||
user_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -241,6 +241,115 @@ CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_primary_connection_id]
|
||||
ON [guacamole_sharing_profile] ([primary_connection_id]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary user attributes. Each attribute is simply a name/value
|
||||
-- pair associated with a user. Arbitrary attributes are defined by other
|
||||
-- extensions. Attributes defined by this extension will be mapped to
|
||||
-- properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_user_attribute] (
|
||||
|
||||
[user_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
CONSTRAINT [PK_guacamole_user_attribute]
|
||||
PRIMARY KEY CLUSTERED ([user_id], [attribute_name]),
|
||||
|
||||
CONSTRAINT [FK_guacamole_user_attribute_user_id]
|
||||
FOREIGN KEY ([user_id])
|
||||
REFERENCES [guacamole_user] ([user_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_user_attribute_user_id]
|
||||
ON [guacamole_user_attribute] ([user_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_connection_attribute] (
|
||||
|
||||
[connection_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_id, attribute_name),
|
||||
|
||||
CONSTRAINT [FK_guacamole_connection_attribute_connection_id]
|
||||
FOREIGN KEY ([connection_id])
|
||||
REFERENCES [guacamole_connection] ([connection_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_attribute_connection_id]
|
||||
ON [guacamole_connection_attribute] ([connection_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection group attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection group. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_connection_group_attribute] (
|
||||
|
||||
[connection_group_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_group_id, attribute_name),
|
||||
|
||||
CONSTRAINT [FK_guacamole_connection_group_attribute_connection_group_id]
|
||||
FOREIGN KEY ([connection_group_id])
|
||||
REFERENCES [guacamole_connection_group] ([connection_group_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_attribute_connection_group_id]
|
||||
ON [guacamole_connection_group_attribute] ([connection_group_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a sharing profile. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_sharing_profile_attribute] (
|
||||
|
||||
[sharing_profile_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
PRIMARY KEY (sharing_profile_id, attribute_name),
|
||||
|
||||
CONSTRAINT [FK_guacamole_sharing_profile_attribute_sharing_profile_id]
|
||||
FOREIGN KEY ([sharing_profile_id])
|
||||
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_attribute_sharing_profile_id]
|
||||
ON [guacamole_sharing_profile_attribute] ([sharing_profile_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of connection parameters. Each parameter is simply a name/value pair
|
||||
-- associated with a connection.
|
||||
@@ -683,3 +792,4 @@ AS BEGIN
|
||||
|
||||
END
|
||||
GO
|
||||
|
||||
|
@@ -0,0 +1,127 @@
|
||||
--
|
||||
-- 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.
|
||||
--
|
||||
|
||||
--
|
||||
-- Table of arbitrary user attributes. Each attribute is simply a name/value
|
||||
-- pair associated with a user. Arbitrary attributes are defined by other
|
||||
-- extensions. Attributes defined by this extension will be mapped to
|
||||
-- properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_user_attribute] (
|
||||
|
||||
[user_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
CONSTRAINT [PK_guacamole_user_attribute]
|
||||
PRIMARY KEY CLUSTERED ([user_id], [attribute_name]),
|
||||
|
||||
CONSTRAINT [FK_guacamole_user_attribute_user_id]
|
||||
FOREIGN KEY ([user_id])
|
||||
REFERENCES [guacamole_user] ([user_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_user_attribute_user_id]
|
||||
ON [guacamole_user_attribute] ([user_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_connection_attribute] (
|
||||
|
||||
[connection_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_id, attribute_name),
|
||||
|
||||
CONSTRAINT [FK_guacamole_connection_attribute_connection_id]
|
||||
FOREIGN KEY ([connection_id])
|
||||
REFERENCES [guacamole_connection] ([connection_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_attribute_connection_id]
|
||||
ON [guacamole_connection_attribute] ([connection_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary connection group attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a connection group. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_connection_group_attribute] (
|
||||
|
||||
[connection_group_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
PRIMARY KEY (connection_group_id, attribute_name),
|
||||
|
||||
CONSTRAINT [FK_guacamole_connection_group_attribute_connection_group_id]
|
||||
FOREIGN KEY ([connection_group_id])
|
||||
REFERENCES [guacamole_connection_group] ([connection_group_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_attribute_connection_group_id]
|
||||
ON [guacamole_connection_group_attribute] ([connection_group_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
||||
|
||||
--
|
||||
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
|
||||
-- name/value pair associated with a sharing profile. Arbitrary attributes are
|
||||
-- defined by other extensions. Attributes defined by this extension will be
|
||||
-- mapped to properly-typed columns of a specific table.
|
||||
--
|
||||
|
||||
CREATE TABLE [guacamole_sharing_profile_attribute] (
|
||||
|
||||
[sharing_profile_id] [int] NOT NULL,
|
||||
[attribute_name] [nvarchar](128) NOT NULL,
|
||||
[attribute_value] [nvarchar](4000) NOT NULL,
|
||||
|
||||
PRIMARY KEY (sharing_profile_id, attribute_name),
|
||||
|
||||
CONSTRAINT [FK_guacamole_sharing_profile_attribute_sharing_profile_id]
|
||||
FOREIGN KEY ([sharing_profile_id])
|
||||
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
|
||||
ON DELETE CASCADE
|
||||
|
||||
);
|
||||
|
||||
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_attribute_sharing_profile_id]
|
||||
ON [guacamole_sharing_profile_attribute] ([sharing_profile_id])
|
||||
INCLUDE ([attribute_name], [attribute_value]);
|
||||
GO
|
@@ -47,6 +47,14 @@
|
||||
<result column="sharing_profile_id"/>
|
||||
</collection>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="connection_id" foreignColumn="connection_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all connection identifiers -->
|
||||
@@ -87,7 +95,7 @@
|
||||
|
||||
<!-- Select multiple connections by identifier -->
|
||||
<select id="select" resultMap="ConnectionResultMap"
|
||||
resultSets="connections,sharingProfiles">
|
||||
resultSets="connections,sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_connection].connection_id,
|
||||
@@ -121,11 +129,22 @@
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM [guacamole_connection_attribute]
|
||||
WHERE connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple connections by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="ConnectionResultMap"
|
||||
resultSets="connections,sharingProfiles">
|
||||
resultSets="connections,sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_connection].connection_id,
|
||||
@@ -165,6 +184,20 @@
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
[guacamole_connection_attribute].connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM [guacamole_connection_attribute]
|
||||
JOIN [guacamole_connection_permission] ON [guacamole_connection_permission].connection_id = [guacamole_connection_attribute].connection_id
|
||||
WHERE [guacamole_connection_attribute].connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single connection by name -->
|
||||
@@ -248,4 +281,25 @@
|
||||
WHERE connection_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with connection -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM [guacamole_connection_attribute]
|
||||
WHERE connection_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for connection -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO [guacamole_connection_attribute] (
|
||||
connection_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -48,6 +48,14 @@
|
||||
<result column="connection_id"/>
|
||||
</collection>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="connection_group_id" foreignColumn="connection_group_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all connection group identifiers -->
|
||||
@@ -88,7 +96,7 @@
|
||||
|
||||
<!-- Select multiple connection groups by identifier -->
|
||||
<select id="select" resultMap="ConnectionGroupResultMap"
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections">
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
connection_group_id,
|
||||
@@ -121,11 +129,22 @@
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM [guacamole_connection_group_attribute]
|
||||
WHERE connection_group_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple connection groups by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="ConnectionGroupResultMap"
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections">
|
||||
resultSets="connectionGroups,childConnectionGroups,childConnections,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_connection_group].connection_group_id,
|
||||
@@ -167,6 +186,20 @@
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
[guacamole_connection_group_attribute].connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM [guacamole_connection_group_attribute]
|
||||
JOIN [guacamole_connection_group_permission] ON [guacamole_connection_group_permission].connection_group_id = [guacamole_connection_group_attribute].connection_group_id
|
||||
WHERE [guacamole_connection_group_attribute].connection_group_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single connection group by name -->
|
||||
@@ -229,4 +262,25 @@
|
||||
WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with connection group -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM [guacamole_connection_group_attribute]
|
||||
WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for connection group -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO [guacamole_connection_group_attribute] (
|
||||
connection_group_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -25,9 +25,20 @@
|
||||
|
||||
<!-- Result mapper for sharing profile objects -->
|
||||
<resultMap id="SharingProfileResultMap" type="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileModel">
|
||||
|
||||
<!-- Sharing profile properties -->
|
||||
<id column="sharing_profile_id" property="objectID" jdbcType="INTEGER"/>
|
||||
<result column="sharing_profile_name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="primary_connection_id" property="parentIdentifier" jdbcType="INTEGER"/>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="sharing_profile_id" foreignColumn="sharing_profile_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all sharing profile identifiers -->
|
||||
@@ -46,7 +57,8 @@
|
||||
</select>
|
||||
|
||||
<!-- Select multiple sharing profiles by identifier -->
|
||||
<select id="select" resultMap="SharingProfileResultMap">
|
||||
<select id="select" resultMap="SharingProfileResultMap"
|
||||
resultSets="sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
sharing_profile_id,
|
||||
@@ -57,12 +69,24 @@
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM [guacamole_sharing_profile_attribute]
|
||||
WHERE sharing_profile_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple sharing profiles by identifier only if readable -->
|
||||
<select id="selectReadable" resultMap="SharingProfileResultMap">
|
||||
<select id="selectReadable" resultMap="SharingProfileResultMap"
|
||||
resultSets="sharingProfiles,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_sharing_profile].sharing_profile_id,
|
||||
@@ -76,7 +100,21 @@
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
[guacamole_sharing_profile_attribute].sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
FROM [guacamole_sharing_profile_attribute]
|
||||
JOIN [guacamole_sharing_profile_permission] ON [guacamole_sharing_profile_permission].sharing_profile_id = [guacamole_sharing_profile_attribute].sharing_profile_id
|
||||
WHERE [guacamole_sharing_profile_attribute].sharing_profile_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
@@ -123,4 +161,25 @@
|
||||
WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
<!-- Delete attributes associated with sharing profile -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM [guacamole_sharing_profile_attribute]
|
||||
WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for sharing profile -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO [guacamole_sharing_profile_attribute] (
|
||||
sharing_profile_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
@@ -25,6 +25,8 @@
|
||||
|
||||
<!-- Result mapper for user objects -->
|
||||
<resultMap id="UserResultMap" type="org.apache.guacamole.auth.jdbc.user.UserModel" >
|
||||
|
||||
<!-- User properties -->
|
||||
<id column="user_id" property="objectID" jdbcType="INTEGER"/>
|
||||
<result column="username" property="identifier" jdbcType="VARCHAR"/>
|
||||
<result column="password_hash" property="passwordHash" jdbcType="BINARY"/>
|
||||
@@ -42,6 +44,15 @@
|
||||
<result column="organization" property="organization" jdbcType="VARCHAR"/>
|
||||
<result column="organizational_role" property="organizationalRole" jdbcType="VARCHAR"/>
|
||||
<result column="last_active" property="lastActive" jdbcType="TIMESTAMP"/>
|
||||
|
||||
<!-- Arbitrary attributes -->
|
||||
<collection property="arbitraryAttributes" resultSet="arbitraryAttributes"
|
||||
ofType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel"
|
||||
column="user_id" foreignColumn="user_id">
|
||||
<result property="name" column="attribute_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="attribute_value" jdbcType="VARCHAR"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all usernames -->
|
||||
@@ -61,7 +72,8 @@
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username -->
|
||||
<select id="select" resultMap="UserResultMap">
|
||||
<select id="select" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_user].user_id,
|
||||
@@ -92,10 +104,23 @@
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
|
||||
SELECT
|
||||
[guacamole_user_attribute].user_id,
|
||||
[guacamole_user_attribute].attribute_name,
|
||||
[guacamole_user_attribute].attribute_value
|
||||
FROM [guacamole_user_attribute]
|
||||
JOIN [guacamole_user] ON [guacamole_user].user_id = [guacamole_user_attribute].user_id
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>;
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username only if readable -->
|
||||
<select id="selectReadable" resultMap="UserResultMap">
|
||||
<select id="selectReadable" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_user].user_id,
|
||||
@@ -127,12 +152,28 @@
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND [guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
AND permission = 'READ';
|
||||
|
||||
SELECT
|
||||
[guacamole_user_attribute].user_id,
|
||||
[guacamole_user_attribute].attribute_name,
|
||||
[guacamole_user_attribute].attribute_value
|
||||
FROM [guacamole_user_attribute]
|
||||
JOIN [guacamole_user] ON [guacamole_user].user_id = [guacamole_user_attribute].user_id
|
||||
JOIN [guacamole_user_permission] ON affected_user_id = [guacamole_user].user_id
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=INTEGER}
|
||||
</foreach>
|
||||
AND [guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Select single user by username -->
|
||||
<select id="selectOne" resultMap="UserResultMap">
|
||||
<select id="selectOne" resultMap="UserResultMap"
|
||||
resultSets="users,arbitraryAttributes">
|
||||
|
||||
SELECT
|
||||
[guacamole_user].user_id,
|
||||
@@ -159,7 +200,15 @@
|
||||
FROM [guacamole_user]
|
||||
LEFT JOIN [guacamole_user_history] ON [guacamole_user_history].user_id = [guacamole_user].user_id
|
||||
WHERE
|
||||
[guacamole_user].username = #{username,jdbcType=VARCHAR}
|
||||
[guacamole_user].username = #{username,jdbcType=VARCHAR};
|
||||
|
||||
SELECT
|
||||
[guacamole_user_attribute].user_id,
|
||||
[guacamole_user_attribute].attribute_name,
|
||||
[guacamole_user_attribute].attribute_value
|
||||
FROM [guacamole_user_attribute]
|
||||
JOIN [guacamole_user] ON [guacamole_user].user_id = [guacamole_user_attribute].user_id
|
||||
WHERE username = #{username,jdbcType=VARCHAR};
|
||||
|
||||
</select>
|
||||
|
||||
@@ -230,4 +279,25 @@
|
||||
WHERE user_id = #{object.objectID,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
<!-- Delete attributes associated with user -->
|
||||
<delete id="deleteAttributes">
|
||||
DELETE FROM [guacamole_user_attribute]
|
||||
WHERE user_id = #{object.objectID,jdbcType=INTEGER}
|
||||
</delete>
|
||||
|
||||
<!-- Insert attributes for user -->
|
||||
<insert id="insertAttributes" parameterType="org.apache.guacamole.auth.jdbc.base.ArbitraryAttributeModel">
|
||||
INSERT INTO [guacamole_user_attribute] (
|
||||
user_id,
|
||||
attribute_name,
|
||||
attribute_value
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="object.arbitraryAttributes" item="attribute" separator=",">
|
||||
(#{object.objectID,jdbcType=INTEGER},
|
||||
#{attribute.name,jdbcType=VARCHAR},
|
||||
#{attribute.value,jdbcType=VARCHAR})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.net.auth;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An object which is associated with a set of arbitrary attributes, defined
|
||||
* as name/value pairs.
|
||||
*/
|
||||
public interface Attributes {
|
||||
|
||||
/**
|
||||
* Returns all attributes associated with this object. The returned map
|
||||
* may not be modifiable.
|
||||
*
|
||||
* @return
|
||||
* A map of all attribute identifiers to their corresponding values,
|
||||
* for all attributes associated with this object, which may not be
|
||||
* modifiable.
|
||||
*/
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
/**
|
||||
* Sets the given attributes. If an attribute within the map is not
|
||||
* supported, it will simply be dropped. Any attributes not within the given
|
||||
* map will be left untouched. Attributes which are not declared within the
|
||||
* associated UserContext MUST NOT be submitted, but other extensions may
|
||||
* manipulate the declared attributes through decorate() and redecorate().
|
||||
*
|
||||
* Implementations may optionally allow storage of unsupported attributes.
|
||||
* Extensions which rely on other extensions to store their attribute
|
||||
* values should verify that such storage is supported by first testing
|
||||
* that the attribute value is retrievable via getAttributes() after being
|
||||
* set.
|
||||
*
|
||||
* @param attributes
|
||||
* A map of all attribute identifiers to their corresponding values.
|
||||
*/
|
||||
void setAttributes(Map<String, String> attributes);
|
||||
|
||||
}
|
@@ -21,7 +21,6 @@ package org.apache.guacamole.net.auth;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||
@@ -32,7 +31,7 @@ import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||
* backing GuacamoleConfiguration may be intentionally obfuscated or tokenized
|
||||
* to protect sensitive configuration information.
|
||||
*/
|
||||
public interface Connection extends Identifiable, Connectable {
|
||||
public interface Connection extends Identifiable, Connectable, Attributes {
|
||||
|
||||
/**
|
||||
* Returns the name assigned to this Connection.
|
||||
@@ -82,27 +81,6 @@ public interface Connection extends Identifiable, Connectable {
|
||||
*/
|
||||
public void setConfiguration(GuacamoleConfiguration config);
|
||||
|
||||
/**
|
||||
* Returns all attributes associated with this connection. The returned map
|
||||
* may not be modifiable.
|
||||
*
|
||||
* @return
|
||||
* A map of all attribute identifiers to their corresponding values,
|
||||
* for all attributes associated with this connection, which may not be
|
||||
* modifiable.
|
||||
*/
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
/**
|
||||
* Sets the given attributes. If an attribute within the map is not
|
||||
* supported, it will simply be dropped. Any attributes not within the
|
||||
* given map will be left untouched.
|
||||
*
|
||||
* @param attributes
|
||||
* A map of all attribute identifiers to their corresponding values.
|
||||
*/
|
||||
void setAttributes(Map<String, String> attributes);
|
||||
|
||||
/**
|
||||
* Returns the date and time that this connection was last used. If the
|
||||
* connection was never used, the time that the connection was last used is
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
package org.apache.guacamole.net.auth;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
|
||||
@@ -27,7 +26,7 @@ import org.apache.guacamole.GuacamoleException;
|
||||
* Represents a connection group, which can contain both other connection groups
|
||||
* as well as connections.
|
||||
*/
|
||||
public interface ConnectionGroup extends Identifiable, Connectable {
|
||||
public interface ConnectionGroup extends Identifiable, Connectable, Attributes {
|
||||
|
||||
/**
|
||||
* All legal types of connection group.
|
||||
@@ -124,25 +123,4 @@ public interface ConnectionGroup extends Identifiable, Connectable {
|
||||
public Set<String> getConnectionGroupIdentifiers()
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns all attributes associated with this connection group. The
|
||||
* returned map may not be modifiable.
|
||||
*
|
||||
* @return
|
||||
* A map of all attribute identifiers to their corresponding values,
|
||||
* for all attributes associated with this connection group, which may
|
||||
* not be modifiable.
|
||||
*/
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
/**
|
||||
* Sets the given attributes. If an attribute within the map is not
|
||||
* supported, it will simply be dropped. Any attributes not within the
|
||||
* given map will be left untouched.
|
||||
*
|
||||
* @param attributes
|
||||
* A map of all attribute identifiers to their corresponding values.
|
||||
*/
|
||||
void setAttributes(Map<String, String> attributes);
|
||||
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ import java.util.Map;
|
||||
* Represents the semantics which apply to an existing connection when shared,
|
||||
* along with a human-readable name and unique identifier.
|
||||
*/
|
||||
public interface SharingProfile extends Identifiable {
|
||||
public interface SharingProfile extends Identifiable, Attributes {
|
||||
|
||||
/**
|
||||
* Returns the human-readable name assigned to this SharingProfile.
|
||||
@@ -93,25 +93,4 @@ public interface SharingProfile extends Identifiable {
|
||||
*/
|
||||
public void setParameters(Map<String, String> parameters);
|
||||
|
||||
/**
|
||||
* Returns all attributes associated with this sharing profile. The returned
|
||||
* map may not be modifiable.
|
||||
*
|
||||
* @return
|
||||
* A map of all attribute identifiers to their corresponding values,
|
||||
* for all attributes associated with this sharing profile, which may
|
||||
* not be modifiable.
|
||||
*/
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
/**
|
||||
* Sets the given attributes. If an attribute within the map is not
|
||||
* supported, it will simply be dropped. Any attributes not within the
|
||||
* given map will be left untouched.
|
||||
*
|
||||
* @param attributes
|
||||
* A map of all attribute identifiers to their corresponding values.
|
||||
*/
|
||||
void setAttributes(Map<String, String> attributes);
|
||||
|
||||
}
|
||||
|
@@ -21,7 +21,6 @@ package org.apache.guacamole.net.auth;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.apache.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
@@ -30,7 +29,7 @@ import org.apache.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
/**
|
||||
* A user of the Guacamole web application.
|
||||
*/
|
||||
public interface User extends Identifiable {
|
||||
public interface User extends Identifiable, Attributes {
|
||||
|
||||
/**
|
||||
* All standard attribute names with semantics defined by the Guacamole web
|
||||
@@ -81,27 +80,6 @@ public interface User extends Identifiable {
|
||||
*/
|
||||
public void setPassword(String password);
|
||||
|
||||
/**
|
||||
* Returns all attributes associated with this user. The returned map may
|
||||
* not be modifiable.
|
||||
*
|
||||
* @return
|
||||
* A map of all attribute identifiers to their corresponding values,
|
||||
* for all attributes associated with this user, which may not be
|
||||
* modifiable.
|
||||
*/
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
/**
|
||||
* Sets the given attributes. If an attribute within the map is not
|
||||
* supported, it will simply be dropped. Any attributes not within the
|
||||
* given map will be left untouched.
|
||||
*
|
||||
* @param attributes
|
||||
* A map of all attribute identifiers to their corresponding values.
|
||||
*/
|
||||
void setAttributes(Map<String, String> attributes);
|
||||
|
||||
/**
|
||||
* Returns the date and time that this user was last active. If the user
|
||||
* was never active, the time that the user was last active is unknown, or
|
||||
|
@@ -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