From c5364f4bffcca84e68b1be24cbbc5b440b893fa8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 24 May 2015 15:56:49 -0700 Subject: [PATCH] GUAC-800: Update REST services to allow read/write of attributes on users, connections, and groups. --- .../basic/rest/connection/APIConnection.java | 36 ++++++++++++++++- .../rest/connection/APIConnectionWrapper.java | 10 +++++ .../connection/ConnectionRESTService.java | 1 + .../connectiongroup/APIConnectionGroup.java | 39 ++++++++++++++++++- .../APIConnectionGroupWrapper.java | 11 ++++++ .../ConnectionGroupRESTService.java | 1 + .../net/basic/rest/user/APIUser.java | 36 +++++++++++++++++ .../net/basic/rest/user/APIUserWrapper.java | 11 ++++++ .../net/basic/rest/user/UserRESTService.java | 3 ++ .../main/webapp/app/rest/types/Connection.js | 11 +++++- .../webapp/app/rest/types/ConnectionGroup.js | 9 +++++ .../src/main/webapp/app/rest/types/User.js | 9 +++++ 12 files changed, 173 insertions(+), 4 deletions(-) diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnection.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnection.java index 5b8da3f75..628ee1c30 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnection.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnection.java @@ -24,6 +24,7 @@ package org.glyptodon.guacamole.net.basic.rest.connection; import java.util.Map; import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.auth.Connection; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; @@ -34,6 +35,7 @@ import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; * @author James Muehlner */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) public class APIConnection { /** @@ -61,6 +63,11 @@ public class APIConnection { */ private Map parameters; + /** + * Map of all associated attributes by attribute identifier. + */ + private Map attributes; + /** * The count of currently active connections using this connection. */ @@ -92,6 +99,9 @@ public class APIConnection { GuacamoleConfiguration configuration = connection.getConfiguration(); this.protocol = configuration.getProtocol(); + // Associate any attributes + this.attributes = connection.getAttributes(); + } /** @@ -195,5 +205,29 @@ public class APIConnection { public void setActiveUsers(int activeConnections) { this.activeConnections = activeConnections; } - + + /** + * Returns a map of all attributes associated with this connection. Each + * entry key is the attribute identifier, while each value is the attribute + * value itself. + * + * @return + * The attribute map for this connection. + */ + public Map getAttributes() { + return attributes; + } + + /** + * Sets the map of all attributes associated with this connection. Each + * entry key is the attribute identifier, while each value is the attribute + * value itself. + * + * @param attributes + * The attribute map for this connection. + */ + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnectionWrapper.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnectionWrapper.java index 41d64ceb3..ec0b3c7fb 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnectionWrapper.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/APIConnectionWrapper.java @@ -115,6 +115,16 @@ public class APIConnectionWrapper implements Connection { } + @Override + public Map getAttributes() { + return apiConnection.getAttributes(); + } + + @Override + public void setAttributes(Map attributes) { + apiConnection.setAttributes(attributes); + } + @Override public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException { throw new UnsupportedOperationException("Operation not supported."); diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java index 30cd75f94..5b67465c5 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java @@ -305,6 +305,7 @@ public class ConnectionRESTService { existingConnection.setConfiguration(config); existingConnection.setParentIdentifier(connection.getParentIdentifier()); existingConnection.setName(connection.getName()); + existingConnection.setAttributes(connection.getAttributes()); connectionDirectory.update(existingConnection); } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroup.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroup.java index b980983b5..82418b906 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroup.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroup.java @@ -23,7 +23,9 @@ package org.glyptodon.guacamole.net.basic.rest.connectiongroup; import java.util.Collection; +import java.util.Map; import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; import org.glyptodon.guacamole.net.auth.ConnectionGroup; import org.glyptodon.guacamole.net.auth.ConnectionGroup.Type; import org.glyptodon.guacamole.net.basic.rest.connection.APIConnection; @@ -34,6 +36,7 @@ import org.glyptodon.guacamole.net.basic.rest.connection.APIConnection; * @author James Muehlner */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) public class APIConnectionGroup { /** @@ -78,6 +81,11 @@ public class APIConnectionGroup { */ private Collection childConnections; + /** + * Map of all associated attributes by attribute identifier. + */ + private Map attributes; + /** * Create an empty APIConnectionGroup. */ @@ -91,13 +99,16 @@ public class APIConnectionGroup { */ public APIConnectionGroup(ConnectionGroup connectionGroup) { + // Set connection group information this.identifier = connectionGroup.getIdentifier(); this.parentIdentifier = connectionGroup.getParentIdentifier(); - this.name = connectionGroup.getName(); this.type = connectionGroup.getType(); this.activeConnections = connectionGroup.getActiveConnections(); + // Associate any attributes + this.attributes = connectionGroup.getAttributes(); + } /** @@ -233,5 +244,29 @@ public class APIConnectionGroup { public void setActiveUsers(int activeConnections) { this.activeConnections = activeConnections; } - + + /** + * Returns a map of all attributes associated with this connection group. + * Each entry key is the attribute identifier, while each value is the + * attribute value itself. + * + * @return + * The attribute map for this connection group. + */ + public Map getAttributes() { + return attributes; + } + + /** + * Sets the map of all attributes associated with this connection group. + * Each entry key is the attribute identifier, while each value is the + * attribute value itself. + * + * @param attributes + * The attribute map for this connection group. + */ + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java index c37aee94a..8d3dd2679 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/APIConnectionGroupWrapper.java @@ -22,6 +22,7 @@ package org.glyptodon.guacamole.net.basic.rest.connectiongroup; +import java.util.Map; import java.util.Set; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.GuacamoleTunnel; @@ -105,6 +106,16 @@ public class APIConnectionGroupWrapper implements ConnectionGroup { throw new UnsupportedOperationException("Operation not supported."); } + @Override + public Map getAttributes() { + return apiConnectionGroup.getAttributes(); + } + + @Override + public void setAttributes(Map attributes) { + apiConnectionGroup.setAttributes(attributes); + } + @Override public GuacamoleTunnel connect(GuacamoleClientInformation info) throws GuacamoleException { throw new UnsupportedOperationException("Operation not supported."); diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java index 8153421cf..2dbf94d1e 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java @@ -253,6 +253,7 @@ public class ConnectionGroupRESTService { existingConnectionGroup.setName(connectionGroup.getName()); existingConnectionGroup.setParentIdentifier(connectionGroup.getParentIdentifier()); existingConnectionGroup.setType(connectionGroup.getType()); + existingConnectionGroup.setAttributes(connectionGroup.getAttributes()); connectionGroupDirectory.update(existingConnectionGroup); } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUser.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUser.java index 6351f2942..a278e0797 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUser.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUser.java @@ -22,6 +22,7 @@ package org.glyptodon.guacamole.net.basic.rest.user; +import java.util.Map; import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.glyptodon.guacamole.net.auth.User; @@ -45,6 +46,11 @@ public class APIUser { */ private String password; + /** + * Map of all associated attributes by attribute identifier. + */ + private Map attributes; + /** * Construct a new empty APIUser. */ @@ -55,8 +61,14 @@ public class APIUser { * @param user The User to construct the APIUser from. */ public APIUser(User user) { + + // Set user information this.username = user.getIdentifier(); this.password = user.getPassword(); + + // Associate any attributes + this.attributes = user.getAttributes(); + } /** @@ -91,4 +103,28 @@ public class APIUser { this.password = password; } + /** + * Returns a map of all attributes associated with this user. Each entry + * key is the attribute identifier, while each value is the attribute + * value itself. + * + * @return + * The attribute map for this user. + */ + public Map getAttributes() { + return attributes; + } + + /** + * Sets the map of all attributes associated with this user. Each entry key + * is the attribute identifier, while each value is the attribute value + * itself. + * + * @param attributes + * The attribute map for this user. + */ + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUserWrapper.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUserWrapper.java index c1bc8b58a..f918dbf05 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUserWrapper.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/APIUserWrapper.java @@ -22,6 +22,7 @@ package org.glyptodon.guacamole.net.basic.rest.user; +import java.util.Map; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleUnsupportedException; import org.glyptodon.guacamole.net.auth.User; @@ -71,6 +72,16 @@ public class APIUserWrapper implements User { apiUser.setPassword(password); } + @Override + public Map getAttributes() { + return apiUser.getAttributes(); + } + + @Override + public void setAttributes(Map attributes) { + apiUser.setAttributes(attributes); + } + @Override public SystemPermissionSet getSystemPermissions() throws GuacamoleException { diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java index af785fc65..6e57520d1 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java @@ -291,6 +291,9 @@ public class UserRESTService { if (user.getPassword() != null) existingUser.setPassword(user.getPassword()); + // Update user attributes + existingUser.setAttributes(user.getAttributes()); + // Update the user userDirectory.update(existingUser); diff --git a/guacamole/src/main/webapp/app/rest/types/Connection.js b/guacamole/src/main/webapp/app/rest/types/Connection.js index 3c3efb87a..488cfdcff 100644 --- a/guacamole/src/main/webapp/app/rest/types/Connection.js +++ b/guacamole/src/main/webapp/app/rest/types/Connection.js @@ -79,7 +79,16 @@ angular.module('rest').factory('Connection', [function defineConnection() { * @type Object. */ this.parameters = template.parameters; - + + /** + * Arbitrary name/value pairs which further describe this connection. + * The semantics and validity of these attributes are dictated by the + * extension which defines them. + * + * @type Object. + */ + this.attributes = {}; + /** * The count of currently active connections using this connection. * This field will be returned from the REST API during a get diff --git a/guacamole/src/main/webapp/app/rest/types/ConnectionGroup.js b/guacamole/src/main/webapp/app/rest/types/ConnectionGroup.js index cdb3fe232..7c3dc2b85 100644 --- a/guacamole/src/main/webapp/app/rest/types/ConnectionGroup.js +++ b/guacamole/src/main/webapp/app/rest/types/ConnectionGroup.js @@ -91,6 +91,15 @@ angular.module('rest').factory('ConnectionGroup', [function defineConnectionGrou */ this.childConnectionGroups = template.childConnectionGroups; + /** + * Arbitrary name/value pairs which further describe this connection + * group. The semantics and validity of these attributes are dictated + * by the extension which defines them. + * + * @type Object. + */ + this.attributes = {}; + /** * The count of currently active connections using this connection * group. This field will be returned from the REST API during a get diff --git a/guacamole/src/main/webapp/app/rest/types/User.js b/guacamole/src/main/webapp/app/rest/types/User.js index 499e4d2ab..8c18d0157 100644 --- a/guacamole/src/main/webapp/app/rest/types/User.js +++ b/guacamole/src/main/webapp/app/rest/types/User.js @@ -56,6 +56,15 @@ angular.module('rest').factory('User', [function defineUser() { */ this.password = template.password; + /** + * Arbitrary name/value pairs which further describe this user. The + * semantics and validity of these attributes are dictated by the + * extension which defines them. + * + * @type Object. + */ + this.attributes = {}; + }; return User;