GUAC-800: Handle attributes as dynamic properties (no GuacamoleExceptions). Use Attribute for schema information only. Allow retrieval of schema information from UserContext. Add attributes to ConnectionGroup.

This commit is contained in:
Michael Jumper
2015-05-24 15:01:15 -07:00
parent 75f6e75176
commit 9585d0fc6c
13 changed files with 177 additions and 401 deletions

View File

@@ -23,8 +23,8 @@
package org.glyptodon.guacamole.net.auth;
import java.util.List;
import java.util.Map;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.attribute.ObjectAttributeSet;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
/**
@@ -85,6 +85,25 @@ public interface Connection extends Identifiable, Connectable {
*/
public void setConfiguration(GuacamoleConfiguration config);
/**
* Returns all attributes associated with this connection.
*
* @return
* A map of all attribute identifiers to their corresponding values,
* for all attributes associated with this connection.
*/
Map<String, String> getAttributes();
/**
* Replaces all attributes associated with this connection with the
* attributes in the given map.
*
* @param attributes
* A map of all attribute identifiers to their corresponding values,
* for all attributes associated with this connection.
*/
void setAttributes(Map<String, String> attributes);
/**
* Returns a list of ConnectionRecords representing the usage history
* of this Connection, including any active users. ConnectionRecords
@@ -101,17 +120,4 @@ public interface Connection extends Identifiable, Connectable {
*/
public List<? extends ConnectionRecord> getHistory() throws GuacamoleException;
/**
* Returns all attributes associated with this connection.
*
* @return
* An ObjectAttributeSet of all attributes associated with this
* connection
*
* @throws GuacamoleException
* If an error occurs while retrieving the attributes, or if reading
* attributes is not allowed.
*/
ObjectAttributeSet getAttributes() throws GuacamoleException;
}

View File

@@ -22,6 +22,7 @@
package org.glyptodon.guacamole.net.auth;
import java.util.Map;
import java.util.Set;
import org.glyptodon.guacamole.GuacamoleException;
@@ -127,5 +128,24 @@ public interface ConnectionGroup extends Identifiable, Connectable {
public Set<String> getConnectionGroupIdentifiers()
throws GuacamoleException;
/**
* Returns all attributes associated with this connection group.
*
* @return
* A map of all attribute identifiers to their corresponding values,
* for all attributes associated with this connection group.
*/
Map<String, String> getAttributes();
/**
* Replaces all attributes associated with this connection group with the
* attributes in the given map.
*
* @param attributes
* A map of all attribute identifiers to their corresponding values,
* for all attributes associated with this connection group.
*/
void setAttributes(Map<String, String> attributes);
}

View File

@@ -22,8 +22,8 @@
package org.glyptodon.guacamole.net.auth;
import java.util.Map;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.attribute.ObjectAttributeSet;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
@@ -52,6 +52,25 @@ public interface User extends Identifiable {
*/
public void setPassword(String password);
/**
* Returns all attributes associated with this user.
*
* @return
* A map of all attribute identifiers to their corresponding values,
* for all attributes associated with this user.
*/
Map<String, String> getAttributes();
/**
* Replaces all attributes associated with this user with the attributes in
* the given map.
*
* @param attributes
* A map of all attribute identifiers to their corresponding values,
* for all attributes associated with this user.
*/
void setAttributes(Map<String, String> attributes);
/**
* Returns all system-level permissions given to this user.
*
@@ -120,16 +139,4 @@ public interface User extends Identifiable {
*/
ObjectPermissionSet getUserPermissions() throws GuacamoleException;
/**
* Returns all attributes associated with this user.
*
* @return
* An ObjectAttributeSet of all attributes associated with this user.
*
* @throws GuacamoleException
* If an error occurs while retrieving the attributes, or if reading
* attributes is not allowed.
*/
ObjectAttributeSet getAttributes() throws GuacamoleException;
}

View File

@@ -22,7 +22,9 @@
package org.glyptodon.guacamole.net.auth;
import java.util.Collection;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.attribute.Attribute;
/**
* The context of an active user. The functions of this class enforce all
@@ -110,4 +112,37 @@ public interface UserContext {
*/
ConnectionGroup getRootConnectionGroup() throws GuacamoleException;
/**
* Retrieves a collection of all attributes applicable to users. This
* collection will contain only those attributes which the current user has
* general permission to view or modify. If there are no such attributes,
* this collection will be empty.
*
* @return
* A collection of all attributes applicable to users.
*/
Collection<Attribute> getUserAttributes();
/**
* Retrieves a collection of all attributes applicable to connections. This
* collection will contain only those attributes which the current user has
* general permission to view or modify. If there are no such attributes,
* this collection will be empty.
*
* @return
* A collection of all attributes applicable to connections.
*/
Collection<Attribute> getConnectionAttributes();
/**
* Retrieves a collection of all attributes applicable to connection
* groups. This collection will contain only those attributes which the
* current user has general permission to view or modify. If there are no
* such attributes, this collection will be empty.
*
* @return
* A collection of all attributes applicable to connection groups.
*/
Collection<Attribute> getConnectionGroupAttributes();
}

View File

@@ -26,12 +26,22 @@ import org.glyptodon.guacamole.net.auth.Identifiable;
/**
* An arbitrary attribute. Each attribute associates an identifier with a
* value, essentially a key/value pair, where the type dictates the semantics
* and legal values of the attribute.
* type, where the type dictates the semantics and legal values of the
* attribute.
*
* @author Michael Jumper
*/
public interface Attribute extends Identifiable {
public class Attribute implements Identifiable {
/**
* The string which uniquely identifies this attribute.
*/
private String identifier;
/**
* The type of this attribute.
*/
private Type type;
/**
* Specific types of attributes. Each attribute type describes the kind of
@@ -80,6 +90,16 @@ public interface Attribute extends Identifiable {
}
@Override
public String getIdentifier() {
return identifier;
}
@Override
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
/**
* Returns the type of this attribute. The attribute type dictates the kind
* of values the attribute can contain, and the semantics of the attribute
@@ -88,7 +108,9 @@ public interface Attribute extends Identifiable {
* @return
* The type of this attribute.
*/
Type getType();
public Type getType() {
return type;
}
/**
* Sets the type of this attribute. Attribute type dictates the kind of
@@ -98,25 +120,8 @@ public interface Attribute extends Identifiable {
* @param type
* The type to associate with this attribute.
*/
void setType(Type type);
/**
* Returns the value currently associated with this attribute, if any. The
* values acceptable by this attribute are dictated by the type.
*
* @return
* The value currently associated with this attribute, or null if no
* value is present.
*/
String getValue();
/**
* Sets the value currently associated with this attribute, if any. The
* values acceptable by this attribute are dictated by the type.
*
* @param value
* The value to associate with this attribute.
*/
void setValue(String value);
void setType(Type type) {
this.type = type;
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) 2015 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.net.auth.attribute;
import java.util.Set;
import org.glyptodon.guacamole.GuacamoleException;
/**
* An arbitrary set of attributes.
*
* @author Michael Jumper
* @param <AttributeType>
* The type of attribute stored within this AttributeSet.
*/
public interface AttributeSet<AttributeType extends Attribute> {
/**
* Returns a Set which contains all attributes stored or storable within
* this attribute set. The value of each attribute, if any, is associated
* with the attribute object within the set. The set itself may not be
* mutable.
*
* @return
* A Set containing all attributes stored or storable within this
* attribute set, which may not be mutable.
*
* @throws GuacamoleException
* If an error occurs while retrieving the attributes, or if attributes
* cannot be retrieved due to lack of permissions to do so.
*/
Set<AttributeType> getAttributes() throws GuacamoleException;
/**
* Changes each of the given attributes. If a specified attribute is
* already set, the previous value will be overwritten with the new value.
* If the new value is null, the previous value will be unset.
*
* @param attributes
* The attributes to update.
*
* @throws GuacamoleException
* If an error occurs while updating the attributes, if permission to
* update attributes is denied, or if any one of the given attributes
* is invalid or malformed.
*/
void updateAttributes(Set<AttributeType> attributes)
throws GuacamoleException;
}

View File

@@ -1,152 +0,0 @@
/*
* Copyright (C) 2015 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.net.auth.attribute;
/**
* An attribute which applies to a specific object.
*
* @author Michael Jumper
*/
public class ObjectAttribute implements Attribute {
/**
* The identifier of the object associated with the attribute.
*/
private String objectIdentifier;
/**
* The type of value stored within this attribute.
*/
private Type type;
/**
* A string which uniquely identifies this attribute.
*/
private String identifier;
/**
* The value currently assigned to this attribute.
*/
private String value;
/**
* Creates a new ObjectAttribute having the given identifier and type.
* The identifier must be unique with respect to other attributes that
* apply to the same kind of object.
*
* @param identifier
* The string which uniquely identifies this attribute.
*
* @param type
* The type of value stored within this attribute.
*/
public ObjectAttribute(String identifier, Type type) {
this.identifier = identifier;
this.type = type;
}
/**
* Returns the identifier of the specific object associated with this
* attribute.
*
* @return
* The identifier of the specific object associated with this
* attribute.
*/
public String getObjectIdentifier() {
return objectIdentifier;
}
/**
* Sets the identifier of the specific object associated with this
* attribute.
*
* @param objectIdentifier
* The identifier of the specific object associated with this
* attribute.
*/
public void setObjectIdentifier(String objectIdentifier) {
this.objectIdentifier = objectIdentifier;
}
@Override
public Type getType() {
return type;
}
@Override
public void setType(Type type) {
this.type = type;
}
@Override
public String getIdentifier() {
return identifier;
}
@Override
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public int hashCode() {
// The identifier always uniquely identifies an attribute
if (identifier != null)
return identifier.hashCode();
return 0;
}
@Override
public boolean equals(Object obj) {
// Not equal if null or wrong type
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
final ObjectAttribute other = (ObjectAttribute) obj;
// If null identifier, equality depends on whether other identifier
// is null
if (identifier == null)
return other.identifier == null;
// Otherwise, equality depends entirely on identifier
return identifier.equals(other.identifier);
}
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2015 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.net.auth.attribute;
/**
* A set of attributes associated with a particular object or group of objects.
*
* @author Michael Jumper
*/
public interface ObjectAttributeSet extends AttributeSet<ObjectAttribute> {
}

View File

@@ -24,6 +24,7 @@ package org.glyptodon.guacamole.net.auth.simple;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.environment.Environment;
import org.glyptodon.guacamole.environment.LocalEnvironment;
@@ -34,7 +35,6 @@ import org.glyptodon.guacamole.net.SSLGuacamoleSocket;
import org.glyptodon.guacamole.net.SimpleGuacamoleTunnel;
import org.glyptodon.guacamole.net.auth.AbstractConnection;
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
import org.glyptodon.guacamole.net.auth.attribute.ObjectAttributeSet;
import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket;
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
@@ -98,6 +98,16 @@ public class SimpleConnection extends AbstractConnection {
return 0;
}
@Override
public Map<String, String> getAttributes() {
return Collections.<String, String>emptyMap();
}
@Override
public void setAttributes(Map<String, String> attributes) {
// Do nothing - there are no attributes
}
@Override
public GuacamoleTunnel connect(GuacamoleClientInformation info)
throws GuacamoleException {
@@ -133,9 +143,4 @@ public class SimpleConnection extends AbstractConnection {
return Collections.<ConnectionRecord>emptyList();
}
@Override
public ObjectAttributeSet getAttributes() throws GuacamoleException {
return new SimpleObjectAttributeSet();
}
}

View File

@@ -23,7 +23,9 @@
package org.glyptodon.guacamole.net.auth.simple;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleSecurityException;
@@ -101,6 +103,16 @@ public class SimpleConnectionGroup extends AbstractConnectionGroup {
return connectionGroupIdentifiers;
}
@Override
public Map<String, String> getAttributes() {
return Collections.<String, String>emptyMap();
}
@Override
public void setAttributes(Map<String, String> attributes) {
// Do nothing - there are no attributes
}
@Override
public GuacamoleTunnel connect(GuacamoleClientInformation info)
throws GuacamoleException {

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) 2015 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.net.auth.simple;
import java.util.Collections;
import java.util.Set;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleSecurityException;
import org.glyptodon.guacamole.net.auth.attribute.ObjectAttribute;
import org.glyptodon.guacamole.net.auth.attribute.ObjectAttributeSet;
/**
* A read-only implementation of ObjectAttributeSet which uses a backing Set
* of Attribute for attribute/value storage.
*
* @author Michael Jumper
*/
public class SimpleObjectAttributeSet implements ObjectAttributeSet {
/**
* The set of all attributes currently set.
*/
private Set<ObjectAttribute> attributes = Collections.<ObjectAttribute>emptySet();
/**
* Creates a new empty SimpleObjectAttributeSet.
*/
public SimpleObjectAttributeSet() {
}
/**
* Creates a new SimpleObjectAttributeSet which contains the attributes
* within the given Set.
*
* @param attributes
* The Set of attributes this SimpleObjectAttributeSet should
* contain.
*/
public SimpleObjectAttributeSet(Set<ObjectAttribute> attributes) {
this.attributes = attributes;
}
/**
* Sets the Set which backs this SimpleObjectAttributeSet. Future function
* calls on this SimpleObjectAttributeSet will use the provided Set.
*
* @param attributes
* The Set of attributes this SimpleObjectAttributeSet should
* contain.
*/
protected void setAttributes(Set<ObjectAttribute> attributes) {
this.attributes = attributes;
}
@Override
public Set<ObjectAttribute> getAttributes() throws GuacamoleException {
return attributes;
}
@Override
public void updateAttributes(Set<ObjectAttribute> attributes) throws GuacamoleException {
throw new GuacamoleSecurityException("Permission denied.");
}
}

View File

@@ -23,11 +23,13 @@
package org.glyptodon.guacamole.net.auth.simple;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleSecurityException;
import org.glyptodon.guacamole.net.auth.AbstractUser;
import org.glyptodon.guacamole.net.auth.attribute.ObjectAttributeSet;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
@@ -107,6 +109,16 @@ public class SimpleUser extends AbstractUser {
}
@Override
public Map<String, String> getAttributes() {
return Collections.<String, String>emptyMap();
}
@Override
public void setAttributes(Map<String, String> attributes) {
// Do nothing - there are no attributes
}
@Override
public SystemPermissionSet getSystemPermissions()
throws GuacamoleException {
@@ -137,9 +149,4 @@ public class SimpleUser extends AbstractUser {
return new SimpleObjectPermissionSet();
}
@Override
public ObjectAttributeSet getAttributes() throws GuacamoleException {
return new SimpleObjectAttributeSet();
}
}

View File

@@ -34,6 +34,7 @@ import org.glyptodon.guacamole.net.auth.ConnectionGroup;
import org.glyptodon.guacamole.net.auth.Directory;
import org.glyptodon.guacamole.net.auth.User;
import org.glyptodon.guacamole.net.auth.UserContext;
import org.glyptodon.guacamole.net.auth.attribute.Attribute;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
/**
@@ -174,4 +175,19 @@ public class SimpleUserContext implements UserContext {
return new SimpleDirectory<ActiveConnection>();
}
@Override
public Collection<Attribute> getUserAttributes() {
return Collections.<Attribute>emptyList();
}
@Override
public Collection<Attribute> getConnectionAttributes() {
return Collections.<Attribute>emptyList();
}
@Override
public Collection<Attribute> getConnectionGroupAttributes() {
return Collections.<Attribute>emptyList();
}
}