You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2016/07/17 22:28:38 UTC

[10/19] incubator-guacamole-client git commit: GUACAMOLE-5: Add SharingProfiles to REST API.

GUACAMOLE-5: Add SharingProfiles to REST API.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/c231f4eb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/c231f4eb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/c231f4eb

Branch: refs/heads/master
Commit: c231f4eb571101e92afef27a929ed31d8da23040
Parents: 2131abb
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Jul 15 18:10:05 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Sat Jul 16 11:42:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   2 +
 .../rest/history/APIConnectionRecord.java       |  52 ++++-
 .../rest/permission/APIPermissionSet.java       |  35 ++++
 .../rest/permission/PermissionSetResource.java  |  21 ++
 .../rest/session/UserContextResource.java       |  28 +++
 .../rest/sharingprofile/APISharingProfile.java  | 207 +++++++++++++++++++
 .../APISharingProfileWrapper.java               | 101 +++++++++
 .../SharingProfileDirectoryResource.java        |  72 +++++++
 .../sharingprofile/SharingProfileModule.java    |  65 ++++++
 .../SharingProfileObjectTranslator.java         |  58 ++++++
 .../sharingprofile/SharingProfileResource.java  | 125 +++++++++++
 .../rest/sharingprofile/package-info.java       |  25 +++
 .../guacamole/rest/user/APIUserWrapper.java     |   5 +
 13 files changed, 789 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
index 2978278..7b7322b 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -39,6 +39,7 @@ import org.apache.guacamole.rest.connectiongroup.ConnectionGroupModule;
 import org.apache.guacamole.rest.language.LanguageRESTService;
 import org.apache.guacamole.rest.patch.PatchRESTService;
 import org.apache.guacamole.rest.session.SessionResourceFactory;
+import org.apache.guacamole.rest.sharingprofile.SharingProfileModule;
 import org.apache.guacamole.rest.user.UserModule;
 
 /**
@@ -96,6 +97,7 @@ public class RESTServiceModule extends ServletModule {
         install(new ActiveConnectionModule());
         install(new ConnectionModule());
         install(new ConnectionGroupModule());
+        install(new SharingProfileModule());
         install(new UserModule());
 
         // Set up the servlet and JSON mappings

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java
index b1a796e..36e639c 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java
@@ -40,6 +40,16 @@ public class APIConnectionRecord {
     private final String connectionName;
 
     /**
+     * The identifier of the sharing profile associated with this record.
+     */
+    private final String sharingProfileIdentifier;
+
+    /**
+     * The identifier of the sharing profile associated with this record.
+     */
+    private final String sharingProfileName;
+
+    /**
      * The date and time the connection began.
      */
     private final Date startDate;
@@ -73,13 +83,15 @@ public class APIConnectionRecord {
      *     The record to copy data from.
      */
     public APIConnectionRecord(ConnectionRecord record) {
-        this.connectionIdentifier = record.getConnectionIdentifier();
-        this.connectionName       = record.getConnectionName();
-        this.startDate            = record.getStartDate();
-        this.endDate              = record.getEndDate();
-        this.remoteHost           = record.getRemoteHost();
-        this.username             = record.getUsername();
-        this.active               = record.isActive();
+        this.connectionIdentifier     = record.getConnectionIdentifier();
+        this.connectionName           = record.getConnectionName();
+        this.sharingProfileIdentifier = record.getSharingProfileIdentifier();
+        this.sharingProfileName       = record.getSharingProfileName();
+        this.startDate                = record.getStartDate();
+        this.endDate                  = record.getEndDate();
+        this.remoteHost               = record.getRemoteHost();
+        this.username                 = record.getUsername();
+        this.active                   = record.isActive();
     }
 
     /**
@@ -104,6 +116,32 @@ public class APIConnectionRecord {
     }
 
     /**
+     * Returns the identifier of the sharing profile associated with this
+     * record. If the connection was not being used via a sharing profile, this
+     * will be null.
+     *
+     * @return
+     *     The identifier of the sharing profile associated with this record,
+     *     or null if no sharing profile was used.
+     */
+    public String getSharingProfileIdentifier() {
+        return sharingProfileIdentifier;
+    }
+
+    /**
+     * Returns the name of the sharing profile associated with this record. If
+     * the connection was not being used via a sharing profile, this will be
+     * null.
+     *
+     * @return
+     *     The name of the sharing profile associated with this record, or null
+     *     if no sharing profile was used.
+     */
+    public String getSharingProfileName() {
+        return sharingProfileName;
+    }
+
+    /**
      * Returns the date and time the connection began.
      *
      * @return

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java b/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java
index 7439401..5c15a2b 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java
@@ -54,6 +54,12 @@ public class APIPermissionSet {
             new HashMap<String, Set<ObjectPermission.Type>>();
 
     /**
+     * Map of sharing profile ID to the set of granted permissions.
+     */
+    private Map<String, Set<ObjectPermission.Type>> sharingProfilePermissions =
+            new HashMap<String, Set<ObjectPermission.Type>>();
+
+    /**
      * Map of active connection ID to the set of granted permissions.
      */
     private Map<String, Set<ObjectPermission.Type>> activeConnectionPermissions =
@@ -155,6 +161,7 @@ public class APIPermissionSet {
         addSystemPermissions(systemPermissions,           user.getSystemPermissions());
         addObjectPermissions(connectionPermissions,       user.getConnectionPermissions());
         addObjectPermissions(connectionGroupPermissions,  user.getConnectionGroupPermissions());
+        addObjectPermissions(sharingProfilePermissions,   user.getSharingProfilePermissions());
         addObjectPermissions(activeConnectionPermissions, user.getActiveConnectionPermissions());
         addObjectPermissions(userPermissions,             user.getUserPermissions());
         
@@ -191,6 +198,21 @@ public class APIPermissionSet {
     }
 
     /**
+     * Returns a map of sharing profile identifiers to the set of permissions
+     * granted for that sharing profile. If no permissions are granted to a
+     * particular sharing profile, its identifier will not be present as a key
+     * in the map. This map is mutable, and changes to this map will affect the
+     * permission set directly.
+     *
+     * @return
+     *     A map of sharing profile identifiers to the set of permissions
+     *     granted for that sharing profile.
+     */
+    public Map<String, Set<ObjectPermission.Type>> getSharingProfilePermissions() {
+        return sharingProfilePermissions;
+    }
+
+    /**
      * Returns a map of active connection IDs to the set of permissions granted
      * for that active connection. If no permissions are granted to a particular
      * active connection, its ID will not be present as a key in the map. This
@@ -258,6 +280,19 @@ public class APIPermissionSet {
     }
 
     /**
+     * Replaces the current map of sharing profile permissions with the given
+     * map, which must map each sharing profile identifier to its corresponding
+     * set of granted permissions. If a sharing profile has no permissions, its
+     * identifier must not be present as a key in the map.
+     *
+     * @param sharingProfilePermissions
+     *     The map which must replace the currently-stored map of permissions.
+     */
+    public void setSharingProfilePermissions(Map<String, Set<ObjectPermission.Type>> sharingProfilePermissions) {
+        this.sharingProfilePermissions = sharingProfilePermissions;
+    }
+
+    /**
      * Replaces the current map of active connection permissions with the give
      * map, which must map active connection ID to its corresponding set of
      * granted permissions. If an active connection has no permissions, its ID

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java
index e75460c..3ad005c 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java
@@ -57,6 +57,12 @@ public class PermissionSetResource {
 
     /**
      * The prefix of any path within an operation of a JSON patch which
+     * modifies the permissions of a user regarding a specific sharing profile.
+     */
+    private static final String SHARING_PROFILE_PERMISSION_PATCH_PATH_PREFIX = "/sharingProfilePermissions/";
+
+    /**
+     * The prefix of any path within an operation of a JSON patch which
      * modifies the permissions of a user regarding a specific active connection.
      */
     private static final String ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX = "/activeConnectionPermissions/";
@@ -170,6 +176,7 @@ public class PermissionSetResource {
         // Permission patches for all types of permissions
         PermissionSetPatch<ObjectPermission> connectionPermissionPatch       = new PermissionSetPatch<ObjectPermission>();
         PermissionSetPatch<ObjectPermission> connectionGroupPermissionPatch  = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> sharingProfilePermissionPatch   = new PermissionSetPatch<ObjectPermission>();
         PermissionSetPatch<ObjectPermission> activeConnectionPermissionPatch = new PermissionSetPatch<ObjectPermission>();
         PermissionSetPatch<ObjectPermission> userPermissionPatch             = new PermissionSetPatch<ObjectPermission>();
         PermissionSetPatch<SystemPermission> systemPermissionPatch           = new PermissionSetPatch<SystemPermission>();
@@ -205,6 +212,19 @@ public class PermissionSetResource {
 
             }
 
+            // Create sharing profile permission if path has sharing profileprefix
+            else if (path.startsWith(SHARING_PROFILE_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(SHARING_PROFILE_PERMISSION_PATCH_PATH_PREFIX.length());
+                ObjectPermission.Type type = ObjectPermission.Type.valueOf(patch.getValue());
+
+                // Create and update corresponding permission
+                ObjectPermission permission = new ObjectPermission(type, identifier);
+                updatePermissionSet(patch.getOp(), sharingProfilePermissionPatch, permission);
+
+            }
+
             // Create active connection permission if path has active connection prefix
             else if (path.startsWith(ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
 
@@ -252,6 +272,7 @@ public class PermissionSetResource {
         // Save the permission changes
         connectionPermissionPatch.apply(user.getConnectionPermissions());
         connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions());
+        sharingProfilePermissionPatch.apply(user.getSharingProfilePermissions());
         activeConnectionPermissionPatch.apply(user.getActiveConnectionPermissions());
         userPermissionPatch.apply(user.getUserPermissions());
         systemPermissionPatch.apply(user.getSystemPermissions());

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java
index e0c8855..31bb002 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java
@@ -32,6 +32,7 @@ import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.net.auth.ActiveConnection;
 import org.apache.guacamole.net.auth.Connection;
 import org.apache.guacamole.net.auth.ConnectionGroup;
+import org.apache.guacamole.net.auth.SharingProfile;
 import org.apache.guacamole.net.auth.User;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.rest.activeconnection.APIActiveConnection;
@@ -39,6 +40,7 @@ import org.apache.guacamole.rest.connection.APIConnection;
 import org.apache.guacamole.rest.connectiongroup.APIConnectionGroup;
 import org.apache.guacamole.rest.history.HistoryResource;
 import org.apache.guacamole.rest.schema.SchemaResource;
+import org.apache.guacamole.rest.sharingprofile.APISharingProfile;
 import org.apache.guacamole.rest.user.APIUser;
 
 /**
@@ -81,6 +83,14 @@ public class UserContextResource {
 
     /**
      * Factory for creating DirectoryResources which expose a given
+     * SharingProfile Directory.
+     */
+    @Inject
+    private DirectoryResourceFactory<SharingProfile, APISharingProfile>
+            sharingProfileDirectoryResourceFactory;
+
+    /**
+     * Factory for creating DirectoryResources which expose a given
      * User Directory.
      */
     @Inject
@@ -154,6 +164,24 @@ public class UserContextResource {
     }
 
     /**
+     * Returns a new resource which represents the SharingProfile Directory
+     * contained within the UserContext exposed by this UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the SharingProfile Directory
+     *     contained within the UserContext exposed by this UserContextResource.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the SharingProfile Directory.
+     */
+    @Path("sharingProfiles")
+    public DirectoryResource<SharingProfile, APISharingProfile>
+        getSharingProfileDirectoryResource() throws GuacamoleException {
+        return sharingProfileDirectoryResourceFactory.create(userContext,
+                userContext.getSharingProfileDirectory());
+    }
+
+    /**
      * Returns a new resource which represents the User Directory contained
      * within the UserContext exposed by this UserContextResource.
      *

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java
new file mode 100644
index 0000000..822bcee
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java
@@ -0,0 +1,207 @@
+/*
+ * 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.rest.sharingprofile;
+
+import java.util.Map;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.apache.guacamole.net.auth.SharingProfile;
+
+/**
+ * The external representation used by the REST API for sharing profiles.
+ * 
+ * @author Michael Jumper
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class APISharingProfile {
+
+    /**
+     * The human-readable name of this sharing profile.
+     */
+    private String name;
+    
+    /**
+     * The unique string which identifies this sharing profile within its
+     * containing directory.
+     */
+    private String identifier;
+    
+    /**
+     * The identifier of the primary connection that this sharing profile
+     * can be used to share.
+     */
+    private String primaryConnectionIdentifier;
+
+    /**
+     * Map of all associated connection parameter values which apply when the
+     * sharing profile is used, indexed by parameter name.
+     */
+    private Map<String, String> parameters;
+    
+    /**
+     * Map of all associated attributes by attribute identifier.
+     */
+    private Map<String, String> attributes;
+
+    /**
+     * Creates an empty, uninitialized APISharingProfile. The properties of the
+     * created APISharingProfile will need to be set individually as necessary
+     * via their corresponding setters.
+     */
+    public APISharingProfile() {}
+    
+    /**
+     * Creates a new APISharingProfile with its data populated from that of an
+     * existing SharingProfile. As the connection parameters of the
+     * SharingProfile are potentially sensitive, they will not be included in
+     * the new APISharingProfile.
+     *
+     * @param sharingProfile
+     *     The sharing profile to use to populate the data of the new
+     *     APISharingProfile.
+     */
+    public APISharingProfile(SharingProfile sharingProfile) {
+
+        // Set main information
+        this.name = sharingProfile.getName();
+        this.identifier = sharingProfile.getIdentifier();
+        this.primaryConnectionIdentifier = sharingProfile.getPrimaryConnectionIdentifier();
+        
+        // Associate any attributes
+        this.attributes = sharingProfile.getAttributes();
+
+    }
+
+    /**
+     * Returns the human-readable name of this sharing profile.
+     *
+     * @return
+     *     The human-readable name of this sharing profile.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the human-readable name of this sharing profile.
+     *
+     * @param name
+     *     The human-readable name of this sharing profile.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    /**
+     * Returns the unique string which identifies this sharing profile within
+     * its containing directory.
+     *
+     * @return
+     *     The unique string which identifies this sharing profile within its
+     *     containing directory.
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * Sets the unique string which identifies this sharing profile within
+     * its containing directory.
+     *
+     * @param identifier
+     *     The unique string which identifies this sharing profile within its
+     *     containing directory.
+     */
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+    
+    /**
+     * Returns the identifier of the primary connection that this sharing
+     * profile can be used to share.
+     *
+     * @return
+     *     The identifier of the primary connection that this sharing profile
+     *     can be used to share.
+     */
+    public String getPrimaryConnectionIdentifier() {
+        return primaryConnectionIdentifier;
+    }
+
+    /**
+     * Sets the identifier of the primary connection that this sharing profile
+     * can be used to share.
+     *
+     * @param primaryConnectionIdentifier
+     *     The identifier of the primary connection that this sharing profile
+     *     can be used to share.
+     */
+    public void setPrimaryConnectionIdentifier(String primaryConnectionIdentifier) {
+        this.primaryConnectionIdentifier = primaryConnectionIdentifier;
+    }
+
+    /**
+     * Returns a map of all associated connection parameter values which apply
+     * when the sharing profile is used, indexed by parameter name.
+     *
+     * @return
+     *     A map of all associated connection parameter values which apply when
+     *     the sharing profile is used, indexed by parameter name.
+     */
+    public Map<String, String> getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Sets the map of all associated connection parameter values which apply
+     * when the sharing profile is used, indexed by parameter name.
+     *
+     * @param parameters
+     *     The map of all associated connection parameter values which apply
+     *     when the sharing profile is used, indexed by parameter name.
+     */
+    public void setParameters(Map<String, String> parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * Returns a map of all attributes associated with this sharing profile.
+     * Each entry key is the attribute identifier, while each value is the
+     * attribute value itself.
+     *
+     * @return
+     *     The attribute map for this sharing profile.
+     */
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * Sets the map of all attributes associated with this sharing profile. Each
+     * entry key is the attribute identifier, while each value is the attribute
+     * value itself.
+     *
+     * @param attributes
+     *     The attribute map for this sharing profile.
+     */
+    public void setAttributes(Map<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java
new file mode 100644
index 0000000..effb1d4
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java
@@ -0,0 +1,101 @@
+/*
+ * 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.rest.sharingprofile;
+
+import java.util.Map;
+import org.apache.guacamole.net.auth.SharingProfile;
+
+/**
+ * Wrapper for APISharingProfile which provides a SharingProfile interface.
+ * Changes to the underlying APISharingProfile are reflected immediately in the
+ * values exposed by the SharingProfile interface, and changes made through the
+ * SharingProfile interface immediately affect the underlying APISharingProfile.
+ *
+ * @author Michael Jumper
+ */
+public class APISharingProfileWrapper implements SharingProfile {
+
+    /**
+     * The wrapped APISharingProfile.
+     */
+    private final APISharingProfile apiSharingProfile;
+
+    /**
+     * Creates a new APISharingProfileWrapper which is backed by the given
+     * APISharingProfile.
+     *
+     * @param apiSharingProfile
+     *     The APISharingProfile to wrap.
+     */
+    public APISharingProfileWrapper(APISharingProfile apiSharingProfile) {
+        this.apiSharingProfile = apiSharingProfile;
+    }
+
+    @Override
+    public String getName() {
+        return apiSharingProfile.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        apiSharingProfile.setName(name);
+    }
+
+    @Override
+    public String getIdentifier() {
+        return apiSharingProfile.getIdentifier();
+    }
+
+    @Override
+    public void setIdentifier(String identifier) {
+        apiSharingProfile.setIdentifier(identifier);
+    }
+
+    @Override
+    public String getPrimaryConnectionIdentifier() {
+        return apiSharingProfile.getPrimaryConnectionIdentifier();
+    }
+
+    @Override
+    public void setPrimaryConnectionIdentifier(String primaryConnectionIdentifier) {
+        apiSharingProfile.setPrimaryConnectionIdentifier(primaryConnectionIdentifier);
+    }
+
+    @Override
+    public Map<String, String> getParameters() {
+        return apiSharingProfile.getParameters();
+    }
+
+    @Override
+    public void setParameters(Map<String, String> parameters) {
+        apiSharingProfile.setParameters(parameters);
+    }
+
+    @Override
+    public Map<String, String> getAttributes() {
+        return apiSharingProfile.getAttributes();
+    }
+
+    @Override
+    public void setAttributes(Map<String, String> attributes) {
+        apiSharingProfile.setAttributes(attributes);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java
new file mode 100644
index 0000000..3371fdb
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java
@@ -0,0 +1,72 @@
+/*
+ * 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.rest.sharingprofile;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.SharingProfile;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.directory.DirectoryObjectResourceFactory;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+import org.apache.guacamole.rest.directory.DirectoryResource;
+
+/**
+ * A REST resource which abstracts the operations available on a Directory of
+ * SharingProfiles.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SharingProfileDirectoryResource
+        extends DirectoryResource<SharingProfile, APISharingProfile> {
+
+    /**
+     * Creates a new SharingProfileDirectoryResource which exposes the
+     * operations and subresources available for the given SharingProfile
+     * Directory.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory being exposed.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles
+     *     SharingProfiles.
+     *
+     * @param resourceFactory
+     *     A factory which can be used to create instances of resources
+     *     representing SharingProfiles.
+     */
+    @AssistedInject
+    public SharingProfileDirectoryResource(@Assisted UserContext userContext,
+            @Assisted Directory<SharingProfile> directory,
+            DirectoryObjectTranslator<SharingProfile, APISharingProfile> translator,
+            DirectoryObjectResourceFactory<SharingProfile, APISharingProfile> resourceFactory) {
+        super(userContext, directory, translator, resourceFactory);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java
new file mode 100644
index 0000000..dabec70
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java
@@ -0,0 +1,65 @@
+/*
+ * 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.rest.sharingprofile;
+
+import com.google.inject.AbstractModule;
+import org.apache.guacamole.rest.directory.DirectoryObjectResourceFactory;
+import org.apache.guacamole.rest.directory.DirectoryObjectResource;
+import com.google.inject.TypeLiteral;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import org.apache.guacamole.net.auth.SharingProfile;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+import org.apache.guacamole.rest.directory.DirectoryResource;
+import org.apache.guacamole.rest.directory.DirectoryResourceFactory;
+
+/**
+ * Guice Module which configures injections required for handling SharingProfile
+ * resources via the REST API.
+ *
+ * @author Michael Jumper
+ */
+public class SharingProfileModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+
+        // Create the required DirectoryResourceFactory implementation
+        install(new FactoryModuleBuilder()
+                .implement(
+                    new TypeLiteral<DirectoryResource<SharingProfile, APISharingProfile>>() {},
+                    SharingProfileDirectoryResource.class
+                )
+                .build(new TypeLiteral<DirectoryResourceFactory<SharingProfile, APISharingProfile>>() {}));
+
+        // Create the required DirectoryObjectResourceFactory implementation
+        install(new FactoryModuleBuilder()
+                .implement(
+                    new TypeLiteral<DirectoryObjectResource<SharingProfile, APISharingProfile>>() {},
+                    SharingProfileResource.class
+                )
+                .build(new TypeLiteral<DirectoryObjectResourceFactory<SharingProfile, APISharingProfile>>() {}));
+
+        // Bind translator for converting between SharingProfile and APISharingProfile
+        bind(new TypeLiteral<DirectoryObjectTranslator<SharingProfile, APISharingProfile>>() {})
+                .to(SharingProfileObjectTranslator.class);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java
new file mode 100644
index 0000000..42dbc1c
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.rest.sharingprofile;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.SharingProfile;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+
+/**
+ * Translator which converts between SharingProfile objects and
+ * APISharingProfile objects.
+ *
+ * @author Michael Jumper
+ */
+public class SharingProfileObjectTranslator
+        implements DirectoryObjectTranslator<SharingProfile, APISharingProfile> {
+
+    @Override
+    public APISharingProfile toExternalObject(SharingProfile object)
+            throws GuacamoleException {
+        return new APISharingProfile(object);
+    }
+
+    @Override
+    public SharingProfile toInternalObject(APISharingProfile object) {
+        return new APISharingProfileWrapper(object);
+    }
+
+    @Override
+    public void applyExternalChanges(SharingProfile existingObject,
+            APISharingProfile object) {
+
+        // Update the sharing profile
+        existingObject.setPrimaryConnectionIdentifier(object.getPrimaryConnectionIdentifier());
+        existingObject.setName(object.getName());
+        existingObject.setParameters(object.getParameters());
+        existingObject.setAttributes(object.getAttributes());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java
new file mode 100644
index 0000000..debf804
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java
@@ -0,0 +1,125 @@
+/*
+ * 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.rest.sharingprofile;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.util.Map;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSecurityException;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.SharingProfile;
+import org.apache.guacamole.net.auth.User;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.net.auth.permission.ObjectPermission;
+import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
+import org.apache.guacamole.net.auth.permission.SystemPermission;
+import org.apache.guacamole.net.auth.permission.SystemPermissionSet;
+import org.apache.guacamole.rest.directory.DirectoryObjectResource;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+
+/**
+ * A REST resource which abstracts the operations available on an existing
+ * SharingProfile.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SharingProfileResource
+        extends DirectoryObjectResource<SharingProfile, APISharingProfile> {
+
+    /**
+     * The UserContext associated with the Directory which contains the
+     * SharingProfile exposed by this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The SharingProfile object represented by this SharingProfileResource.
+     */
+    private final SharingProfile sharingProfile;
+
+    /**
+     * Creates a new SharingProfileResource which exposes the operations and
+     * subresources available for the given SharingProfile.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory which contains the given SharingProfile.
+     *
+     * @param sharingProfile
+     *     The SharingProfile that this SharingProfileResource should represent.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles the type of
+     *     object given.
+     */
+    @AssistedInject
+    public SharingProfileResource(@Assisted UserContext userContext,
+            @Assisted Directory<SharingProfile> directory,
+            @Assisted SharingProfile sharingProfile,
+            DirectoryObjectTranslator<SharingProfile, APISharingProfile> translator) {
+        super(directory, sharingProfile, translator);
+        this.userContext = userContext;
+        this.sharingProfile = sharingProfile;
+    }
+
+    /**
+     * Retrieves the connection parameters associated with the SharingProfile
+     * exposed by this SharingProfile resource.
+       *
+     * @return
+     *     A map of parameter name/value pairs.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the connection parameters of the
+     *     SharingProfile.
+     */
+    @GET
+    @Path("parameters")
+    public Map<String, String> getParameters()
+            throws GuacamoleException {
+
+        User self = userContext.self();
+
+        // Retrieve permission sets
+        SystemPermissionSet systemPermissions = self.getSystemPermissions();
+        ObjectPermissionSet sharingProfilePermissions = self.getSharingProfilePermissions();
+
+        // Deny access if adminstrative or update permission is missing
+        String identifier = sharingProfile.getIdentifier();
+        if (!systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER)
+         && !sharingProfilePermissions.hasPermission(ObjectPermission.Type.UPDATE, identifier))
+            throw new GuacamoleSecurityException("Permission to read sharing profile parameters denied.");
+
+        // Return parameter map
+        return sharingProfile.getParameters();
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java
new file mode 100644
index 0000000..53a76f7
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+/**
+ * Classes related to retrieving or manipulating sharing profiles using the
+ * Guacamole REST API.
+ */
+package org.apache.guacamole.rest.sharingprofile;
+

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c231f4eb/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java
index f9a05bb..cef6aec 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java
@@ -98,6 +98,11 @@ public class APIUserWrapper implements User {
     }
 
     @Override
+    public ObjectPermissionSet getSharingProfilePermissions() throws GuacamoleException {
+        throw new GuacamoleUnsupportedException("APIUserWrapper does not provide permission access.");
+    }
+
+    @Override
     public ObjectPermissionSet getUserPermissions()
             throws GuacamoleException {
         throw new GuacamoleUnsupportedException("APIUserWrapper does not provide permission access.");