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/20 05:29:19 UTC

[7/8] incubator-guacamole-client git commit: GUACAMOLE-5: Expose sharing profiles via a Directory on the UserContext according to granted permissions.

GUACAMOLE-5: Expose sharing profiles via a Directory on the UserContext according to granted permissions.


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/a03b76d9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/a03b76d9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/a03b76d9

Branch: refs/heads/master
Commit: a03b76d9dda02849a26e90815ac312448fad39ef
Parents: 53a856b
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 19 16:11:45 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 19 22:26:30 2016 -0700

----------------------------------------------------------------------
 .../jdbc/JDBCAuthenticationProviderModule.java  |  10 +
 .../SharingProfilePermissionService.java        |  66 ++++
 .../permission/SharingProfilePermissionSet.java |  44 +++
 .../sharingprofile/ModeledSharingProfile.java   | 110 +++++++
 .../sharingprofile/SharingProfileDirectory.java |  85 +++++
 .../sharingprofile/SharingProfileService.java   | 328 +++++++++++++++++++
 .../guacamole/auth/jdbc/user/UserContext.java   |  16 +-
 7 files changed, 655 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderModule.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderModule.java
index 35b15af..71d784a 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderModule.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderModule.java
@@ -60,8 +60,13 @@ import org.apache.guacamole.auth.jdbc.activeconnection.ActiveConnectionService;
 import org.apache.guacamole.auth.jdbc.activeconnection.TrackedActiveConnection;
 import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper;
 import org.apache.guacamole.auth.jdbc.permission.SharingProfilePermissionMapper;
+import org.apache.guacamole.auth.jdbc.permission.SharingProfilePermissionService;
+import org.apache.guacamole.auth.jdbc.permission.SharingProfilePermissionSet;
+import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile;
+import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileDirectory;
 import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileMapper;
 import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileParameterMapper;
+import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileService;
 import org.apache.guacamole.auth.jdbc.tunnel.RestrictedGuacamoleTunnelService;
 import org.apache.guacamole.net.auth.AuthenticationProvider;
 import org.mybatis.guice.MyBatisModule;
@@ -141,8 +146,11 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
         bind(ModeledConnection.class);
         bind(ModeledConnectionGroup.class);
         bind(ModeledGuacamoleConfiguration.class);
+        bind(ModeledSharingProfile.class);
         bind(ModeledUser.class);
         bind(RootConnectionGroup.class);
+        bind(SharingProfileDirectory.class);
+        bind(SharingProfilePermissionSet.class);
         bind(SystemPermissionSet.class);
         bind(TrackedActiveConnection.class);
         bind(UserContext.class);
@@ -159,6 +167,8 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
         bind(GuacamoleTunnelService.class).to(RestrictedGuacamoleTunnelService.class);
         bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
         bind(SaltService.class).to(SecureRandomSaltService.class);
+        bind(SharingProfilePermissionService.class);
+        bind(SharingProfileService.class);
         bind(SystemPermissionService.class);
         bind(UserPermissionService.class);
         bind(UserService.class);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionService.java
new file mode 100644
index 0000000..7c12afd
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionService.java
@@ -0,0 +1,66 @@
+/*
+ * 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.permission;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import org.apache.guacamole.auth.jdbc.user.AuthenticatedUser;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.user.ModeledUser;
+
+/**
+ * Service which provides convenience methods for creating, retrieving, and
+ * deleting sharing profile permissions. This service will automatically enforce
+ * the permissions of the current user.
+ *
+ * @author Michael Jumper
+ */
+public class SharingProfilePermissionService extends ModeledObjectPermissionService {
+
+    /**
+     * Mapper for sharing profile permissions.
+     */
+    @Inject
+    private SharingProfilePermissionMapper sharingProfilePermissionMapper;
+    
+    /**
+     * Provider for sharing profile permission sets.
+     */
+    @Inject
+    private Provider<SharingProfilePermissionSet> sharingProfilePermissionSetProvider;
+    
+    @Override
+    protected ObjectPermissionMapper getPermissionMapper() {
+        return sharingProfilePermissionMapper;
+    }
+
+    @Override
+    public ObjectPermissionSet getPermissionSet(AuthenticatedUser user,
+            ModeledUser targetUser) throws GuacamoleException {
+
+        // Create permission set for requested user
+        ObjectPermissionSet permissionSet = sharingProfilePermissionSetProvider.get();
+        permissionSet.init(user, targetUser);
+
+        return permissionSet;
+        
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionSet.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionSet.java
new file mode 100644
index 0000000..77cb37e
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionSet.java
@@ -0,0 +1,44 @@
+/*
+ * 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.permission;
+
+import com.google.inject.Inject;
+
+/**
+ * A database implementation of ObjectPermissionSet which uses an injected
+ * service to query and manipulate the sharing profile permissions associated
+ * with a particular user.
+ *
+ * @author Michael Jumper
+ */
+public class SharingProfilePermissionSet extends ObjectPermissionSet {
+
+    /**
+     * Service for querying and manipulating sharing profile permissions.
+     */
+    @Inject
+    private SharingProfilePermissionService sharingProfilePermissionService;
+    
+    @Override
+    protected ObjectPermissionService getObjectPermissionService() {
+        return sharingProfilePermissionService;
+    }
+ 
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java
new file mode 100644
index 0000000..318efed
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/ModeledSharingProfile.java
@@ -0,0 +1,110 @@
+/*
+ * 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.sharingprofile;
+
+import com.google.inject.Inject;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObject;
+import org.apache.guacamole.form.Form;
+import org.apache.guacamole.net.auth.SharingProfile;
+
+/**
+ * An implementation of the SharingProfile object which is backed by a database
+ * model.
+ *
+ * @author Michael Jumper
+ */
+public class ModeledSharingProfile
+        extends ModeledDirectoryObject<SharingProfileModel>
+        implements SharingProfile {
+
+    /**
+     * All possible attributes of sharing profile objects organized as
+     * individual, logical forms. Currently, there are no such attributes.
+     */
+    public static final Collection<Form> ATTRIBUTES = Collections.<Form>emptyList();
+
+    /**
+     * The manually-set parameter map, if any.
+     */
+    private Map<String, String> parameters = null;
+
+    /**
+     * Service for managing sharing profiles.
+     */
+    @Inject
+    private SharingProfileService sharingProfileService;
+
+    /**
+     * Creates a new, empty ModeledSharingProfile.
+     */
+    public ModeledSharingProfile() {
+    }
+
+    @Override
+    public String getName() {
+        return getModel().getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        getModel().setName(name);
+    }
+
+    @Override
+    public String getPrimaryConnectionIdentifier() {
+        return getModel().getPrimaryConnectionIdentifier();
+    }
+
+    @Override
+    public void setPrimaryConnectionIdentifier(String identifier) {
+        getModel().setPrimaryConnectionIdentifier(identifier);
+    }
+
+    @Override
+    public Map<String, String> getParameters() {
+
+        // Retrieve visible parameters, if not overridden by setParameters()
+        if (parameters == null)
+            return sharingProfileService.retrieveParameters(getCurrentUser(),
+                    getModel().getIdentifier());
+
+        return parameters;
+
+    }
+
+    @Override
+    public void setParameters(Map<String, String> parameters) {
+        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
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileDirectory.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileDirectory.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileDirectory.java
new file mode 100644
index 0000000..6551274
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileDirectory.java
@@ -0,0 +1,85 @@
+/*
+ * 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.sharingprofile;
+
+import com.google.inject.Inject;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.base.RestrictedObject;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.SharingProfile;
+import org.mybatis.guice.transactional.Transactional;
+
+/**
+ * Implementation of the SharingProfile Directory which is driven by an
+ * underlying, arbitrary database.
+ *
+ * @author Michael Jumper
+ */
+public class SharingProfileDirectory extends RestrictedObject
+    implements Directory<SharingProfile> {
+
+    /**
+     * Service for managing sharing profile objects.
+     */
+    @Inject
+    private SharingProfileService sharingProfileService;
+
+    @Override
+    public SharingProfile get(String identifier) throws GuacamoleException {
+        return sharingProfileService.retrieveObject(getCurrentUser(), identifier);
+    }
+
+    @Override
+    @Transactional
+    public Collection<SharingProfile> getAll(Collection<String> identifiers) throws GuacamoleException {
+        return Collections.<SharingProfile>unmodifiableCollection(
+            sharingProfileService.retrieveObjects(getCurrentUser(), identifiers)
+        );
+    }
+
+    @Override
+    @Transactional
+    public Set<String> getIdentifiers() throws GuacamoleException {
+        return sharingProfileService.getIdentifiers(getCurrentUser());
+    }
+
+    @Override
+    @Transactional
+    public void add(SharingProfile object) throws GuacamoleException {
+        sharingProfileService.createObject(getCurrentUser(), object);
+    }
+
+    @Override
+    @Transactional
+    public void update(SharingProfile object) throws GuacamoleException {
+        ModeledSharingProfile sharingProfile = (ModeledSharingProfile) object;
+        sharingProfileService.updateObject(getCurrentUser(), sharingProfile);
+    }
+
+    @Override
+    @Transactional
+    public void remove(String identifier) throws GuacamoleException {
+        sharingProfileService.deleteObject(getCurrentUser(), identifier);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileService.java
new file mode 100644
index 0000000..11c70d2
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileService.java
@@ -0,0 +1,328 @@
+/*
+ * 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.sharingprofile;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.apache.guacamole.auth.jdbc.user.AuthenticatedUser;
+import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
+import org.apache.guacamole.GuacamoleClientException;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectService;
+import org.apache.guacamole.auth.jdbc.permission.SharingProfilePermissionMapper;
+import org.apache.guacamole.auth.jdbc.permission.ObjectPermissionMapper;
+import org.apache.guacamole.net.auth.SharingProfile;
+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;
+
+/**
+ * Service which provides convenience methods for creating, retrieving, and
+ * manipulating sharing profiles.
+ *
+ * @author Michael Jumper
+ */
+public class SharingProfileService
+        extends ModeledDirectoryObjectService<ModeledSharingProfile,
+            SharingProfile, SharingProfileModel> {
+
+    /**
+     * Mapper for accessing sharing profiles.
+     */
+    @Inject
+    private SharingProfileMapper sharingProfileMapper;
+
+    /**
+     * Mapper for manipulating sharing profile permissions.
+     */
+    @Inject
+    private SharingProfilePermissionMapper sharingProfilePermissionMapper;
+    
+    /**
+     * Mapper for accessing sharing profile parameters.
+     */
+    @Inject
+    private SharingProfileParameterMapper parameterMapper;
+
+    /**
+     * Provider for creating sharing profiles.
+     */
+    @Inject
+    private Provider<ModeledSharingProfile> sharingProfileProvider;
+
+    @Override
+    protected ModeledDirectoryObjectMapper<SharingProfileModel> getObjectMapper() {
+        return sharingProfileMapper;
+    }
+
+    @Override
+    protected ObjectPermissionMapper getPermissionMapper() {
+        return sharingProfilePermissionMapper;
+    }
+
+    @Override
+    protected ModeledSharingProfile getObjectInstance(AuthenticatedUser currentUser,
+            SharingProfileModel model) {
+        ModeledSharingProfile sharingProfile = sharingProfileProvider.get();
+        sharingProfile.init(currentUser, model);
+        return sharingProfile;
+    }
+
+    @Override
+    protected SharingProfileModel getModelInstance(AuthenticatedUser currentUser,
+            final SharingProfile object) {
+
+        // Create new ModeledSharingProfile backed by blank model
+        SharingProfileModel model = new SharingProfileModel();
+        ModeledSharingProfile sharingProfile = getObjectInstance(currentUser, model);
+
+        // Set model contents through ModeledSharingProfile, copying the
+        // provided sharing profile
+        sharingProfile.setPrimaryConnectionIdentifier(object.getPrimaryConnectionIdentifier());
+        sharingProfile.setName(object.getName());
+        sharingProfile.setParameters(object.getParameters());
+        sharingProfile.setAttributes(object.getAttributes());
+
+        return model;
+        
+    }
+
+    @Override
+    protected boolean hasCreatePermission(AuthenticatedUser user)
+            throws GuacamoleException {
+
+        // Return whether user has explicit sharing profile creation permission
+        SystemPermissionSet permissionSet = user.getUser().getSystemPermissions();
+        return permissionSet.hasPermission(SystemPermission.Type.CREATE_SHARING_PROFILE);
+
+    }
+
+    @Override
+    protected ObjectPermissionSet getPermissionSet(AuthenticatedUser user)
+            throws GuacamoleException {
+
+        // Return permissions related to sharing profiles
+        return user.getUser().getSharingProfilePermissions();
+
+    }
+
+    @Override
+    protected void beforeCreate(AuthenticatedUser user,
+            SharingProfileModel model) throws GuacamoleException {
+
+        super.beforeCreate(user, model);
+        
+        // Name must not be blank
+        if (model.getName() == null || model.getName().trim().isEmpty())
+            throw new GuacamoleClientException("Sharing profile names must not be blank.");
+
+        // Do not attempt to create duplicate sharing profiles
+        SharingProfileModel existing = sharingProfileMapper.selectOneByName(model.getPrimaryConnectionIdentifier(), model.getName());
+        if (existing != null)
+            throw new GuacamoleClientException("The sharing profile \"" + model.getName() + "\" already exists.");
+
+    }
+
+    @Override
+    protected void beforeUpdate(AuthenticatedUser user,
+            SharingProfileModel model) throws GuacamoleException {
+
+        super.beforeUpdate(user, model);
+        
+        // Name must not be blank
+        if (model.getName() == null || model.getName().trim().isEmpty())
+            throw new GuacamoleClientException("Sharing profile names must not be blank.");
+        
+        // Check whether such a sharing profile is already present
+        SharingProfileModel existing = sharingProfileMapper.selectOneByName(model.getPrimaryConnectionIdentifier(), model.getName());
+        if (existing != null) {
+
+            // If the specified name matches a DIFFERENT existing sharing profile, the update cannot continue
+            if (!existing.getObjectID().equals(model.getObjectID()))
+                throw new GuacamoleClientException("The sharing profile \"" + model.getName() + "\" already exists.");
+
+        }
+
+    }
+
+    /**
+     * Given an arbitrary Guacamole sharing profile, produces a collection of
+     * parameter model objects containing the name/value pairs of that
+     * sharing profile's parameters.
+     *
+     * @param sharingProfile
+     *     The sharing profile whose configuration should be used to produce the
+     *     collection of parameter models.
+     *
+     * @return
+     *     A collection of parameter models containing the name/value pairs
+     *     of the given sharing profile's parameters.
+     */
+    private Collection<SharingProfileParameterModel> getParameterModels(ModeledSharingProfile sharingProfile) {
+
+        Map<String, String> parameters = sharingProfile.getParameters();
+        
+        // Convert parameters to model objects
+        Collection<SharingProfileParameterModel> parameterModels = new ArrayList<SharingProfileParameterModel>(parameters.size());
+        for (Map.Entry<String, String> parameterEntry : parameters.entrySet()) {
+
+            // Get parameter name and value
+            String name = parameterEntry.getKey();
+            String value = parameterEntry.getValue();
+
+            // There is no need to insert empty parameters
+            if (value == null || value.isEmpty())
+                continue;
+            
+            // Produce model object from parameter
+            SharingProfileParameterModel model = new SharingProfileParameterModel();
+            model.setSharingProfileIdentifier(sharingProfile.getIdentifier());
+            model.setName(name);
+            model.setValue(value);
+
+            // Add model to list
+            parameterModels.add(model);
+            
+        }
+
+        return parameterModels;
+
+    }
+
+    @Override
+    public ModeledSharingProfile createObject(AuthenticatedUser user, SharingProfile object)
+            throws GuacamoleException {
+
+        // Create sharing profile
+        ModeledSharingProfile sharingProfile = super.createObject(user, object);
+        sharingProfile.setParameters(object.getParameters());
+
+        // Insert new parameters, if any
+        Collection<SharingProfileParameterModel> parameterModels = getParameterModels(sharingProfile);
+        if (!parameterModels.isEmpty())
+            parameterMapper.insert(parameterModels);
+
+        return sharingProfile;
+
+    }
+    
+    @Override
+    public void updateObject(AuthenticatedUser user, ModeledSharingProfile object)
+            throws GuacamoleException {
+
+        // Update sharing profile
+        super.updateObject(user, object);
+
+        // Replace existing parameters with new parameters, if any
+        Collection<SharingProfileParameterModel> parameterModels = getParameterModels(object);
+        parameterMapper.delete(object.getIdentifier());
+        if (!parameterModels.isEmpty())
+            parameterMapper.insert(parameterModels);
+        
+    }
+
+    /**
+     * Returns the set of all identifiers for all sharing profiles associated
+     * with the given primary connection. Only sharing profiles that the user
+     * has read access to will be returned.
+     *
+     * Permission to read the primary connection having the given identifier is
+     * NOT checked.
+     *
+     * @param user
+     *     The user retrieving the identifiers.
+     * 
+     * @param identifier
+     *     The identifier of the primary connection.
+     *
+     * @return
+     *     The set of all identifiers for all sharing profiles associated with
+     *     the primary connection having the given identifier that the user has
+     *     read access to.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while reading identifiers.
+     */
+    public Set<String> getIdentifiersWithin(AuthenticatedUser user,
+            String identifier)
+            throws GuacamoleException {
+
+        // Bypass permission checks if the user is a system admin
+        if (user.getUser().isAdministrator())
+            return sharingProfileMapper.selectIdentifiersWithin(identifier);
+
+        // Otherwise only return explicitly readable identifiers
+        else
+            return sharingProfileMapper.selectReadableIdentifiersWithin(
+                    user.getUser().getModel(), identifier);
+
+    }
+
+    /**
+     * Retrieves all parameters visible to the given user and associated with
+     * the sharing profile having the given identifier. If the given user has no
+     * access to such parameters, or no such sharing profile exists, the
+     * returned map will be empty.
+     *
+     * @param user
+     *     The user retrieving sharing profile parameters.
+     *
+     * @param identifier
+     *     The identifier of the sharing profile whose parameters are being
+     *     retrieved.
+     *
+     * @return
+     *     A new map of all parameter name/value pairs that the given user has
+     *     access to.
+     */
+    public Map<String, String> retrieveParameters(AuthenticatedUser user,
+            String identifier) {
+
+        Map<String, String> parameterMap = new HashMap<String, String>();
+
+        // Determine whether we have permission to read parameters
+        boolean canRetrieveParameters;
+        try {
+            canRetrieveParameters = hasObjectPermission(user, identifier,
+                    ObjectPermission.Type.UPDATE);
+        }
+
+        // Provide empty (but mutable) map if unable to check permissions
+        catch (GuacamoleException e) {
+            return parameterMap;
+        }
+
+        // Populate parameter map if we have permission to do so
+        if (canRetrieveParameters) {
+            for (SharingProfileParameterModel parameter : parameterMapper.select(identifier))
+                parameterMap.put(parameter.getName(), parameter.getValue());
+        }
+
+        return parameterMap;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a03b76d9/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserContext.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserContext.java
index 7cb52f0..5ddea97 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserContext.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserContext.java
@@ -26,13 +26,14 @@ import org.apache.guacamole.auth.jdbc.connection.ConnectionDirectory;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.util.Collection;
-import java.util.Collections;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.auth.jdbc.base.RestrictedObject;
 import org.apache.guacamole.auth.jdbc.activeconnection.ActiveConnectionDirectory;
 import org.apache.guacamole.auth.jdbc.connection.ConnectionRecordSet;
 import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
 import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
+import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile;
+import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileDirectory;
 import org.apache.guacamole.form.Form;
 import org.apache.guacamole.net.auth.ActiveConnection;
 import org.apache.guacamole.net.auth.AuthenticationProvider;
@@ -41,7 +42,6 @@ import org.apache.guacamole.net.auth.ConnectionGroup;
 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.simple.SimpleDirectory;
 
 /**
  * UserContext implementation which is driven by an arbitrary, underlying
@@ -81,6 +81,13 @@ public class UserContext extends RestrictedObject
     private ConnectionGroupDirectory connectionGroupDirectory;
 
     /**
+     * Sharing profile directory restricted by the permissions of the user
+     * associated with this context.
+     */
+    @Inject
+    private SharingProfileDirectory sharingProfileDirectory;
+
+    /**
      * ActiveConnection directory restricted by the permissions of the user
      * associated with this context.
      */
@@ -108,6 +115,7 @@ public class UserContext extends RestrictedObject
         userDirectory.init(currentUser);
         connectionDirectory.init(currentUser);
         connectionGroupDirectory.init(currentUser);
+        sharingProfileDirectory.init(currentUser);
         activeConnectionDirectory.init(currentUser);
 
     }
@@ -140,7 +148,7 @@ public class UserContext extends RestrictedObject
     @Override
     public Directory<SharingProfile> getSharingProfileDirectory()
             throws GuacamoleException {
-        return new SimpleDirectory<SharingProfile>();
+        return sharingProfileDirectory;
     }
 
     @Override
@@ -184,7 +192,7 @@ public class UserContext extends RestrictedObject
 
     @Override
     public Collection<Form> getSharingProfileAttributes() {
-        return Collections.<Form>emptyList();
+        return ModeledSharingProfile.ATTRIBUTES;
     }
 
 }