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/13 05:09:39 UTC

[01/24] incubator-guacamole-client git commit: GUACAMOLE-5: Define base classes for REST API subresource locators.

Repository: incubator-guacamole-client
Updated Branches:
  refs/heads/master 3c2dbbe4f -> 6e81a2018


GUACAMOLE-5: Define base classes for REST API subresource locators.


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

Branch: refs/heads/master
Commit: d3a9cecb17f12903141a616bf051cf832b06fb69
Parents: 3c2dbbe
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Jul 11 23:44:56 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Jul 11 23:45:48 2016 -0700

----------------------------------------------------------------------
 guacamole/pom.xml                               |   5 +
 .../rest/directory/DirectoryObjectResource.java | 138 ++++++++++
 .../DirectoryObjectResourceFactory.java         |  56 ++++
 .../directory/DirectoryObjectTranslator.java    |  94 +++++++
 .../rest/directory/DirectoryResource.java       | 261 +++++++++++++++++++
 .../directory/DirectoryResourceFactory.java     |  57 ++++
 .../guacamole/rest/directory/package-info.java  |  24 ++
 7 files changed, 635 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/pom.xml
----------------------------------------------------------------------
diff --git a/guacamole/pom.xml b/guacamole/pom.xml
index e737bb1..c0b6b3b 100644
--- a/guacamole/pom.xml
+++ b/guacamole/pom.xml
@@ -290,6 +290,11 @@
             <artifactId>guice</artifactId>
             <version>3.0</version>
         </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-assistedinject</artifactId>
+            <version>3.0</version>
+        </dependency>
         
         <!-- Guice Servlet -->
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
new file mode 100644
index 0000000..298f76b
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
@@ -0,0 +1,138 @@
+/*
+ * 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.directory;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.Identifiable;
+
+/**
+ * A REST resource which abstracts the operations available on an existing
+ * Guacamole object that is contained within a Directory, such as modification,
+ * deletion, or individual retrieval.
+ *
+ * @author Michael Jumper
+ * @param <InternalType>
+ *     The type of object that this DirectoryObjectResource represents. To
+ *     avoid coupling the REST API too tightly to the extension API, these
+ *     objects are not directly serialized or deserialized when handling REST
+ *     requests.
+ *
+ * @param <ExternalType>
+ *     The type of object used in interchange (ie: serialized/deserialized as
+ *     JSON) between REST clients and this DirectoryObjectResource to
+ *     represent the InternalType.
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class DirectoryObjectResource<InternalType extends Identifiable, ExternalType> {
+
+    /**
+     * The Directory which contains the object represented by this
+     * DirectoryObjectResource.
+     */
+    private final Directory<InternalType> directory;
+
+    /**
+     * The object represented by this DirectoryObjectResource.
+     */
+    private final InternalType object;
+
+    /**
+     * A DirectoryObjectTranslator implementation which handles the type of
+     * objects represented by this DirectoryObjectResource.
+     */
+    private final DirectoryObjectTranslator<InternalType, ExternalType> translator;
+
+    /**
+     * Creates a new DirectoryObjectResource which exposes the operations
+     * available for the given object.
+     *
+     * @param directory
+     *     The Directory which contains the given object.
+     *
+     * @param object
+     *     The object that this DirectoryObjectResource should represent.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles the type of
+     *     object given.
+     */
+    @AssistedInject
+    public DirectoryObjectResource(@Assisted Directory<InternalType> directory,
+            @Assisted InternalType object,
+            DirectoryObjectTranslator<InternalType, ExternalType> translator) {
+        this.directory = directory;
+        this.object = object;
+        this.translator = translator;
+    }
+
+    /**
+     * Returns the object represented by this DirectoryObjectResource, in a
+     * format intended for interchange.
+     *
+     * @return
+     *     The object that this DirectoryObjectResource represents, in a format
+     *     intended for interchange.
+     *
+     * @throws GuacamoleException
+     *     If an error is encountered while retrieving the object.
+     */
+    @GET
+    public ExternalType getObject() throws GuacamoleException {
+        return translator.toExternalObject(object);
+    }
+
+    /**
+     * Updates an existing object. The changes to be made to the corresponding
+     * object within the directory indicated by the provided data.
+     *
+     * @param modifiedObject
+     *     The data to update the corresponding object with.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while updating the object.
+     */
+    @PUT
+    public void updateObject(ExternalType modifiedObject) throws GuacamoleException {
+        translator.applyExternalChanges(object, modifiedObject);
+        directory.update(object);
+    }
+
+    /**
+     * Removes this object from the containing directory.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while removing the object.
+     */
+    @DELETE
+    public void deleteObject() throws GuacamoleException {
+        directory.remove(object.getIdentifier());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
new file mode 100644
index 0000000..ba17382
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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.directory;
+
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.Identifiable;
+
+/**
+ * Factory which creates DirectoryObjectResource instances exposing objects of
+ * a particular type.
+ *
+ * @param <InternalType>
+ *     The type of object exposed by the DirectoryObjectResource instances
+ *     created by this DirectoryResourceFactory.
+ *
+ * @param <ExternalType>
+ *     The type of object used in interchange (ie: serialized or deserialized
+ *     as JSON) between REST clients and resources when representing the
+ *     InternalType.
+ */
+public interface DirectoryObjectResourceFactory<InternalType extends Identifiable, ExternalType> {
+
+    /**
+     * Creates a new DirectoryObjectResource which exposes the given object.
+     *
+     * @param directory
+     *     The Directory which contains the object being exposed.
+     *
+     * @param object
+     *     The object which should be exposed by the created
+     *     DirectoryObjectResource.
+     *
+     * @return
+     *     A new DirectoryObjectResource which exposes the given object.
+     */
+    DirectoryObjectResource<InternalType, ExternalType>
+        create(Directory<InternalType> directory, InternalType object);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectTranslator.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectTranslator.java
new file mode 100644
index 0000000..bac4795
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectTranslator.java
@@ -0,0 +1,94 @@
+/*
+ * 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.directory;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.Identifiable;
+
+/**
+ * Provides bidirectional conversion between REST-specific objects and the
+ * internal objects defined by the Guacamole extension API.
+ *
+ * @author Michael Jumper
+ * @param <InternalType>
+ *     The type of object converted by this DirectoryObjectTranslator which is
+ *     not necessarily intended for use in interchange.
+ *
+ * @param <ExternalType>
+ *     The type of object used in interchange (ie: serialized or
+ *     deserialized as JSON) between REST clients and resource implementations
+ *     when representing the InternalType.
+ */
+public interface DirectoryObjectTranslator<InternalType extends Identifiable, ExternalType> {
+
+    /**
+     * Converts the given object to an object which is intended to be used in
+     * interchange.
+     *
+     * @param object
+     *     The object to convert for the sake of interchange.
+     *
+     * @return
+     *     A new object containing the same data as the given internal object,
+     *     but intended for use in interchange.
+     *
+     * @throws GuacamoleException
+     *     If the provided object cannot be converted for any reason.
+     */
+    ExternalType toExternalObject(InternalType object)
+            throws GuacamoleException;
+
+    /**
+     * Converts the given object to an object which is intended to be used
+     * within the Guacamole extension API.
+     *
+     * @param object
+     *     An object of the type intended for use in interchange, such as that
+     *     produced by toExternalObject() or received from a user via REST.
+     *
+     * @return
+     *     A new object containing the same data as the given external object,
+     *     but intended for use within the Guacamole extension API.
+     *
+     * @throws GuacamoleException
+     *     If the provided object cannot be converted for any reason.
+     */
+    InternalType toInternalObject(ExternalType object)
+            throws GuacamoleException;
+
+    /**
+     * Overlays the changes indicated by the given external object, modifying
+     * the given existing object from the Guacamole extension API.
+     *
+     * @param existingObject
+     *     The existing object from the Guacamole extension API which should be
+     *     modified.
+     *
+     * @param object
+     *     The external object representing the modifications to the existing
+     *     internal object.
+     *
+     * @throws GuacamoleException
+     *     If the provided modifications cannot be applied for any reason.
+     */
+    void applyExternalChanges(InternalType existingObject, ExternalType object)
+            throws GuacamoleException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
new file mode 100644
index 0000000..8c748b0
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
@@ -0,0 +1,261 @@
+/*
+ * 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.directory;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleClientException;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleResourceNotFoundException;
+import org.apache.guacamole.GuacamoleUnsupportedException;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.Identifiable;
+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.APIPatch;
+import org.apache.guacamole.rest.PATCH;
+
+/**
+ * A REST resource which abstracts the operations available on all Guacamole
+ * Directory implementations, such as the creation of new objects, or listing
+ * of existing objects. A DirectoryResource functions as the parent of any
+ * number of child DirectoryObjectResources, which are created with the factory
+ * provided at the time of this object's construction.
+ *
+ * @author Michael Jumper
+ * @param <InternalType>
+ *     The type of object contained within the Directory that this
+ *     DirectoryResource exposes. To avoid coupling the REST API too tightly to
+ *     the extension API, these objects are not directly serialized or
+ *     deserialized when handling REST requests.
+ *
+ * @param <ExternalType>
+ *     The type of object used in interchange (ie: serialized/deserialized as
+ *     JSON) between REST clients and this DirectoryResource when representing
+ *     the InternalType.
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class DirectoryResource<InternalType extends Identifiable, ExternalType> {
+
+    /**
+     * The UserContext associated with the Directory being exposed by this
+     * DirectoryResource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The Directory being exposed by this DirectoryResource.
+     */
+    private final Directory<InternalType> directory;
+
+    /**
+     * A DirectoryObjectTranslator implementation which handles the type of
+     * objects contained within the Directory exposed by this DirectoryResource.
+     */
+    private final DirectoryObjectTranslator<InternalType, ExternalType> translator;
+
+    /**
+     * A factory which can be used to create instances of resources representing
+     * individual objects contained within the Directory exposed by this
+     * DirectoryResource.
+     */
+    private final DirectoryObjectResourceFactory<InternalType, ExternalType> resourceFactory;
+
+    /**
+     * Creates a new DirectoryResource which exposes the operations available
+     * for the given Directory.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory being exposed by this DirectoryResource.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles the type of
+     *     objects contained within the given Directory.
+     *
+     * @param resourceFactory
+     *     A factory which can be used to create instances of resources
+     *     representing individual objects contained within the given Directory.
+     */
+    @AssistedInject
+    public DirectoryResource(@Assisted UserContext userContext,
+            @Assisted Directory<InternalType> directory,
+            DirectoryObjectTranslator<InternalType, ExternalType> translator,
+            DirectoryObjectResourceFactory<InternalType, ExternalType> resourceFactory) {
+        this.userContext = userContext;
+        this.directory = directory;
+        this.translator = translator;
+        this.resourceFactory = resourceFactory;
+    }
+
+    /**
+     * Returns a map of all objects available within this DirectoryResource,
+     * filtering the returned map by the given permission, if specified.
+     *
+     * @param permissions
+     *     The set of permissions to filter with. A user must have one or more
+     *     of these permissions for a user to appear in the result.
+     *     If null, no filtering will be performed.
+     *
+     * @return
+     *     A map of all visible objects. If a permission was specified, this
+     *     map will contain only those objects for which the current user has
+     *     that permission.
+     *
+     * @throws GuacamoleException
+     *     If an error is encountered while retrieving the objects.
+     */
+    @GET
+    public Map<String, ExternalType> getObjects(
+            @QueryParam("permission") List<ObjectPermission.Type> permissions)
+            throws GuacamoleException {
+
+        // An admin user has access to all objects
+        User self = userContext.self();
+        SystemPermissionSet systemPermissions = self.getSystemPermissions();
+        boolean isAdmin = systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER);
+
+        // Filter objects, if requested
+        Collection<String> identifiers = directory.getIdentifiers();
+        if (!isAdmin && permissions != null && !permissions.isEmpty()) {
+            ObjectPermissionSet objectPermissions = self.getUserPermissions();
+            identifiers = objectPermissions.getAccessibleObjects(permissions, identifiers);
+        }
+
+        Map<String, ExternalType> apiObjects = new HashMap<String, ExternalType>();
+        for (InternalType object : directory.getAll(identifiers))
+            apiObjects.put(object.getIdentifier(), translator.toExternalObject(object));
+
+        return apiObjects;
+
+    }
+
+    /**
+     * Applies the given object patches, updating the underlying directory
+     * accordingly. This operation currently only supports deletion of objects
+     * through the "remove" patch operation. The path of each patch operation is
+     * of the form "/ID" where ID is the identifier of the object being
+     * modified.
+     *
+     * @param patches
+     *     The patches to apply for this request.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while deleting the objects.
+     */
+    @PATCH
+    public void patchObjects(List<APIPatch<String>> patches)
+            throws GuacamoleException {
+
+        // Apply each operation specified within the patch
+        for (APIPatch<String> patch : patches) {
+
+            // Only remove is supported
+            if (patch.getOp() != APIPatch.Operation.remove)
+                throw new GuacamoleUnsupportedException("Only the \"remove\" "
+                        + "operation is supported.");
+
+            // Retrieve and validate path
+            String path = patch.getPath();
+            if (!path.startsWith("/"))
+                throw new GuacamoleClientException("Patch paths must start with \"/\".");
+
+            // Remove specified object
+            directory.remove(path.substring(1));
+
+        }
+
+    }
+
+    /**
+     * Creates a new object within the underlying Directory, returning the
+     * object that was created. The identifier of the created object will be
+     * populated, if applicable.
+     *
+     * @param object
+     *     The object to create.
+     *
+     * @return
+     *     The object that was created.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while adding the object to the underlying
+     *     directory.
+     */
+    @POST
+    public ExternalType createObject(ExternalType object)
+            throws GuacamoleException {
+
+        // Create the new object within the directory
+        directory.add(translator.toInternalObject(object));
+
+        return object;
+
+    }
+
+    /**
+     * Retrieves an individual object, returning a DirectoryObjectResource
+     * implementation which exposes operations available on that object.
+     *
+     * @param identifier
+     *     The identifier of the object to retrieve.
+     *
+     * @return
+     *     A DirectoryObjectResource exposing operations available on the
+     *     object having the given identifier.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the object.
+     */
+    @Path("{identifier}")
+    public DirectoryObjectResource<InternalType, ExternalType>
+        getObjectResource(@PathParam("identifier") String identifier)
+            throws GuacamoleException {
+
+        // Retrieve the object having the given identifier
+        InternalType object = directory.get(identifier);
+        if (object == null)
+            throw new GuacamoleResourceNotFoundException("Not found: \"" + identifier + "\"");
+
+        // Return a resource which provides access to the retrieved object
+        return resourceFactory.create(directory, object);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResourceFactory.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResourceFactory.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResourceFactory.java
new file mode 100644
index 0000000..357777a
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResourceFactory.java
@@ -0,0 +1,57 @@
+/*
+ * 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.directory;
+
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.Identifiable;
+import org.apache.guacamole.net.auth.UserContext;
+
+/**
+ * Factory which creates DirectoryResource instances exposing Directory
+ * objects of a particular type.
+ *
+ * @param <InternalType>
+ *     The type of object contained within the Directory objects exposed by the
+ *     DirectoryResource instances created by this DirectoryResourceFactory.
+ *
+ * @param <ExternalType>
+ *     The type of object used in interchange (ie: serialized or deserialized
+ *     as JSON) between REST clients and resources when representing the
+ *     InternalType.
+ */
+public interface DirectoryResourceFactory<InternalType extends Identifiable, ExternalType> {
+
+    /**
+     * Creates a new DirectoryResource which exposes the given Directory.
+     *
+     * @param userContext
+     *     The UserContext from which the given Directory was obtained.
+     *
+     * @param directory
+     *     The Directory which should be exposed by the created
+     *     DirectoryResource.
+     *
+     * @return
+     *     A new DirectoryResource which exposes the given Directory.
+     */
+    DirectoryResource<InternalType, ExternalType>
+        create(UserContext userContext, Directory<InternalType> directory);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/d3a9cecb/guacamole/src/main/java/org/apache/guacamole/rest/directory/package-info.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/package-info.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/package-info.java
new file mode 100644
index 0000000..5283e87
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * Base classes providing support for exposing and manipulating Directory
+ * objects and their contents via the Guacamole REST API.
+ */
+package org.apache.guacamole.rest.directory;


[23/24] incubator-guacamole-client git commit: GUACAMOLE-5: Update tunnelService to match REST changes.

Posted by jm...@apache.org.
GUACAMOLE-5: Update tunnelService to match REST changes.

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

Branch: refs/heads/master
Commit: b66925c3d000c1ddc660a36ab8ccb4427669a1f8
Parents: abef36e
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 22:02:41 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 22:02:41 2016 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/rest/services/tunnelService.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b66925c3/guacamole/src/main/webapp/app/rest/services/tunnelService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/tunnelService.js b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
index 35c42a8..e93c50f 100644
--- a/guacamole/src/main/webapp/app/rest/services/tunnelService.js
+++ b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
@@ -62,7 +62,7 @@ angular.module('rest').factory('tunnelService', ['$injector',
         // Retrieve tunnels
         return $http({
             method  : 'GET',
-            url     : 'api/tunnels',
+            url     : 'api/session/tunnels',
             params  : httpParameters
         });
 
@@ -100,7 +100,7 @@ angular.module('rest').factory('tunnelService', ['$injector',
         // Build download URL
         var url = $window.location.origin
                 + $window.location.pathname
-                + 'api/tunnels/' + encodeURIComponent(tunnel)
+                + 'api/session/tunnels/' + encodeURIComponent(tunnel)
                 + '/streams/' + encodeURIComponent(stream.index)
                 + '/' + encodeURIComponent(filename)
                 + '?token=' + encodeURIComponent(authenticationService.getCurrentToken());
@@ -163,7 +163,7 @@ angular.module('rest').factory('tunnelService', ['$injector',
         // Build upload URL
         var url = $window.location.origin
                 + $window.location.pathname
-                + 'api/tunnels/' + encodeURIComponent(tunnel)
+                + 'api/session/tunnels/' + encodeURIComponent(tunnel)
                 + '/streams/' + encodeURIComponent(stream.index)
                 + '/' + encodeURIComponent(file.name)
                 + '?token=' + encodeURIComponent(authenticationService.getCurrentToken());


[09/24] incubator-guacamole-client git commit: GUACAMOLE-5: Refactor HistoryRESTService as a resource.

Posted by jm...@apache.org.
GUACAMOLE-5: Refactor HistoryRESTService as a resource.


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

Branch: refs/heads/master
Commit: 3658b91fe18e386b10d251922610c03075cc55a3
Parents: 3f7f6e6
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 13:43:37 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:46 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   2 -
 .../rest/history/HistoryRESTService.java        | 144 -------------------
 .../guacamole/rest/history/HistoryResource.java | 122 ++++++++++++++++
 .../rest/session/UserContextResource.java       |  14 ++
 4 files changed, 136 insertions(+), 146 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3658b91f/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 dbdcaba..c6de0dc 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -36,7 +36,6 @@ import org.apache.guacamole.rest.auth.SecureRandomAuthTokenGenerator;
 import org.apache.guacamole.rest.auth.TokenSessionMap;
 import org.apache.guacamole.rest.connection.ConnectionModule;
 import org.apache.guacamole.rest.connectiongroup.ConnectionGroupModule;
-import org.apache.guacamole.rest.history.HistoryRESTService;
 import org.apache.guacamole.rest.language.LanguageRESTService;
 import org.apache.guacamole.rest.patch.PatchRESTService;
 import org.apache.guacamole.rest.schema.SchemaRESTService;
@@ -88,7 +87,6 @@ public class RESTServiceModule extends ServletModule {
         bind(ObjectRetrievalService.class);
 
         // Set up the API endpoints
-        bind(HistoryRESTService.class);
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);
         bind(SchemaRESTService.class);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3658b91f/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryRESTService.java
deleted file mode 100644
index fd3738e..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryRESTService.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.history;
-
-import com.google.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.net.auth.ConnectionRecord;
-import org.apache.guacamole.net.auth.ConnectionRecordSet;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A REST Service for retrieving and managing the history records of Guacamole
- * objects.
- *
- * @author Michael Jumper
- */
-@Path("/data/{dataSource}/history")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class HistoryRESTService {
-
-    /**
-     * Logger for this class.
-     */
-    private static final Logger logger = LoggerFactory.getLogger(HistoryRESTService.class);
-
-    /**
-     * The maximum number of history records to return in any one response.
-     */
-    private static final int MAXIMUM_HISTORY_SIZE = 1000;
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
-     * Retrieves the usage history for all connections, restricted by optional
-     * filter parameters.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection whose history is to be
-     *     retrieved.
-     *
-     * @param requiredContents
-     *     The set of strings that each must occur somewhere within the
-     *     returned connection records, whether within the associated username,
-     *     the name of the associated connection, or any associated date. If
-     *     non-empty, any connection record not matching each of the strings
-     *     within the collection will be excluded from the results.
-     *
-     * @param sortPredicates
-     *     A list of predicates to apply while sorting the resulting connection
-     *     records, describing the properties involved and the sort order for
-     *     those properties.
-     *
-     * @return
-     *     A list of connection records, describing the start and end times of
-     *     various usages of this connection.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the connection history.
-     */
-    @GET
-    @Path("/connections")
-    public List<APIConnectionRecord> getConnectionHistory(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @QueryParam("contains") List<String> requiredContents,
-            @QueryParam("order") List<APIConnectionRecordSortPredicate> sortPredicates)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Retrieve overall connection history
-        ConnectionRecordSet history = userContext.getConnectionHistory();
-
-        // Restrict to records which contain the specified strings
-        for (String required : requiredContents) {
-            if (!required.isEmpty())
-                history = history.contains(required);
-        }
-
-        // Sort according to specified ordering
-        for (APIConnectionRecordSortPredicate predicate : sortPredicates)
-            history = history.sort(predicate.getProperty(), predicate.isDescending());
-
-        // Limit to maximum result size
-        history = history.limit(MAXIMUM_HISTORY_SIZE);
-
-        // Convert record set to collection of API connection records
-        List<APIConnectionRecord> apiRecords = new ArrayList<APIConnectionRecord>();
-        for (ConnectionRecord record : history.asCollection())
-            apiRecords.add(new APIConnectionRecord(record));
-
-        // Return the converted history
-        return apiRecords;
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3658b91f/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java
new file mode 100644
index 0000000..d71d445
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java
@@ -0,0 +1,122 @@
+/*
+ * 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.history;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.ConnectionRecord;
+import org.apache.guacamole.net.auth.ConnectionRecordSet;
+import org.apache.guacamole.net.auth.UserContext;
+
+/**
+ * A REST resource for retrieving and managing the history records of Guacamole
+ * objects.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class HistoryResource {
+
+    /**
+     * The maximum number of history records to return in any one response.
+     */
+    private static final int MAXIMUM_HISTORY_SIZE = 1000;
+
+    /**
+     * The UserContext whose associated connection history is being exposed.
+     */
+    private final UserContext userContext;
+
+    /**
+     * Creates a new HistoryResource which exposes the connection history
+     * associated with the given UserContext.
+     *
+     * @param userContext
+     *     The UserContext whose connection history should be exposed.
+     */
+    public HistoryResource(UserContext userContext) {
+        this.userContext = userContext;
+    }
+
+    /**
+     * Retrieves the usage history for all connections, restricted by optional
+     * filter parameters.
+     *
+     * @param requiredContents
+     *     The set of strings that each must occur somewhere within the
+     *     returned connection records, whether within the associated username,
+     *     the name of the associated connection, or any associated date. If
+     *     non-empty, any connection record not matching each of the strings
+     *     within the collection will be excluded from the results.
+     *
+     * @param sortPredicates
+     *     A list of predicates to apply while sorting the resulting connection
+     *     records, describing the properties involved and the sort order for
+     *     those properties.
+     *
+     * @return
+     *     A list of connection records, describing the start and end times of
+     *     various usages of this connection.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the connection history.
+     */
+    @GET
+    @Path("connections")
+    public List<APIConnectionRecord> getConnectionHistory(
+            @QueryParam("contains") List<String> requiredContents,
+            @QueryParam("order") List<APIConnectionRecordSortPredicate> sortPredicates)
+            throws GuacamoleException {
+
+        // Retrieve overall connection history
+        ConnectionRecordSet history = userContext.getConnectionHistory();
+
+        // Restrict to records which contain the specified strings
+        for (String required : requiredContents) {
+            if (!required.isEmpty())
+                history = history.contains(required);
+        }
+
+        // Sort according to specified ordering
+        for (APIConnectionRecordSortPredicate predicate : sortPredicates)
+            history = history.sort(predicate.getProperty(), predicate.isDescending());
+
+        // Limit to maximum result size
+        history = history.limit(MAXIMUM_HISTORY_SIZE);
+
+        // Convert record set to collection of API connection records
+        List<APIConnectionRecord> apiRecords = new ArrayList<APIConnectionRecord>();
+        for (ConnectionRecord record : history.asCollection())
+            apiRecords.add(new APIConnectionRecord(record));
+
+        // Return the converted history
+        return apiRecords;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3658b91f/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 c9ff670..81344c6 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
@@ -37,6 +37,7 @@ import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.rest.activeconnection.APIActiveConnection;
 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.user.APIUser;
 
 /**
@@ -169,4 +170,17 @@ public class UserContextResource {
                 userContext.getUserDirectory());
     }
 
+    /**
+     * Returns a new resource which represents historical data contained
+     * within the UserContext exposed by this UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the historical data contained within
+     *     the UserContext exposed by this UserContextResource.
+     */
+    @Path("history")
+    public HistoryResource getHistoryResource() {
+        return new HistoryResource(userContext);
+    }
+
 }


[17/24] incubator-guacamole-client git commit: GUACAMOLE-5: Take superclass into account when determining whether a method is a REST method.

Posted by jm...@apache.org.
GUACAMOLE-5: Take superclass into account when determining whether a method is a REST method.


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

Branch: refs/heads/master
Commit: 1aa256b26cd44d78f9ca201ca70eac7bcbb46363
Parents: 5029508
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 14:47:47 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTMethodMatcher.java       | 21 +++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/1aa256b2/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
index 3a862c8..c80750c 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
@@ -88,7 +88,26 @@ public class RESTMethodMatcher extends AbstractMatcher<Method> {
 
         }
 
-        // The method is not an HTTP method
+        // A method is also REST method if it overrides a REST method within
+        // the superclass
+        Class<?> superclass = method.getDeclaringClass().getSuperclass();
+        if (superclass != null) {
+
+            // Recheck against identical method within superclass
+            try {
+                return isRESTMethod(superclass.getMethod(method.getName(),
+                        method.getParameterTypes()));
+            }
+
+            // If there is no such method, then this method cannot possibly be
+            // a REST method
+            catch (NoSuchMethodException e) {
+                return false;
+            }
+
+        }
+
+        // Lacking a superclass, the search stops here - it's not a REST method
         return false;
 
     }


[05/24] incubator-guacamole-client git commit: GUACAMOLE-5: Replace ConnectionRESTService with new resource-driven implementation.

Posted by jm...@apache.org.
GUACAMOLE-5: Replace ConnectionRESTService with new resource-driven implementation.


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

Branch: refs/heads/master
Commit: 06b7887807d15b253ec8e1198e2cf865660402c1
Parents: bca4e34
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 00:49:46 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 11:42:16 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   6 +-
 .../rest/connection/ConnectionModule.java       |  60 ++++
 .../connection/ConnectionObjectTranslator.java  |  64 ++++
 .../rest/connection/ConnectionRESTService.java  | 346 -------------------
 .../rest/connection/ConnectionResource.java     | 155 +++++++++
 .../rest/session/UserContextResource.java       |  32 ++
 6 files changed, 315 insertions(+), 348 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/06b78878/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 bc8d7b6..c79cb29 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -29,13 +29,13 @@ import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
 import org.apache.guacamole.rest.auth.TokenRESTService;
-import org.apache.guacamole.rest.connection.ConnectionRESTService;
 import org.apache.guacamole.rest.connectiongroup.ConnectionGroupRESTService;
 import org.apache.guacamole.rest.activeconnection.ActiveConnectionRESTService;
 import org.apache.guacamole.rest.auth.AuthTokenGenerator;
 import org.apache.guacamole.rest.auth.AuthenticationService;
 import org.apache.guacamole.rest.auth.SecureRandomAuthTokenGenerator;
 import org.apache.guacamole.rest.auth.TokenSessionMap;
+import org.apache.guacamole.rest.connection.ConnectionModule;
 import org.apache.guacamole.rest.history.HistoryRESTService;
 import org.apache.guacamole.rest.language.LanguageRESTService;
 import org.apache.guacamole.rest.patch.PatchRESTService;
@@ -90,7 +90,6 @@ public class RESTServiceModule extends ServletModule {
         // Set up the API endpoints
         bind(ActiveConnectionRESTService.class);
         bind(ConnectionGroupRESTService.class);
-        bind(ConnectionRESTService.class);
         bind(HistoryRESTService.class);
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);
@@ -103,6 +102,9 @@ public class RESTServiceModule extends ServletModule {
         bind(SessionResource.class);
         install(new FactoryModuleBuilder().build(UserContextResourceFactory.class));
 
+        // Resources below root
+        install(new ConnectionModule());
+
         // Set up the servlet and JSON mappings
         bind(GuiceContainer.class);
         bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);

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

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/06b78878/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionObjectTranslator.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionObjectTranslator.java
new file mode 100644
index 0000000..de6253f
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionObjectTranslator.java
@@ -0,0 +1,64 @@
+/*
+ * 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.connection;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.Connection;
+import org.apache.guacamole.protocol.GuacamoleConfiguration;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+
+/**
+ * Translator which converts between Connection objects and APIConnection
+ * objects.
+ *
+ * @author Michael Jumper
+ */
+public class ConnectionObjectTranslator
+        implements DirectoryObjectTranslator<Connection, APIConnection> {
+
+    @Override
+    public APIConnection toExternalObject(Connection object)
+            throws GuacamoleException {
+        return new APIConnection(object);
+    }
+
+    @Override
+    public Connection toInternalObject(APIConnection object) {
+        return new APIConnectionWrapper(object);
+    }
+
+    @Override
+    public void applyExternalChanges(Connection existingObject,
+            APIConnection object) {
+
+        // Build updated configuration
+        GuacamoleConfiguration config = new GuacamoleConfiguration();
+        config.setProtocol(object.getProtocol());
+        config.setParameters(object.getParameters());
+
+        // Update the connection
+        existingObject.setConfiguration(config);
+        existingObject.setParentIdentifier(object.getParentIdentifier());
+        existingObject.setName(object.getName());
+        existingObject.setAttributes(object.getAttributes());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/06b78878/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionRESTService.java
deleted file mode 100644
index feb0324..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionRESTService.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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.connection;
-
-import com.google.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleClientException;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleSecurityException;
-import org.apache.guacamole.net.auth.Connection;
-import org.apache.guacamole.net.auth.ConnectionRecord;
-import org.apache.guacamole.net.auth.Directory;
-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.GuacamoleSession;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.apache.guacamole.rest.history.APIConnectionRecord;
-import org.apache.guacamole.protocol.GuacamoleConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A REST Service for handling connection CRUD operations.
- * 
- * @author James Muehlner
- */
-@Path("/data/{dataSource}/connections")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class ConnectionRESTService {
-
-    /**
-     * Logger for this class.
-     */
-    private static final Logger logger = LoggerFactory.getLogger(ConnectionRESTService.class);
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-    
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-    
-    /**
-     * Retrieves an individual connection.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection to be retrieved.
-     *
-     * @param connectionID
-     *     The identifier of the connection to retrieve.
-     *
-     * @return
-     *     The connection having the given identifier.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the connection.
-     */
-    @GET
-    @Path("/{connectionID}")
-    public APIConnection getConnection(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionID") String connectionID)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        
-        // Retrieve the requested connection
-        return new APIConnection(retrievalService.retrieveConnection(session, authProviderIdentifier, connectionID));
-
-    }
-
-    /**
-     * Retrieves the parameters associated with a single connection.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection whose parameters are to be
-     *     retrieved.
-     *
-     * @param connectionID
-     *     The identifier of the connection.
-     *
-     * @return
-     *     A map of parameter name/value pairs.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the connection parameters.
-     */
-    @GET
-    @Path("/{connectionID}/parameters")
-    public Map<String, String> getConnectionParameters(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionID") String connectionID)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        User self = userContext.self();
-
-        // Retrieve permission sets
-        SystemPermissionSet systemPermissions = self.getSystemPermissions();
-        ObjectPermissionSet connectionPermissions = self.getConnectionPermissions();
-
-        // Deny access if adminstrative or update permission is missing
-        if (!systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER)
-         && !connectionPermissions.hasPermission(ObjectPermission.Type.UPDATE, connectionID))
-            throw new GuacamoleSecurityException("Permission to read connection parameters denied.");
-
-        // Retrieve the requested connection
-        Connection connection = retrievalService.retrieveConnection(userContext, connectionID);
-
-        // Retrieve connection configuration
-        GuacamoleConfiguration config = connection.getConfiguration();
-
-        // Return parameter map
-        return config.getParameters();
-
-    }
-
-    /**
-     * Retrieves the usage history of a single connection.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection whose history is to be
-     *     retrieved.
-     *
-     * @param connectionID
-     *     The identifier of the connection.
-     *
-     * @return
-     *     A list of connection records, describing the start and end times of
-     *     various usages of this connection.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the connection history.
-     */
-    @GET
-    @Path("/{connectionID}/history")
-    public List<APIConnectionRecord> getConnectionHistory(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionID") String connectionID)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-
-        // Retrieve the requested connection
-        Connection connection = retrievalService.retrieveConnection(session, authProviderIdentifier, connectionID);
-
-        // Retrieve the requested connection's history
-        List<APIConnectionRecord> apiRecords = new ArrayList<APIConnectionRecord>();
-        for (ConnectionRecord record : connection.getHistory())
-            apiRecords.add(new APIConnectionRecord(record));
-
-        // Return the converted history
-        return apiRecords;
-
-    }
-
-    /**
-     * Deletes an individual connection.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection to be deleted.
-     *
-     * @param connectionID
-     *     The identifier of the connection to delete.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while deleting the connection.
-     */
-    @DELETE
-    @Path("/{connectionID}")
-    public void deleteConnection(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionID") String connectionID)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get the connection directory
-        Directory<Connection> connectionDirectory = userContext.getConnectionDirectory();
-
-        // Delete the specified connection
-        connectionDirectory.remove(connectionID);
-
-    }
-
-    /**
-     * Creates a new connection and returns the new connection, with identifier
-     * field populated.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the connection is to be created.
-     *
-     * @param connection
-     *     The connection to create.
-     *
-     * @return
-     *     The new connection.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while creating the connection.
-     */
-    @POST
-    public APIConnection createConnection(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            APIConnection connection) throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        
-        // Validate that connection data was provided
-        if (connection == null)
-            throw new GuacamoleClientException("Connection JSON must be submitted when creating connections.");
-
-        // Add the new connection
-        Directory<Connection> connectionDirectory = userContext.getConnectionDirectory();
-        connectionDirectory.add(new APIConnectionWrapper(connection));
-
-        // Return the new connection
-        return connection;
-
-    }
-  
-    /**
-     * Updates an existing connection. If the parent identifier of the
-     * connection is changed, the connection will also be moved to the new
-     * parent group.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection to be updated.
-     *
-     * @param connectionID
-     *     The identifier of the connection to update.
-     *
-     * @param connection
-     *     The connection data to update the specified connection with.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while updating the connection.
-     */
-    @PUT
-    @Path("/{connectionID}")
-    public void updateConnection(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionID") String connectionID,
-            APIConnection connection) throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        
-        // Validate that connection data was provided
-        if (connection == null)
-            throw new GuacamoleClientException("Connection JSON must be submitted when updating connections.");
-
-        // Get the connection directory
-        Directory<Connection> connectionDirectory = userContext.getConnectionDirectory();
-        
-        // Retrieve connection to update
-        Connection existingConnection = retrievalService.retrieveConnection(userContext, connectionID);
-
-        // Build updated configuration
-        GuacamoleConfiguration config = new GuacamoleConfiguration();
-        config.setProtocol(connection.getProtocol());
-        config.setParameters(connection.getParameters());
-
-        // Update the connection
-        existingConnection.setConfiguration(config);
-        existingConnection.setParentIdentifier(connection.getParentIdentifier());
-        existingConnection.setName(connection.getName());
-        existingConnection.setAttributes(connection.getAttributes());
-        connectionDirectory.update(existingConnection);
-
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/06b78878/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionResource.java
new file mode 100644
index 0000000..9238af1
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connection/ConnectionResource.java
@@ -0,0 +1,155 @@
+/*
+ * 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.connection;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.util.ArrayList;
+import java.util.List;
+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.Connection;
+import org.apache.guacamole.net.auth.ConnectionRecord;
+import org.apache.guacamole.net.auth.Directory;
+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.history.APIConnectionRecord;
+import org.apache.guacamole.protocol.GuacamoleConfiguration;
+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
+ * Connection.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class ConnectionResource extends DirectoryObjectResource<Connection, APIConnection> {
+
+    /**
+     * The UserContext associated with the Directory which contains the
+     * Connection exposed by this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The Connection object represented by this ConnectionResource.
+     */
+    private final Connection connection;
+
+    /**
+     * Creates a new ConnectionResource which exposes the operations and
+     * subresources available for the given Connection.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory which contains the given Connection.
+     *
+     * @param connection
+     *     The Connection that this ConnectionResource should represent.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles the type of
+     *     object given.
+     */
+    @AssistedInject
+    public ConnectionResource(@Assisted UserContext userContext,
+            @Assisted Directory<Connection> directory,
+            @Assisted Connection connection,
+            DirectoryObjectTranslator<Connection, APIConnection> translator) {
+        super(directory, connection, translator);
+        this.userContext = userContext;
+        this.connection = connection;
+    }
+
+    /**
+     * Retrieves the parameters associated with a single connection.
+     * 
+     * @return
+     *     A map of parameter name/value pairs.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the connection parameters.
+     */
+    @GET
+    @Path("parameters")
+    public Map<String, String> getConnectionParameters()
+            throws GuacamoleException {
+
+        User self = userContext.self();
+
+        // Retrieve permission sets
+        SystemPermissionSet systemPermissions = self.getSystemPermissions();
+        ObjectPermissionSet connectionPermissions = self.getConnectionPermissions();
+
+        // Deny access if adminstrative or update permission is missing
+        String identifier = connection.getIdentifier();
+        if (!systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER)
+         && !connectionPermissions.hasPermission(ObjectPermission.Type.UPDATE, identifier))
+            throw new GuacamoleSecurityException("Permission to read connection parameters denied.");
+
+        // Retrieve connection configuration
+        GuacamoleConfiguration config = connection.getConfiguration();
+
+        // Return parameter map
+        return config.getParameters();
+
+    }
+
+    /**
+     * Retrieves the usage history of a single connection.
+     * 
+     * @return
+     *     A list of connection records, describing the start and end times of
+     *     various usages of this connection.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the connection history.
+     */
+    @GET
+    @Path("history")
+    public List<APIConnectionRecord> getConnectionHistory()
+            throws GuacamoleException {
+
+        // Retrieve the requested connection's history
+        List<APIConnectionRecord> apiRecords = new ArrayList<APIConnectionRecord>();
+        for (ConnectionRecord record : connection.getHistory())
+            apiRecords.add(new APIConnectionRecord(record));
+
+        // Return the converted history
+        return apiRecords;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/06b78878/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 e5dcc0c..7518c71 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
@@ -19,12 +19,19 @@
 
 package org.apache.guacamole.rest.session;
 
+import org.apache.guacamole.rest.directory.DirectoryResource;
+import org.apache.guacamole.rest.directory.DirectoryResourceFactory;
+import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
 import javax.ws.rs.Consumes;
+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.net.auth.Connection;
 import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.connection.APIConnection;
 
 /**
  * A REST resource which exposes the contents of a particular UserContext.
@@ -41,6 +48,13 @@ public class UserContextResource {
     private final UserContext userContext;
 
     /**
+     * Factory for creating DirectoryResources which expose a given
+     * Connection Directory.
+     */
+    @Inject
+    private DirectoryResourceFactory<Connection, APIConnection> connectionDirectoryResourceFactory;
+
+    /**
      * Creates a new UserContextResource which exposes the data within the
      * given UserContext.
      *
@@ -53,4 +67,22 @@ public class UserContextResource {
         this.userContext = userContext;
     }
 
+    /**
+     * Returns a new resource which represents the Connection Directory
+     * contained within the UserContext exposed by this UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the Connection Directory contained
+     *     within the UserContext exposed by this UserContextResource.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the Connection Directory.
+     */
+    @Path("connections")
+    public DirectoryResource<Connection, APIConnection> getConnectionDirectoryResource()
+            throws GuacamoleException {
+        return connectionDirectoryResourceFactory.create(userContext,
+                userContext.getConnectionDirectory());
+    }
+
 }


[16/24] incubator-guacamole-client git commit: GUACAMOLE-5: Remove unneeded functions from ObjectRetrievalService.

Posted by jm...@apache.org.
GUACAMOLE-5: Remove unneeded functions from ObjectRetrievalService.


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

Branch: refs/heads/master
Commit: 50295083d2f3e23a25c8c98097dbca255936ff65
Parents: 3c9da92
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 14:12:11 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/ObjectRetrievalService.java  | 202 +------------------
 1 file changed, 1 insertion(+), 201 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/50295083/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java b/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
index d0e403c..edcb2fa 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
@@ -23,19 +23,11 @@ import java.util.List;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.GuacamoleResourceNotFoundException;
 import org.apache.guacamole.net.auth.AuthenticationProvider;
-import org.apache.guacamole.net.auth.Connection;
-import org.apache.guacamole.net.auth.ConnectionGroup;
-import org.apache.guacamole.net.auth.Directory;
-import org.apache.guacamole.net.auth.User;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.rest.connectiongroup.APIConnectionGroup;
 
 /**
- * Provides easy access and automatic error handling for retrieval of objects,
- * such as users, connections, or connection groups. REST API semantics, such
- * as the special root connection group identifier, are also handled
- * automatically.
+ * Provides easy access and automatic error handling for retrieval of objects.
  */
 public class ObjectRetrievalService {
 
@@ -82,196 +74,4 @@ public class ObjectRetrievalService {
 
     }
 
-    /**
-     * Retrieves a single user from the given user context.
-     *
-     * @param userContext
-     *     The user context to retrieve the user from.
-     *
-     * @param identifier
-     *     The identifier of the user to retrieve.
-     *
-     * @return
-     *     The user having the given identifier.
-     *
-     * @throws GuacamoleException 
-     *     If an error occurs while retrieving the user, or if the
-     *     user does not exist.
-     */
-    public User retrieveUser(UserContext userContext,
-            String identifier) throws GuacamoleException {
-
-        // Get user directory
-        Directory<User> directory = userContext.getUserDirectory();
-
-        // Pull specified user
-        User user = directory.get(identifier);
-        if (user == null)
-            throw new GuacamoleResourceNotFoundException("No such user: \"" + identifier + "\"");
-
-        return user;
-
-    }
-
-    /**
-     * Retrieves a single user from the given GuacamoleSession.
-     *
-     * @param session
-     *     The GuacamoleSession to retrieve the user from.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider that created the
-     *     UserContext from which the user should be retrieved. Only one
-     *     UserContext per User per AuthenticationProvider can exist.
-     *
-     * @param identifier
-     *     The identifier of the user to retrieve.
-     *
-     * @return
-     *     The user having the given identifier.
-     *
-     * @throws GuacamoleException 
-     *     If an error occurs while retrieving the user, or if the
-     *     user does not exist.
-     */
-    public User retrieveUser(GuacamoleSession session, String authProviderIdentifier,
-            String identifier) throws GuacamoleException {
-
-        UserContext userContext = retrieveUserContext(session, authProviderIdentifier);
-        return retrieveUser(userContext, identifier);
-
-    }
-
-    /**
-     * Retrieves a single connection from the given user context.
-     *
-     * @param userContext
-     *     The user context to retrieve the connection from.
-     *
-     * @param identifier
-     *     The identifier of the connection to retrieve.
-     *
-     * @return
-     *     The connection having the given identifier.
-     *
-     * @throws GuacamoleException 
-     *     If an error occurs while retrieving the connection, or if the
-     *     connection does not exist.
-     */
-    public Connection retrieveConnection(UserContext userContext,
-            String identifier) throws GuacamoleException {
-
-        // Get connection directory
-        Directory<Connection> directory = userContext.getConnectionDirectory();
-
-        // Pull specified connection
-        Connection connection = directory.get(identifier);
-        if (connection == null)
-            throw new GuacamoleResourceNotFoundException("No such connection: \"" + identifier + "\"");
-
-        return connection;
-
-    }
-
-    /**
-     * Retrieves a single connection from the given GuacamoleSession.
-     *
-     * @param session
-     *     The GuacamoleSession to retrieve the connection from.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider that created the
-     *     UserContext from which the connection should be retrieved. Only one
-     *     UserContext per User per AuthenticationProvider can exist.
-     *
-     * @param identifier
-     *     The identifier of the connection to retrieve.
-     *
-     * @return
-     *     The connection having the given identifier.
-     *
-     * @throws GuacamoleException 
-     *     If an error occurs while retrieving the connection, or if the
-     *     connection does not exist.
-     */
-    public Connection retrieveConnection(GuacamoleSession session,
-            String authProviderIdentifier, String identifier)
-            throws GuacamoleException {
-
-        UserContext userContext = retrieveUserContext(session, authProviderIdentifier);
-        return retrieveConnection(userContext, identifier);
-
-    }
-
-    /**
-     * Retrieves a single connection group from the given user context. If
-     * the given identifier the REST API root identifier, the root connection
-     * group will be returned. The underlying authentication provider may
-     * additionally use a different identifier for root.
-     *
-     * @param userContext
-     *     The user context to retrieve the connection group from.
-     *
-     * @param identifier
-     *     The identifier of the connection group to retrieve.
-     *
-     * @return
-     *     The connection group having the given identifier, or the root
-     *     connection group if the identifier the root identifier.
-     *
-     * @throws GuacamoleException 
-     *     If an error occurs while retrieving the connection group, or if the
-     *     connection group does not exist.
-     */
-    public ConnectionGroup retrieveConnectionGroup(UserContext userContext,
-            String identifier) throws GuacamoleException {
-
-        // Use root group if identifier is the standard root identifier
-        if (identifier != null && identifier.equals(APIConnectionGroup.ROOT_IDENTIFIER))
-            return userContext.getRootConnectionGroup();
-
-        // Pull specified connection group otherwise
-        Directory<ConnectionGroup> directory = userContext.getConnectionGroupDirectory();
-        ConnectionGroup connectionGroup = directory.get(identifier);
-
-        if (connectionGroup == null)
-            throw new GuacamoleResourceNotFoundException("No such connection group: \"" + identifier + "\"");
-
-        return connectionGroup;
-
-    }
-
-    /**
-     * Retrieves a single connection group from the given GuacamoleSession. If
-     * the given identifier is the REST API root identifier, the root
-     * connection group will be returned. The underlying authentication
-     * provider may additionally use a different identifier for root.
-     *
-     * @param session
-     *     The GuacamoleSession to retrieve the connection group from.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider that created the
-     *     UserContext from which the connection group should be retrieved.
-     *     Only one UserContext per User per AuthenticationProvider can exist.
-     *
-     * @param identifier
-     *     The identifier of the connection group to retrieve.
-     *
-     * @return
-     *     The connection group having the given identifier, or the root
-     *     connection group if the identifier is the root identifier.
-     *
-     * @throws GuacamoleException 
-     *     If an error occurs while retrieving the connection group, or if the
-     *     connection group does not exist.
-     */
-    public ConnectionGroup retrieveConnectionGroup(GuacamoleSession session,
-            String authProviderIdentifier, String identifier) throws GuacamoleException {
-
-        UserContext userContext = retrieveUserContext(session, authProviderIdentifier);
-        return retrieveConnectionGroup(userContext, identifier);
-
-    }
-
 }


[18/24] incubator-guacamole-client git commit: GUACAMOLE-5: Expose session as a REST resource. Refactor /api/data to /api/session/data.

Posted by jm...@apache.org.
GUACAMOLE-5: Expose session as a REST resource. Refactor /api/data to /api/session/data.


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

Branch: refs/heads/master
Commit: c586d1840d7d48f3e5efd5d51ce3d06ed1d9dfc1
Parents: 1aa256b
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 16:57:29 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   6 +-
 .../rest/session/SessionDataRESTService.java    | 100 ------------------
 .../rest/session/SessionRESTService.java        |  81 +++++++++++++++
 .../guacamole/rest/session/SessionResource.java | 104 +++++++++++++++++++
 .../rest/session/SessionResourceFactory.java    |  45 ++++++++
 .../rest/services/activeConnectionService.js    |   4 +-
 .../app/rest/services/connectionGroupService.js |  10 +-
 .../app/rest/services/connectionService.js      |  12 +--
 .../webapp/app/rest/services/historyService.js  |   2 +-
 .../app/rest/services/permissionService.js      |   4 +-
 .../webapp/app/rest/services/schemaService.js   |   8 +-
 .../webapp/app/rest/services/userService.js     |  12 +--
 12 files changed, 260 insertions(+), 128 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/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 a94f836..3708640 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -20,7 +20,7 @@
 package org.apache.guacamole.rest;
 
 import org.apache.guacamole.rest.session.UserContextResourceFactory;
-import org.apache.guacamole.rest.session.SessionDataRESTService;
+import org.apache.guacamole.rest.session.SessionRESTService;
 import com.google.inject.Scopes;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.matcher.Matchers;
@@ -38,6 +38,7 @@ import org.apache.guacamole.rest.connection.ConnectionModule;
 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.tunnel.TunnelRESTService;
 import org.apache.guacamole.rest.user.UserModule;
 
@@ -92,7 +93,8 @@ public class RESTServiceModule extends ServletModule {
         bind(TunnelRESTService.class);
 
         // Root-level resources
-        bind(SessionDataRESTService.class);
+        bind(SessionRESTService.class);
+        install(new FactoryModuleBuilder().build(SessionResourceFactory.class));
         install(new FactoryModuleBuilder().build(UserContextResourceFactory.class));
 
         // Resources below root

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java
deleted file mode 100644
index e21eaa4..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.session;
-
-import com.google.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-
-/**
- * A REST service which exposes all data associated with a Guacamole user's
- * session via the underlying UserContexts.
- *
- * @author Michael Jumper
- */
-@Path("/data")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class SessionDataRESTService {
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
-     * Factory for creating UserContextResources which expose a given
-     * UserContext.
-     */
-    @Inject
-    private UserContextResourceFactory userContextResourceFactory;
-
-    /**
-     * Retrieves a resource representing the UserContext associated with the
-     * AuthenticationProvider having the given identifier.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext being retrieved.
-     *
-     * @return
-     *     A resource representing the UserContext associated with the
-     *     AuthenticationProvider having the given identifier.
-     *
-     * @throws GuacamoleException
-     *     If the authentication token or AuthenticationProvider identifier are
-     *     invalid.
-     */
-    @Path("{dataSource}")
-    public UserContextResource getUserContextResource(
-            @QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier)
-            throws GuacamoleException {
-
-        // Pull UserContext defined by the given auth provider identifier
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Return a resource exposing the retrieved UserContext
-        return userContextResourceFactory.create(userContext);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionRESTService.java
new file mode 100644
index 0000000..e8c4d75
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionRESTService.java
@@ -0,0 +1,81 @@
+/*
+ * 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.session;
+
+import com.google.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSession;
+import org.apache.guacamole.rest.auth.AuthenticationService;
+
+/**
+ * A REST service which exposes all data associated with Guacamole users'
+ * sessions.
+ *
+ * @author Michael Jumper
+ */
+@Path("/session")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SessionRESTService {
+
+    /**
+     * A service for authenticating users from auth tokens.
+     */
+    @Inject
+    private AuthenticationService authenticationService;
+
+    /**
+     * Factory for creating SessionResources which expose a given
+     * GuacamoleSession.
+     */
+    @Inject
+    private SessionResourceFactory sessionResourceFactory;
+
+    /**
+     * Retrieves a resource representing the GuacamoleSession associated with
+     * the given authentication token.
+     *
+     * @param authToken
+     *     The authentication token that is used to authenticate the user
+     *     having the session being exposed.
+     *
+     * @return
+     *     A resource representing the GuacamoleSession associated with the
+     *     given authentication token.
+     *
+     * @throws GuacamoleException
+     *     If the authentication token is invalid.
+     */
+    @Path("/")
+    public SessionResource getSessionResource(@QueryParam("token") String authToken)
+            throws GuacamoleException {
+
+        // Return a resource exposing the retrieved session
+        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
+        return sessionResourceFactory.create(session);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
new file mode 100644
index 0000000..c9e9834
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.rest.session;
+
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSession;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.ObjectRetrievalService;
+
+/**
+ * A REST resource which exposes all data associated with a Guacamole user's
+ * session via the underlying UserContexts.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SessionResource {
+
+    /**
+     * The GuacamoleSession being exposed by this SessionResource.
+     */
+    private final GuacamoleSession session;
+
+    /**
+     * Service for convenient retrieval of objects.
+     */
+    @Inject
+    private ObjectRetrievalService retrievalService;
+
+    /**
+     * Factory for creating UserContextResources which expose a given
+     * UserContext.
+     */
+    @Inject
+    private UserContextResourceFactory userContextResourceFactory;
+
+    /**
+     * Creates a new SessionResource which exposes the data within the given
+     * GuacamoleSession.
+     *
+     * @param session
+     *     The GuacamoleSession which should be exposed through this
+     *     SessionResource.
+     */
+    @AssistedInject
+    public SessionResource(@Assisted GuacamoleSession session) {
+        this.session = session;
+    }
+
+    /**
+     * Retrieves a resource representing the UserContext associated with the
+     * AuthenticationProvider having the given identifier.
+     *
+     * @param authProviderIdentifier
+     *     The unique identifier of the AuthenticationProvider associated with
+     *     the UserContext being retrieved.
+     *
+     * @return
+     *     A resource representing the UserContext associated with the
+     *     AuthenticationProvider having the given identifier.
+     *
+     * @throws GuacamoleException
+     *     If the AuthenticationProvider identifier is invalid.
+     */
+    @Path("data/{dataSource}")
+    public UserContextResource getUserContextResource(
+            @PathParam("dataSource") String authProviderIdentifier)
+            throws GuacamoleException {
+
+        // Pull UserContext defined by the given auth provider identifier
+        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
+
+        // Return a resource exposing the retrieved UserContext
+        return userContextResourceFactory.create(userContext);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResourceFactory.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResourceFactory.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResourceFactory.java
new file mode 100644
index 0000000..eaa8394
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResourceFactory.java
@@ -0,0 +1,45 @@
+/*
+ * 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.session;
+
+import org.apache.guacamole.GuacamoleSession;
+
+/**
+ * Factory which creates resources that expose the contents of a given
+ * GuacamoleSession.
+ *
+ * @author Michael Jumper
+ */
+public interface SessionResourceFactory {
+
+    /**
+     * Creates a new SessionResource which exposes the contents of the
+     * given GuacamoleSession.
+     *
+     * @param session
+     *     The GuacamoleSession whose contents should be exposed.
+     *
+     * @return
+     *     A new SessionResource which exposes the contents of the given
+     *     GuacamoleSession.
+     */
+    SessionResource create(GuacamoleSession session);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
index 4ebb131..9c967be 100644
--- a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
@@ -60,7 +60,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
         // Retrieve tunnels
         return $http({
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/activeConnections',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/activeConnections',
             params  : httpParameters
         });
 
@@ -159,7 +159,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
         // Perform active connection deletion via PATCH
         return $http({
             method  : 'PATCH',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/activeConnections',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/activeConnections',
             params  : httpParameters,
             data    : activeConnectionPatch
         });

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
index 3283102..0662e4d 100644
--- a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
+++ b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
@@ -73,7 +73,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         return $http({
             cache   : cacheService.connections,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroupID) + '/tree',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroupID) + '/tree',
             params  : httpParameters
         });
        
@@ -106,7 +106,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         return $http({
             cache   : cacheService.connections,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroupID),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroupID),
             params  : httpParameters
         });
 
@@ -136,7 +136,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         if (!connectionGroup.identifier) {
             return $http({
                 method  : 'POST',
-                url     : 'api/data/' + encodeURIComponent(dataSource) + '/connectionGroups',
+                url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups',
                 params  : httpParameters,
                 data    : connectionGroup
             })
@@ -152,7 +152,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         else {
             return $http({
                 method  : 'PUT',
-                url     : 'api/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroup.identifier),
+                url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroup.identifier),
                 params  : httpParameters,
                 data    : connectionGroup
             })
@@ -185,7 +185,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         // Delete connection group
         return $http({
             method  : 'DELETE',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroup.identifier),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroup.identifier),
             params  : httpParameters
         })
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/connectionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/connectionService.js b/guacamole/src/main/webapp/app/rest/services/connectionService.js
index 7629cd1..7b63a7e 100644
--- a/guacamole/src/main/webapp/app/rest/services/connectionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/connectionService.js
@@ -56,7 +56,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         return $http({
             cache   : cacheService.connections,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id),
             params  : httpParameters
         });
 
@@ -84,7 +84,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         // Retrieve connection history
         return $http({
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id) + '/history',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id) + '/history',
             params  : httpParameters
         });
  
@@ -113,7 +113,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         return $http({
             cache   : cacheService.connections,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id) + '/parameters',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id) + '/parameters',
             params  : httpParameters
         });
  
@@ -143,7 +143,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         if (!connection.identifier) {
             return $http({
                 method  : 'POST',
-                url     : 'api/data/' + encodeURIComponent(dataSource) + '/connections',
+                url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections',
                 params  : httpParameters,
                 data    : connection
             })
@@ -159,7 +159,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         else {
             return $http({
                 method  : 'PUT',
-                url     : 'api/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(connection.identifier),
+                url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(connection.identifier),
                 params  : httpParameters,
                 data    : connection
             })
@@ -192,7 +192,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         // Delete connection
         return $http({
             method  : 'DELETE',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(connection.identifier),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(connection.identifier),
             params  : httpParameters
         })
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/historyService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/historyService.js b/guacamole/src/main/webapp/app/rest/services/historyService.js
index 717389d..c77c4ab 100644
--- a/guacamole/src/main/webapp/app/rest/services/historyService.js
+++ b/guacamole/src/main/webapp/app/rest/services/historyService.js
@@ -76,7 +76,7 @@ angular.module('rest').factory('historyService', ['$injector',
         // Retrieve connection history
         return $http({
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/history/connections',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/history/connections',
             params  : httpParameters
         });
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/permissionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/permissionService.js b/guacamole/src/main/webapp/app/rest/services/permissionService.js
index d398447..8a41845 100644
--- a/guacamole/src/main/webapp/app/rest/services/permissionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/permissionService.js
@@ -62,7 +62,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         return $http({
             cache   : cacheService.users,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(userID) + '/permissions',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(userID) + '/permissions',
             params  : httpParameters
         });
 
@@ -235,7 +235,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         // Patch user permissions
         return $http({
             method  : 'PATCH', 
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(userID) + '/permissions',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(userID) + '/permissions',
             params  : httpParameters,
             data    : permissionPatch
         })

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/schemaService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/schemaService.js b/guacamole/src/main/webapp/app/rest/services/schemaService.js
index 2c874ed..f0db23f 100644
--- a/guacamole/src/main/webapp/app/rest/services/schemaService.js
+++ b/guacamole/src/main/webapp/app/rest/services/schemaService.js
@@ -58,7 +58,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/userAttributes',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/userAttributes',
             params  : httpParameters
         });
 
@@ -92,7 +92,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/connectionAttributes',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/connectionAttributes',
             params  : httpParameters
         });
 
@@ -126,7 +126,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/connectionGroupAttributes',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/connectionGroupAttributes',
             params  : httpParameters
         });
 
@@ -157,7 +157,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/protocols',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/protocols',
             params  : httpParameters
         });
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c586d184/guacamole/src/main/webapp/app/rest/services/userService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js
index 3953f89..659aed7 100644
--- a/guacamole/src/main/webapp/app/rest/services/userService.js
+++ b/guacamole/src/main/webapp/app/rest/services/userService.js
@@ -70,7 +70,7 @@ angular.module('rest').factory('userService', ['$injector',
         return $http({
             cache   : cacheService.users,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users',
             params  : httpParameters
         });
 
@@ -103,7 +103,7 @@ angular.module('rest').factory('userService', ['$injector',
         return $http({
             cache   : cacheService.users,
             method  : 'GET',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username),
             params  : httpParameters
         });
 
@@ -135,7 +135,7 @@ angular.module('rest').factory('userService', ['$injector',
         // Delete user
         return $http({
             method  : 'DELETE',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(user.username),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(user.username),
             params  : httpParameters
         })
 
@@ -173,7 +173,7 @@ angular.module('rest').factory('userService', ['$injector',
         // Create user
         return $http({
             method  : 'POST',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users',
             params  : httpParameters,
             data    : user
         })
@@ -211,7 +211,7 @@ angular.module('rest').factory('userService', ['$injector',
         // Update user
         return $http({
             method  : 'PUT',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(user.username),
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(user.username),
             params  : httpParameters,
             data    : user
         })
@@ -256,7 +256,7 @@ angular.module('rest').factory('userService', ['$injector',
         // Update user password
         return $http({
             method  : 'PUT',
-            url     : 'api/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username) + '/password',
+            url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username) + '/password',
             params  : httpParameters,
             data    : new UserPasswordUpdate({
                 oldPassword : oldPassword,


[13/24] incubator-guacamole-client git commit: GUACAMOLE-5: Ensure all API errors are returned as JSON.

Posted by jm...@apache.org.
GUACAMOLE-5: Ensure all API errors are returned as JSON.


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

Branch: refs/heads/master
Commit: 60c672eeea5f7290443b5a48aa357ef4fb8502e3
Parents: fa286f5
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 18:59:29 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../src/main/java/org/apache/guacamole/rest/APIException.java  | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/60c672ee/guacamole/src/main/java/org/apache/guacamole/rest/APIException.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/APIException.java b/guacamole/src/main/java/org/apache/guacamole/rest/APIException.java
index 0a004be..ea4cf5d 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/APIException.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/APIException.java
@@ -21,6 +21,7 @@ package org.apache.guacamole.rest;
 
 import java.util.Collection;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.guacamole.form.Field;
 import org.apache.guacamole.protocol.GuacamoleStatus;
@@ -44,7 +45,10 @@ public class APIException extends WebApplicationException {
      *     The error that occurred.
      */
     public APIException(APIError error) {
-        super(Response.status(error.getType().getStatus()).entity(error).build());
+        super(Response.status(error.getType().getStatus())
+                .type(MediaType.APPLICATION_JSON)
+                .entity(error)
+                .build());
     }
 
     /**


[08/24] incubator-guacamole-client git commit: GUACAMOLE-5: Ensure random password is generated for new users (if not otherwise specified).

Posted by jm...@apache.org.
GUACAMOLE-5: Ensure random password is generated for new users (if not otherwise specified).


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

Branch: refs/heads/master
Commit: 3f7f6e6d5bb4d91862ea1722d5e9d1272acc4b80
Parents: 86d94d1
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 13:22:10 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:46 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/user/UserDirectoryResource.java      | 12 ++++++++++++
 1 file changed, 12 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3f7f6e6d/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
index a61bf05..04218f1 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
@@ -21,6 +21,7 @@ package org.apache.guacamole.rest.user;
 
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
+import java.util.UUID;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
@@ -90,6 +91,17 @@ public class UserDirectoryResource extends DirectoryResource<User, APIUser> {
     }
 
     @Override
+    public APIUser createObject(APIUser object) throws GuacamoleException {
+
+        // Randomly set the password if it wasn't provided
+        if (object.getPassword() == null)
+            object.setPassword(UUID.randomUUID().toString());
+
+        return super.createObject(object);
+
+    }
+
+    @Override
     public DirectoryObjectResource<User, APIUser>
         getObjectResource(String identifier) throws GuacamoleException {
 


[24/24] incubator-guacamole-client git commit: GUACAMOLE-5: Merge REST resource refactor.

Posted by jm...@apache.org.
GUACAMOLE-5: Merge REST resource refactor.


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

Branch: refs/heads/master
Commit: 6e81a201856f0f16907aa6a8f88985e242498970
Parents: 3c2dbbe b66925c
Author: James Muehlner <ja...@guac-dev.org>
Authored: Tue Jul 12 22:07:06 2016 -0700
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Tue Jul 12 22:07:06 2016 -0700

----------------------------------------------------------------------
 guacamole/pom.xml                               |   5 +
 .../org/apache/guacamole/GuacamoleSession.java  |  39 ++
 .../org/apache/guacamole/rest/APIException.java |   6 +-
 .../guacamole/rest/ObjectRetrievalService.java  | 277 --------
 .../guacamole/rest/RESTMethodMatcher.java       |  28 +-
 .../guacamole/rest/RESTServiceModule.java       |  36 +-
 .../ActiveConnectionModule.java                 |  60 ++
 .../ActiveConnectionObjectTranslator.java       |  61 ++
 .../ActiveConnectionRESTService.java            | 193 ------
 .../ActiveConnectionResource.java               |  70 ++
 .../rest/activeconnection/package-info.java     |  24 +
 .../rest/connection/ConnectionModule.java       |  60 ++
 .../connection/ConnectionObjectTranslator.java  |  64 ++
 .../rest/connection/ConnectionRESTService.java  | 346 ----------
 .../rest/connection/ConnectionResource.java     | 155 +++++
 .../ConnectionGroupDirectoryResource.java       | 107 +++
 .../connectiongroup/ConnectionGroupModule.java  |  65 ++
 .../ConnectionGroupObjectTranslator.java        |  58 ++
 .../ConnectionGroupRESTService.java             | 284 --------
 .../ConnectionGroupResource.java                | 120 ++++
 .../rest/directory/DirectoryObjectResource.java | 146 +++++
 .../DirectoryObjectResourceFactory.java         |  61 ++
 .../directory/DirectoryObjectTranslator.java    |  94 +++
 .../rest/directory/DirectoryResource.java       | 266 ++++++++
 .../directory/DirectoryResourceFactory.java     |  57 ++
 .../guacamole/rest/directory/package-info.java  |  24 +
 .../rest/history/HistoryRESTService.java        | 144 -----
 .../guacamole/rest/history/HistoryResource.java | 122 ++++
 .../rest/permission/PermissionSetPatch.java     |  95 +++
 .../rest/permission/PermissionSetResource.java  | 261 ++++++++
 .../rest/schema/SchemaRESTService.java          | 196 ------
 .../guacamole/rest/schema/SchemaResource.java   | 142 ++++
 .../rest/session/SessionRESTService.java        |  81 +++
 .../guacamole/rest/session/SessionResource.java | 111 ++++
 .../rest/session/SessionResourceFactory.java    |  45 ++
 .../rest/session/UserContextResource.java       | 202 ++++++
 .../session/UserContextResourceFactory.java     |  45 ++
 .../guacamole/rest/session/package-info.java    |  24 +
 .../guacamole/rest/tunnel/StreamResource.java   | 131 ++++
 .../rest/tunnel/TunnelCollectionResource.java   | 105 +++
 .../rest/tunnel/TunnelRESTService.java          | 202 ------
 .../guacamole/rest/tunnel/TunnelResource.java   |  94 +++
 .../guacamole/rest/tunnel/package-info.java     |  24 +
 .../guacamole/rest/user/PermissionSetPatch.java |  95 ---
 .../rest/user/UserDirectoryResource.java        | 116 ++++
 .../apache/guacamole/rest/user/UserModule.java  |  65 ++
 .../rest/user/UserObjectTranslator.java         |  59 ++
 .../guacamole/rest/user/UserRESTService.java    | 644 -------------------
 .../guacamole/rest/user/UserResource.java       | 165 +++++
 .../guacamole/tunnel/TunnelRequestService.java  |   9 +-
 .../rest/services/activeConnectionService.js    |   4 +-
 .../app/rest/services/connectionGroupService.js |  10 +-
 .../app/rest/services/connectionService.js      |  12 +-
 .../webapp/app/rest/services/historyService.js  |   2 +-
 .../app/rest/services/permissionService.js      |   4 +-
 .../webapp/app/rest/services/schemaService.js   |   8 +-
 .../webapp/app/rest/services/tunnelService.js   |   6 +-
 .../webapp/app/rest/services/userService.js     |  19 +-
 .../settings/directives/guacSettingsUsers.js    |   4 +-
 59 files changed, 3509 insertions(+), 2443 deletions(-)
----------------------------------------------------------------------



[07/24] incubator-guacamole-client git commit: GUACAMOLE-5: Replace ConnectionGroupRESTService with new resource-driven implementation.

Posted by jm...@apache.org.
GUACAMOLE-5: Replace ConnectionGroupRESTService with new resource-driven implementation.


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

Branch: refs/heads/master
Commit: 71c2b4e4d4c274f5ef1fe2d3f5ecfcd40639de3a
Parents: 06b7887
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 11:41:59 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 14:53:24 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   4 +-
 .../ConnectionGroupDirectoryResource.java       | 107 +++++++
 .../connectiongroup/ConnectionGroupModule.java  |  65 +++++
 .../ConnectionGroupObjectTranslator.java        |  58 ++++
 .../ConnectionGroupRESTService.java             | 284 -------------------
 .../ConnectionGroupResource.java                | 120 ++++++++
 .../rest/session/UserContextResource.java       |  31 +-
 7 files changed, 382 insertions(+), 287 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/71c2b4e4/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 c79cb29..c40224e 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -29,13 +29,13 @@ import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
 import org.apache.guacamole.rest.auth.TokenRESTService;
-import org.apache.guacamole.rest.connectiongroup.ConnectionGroupRESTService;
 import org.apache.guacamole.rest.activeconnection.ActiveConnectionRESTService;
 import org.apache.guacamole.rest.auth.AuthTokenGenerator;
 import org.apache.guacamole.rest.auth.AuthenticationService;
 import org.apache.guacamole.rest.auth.SecureRandomAuthTokenGenerator;
 import org.apache.guacamole.rest.auth.TokenSessionMap;
 import org.apache.guacamole.rest.connection.ConnectionModule;
+import org.apache.guacamole.rest.connectiongroup.ConnectionGroupModule;
 import org.apache.guacamole.rest.history.HistoryRESTService;
 import org.apache.guacamole.rest.language.LanguageRESTService;
 import org.apache.guacamole.rest.patch.PatchRESTService;
@@ -89,7 +89,6 @@ public class RESTServiceModule extends ServletModule {
 
         // Set up the API endpoints
         bind(ActiveConnectionRESTService.class);
-        bind(ConnectionGroupRESTService.class);
         bind(HistoryRESTService.class);
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);
@@ -104,6 +103,7 @@ public class RESTServiceModule extends ServletModule {
 
         // Resources below root
         install(new ConnectionModule());
+        install(new ConnectionGroupModule());
 
         // Set up the servlet and JSON mappings
         bind(GuiceContainer.class);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/71c2b4e4/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupDirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupDirectoryResource.java
new file mode 100644
index 0000000..2c32e21
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupDirectoryResource.java
@@ -0,0 +1,107 @@
+/*
+ * 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.connectiongroup;
+
+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.GuacamoleException;
+import org.apache.guacamole.net.auth.ConnectionGroup;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.directory.DirectoryObjectResource;
+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
+ * ConnectionGroups.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class ConnectionGroupDirectoryResource
+        extends DirectoryResource<ConnectionGroup, APIConnectionGroup> {
+
+    /**
+     * The UserContext associated with the Directory which contains the
+     * ConnectionGroup exposed by this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The Directory exposed by this resource.
+     */
+    private final Directory<ConnectionGroup> directory;
+
+    /**
+     * A factory which can be used to create instances of resources representing
+     * ConnectionGroups.
+     */
+    private final DirectoryObjectResourceFactory<ConnectionGroup, APIConnectionGroup> resourceFactory;
+
+    /**
+     * Creates a new ConnectionGroupDirectoryResource which exposes the
+     * operations and subresources available for the given ConnectionGroup
+     * Directory.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory being exposed.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles
+     *     ConnectionGroups.
+     *
+     * @param resourceFactory
+     *     A factory which can be used to create instances of resources
+     *     representing ConnectionGroups.
+     */
+    @AssistedInject
+    public ConnectionGroupDirectoryResource(@Assisted UserContext userContext,
+            @Assisted Directory<ConnectionGroup> directory,
+            DirectoryObjectTranslator<ConnectionGroup, APIConnectionGroup> translator,
+            DirectoryObjectResourceFactory<ConnectionGroup, APIConnectionGroup> resourceFactory) {
+        super(userContext, directory, translator, resourceFactory);
+        this.userContext = userContext;
+        this.directory = directory;
+        this.resourceFactory = resourceFactory;
+    }
+
+    @Override
+    public DirectoryObjectResource<ConnectionGroup, APIConnectionGroup>
+        getObjectResource(String identifier) throws GuacamoleException {
+
+        // Use root group if identifier is the standard root identifier
+        if (identifier != null && identifier.equals(APIConnectionGroup.ROOT_IDENTIFIER))
+            return resourceFactory.create(userContext, directory,
+                    userContext.getRootConnectionGroup());
+
+        return super.getObjectResource(identifier);
+
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/71c2b4e4/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupObjectTranslator.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupObjectTranslator.java
new file mode 100644
index 0000000..efd5cb9
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupObjectTranslator.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.connectiongroup;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.ConnectionGroup;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+
+/**
+ * Translator which converts between ConnectionGroup objects and
+ * APIConnectionGroup objects.
+ *
+ * @author Michael Jumper
+ */
+public class ConnectionGroupObjectTranslator
+        implements DirectoryObjectTranslator<ConnectionGroup, APIConnectionGroup> {
+
+    @Override
+    public APIConnectionGroup toExternalObject(ConnectionGroup object)
+            throws GuacamoleException {
+        return new APIConnectionGroup(object);
+    }
+
+    @Override
+    public ConnectionGroup toInternalObject(APIConnectionGroup object) {
+        return new APIConnectionGroupWrapper(object);
+    }
+
+    @Override
+    public void applyExternalChanges(ConnectionGroup existingObject,
+            APIConnectionGroup object) {
+
+        // Update the connection group
+        existingObject.setName(object.getName());
+        existingObject.setParentIdentifier(object.getParentIdentifier());
+        existingObject.setType(object.getType());
+        existingObject.setAttributes(object.getAttributes());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/71c2b4e4/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupRESTService.java
deleted file mode 100644
index bd28a19..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupRESTService.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * 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.connectiongroup;
-
-import com.google.inject.Inject;
-import java.util.List;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleClientException;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.net.auth.ConnectionGroup;
-import org.apache.guacamole.net.auth.Directory;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.net.auth.permission.ObjectPermission;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A REST Service for handling connection group CRUD operations.
- * 
- * @author James Muehlner
- */
-@Path("/data/{dataSource}/connectionGroups")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class ConnectionGroupRESTService {
-
-    /**
-     * Logger for this class.
-     */
-    private static final Logger logger = LoggerFactory.getLogger(ConnectionGroupRESTService.class);
-    
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-    
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-    
-    /**
-     * Gets an individual connection group.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     * 
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection group to be retrieved.
-     *
-     * @param connectionGroupID
-     *     The ID of the connection group to retrieve.
-     * 
-     * @return
-     *     The connection group, without any descendants.
-     *
-     * @throws GuacamoleException
-     *     If a problem is encountered while retrieving the connection group.
-     */
-    @GET
-    @Path("/{connectionGroupID}")
-    public APIConnectionGroup getConnectionGroup(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionGroupID") String connectionGroupID)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-
-        // Retrieve the requested connection group
-        return new APIConnectionGroup(retrievalService.retrieveConnectionGroup(session, authProviderIdentifier, connectionGroupID));
-
-    }
-
-    /**
-     * Gets an individual connection group and all children.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection group to be retrieved.
-     *
-     * @param connectionGroupID
-     *     The ID of the connection group to retrieve.
-     *
-     * @param permissions
-     *     If specified and non-empty, limit the returned list to only those
-     *     connections for which the current user has any of the given
-     *     permissions. Otherwise, all visible connections are returned.
-     *     Connection groups are unaffected by this parameter.
-     * 
-     * @return
-     *     The requested connection group, including all descendants.
-     *
-     * @throws GuacamoleException
-     *     If a problem is encountered while retrieving the connection group or
-     *     its descendants.
-     */
-    @GET
-    @Path("/{connectionGroupID}/tree")
-    public APIConnectionGroup getConnectionGroupTree(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionGroupID") String connectionGroupID,
-            @QueryParam("permission") List<ObjectPermission.Type> permissions)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Retrieve the requested tree, filtering by the given permissions
-        ConnectionGroup treeRoot = retrievalService.retrieveConnectionGroup(userContext, connectionGroupID);
-        ConnectionGroupTree tree = new ConnectionGroupTree(userContext, treeRoot, permissions);
-
-        // Return tree as a connection group
-        return tree.getRootAPIConnectionGroup();
-
-    }
-
-    /**
-     * Deletes an individual connection group.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection group to be deleted.
-     *
-     * @param connectionGroupID
-     *     The identifier of the connection group to delete.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while deleting the connection group.
-     */
-    @DELETE
-    @Path("/{connectionGroupID}")
-    public void deleteConnectionGroup(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionGroupID") String connectionGroupID)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        
-        // Get the connection group directory
-        Directory<ConnectionGroup> connectionGroupDirectory = userContext.getConnectionGroupDirectory();
-
-        // Delete the connection group
-        connectionGroupDirectory.remove(connectionGroupID);
-
-    }
-    
-    /**
-     * Creates a new connection group and returns the new connection group,
-     * with identifier field populated.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the connection group is to be created.
-     *
-     * @param connectionGroup
-     *     The connection group to create.
-     * 
-     * @return
-     *     The new connection group.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while creating the connection group.
-     */
-    @POST
-    public APIConnectionGroup createConnectionGroup(
-            @QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            APIConnectionGroup connectionGroup) throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Validate that connection group data was provided
-        if (connectionGroup == null)
-            throw new GuacamoleClientException("Connection group JSON must be submitted when creating connections groups.");
-
-        // Add the new connection group
-        Directory<ConnectionGroup> connectionGroupDirectory = userContext.getConnectionGroupDirectory();
-        connectionGroupDirectory.add(new APIConnectionGroupWrapper(connectionGroup));
-
-        // Return the new connection group
-        return connectionGroup;
-
-    }
-    
-    /**
-     * Updates a connection group. If the parent identifier of the
-     * connection group is changed, the connection group will also be moved to
-     * the new parent group.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the connection group to be updated.
-     *
-     * @param connectionGroupID
-     *     The identifier of the existing connection group to update.
-     *
-     * @param connectionGroup
-     *     The data to update the existing connection group with.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while updating the connection group.
-     */
-    @PUT
-    @Path("/{connectionGroupID}")
-    public void updateConnectionGroup(@QueryParam("token") String authToken, 
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("connectionGroupID") String connectionGroupID,
-            APIConnectionGroup connectionGroup)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        
-        // Validate that connection group data was provided
-        if (connectionGroup == null)
-            throw new GuacamoleClientException("Connection group JSON must be submitted when updating connection groups.");
-
-        // Get the connection group directory
-        Directory<ConnectionGroup> connectionGroupDirectory = userContext.getConnectionGroupDirectory();
-
-        // Retrieve connection group to update
-        ConnectionGroup existingConnectionGroup = retrievalService.retrieveConnectionGroup(userContext, connectionGroupID);
-        
-        // Update the connection group
-        existingConnectionGroup.setName(connectionGroup.getName());
-        existingConnectionGroup.setParentIdentifier(connectionGroup.getParentIdentifier());
-        existingConnectionGroup.setType(connectionGroup.getType());
-        existingConnectionGroup.setAttributes(connectionGroup.getAttributes());
-        connectionGroupDirectory.update(existingConnectionGroup);
-
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/71c2b4e4/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupResource.java
new file mode 100644
index 0000000..c0b80c4
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/connectiongroup/ConnectionGroupResource.java
@@ -0,0 +1,120 @@
+/*
+ * 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.connectiongroup;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.ConnectionGroup;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.net.auth.permission.ObjectPermission;
+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
+ * ConnectionGroup.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class ConnectionGroupResource
+        extends DirectoryObjectResource<ConnectionGroup, APIConnectionGroup> {
+
+    /**
+     * The UserContext associated with the Directory which contains the
+     * ConnectionGroup exposed by this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The ConnectionGroup object represented by this ConnectionGroupResource.
+     */
+    private final ConnectionGroup connectionGroup;
+
+    /**
+     * Creates a new ConnectionGroupResource which exposes the operations and
+     * subresources available for the given ConnectionGroup.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory which contains the given ConnectionGroup.
+     *
+     * @param connectionGroup
+     *     The ConnectionGroup that this ConnectionGroupResource should
+     *     represent.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles the type of
+     *     object given.
+     */
+    @AssistedInject
+    public ConnectionGroupResource(@Assisted UserContext userContext,
+            @Assisted Directory<ConnectionGroup> directory,
+            @Assisted ConnectionGroup connectionGroup,
+            DirectoryObjectTranslator<ConnectionGroup, APIConnectionGroup> translator) {
+        super(directory, connectionGroup, translator);
+        this.userContext = userContext;
+        this.connectionGroup = connectionGroup;
+    }
+
+    /**
+     * Returns the current connection group along with all descendants.
+     *
+     * @param permissions
+     *     If specified and non-empty, limit the returned list to only those
+     *     connections for which the current user has any of the given
+     *     permissions. Otherwise, all visible connections are returned.
+     *     ConnectionGroups are unaffected by this parameter.
+     *
+     * @return
+     *     The current connection group, including all descendants.
+     *
+     * @throws GuacamoleException
+     *     If a problem is encountered while retrieving the connection group or
+     *     its descendants.
+     */
+    @GET
+    @Path("tree")
+    public APIConnectionGroup getConnectionGroupTree(
+            @QueryParam("permission") List<ObjectPermission.Type> permissions)
+            throws GuacamoleException {
+
+        // Retrieve the requested tree, filtering by the given permissions
+        ConnectionGroupTree tree = new ConnectionGroupTree(userContext,
+                connectionGroup, permissions);
+
+        // Return tree as a connection group
+        return tree.getRootAPIConnectionGroup();
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/71c2b4e4/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 7518c71..e5d5cb5 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
@@ -30,8 +30,10 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.net.auth.Connection;
+import org.apache.guacamole.net.auth.ConnectionGroup;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.rest.connection.APIConnection;
+import org.apache.guacamole.rest.connectiongroup.APIConnectionGroup;
 
 /**
  * A REST resource which exposes the contents of a particular UserContext.
@@ -52,7 +54,16 @@ public class UserContextResource {
      * Connection Directory.
      */
     @Inject
-    private DirectoryResourceFactory<Connection, APIConnection> connectionDirectoryResourceFactory;
+    private DirectoryResourceFactory<Connection, APIConnection>
+            connectionDirectoryResourceFactory;
+
+    /**
+     * Factory for creating DirectoryResources which expose a given
+     * ConnectionGroup Directory.
+     */
+    @Inject
+    private DirectoryResourceFactory<ConnectionGroup, APIConnectionGroup>
+            connectionGroupDirectoryResourceFactory;
 
     /**
      * Creates a new UserContextResource which exposes the data within the
@@ -85,4 +96,22 @@ public class UserContextResource {
                 userContext.getConnectionDirectory());
     }
 
+    /**
+     * Returns a new resource which represents the ConnectionGroup Directory
+     * contained within the UserContext exposed by this UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the ConnectionGroup Directory
+     *     contained within the UserContext exposed by this UserContextResource.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the ConnectionGroup Directory.
+     */
+    @Path("connectionGroups")
+    public DirectoryResource<ConnectionGroup, APIConnectionGroup> getConnectionGroupDirectoryResource()
+            throws GuacamoleException {
+        return connectionGroupDirectoryResourceFactory.create(userContext,
+                userContext.getConnectionGroupDirectory());
+    }
+
 }


[21/24] incubator-guacamole-client git commit: GUACAMOLE-5: DirectoryResource deals with objects, not users.

Posted by jm...@apache.org.
GUACAMOLE-5: DirectoryResource deals with objects, not users.

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

Branch: refs/heads/master
Commit: aeec3eca4009745bce70e9ca1399a42de4dde9b0
Parents: e4ed85c
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 21:40:58 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:40:58 2016 -0700

----------------------------------------------------------------------
 .../org/apache/guacamole/rest/directory/DirectoryResource.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/aeec3eca/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
index ee4fd2c..1716545 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
@@ -130,8 +130,8 @@ public class DirectoryResource<InternalType extends Identifiable, ExternalType>
      *
      * @param permissions
      *     The set of permissions to filter with. A user must have one or more
-     *     of these permissions for a user to appear in the result.
-     *     If null, no filtering will be performed.
+     *     of these permissions for the affected objects to appear in the
+     *     result. If null, no filtering will be performed.
      *
      * @return
      *     A map of all visible objects. If a permission was specified, this


[03/24] incubator-guacamole-client git commit: GUACAMOLE-5: Validate that data was provided when creating/updating resources.

Posted by jm...@apache.org.
GUACAMOLE-5: Validate that data was provided when creating/updating resources.

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

Branch: refs/heads/master
Commit: f440f558230e474032948f52f04f17bf4f17192a
Parents: e579eae
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 00:20:36 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 00:20:36 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/directory/DirectoryObjectResource.java    | 8 ++++++++
 .../apache/guacamole/rest/directory/DirectoryResource.java   | 4 ++++
 2 files changed, 12 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/f440f558/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
index 298f76b..7e45b2b 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResource.java
@@ -27,6 +27,7 @@ import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleClientException;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.net.auth.Directory;
 import org.apache.guacamole.net.auth.Identifiable;
@@ -120,8 +121,15 @@ public class DirectoryObjectResource<InternalType extends Identifiable, External
      */
     @PUT
     public void updateObject(ExternalType modifiedObject) throws GuacamoleException {
+
+        // Validate that data was provided
+        if (modifiedObject == null)
+            throw new GuacamoleClientException("Data must be submitted when updating objects.");
+
+        // Perform update
         translator.applyExternalChanges(object, modifiedObject);
         directory.update(object);
+
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/f440f558/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
index 8c748b0..5f726f6 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
@@ -222,6 +222,10 @@ public class DirectoryResource<InternalType extends Identifiable, ExternalType>
     public ExternalType createObject(ExternalType object)
             throws GuacamoleException {
 
+        // Validate that data was provided
+        if (object == null)
+            throw new GuacamoleClientException("Data must be submitted when creating objects.");
+
         // Create the new object within the directory
         directory.add(translator.toInternalObject(object));
 


[14/24] incubator-guacamole-client git commit: GUACAMOLE-5: Expose UserContext schema as a resource, not a separate REST service. Refactor URLs accordingly.

Posted by jm...@apache.org.
GUACAMOLE-5: Expose UserContext schema as a resource, not a separate REST service. Refactor URLs accordingly.


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

Branch: refs/heads/master
Commit: 89eabc1d70d046d16530e700a4f6a7a7fa37a44e
Parents: 3658b91
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 14:00:17 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   2 -
 .../rest/schema/SchemaRESTService.java          | 196 -------------------
 .../guacamole/rest/schema/SchemaResource.java   | 142 ++++++++++++++
 .../rest/session/UserContextResource.java       |  16 ++
 .../webapp/app/rest/services/schemaService.js   |   8 +-
 5 files changed, 162 insertions(+), 202 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/89eabc1d/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 c6de0dc..88551b3 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -38,7 +38,6 @@ import org.apache.guacamole.rest.connection.ConnectionModule;
 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.schema.SchemaRESTService;
 import org.apache.guacamole.rest.tunnel.TunnelRESTService;
 import org.apache.guacamole.rest.user.UserModule;
 
@@ -89,7 +88,6 @@ public class RESTServiceModule extends ServletModule {
         // Set up the API endpoints
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);
-        bind(SchemaRESTService.class);
         bind(TokenRESTService.class);
         bind(TunnelRESTService.class);
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/89eabc1d/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaRESTService.java
deleted file mode 100644
index a5d9d90..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaRESTService.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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.schema;
-
-import com.google.inject.Inject;
-import java.util.Collection;
-import java.util.Map;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.environment.Environment;
-import org.apache.guacamole.environment.LocalEnvironment;
-import org.apache.guacamole.form.Form;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.apache.guacamole.protocols.ProtocolInfo;
-
-/**
- * A REST service which provides access to descriptions of the properties,
- * attributes, etc. of objects used within the Guacamole REST API.
- *
- * @author Michael Jumper
- */
-@Path("/schema/{dataSource}")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class SchemaRESTService {
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
-     * Retrieves the possible attributes of a user object.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext dictating the available user attributes.
-     *
-     * @return
-     *     A collection of forms which describe the possible attributes of a
-     *     user object.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the possible attributes.
-     */
-    @GET
-    @Path("/users/attributes")
-    public Collection<Form> getUserAttributes(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier)
-            throws GuacamoleException {
-
-        // Retrieve all possible user attributes
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        return userContext.getUserAttributes();
-
-    }
-
-    /**
-     * Retrieves the possible attributes of a connection object.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext dictating the available connection attributes.
-     *
-     * @return
-     *     A collection of forms which describe the possible attributes of a
-     *     connection object.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the possible attributes.
-     */
-    @GET
-    @Path("/connections/attributes")
-    public Collection<Form> getConnectionAttributes(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier)
-            throws GuacamoleException {
-
-        // Retrieve all possible connection attributes
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        return userContext.getConnectionAttributes();
-
-    }
-
-    /**
-     * Retrieves the possible attributes of a connection group object.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext dictating the available connection group
-     *     attributes.
-     *
-     * @return
-     *     A collection of forms which describe the possible attributes of a
-     *     connection group object.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the possible attributes.
-     */
-    @GET
-    @Path("/connectionGroups/attributes")
-    public Collection<Form> getConnectionGroupAttributes(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier)
-            throws GuacamoleException {
-
-        // Retrieve all possible connection group attributes
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        return userContext.getConnectionGroupAttributes();
-
-    }
-
-    /**
-     * Gets a map of protocols defined in the system - protocol name to protocol.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext dictating the protocols available. Currently, the
-     *     UserContext actually does not dictate this, the the same set of
-     *     protocols will be retrieved for all users, though the identifier
-     *     given here will be validated.
-     *
-     * @return
-     *     A map of protocol information, where each key is the unique name
-     *     associated with that protocol.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the available protocols.
-     */
-    @GET
-    @Path("/protocols")
-    public Map<String, ProtocolInfo> getProtocols(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier)
-            throws GuacamoleException {
-
-        // Verify the given auth token and auth provider identifier are valid
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get and return a map of all protocols.
-        Environment env = new LocalEnvironment();
-        return env.getProtocols();
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/89eabc1d/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaResource.java
new file mode 100644
index 0000000..f0fcc86
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/schema/SchemaResource.java
@@ -0,0 +1,142 @@
+/*
+ * 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.schema;
+
+import java.util.Collection;
+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.environment.Environment;
+import org.apache.guacamole.environment.LocalEnvironment;
+import org.apache.guacamole.form.Form;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.protocols.ProtocolInfo;
+
+/**
+ * A REST resource which provides access to descriptions of the properties,
+ * attributes, etc. of objects within a particular UserContext.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SchemaResource {
+
+    /**
+     * The UserContext whose schema is exposed by this SchemaResource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * Creates a new SchemaResource which exposes meta information describing
+     * the kind of data within the given UserContext.
+     *
+     * @param userContext
+     *     The UserContext whose schema should be exposed by this
+     *     SchemaResource.
+     */
+    public SchemaResource(UserContext userContext) {
+        this.userContext = userContext;
+    }
+
+    /**
+     * Retrieves the possible attributes of a user object.
+     *
+     * @return
+     *     A collection of forms which describe the possible attributes of a
+     *     user object.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the possible attributes.
+     */
+    @GET
+    @Path("userAttributes")
+    public Collection<Form> getUserAttributes() throws GuacamoleException {
+
+        // Retrieve all possible user attributes
+        return userContext.getUserAttributes();
+
+    }
+
+    /**
+     * Retrieves the possible attributes of a connection object.
+     *
+     * @return
+     *     A collection of forms which describe the possible attributes of a
+     *     connection object.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the possible attributes.
+     */
+    @GET
+    @Path("connectionAttributes")
+    public Collection<Form> getConnectionAttributes()
+            throws GuacamoleException {
+
+        // Retrieve all possible connection attributes
+        return userContext.getConnectionAttributes();
+
+    }
+
+    /**
+     * Retrieves the possible attributes of a connection group object.
+     *
+     * @return
+     *     A collection of forms which describe the possible attributes of a
+     *     connection group object.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the possible attributes.
+     */
+    @GET
+    @Path("connectionGroupAttributes")
+    public Collection<Form> getConnectionGroupAttributes()
+            throws GuacamoleException {
+
+        // Retrieve all possible connection group attributes
+        return userContext.getConnectionGroupAttributes();
+
+    }
+
+    /**
+     * Gets a map of protocols defined in the system - protocol name to protocol.
+     *
+     * @return
+     *     A map of protocol information, where each key is the unique name
+     *     associated with that protocol.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the available protocols.
+     */
+    @GET
+    @Path("protocols")
+    public Map<String, ProtocolInfo> getProtocols() throws GuacamoleException {
+
+        // Get and return a map of all protocols.
+        Environment env = new LocalEnvironment();
+        return env.getProtocols();
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/89eabc1d/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 81344c6..e0c8855 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
@@ -38,6 +38,7 @@ import org.apache.guacamole.rest.activeconnection.APIActiveConnection;
 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.user.APIUser;
 
 /**
@@ -183,4 +184,19 @@ public class UserContextResource {
         return new HistoryResource(userContext);
     }
 
+    /**
+     * Returns a new resource which represents meta information describing the
+     * kind of data which within the UserContext exposed by this
+     * UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the meta information describing the
+     *     kind of data within the UserContext exposed by this
+     *     UserContextResource.
+     */
+    @Path("schema")
+    public SchemaResource getSchemaResource() {
+        return new SchemaResource(userContext);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/89eabc1d/guacamole/src/main/webapp/app/rest/services/schemaService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/schemaService.js b/guacamole/src/main/webapp/app/rest/services/schemaService.js
index 39d89e1..2c874ed 100644
--- a/guacamole/src/main/webapp/app/rest/services/schemaService.js
+++ b/guacamole/src/main/webapp/app/rest/services/schemaService.js
@@ -58,7 +58,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/schema/' + encodeURIComponent(dataSource) + '/users/attributes',
+            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/userAttributes',
             params  : httpParameters
         });
 
@@ -92,7 +92,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/schema/' + encodeURIComponent(dataSource) + '/connections/attributes',
+            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/connectionAttributes',
             params  : httpParameters
         });
 
@@ -126,7 +126,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/schema/' + encodeURIComponent(dataSource) + '/connectionGroups/attributes',
+            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/connectionGroupAttributes',
             params  : httpParameters
         });
 
@@ -157,7 +157,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         return $http({
             cache   : cacheService.schema,
             method  : 'GET',
-            url     : 'api/schema/' + encodeURIComponent(dataSource) + '/protocols',
+            url     : 'api/data/' + encodeURIComponent(dataSource) + '/schema/protocols',
             params  : httpParameters
         });
 


[20/24] incubator-guacamole-client git commit: GUACAMOLE-5: Refactor away ObjectRetrievalService.

Posted by jm...@apache.org.
GUACAMOLE-5: Refactor away ObjectRetrievalService.


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

Branch: refs/heads/master
Commit: e4ed85cfcbeebef47f68a161b52564da5a3c287f
Parents: b189f5f
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 21:38:07 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:38:07 2016 -0700

----------------------------------------------------------------------
 .../org/apache/guacamole/GuacamoleSession.java  | 39 ++++++++++
 .../guacamole/rest/ObjectRetrievalService.java  | 77 --------------------
 .../guacamole/rest/RESTServiceModule.java       |  3 -
 .../guacamole/rest/session/SessionResource.java |  9 +--
 .../guacamole/tunnel/TunnelRequestService.java  |  9 +--
 5 files changed, 41 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e4ed85cf/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
index 06530c2..41832cb 100644
--- a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
+++ b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
@@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.apache.guacamole.environment.Environment;
 import org.apache.guacamole.net.GuacamoleTunnel;
 import org.apache.guacamole.net.auth.AuthenticatedUser;
+import org.apache.guacamole.net.auth.AuthenticationProvider;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
 import org.slf4j.Logger;
@@ -127,6 +128,44 @@ public class GuacamoleSession {
     }
 
     /**
+     * Returns the UserContext associated with this session that originated
+     * from the AuthenticationProvider with the given identifier. If no such
+     * UserContext exists, an exception is thrown.
+     *
+     * @param authProviderIdentifier
+     *     The unique identifier of the AuthenticationProvider that created the
+     *     UserContext being retrieved.
+     *
+     * @return
+     *     The UserContext that was created by the AuthenticationProvider
+     *     having the given identifier.
+     *
+     * @throws GuacamoleException
+     *     If no such UserContext exists.
+     */
+    public UserContext getUserContext(String authProviderIdentifier)
+            throws GuacamoleException {
+
+        // Locate and return the UserContext associated with the
+        // AuthenticationProvider having the given identifier, if any
+        for (UserContext userContext : getUserContexts()) {
+
+            // Get AuthenticationProvider associated with current UserContext
+            AuthenticationProvider authProvider = userContext.getAuthenticationProvider();
+
+            // If AuthenticationProvider identifier matches, done
+            if (authProvider.getIdentifier().equals(authProviderIdentifier))
+                return userContext;
+
+        }
+
+        throw new GuacamoleResourceNotFoundException("Session not associated "
+                + "with authentication provider \"" + authProviderIdentifier + "\".");
+
+
+    }
+
+    /**
      * Replaces all UserContexts associated with this session with the given
      * List of UserContexts.
      *

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e4ed85cf/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java b/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
deleted file mode 100644
index edcb2fa..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/ObjectRetrievalService.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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;
-
-import java.util.List;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleResourceNotFoundException;
-import org.apache.guacamole.net.auth.AuthenticationProvider;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.GuacamoleSession;
-
-/**
- * Provides easy access and automatic error handling for retrieval of objects.
- */
-public class ObjectRetrievalService {
-
-    /**
-     * Retrieves a single UserContext from the given GuacamoleSession, which
-     * may contain multiple UserContexts.
-     *
-     * @param session
-     *     The GuacamoleSession to retrieve the UserContext from.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider that created the
-     *     UserContext being retrieved. Only one UserContext per User per
-     *     AuthenticationProvider can exist.
-     *
-     * @return
-     *     The UserContext that was created by the AuthenticationProvider
-     *     having the given identifier.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the UserContext, or if the
-     *     UserContext does not exist.
-     */
-    public UserContext retrieveUserContext(GuacamoleSession session,
-            String authProviderIdentifier) throws GuacamoleException {
-
-        // Get list of UserContexts
-        List<UserContext> userContexts = session.getUserContexts();
-
-        // Locate and return the UserContext associated with the
-        // AuthenticationProvider having the given identifier, if any
-        for (UserContext userContext : userContexts) {
-
-            // Get AuthenticationProvider associated with current UserContext
-            AuthenticationProvider authProvider = userContext.getAuthenticationProvider();
-
-            // If AuthenticationProvider identifier matches, done
-            if (authProvider.getIdentifier().equals(authProviderIdentifier))
-                return userContext;
-
-        }
-
-        throw new GuacamoleResourceNotFoundException("Session not associated with authentication provider \"" + authProviderIdentifier + "\".");
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e4ed85cf/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 c386e10..2978278 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -82,9 +82,6 @@ public class RESTServiceModule extends ServletModule {
         requestInjection(interceptor);
         bindInterceptor(Matchers.any(), new RESTMethodMatcher(), interceptor);
 
-        // Bind convenience services used by the REST API
-        bind(ObjectRetrievalService.class);
-
         // Set up the API endpoints
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e4ed85cf/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
index 211e5d5..7c7f14f 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
@@ -30,7 +30,6 @@ import javax.ws.rs.core.MediaType;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.GuacamoleSession;
 import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.rest.ObjectRetrievalService;
 import org.apache.guacamole.rest.tunnel.TunnelCollectionResource;
 
 /**
@@ -49,12 +48,6 @@ public class SessionResource {
     private final GuacamoleSession session;
 
     /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
      * Factory for creating UserContextResources which expose a given
      * UserContext.
      */
@@ -95,7 +88,7 @@ public class SessionResource {
             throws GuacamoleException {
 
         // Pull UserContext defined by the given auth provider identifier
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
+        UserContext userContext = session.getUserContext(authProviderIdentifier);
 
         // Return a resource exposing the retrieved UserContext
         return userContextResourceFactory.create(userContext);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e4ed85cf/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
index 8040472..95e4bb9 100644
--- a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
+++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java
@@ -31,7 +31,6 @@ import org.apache.guacamole.net.auth.Connection;
 import org.apache.guacamole.net.auth.ConnectionGroup;
 import org.apache.guacamole.net.auth.Directory;
 import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.rest.ObjectRetrievalService;
 import org.apache.guacamole.rest.auth.AuthenticationService;
 import org.apache.guacamole.protocol.GuacamoleClientInformation;
 import org.slf4j.Logger;
@@ -62,12 +61,6 @@ public class TunnelRequestService {
     private AuthenticationService authenticationService;
 
     /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
      * Reads and returns the client information provided within the given
      * request.
      *
@@ -327,7 +320,7 @@ public class TunnelRequestService {
         GuacamoleClientInformation info = getClientInformation(request);
 
         GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
+        UserContext userContext = session.getUserContext(authProviderIdentifier);
 
         try {
 


[22/24] incubator-guacamole-client git commit: GUACAMOLE-5: Increase the documentation factor of DirectoryResource.

Posted by jm...@apache.org.
GUACAMOLE-5: Increase the documentation factor of DirectoryResource.

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

Branch: refs/heads/master
Commit: abef36e11f7a470c0d5eb40b062277d681be79ea
Parents: aeec3ec
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 21:42:15 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:42:15 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/guacamole/rest/directory/DirectoryResource.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/abef36e1/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
index 1716545..2dbf7f1 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
@@ -158,6 +158,7 @@ public class DirectoryResource<InternalType extends Identifiable, ExternalType>
             identifiers = objectPermissions.getAccessibleObjects(permissions, identifiers);
         }
 
+        // Translate each retrieved object into the corresponding external object
         Map<String, ExternalType> apiObjects = new HashMap<String, ExternalType>();
         for (InternalType object : directory.getAll(identifiers))
             apiObjects.put(object.getIdentifier(), translator.toExternalObject(object));


[02/24] incubator-guacamole-client git commit: GUACAMOLE-5: Add root-level resources exposing UserContexts.

Posted by jm...@apache.org.
GUACAMOLE-5: Add root-level resources exposing UserContexts.


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

Branch: refs/heads/master
Commit: e579eae95cd93bf1defb8f64d8990a2d31e5331f
Parents: d3a9cec
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 00:15:18 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 00:15:18 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   7 ++
 .../guacamole/rest/session/SessionResource.java | 100 +++++++++++++++++++
 .../rest/session/UserContextResource.java       |  56 +++++++++++
 .../session/UserContextResourceFactory.java     |  45 +++++++++
 .../guacamole/rest/session/package-info.java    |  24 +++++
 5 files changed, 232 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e579eae9/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 ec555e3..bc8d7b6 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -19,7 +19,10 @@
 
 package org.apache.guacamole.rest;
 
+import org.apache.guacamole.rest.session.UserContextResourceFactory;
+import org.apache.guacamole.rest.session.SessionResource;
 import com.google.inject.Scopes;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.matcher.Matchers;
 import com.google.inject.servlet.ServletModule;
 import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
@@ -96,6 +99,10 @@ public class RESTServiceModule extends ServletModule {
         bind(TunnelRESTService.class);
         bind(UserRESTService.class);
 
+        // Root-level resources
+        bind(SessionResource.class);
+        install(new FactoryModuleBuilder().build(UserContextResourceFactory.class));
+
         // Set up the servlet and JSON mappings
         bind(GuiceContainer.class);
         bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e579eae9/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
new file mode 100644
index 0000000..7c98a65
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
@@ -0,0 +1,100 @@
+/*
+ * 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.session;
+
+import com.google.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSession;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.ObjectRetrievalService;
+import org.apache.guacamole.rest.auth.AuthenticationService;
+
+/**
+ * A REST resource which exposes all UserContexts within a Guacamole user's
+ * session.
+ *
+ * @author mjumper
+ */
+@Path("/data")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SessionResource {
+
+    /**
+     * A service for authenticating users from auth tokens.
+     */
+    @Inject
+    private AuthenticationService authenticationService;
+
+    /**
+     * Service for convenient retrieval of objects.
+     */
+    @Inject
+    private ObjectRetrievalService retrievalService;
+
+    /**
+     * Factory for creating UserContextResources which expose a given
+     * UserContext.
+     */
+    @Inject
+    private UserContextResourceFactory userContextResourceFactory;
+
+    /**
+     * Retrieves a resource representing the UserContext associated with the
+     * AuthenticationProvider having the given identifier.
+     *
+     * @param authToken
+     *     The authentication token that is used to authenticate the user
+     *     performing the operation.
+     *
+     * @param authProviderIdentifier
+     *     The unique identifier of the AuthenticationProvider associated with
+     *     the UserContext being retrieved.
+     *
+     * @return
+     *     A resource representing the UserContext associated with the
+     *     AuthenticationProvider having the given identifier.
+     *
+     * @throws GuacamoleException
+     *     If the authentication token or AuthenticationProvider identifier are
+     *     invalid.
+     */
+    @Path("{dataSource}")
+    public UserContextResource getUserContextResource(
+            @QueryParam("token") String authToken,
+            @PathParam("dataSource") String authProviderIdentifier)
+            throws GuacamoleException {
+
+        // Pull UserContext defined by the given auth provider identifier
+        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
+        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
+
+        // Return a resource exposing the retrieved UserContext
+        return userContextResourceFactory.create(userContext);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e579eae9/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
new file mode 100644
index 0000000..e5dcc0c
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java
@@ -0,0 +1,56 @@
+/*
+ * 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.session;
+
+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.UserContext;
+
+/**
+ * A REST resource which exposes the contents of a particular UserContext.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class UserContextResource {
+
+    /**
+     * The UserContext being exposed through this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * Creates a new UserContextResource which exposes the data within the
+     * given UserContext.
+     *
+     * @param userContext
+     *     The UserContext which should be exposed through this
+     *     UserContextResource.
+     */
+    @AssistedInject
+    public UserContextResource(@Assisted UserContext userContext) {
+        this.userContext = userContext;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e579eae9/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResourceFactory.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResourceFactory.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResourceFactory.java
new file mode 100644
index 0000000..04e60ea
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResourceFactory.java
@@ -0,0 +1,45 @@
+/*
+ * 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.session;
+
+import org.apache.guacamole.net.auth.UserContext;
+
+/**
+ * Factory which creates resources that expose the contents of a given
+ * UserContext.
+ *
+ * @author Michael Jumper
+ */
+public interface UserContextResourceFactory {
+
+    /**
+     * Creates a new UserContextResource which exposes the contents of the
+     * given UserContext.
+     *
+     * @param userContext
+     *     The UserContext whose contents should be exposed.
+     *
+     * @return
+     *     A new UserContextResource which exposes the contents of the given
+     *     UserContext.
+     */
+    UserContextResource create(UserContext userContext);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/e579eae9/guacamole/src/main/java/org/apache/guacamole/rest/session/package-info.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/package-info.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/package-info.java
new file mode 100644
index 0000000..118ee2e
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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 which expose the absolute root of the data available to a Guacamole
+ * user's session.
+ */
+package org.apache.guacamole.rest.session;


[04/24] incubator-guacamole-client git commit: GUACAMOLE-5: Provide UserContext to DirectoryObjectResourceFactory, in case needed by a particular resource (such as for additional permission checks).

Posted by jm...@apache.org.
GUACAMOLE-5: Provide UserContext to DirectoryObjectResourceFactory, in case needed by a particular resource (such as for additional permission checks).

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

Branch: refs/heads/master
Commit: bca4e34b512e5b3935ffd41c94d14b95100d898c
Parents: f440f55
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 00:31:52 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 00:31:52 2016 -0700

----------------------------------------------------------------------
 .../rest/directory/DirectoryObjectResourceFactory.java        | 7 ++++++-
 .../apache/guacamole/rest/directory/DirectoryResource.java    | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/bca4e34b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
index ba17382..613ac42 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryObjectResourceFactory.java
@@ -21,6 +21,7 @@ package org.apache.guacamole.rest.directory;
 
 import org.apache.guacamole.net.auth.Directory;
 import org.apache.guacamole.net.auth.Identifiable;
+import org.apache.guacamole.net.auth.UserContext;
 
 /**
  * Factory which creates DirectoryObjectResource instances exposing objects of
@@ -40,6 +41,9 @@ public interface DirectoryObjectResourceFactory<InternalType extends Identifiabl
     /**
      * Creates a new DirectoryObjectResource which exposes the given object.
      *
+     * @param userContext
+     *     The UserContext which contains the given Directory.
+     *
      * @param directory
      *     The Directory which contains the object being exposed.
      *
@@ -51,6 +55,7 @@ public interface DirectoryObjectResourceFactory<InternalType extends Identifiabl
      *     A new DirectoryObjectResource which exposes the given object.
      */
     DirectoryObjectResource<InternalType, ExternalType>
-        create(Directory<InternalType> directory, InternalType object);
+        create(UserContext userContext, Directory<InternalType> directory,
+                InternalType object);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/bca4e34b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
index 5f726f6..ee4fd2c 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java
@@ -258,7 +258,7 @@ public class DirectoryResource<InternalType extends Identifiable, ExternalType>
             throw new GuacamoleResourceNotFoundException("Not found: \"" + identifier + "\"");
 
         // Return a resource which provides access to the retrieved object
-        return resourceFactory.create(directory, object);
+        return resourceFactory.create(userContext, directory, object);
 
     }
 


[12/24] incubator-guacamole-client git commit: GUACAMOLE-5: Consolidate UserContexts and tunnels under the same hierarchy.

Posted by jm...@apache.org.
GUACAMOLE-5: Consolidate UserContexts and tunnels under the same hierarchy.


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

Branch: refs/heads/master
Commit: b189f5fef98c64ad4eeec769c6b39f4bafc17419
Parents: 60c672e
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 21:19:05 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   2 -
 .../guacamole/rest/session/SessionResource.java |  14 ++
 .../guacamole/rest/tunnel/StreamResource.java   | 131 ++++++++++++
 .../rest/tunnel/TunnelCollectionResource.java   | 105 ++++++++++
 .../rest/tunnel/TunnelRESTService.java          | 202 -------------------
 .../guacamole/rest/tunnel/TunnelResource.java   |  94 +++++++++
 .../guacamole/rest/tunnel/package-info.java     |  24 +++
 7 files changed, 368 insertions(+), 204 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/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 3708640..c386e10 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -39,7 +39,6 @@ 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.tunnel.TunnelRESTService;
 import org.apache.guacamole.rest.user.UserModule;
 
 /**
@@ -90,7 +89,6 @@ public class RESTServiceModule extends ServletModule {
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);
         bind(TokenRESTService.class);
-        bind(TunnelRESTService.class);
 
         // Root-level resources
         bind(SessionRESTService.class);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
index c9e9834..211e5d5 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
@@ -31,6 +31,7 @@ import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.GuacamoleSession;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.rest.ObjectRetrievalService;
+import org.apache.guacamole.rest.tunnel.TunnelCollectionResource;
 
 /**
  * A REST resource which exposes all data associated with a Guacamole user's
@@ -101,4 +102,17 @@ public class SessionResource {
 
     }
 
+    /**
+     * Retrieves a resource representing all tunnels associated with session
+     * exposed by this SessionResource.
+     *
+     * @return
+     *     A resource representing all tunnels associated with the
+     *     AuthenticationProvider having the given identifier.
+     */
+    @Path("tunnels")
+    public TunnelCollectionResource getTunnelCollectionResource() {
+        return new TunnelCollectionResource(session);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/StreamResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/StreamResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/StreamResource.java
new file mode 100644
index 0000000..60e48ec
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/StreamResource.java
@@ -0,0 +1,131 @@
+/*
+ * 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.tunnel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
+
+/**
+ * A REST resource providing access to a Guacamole protocol-level stream
+ * within a tunnel.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class StreamResource {
+
+    /**
+     * The tunnel whose stream is exposed through this StreamResource.
+     */
+    private final StreamInterceptingTunnel tunnel;
+
+    /**
+     * The index of the stream being exposed.
+     */
+    private final int streamIndex;
+
+    /**
+     * The media type of the data within the stream being exposed.
+     */
+    private final String mediaType;
+
+    /**
+     * Creates a new StreamResource which provides access to the given
+     * stream.
+     *
+     * @param tunnel
+     *     The tunnel whose stream is being exposed.
+     *
+     * @param streamIndex
+     *     The index of the stream to expose via this StreamResource.
+     *
+     * @param mediaType
+     *     The media type of the data within the stream.
+     */
+    public StreamResource(StreamInterceptingTunnel tunnel, int streamIndex,
+            String mediaType) {
+        this.tunnel = tunnel;
+        this.streamIndex = streamIndex;
+        this.mediaType = mediaType;
+    }
+
+    /**
+     * Intercepts and returns the entire contents the stream represented by
+     * this StreamResource.
+     *
+     * @return
+     *     A response through which the entire contents of the intercepted
+     *     stream will be sent.
+     */
+    @GET
+    public Response getStreamContents() {
+
+        // Intercept all output
+        StreamingOutput stream = new StreamingOutput() {
+
+            @Override
+            public void write(OutputStream output) throws IOException {
+                try {
+                    tunnel.interceptStream(streamIndex, output);
+                }
+                catch (GuacamoleException e) {
+                    throw new IOException(e);
+                }
+            }
+
+        };
+
+        return Response.ok(stream, mediaType).build();
+
+    }
+
+    /**
+     * Intercepts the stream represented by this StreamResource, sending the
+     * contents of the given InputStream over that stream as "blob"
+     * instructions.
+     *
+     * @param data
+     *     An InputStream containing the data to be sent over the intercepted
+     *     stream.
+     *
+     * @throws GuacamoleException
+     *     If the intercepted stream closes with an error.
+     */
+    @POST
+    @Consumes(MediaType.WILDCARD)
+    public void setStreamContents(InputStream data) throws GuacamoleException {
+
+        // Send input over stream
+        tunnel.interceptStream(streamIndex, data);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelCollectionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelCollectionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelCollectionResource.java
new file mode 100644
index 0000000..342cc76
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelCollectionResource.java
@@ -0,0 +1,105 @@
+/*
+ * 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.tunnel;
+
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleResourceNotFoundException;
+import org.apache.guacamole.GuacamoleSession;
+import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
+
+/**
+ * A REST resource which exposes the active tunnels of a Guacamole session.
+ *
+ * @author Michael Jumper
+ */
+@Path("/tunnels")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class TunnelCollectionResource {
+
+    /**
+     * The GuacamoleSession containing the tunnels exposed by this resource.
+     */
+    private final GuacamoleSession session;
+
+    /**
+     * Creates a new TunnelCollectionResource which exposes the active tunnels
+     * of the given GuacamoleSession.
+     *
+     * @param session
+     *     The GuacamoleSession whose tunnels should be exposed by this
+     *     resource.
+     */
+    public TunnelCollectionResource(GuacamoleSession session) {
+        this.session = session;
+    }
+
+    /**
+     * Returns the UUIDs of all tunnels exposed by this
+     * TunnelCollectionResource.
+     *
+     * @return
+     *     A set containing the UUIDs of all tunnels exposed by this
+     *     TunnelCollectionResource.
+     */
+    @GET
+    public Set<String> getTunnelUUIDs() {
+        return session.getTunnels().keySet();
+    }
+
+    /**
+     * Retrieves the tunnel having the given UUID, returning a TunnelResource
+     * representing that tunnel. If no such tunnel exists, an exception will be
+     * thrown.
+     *
+     * @param tunnelUUID
+     *     The UUID of the tunnel to return via a TunnelResource.
+     *
+     * @return
+     *     A TunnelResource which represents the tunnel having the given UUID.
+     *
+     * @throws GuacamoleException
+     *     If no such tunnel exists.
+     */
+    @Path("{tunnel}")
+    public TunnelResource getTunnel(@PathParam("tunnel") String tunnelUUID)
+            throws GuacamoleException {
+
+        Map<String, StreamInterceptingTunnel> tunnels = session.getTunnels();
+
+        // Pull tunnel with given UUID
+        final StreamInterceptingTunnel tunnel = tunnels.get(tunnelUUID);
+        if (tunnel == null)
+            throw new GuacamoleResourceNotFoundException("No such tunnel.");
+
+        // Return corresponding tunnel resource
+        return new TunnelResource(tunnel);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelRESTService.java
deleted file mode 100644
index 49740d1..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelRESTService.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.tunnel;
-
-import com.google.inject.Inject;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.StreamingOutput;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleResourceNotFoundException;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
-
-/**
- * A REST Service for retrieving and managing the tunnels of active
- * connections, including any associated objects.
- *
- * @author Michael Jumper
- */
-@Path("/tunnels")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class TunnelRESTService {
-
-    /**
-     * The media type to send as the content type of stream contents if no
-     * other media type is specified.
-     */
-    private static final String DEFAULT_MEDIA_TYPE = "application/octet-stream";
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-
-    /**
-     * Returns the UUIDs of all currently-active tunnels associated with the
-     * session identified by the given auth token.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @return
-     *     A set containing the UUIDs of all currently-active tunnels.
-     *
-     * @throws GuacamoleException
-     *     If the session associated with the given auth token cannot be
-     *     retrieved.
-     */
-    @GET
-    public Set<String> getTunnelUUIDs(@QueryParam("token") String authToken)
-            throws GuacamoleException {
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        return session.getTunnels().keySet();
-    }
-
-    /**
-     * Intercepts and returns the entire contents of a specific stream.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param tunnelUUID
-     *     The UUID of the tunnel containing the stream being intercepted.
-     *
-     * @param streamIndex
-     *     The index of the stream to intercept.
-     *
-     * @param mediaType
-     *     The media type (mimetype) of the data within the stream.
-     *
-     * @param filename
-     *     The filename to use for the sake of identifying the data returned.
-     *
-     * @return
-     *     A response through which the entire contents of the intercepted
-     *     stream will be sent.
-     *
-     * @throws GuacamoleException
-     *     If the session associated with the given auth token cannot be
-     *     retrieved, or if no such tunnel exists.
-     */
-    @GET
-    @Path("/{tunnel}/streams/{index}/{filename}")
-    public Response getStreamContents(@QueryParam("token") String authToken,
-            @PathParam("tunnel") String tunnelUUID,
-            @PathParam("index") final int streamIndex,
-            @QueryParam("type") @DefaultValue(DEFAULT_MEDIA_TYPE) String mediaType,
-            @PathParam("filename") String filename)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        Map<String, StreamInterceptingTunnel> tunnels = session.getTunnels();
-
-        // Pull tunnel with given UUID
-        final StreamInterceptingTunnel tunnel = tunnels.get(tunnelUUID);
-        if (tunnel == null)
-            throw new GuacamoleResourceNotFoundException("No such tunnel.");
-
-        // Intercept all output
-        StreamingOutput stream = new StreamingOutput() {
-
-            @Override
-            public void write(OutputStream output) throws IOException {
-                try {
-                    tunnel.interceptStream(streamIndex, output);
-                }
-                catch (GuacamoleException e) {
-                    throw new IOException(e);
-                }
-            }
-
-        };
-
-        return Response.ok(stream, mediaType).build();
-
-    }
-
-    /**
-     * Intercepts a specific stream, sending the contents of the given
-     * InputStream over that stream as "blob" instructions.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param tunnelUUID
-     *     The UUID of the tunnel containing the stream being intercepted.
-     *
-     * @param streamIndex
-     *     The index of the stream to intercept.
-     *
-     * @param filename
-     *     The filename to use for the sake of identifying the data being sent.
-     *
-     * @param data
-     *     An InputStream containing the data to be sent over the intercepted
-     *     stream.
-     *
-     * @throws GuacamoleException
-     *     If the session associated with the given auth token cannot be
-     *     retrieved, if no such tunnel exists, or if the intercepted stream
-     *     itself closes with an error.
-     */
-    @POST
-    @Consumes(MediaType.WILDCARD)
-    @Path("/{tunnel}/streams/{index}/{filename}")
-    public void setStreamContents(@QueryParam("token") String authToken,
-            @PathParam("tunnel") String tunnelUUID,
-            @PathParam("index") final int streamIndex,
-            @PathParam("filename") String filename,
-            InputStream data)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        Map<String, StreamInterceptingTunnel> tunnels = session.getTunnels();
-
-        // Pull tunnel with given UUID
-        final StreamInterceptingTunnel tunnel = tunnels.get(tunnelUUID);
-        if (tunnel == null)
-            throw new GuacamoleResourceNotFoundException("No such tunnel.");
-
-        // Send input over stream
-        tunnel.interceptStream(streamIndex, data);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelResource.java
new file mode 100644
index 0000000..3bfcae2
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/TunnelResource.java
@@ -0,0 +1,94 @@
+/*
+ * 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.tunnel;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
+
+/**
+ * A REST resource which abstracts the operations available for an individual
+ * tunnel.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class TunnelResource {
+
+    /**
+     * The media type to send as the content type of stream contents if no
+     * other media type is specified.
+     */
+    private static final String DEFAULT_MEDIA_TYPE = "application/octet-stream";
+
+    /**
+     * The tunnel that this TunnelResource represents.
+     */
+    private final StreamInterceptingTunnel tunnel;
+
+    /**
+     * Creates a new TunnelResource which exposes the operations and
+     * subresources available for the given tunnel.
+     *
+     * @param tunnel
+     *     The tunnel that this TunnelResource should represent.
+     */
+    public TunnelResource(StreamInterceptingTunnel tunnel) {
+        this.tunnel = tunnel;
+    }
+
+    /**
+     * Intercepts and returns the entire contents of a specific stream.
+     *
+     * @param streamIndex
+     *     The index of the stream to intercept.
+     *
+     * @param mediaType
+     *     The media type (mimetype) of the data within the stream.
+     *
+     * @param filename
+     *     The filename to use for the sake of identifying the data returned.
+     *
+     * @return
+     *     A response through which the entire contents of the intercepted
+     *     stream will be sent.
+     *
+     * @throws GuacamoleException
+     *     If the session associated with the given auth token cannot be
+     *     retrieved, or if no such tunnel exists.
+     */
+    @Path("streams/{index}/{filename}")
+    public StreamResource getStream(@PathParam("index") final int streamIndex,
+            @QueryParam("type") @DefaultValue(DEFAULT_MEDIA_TYPE) String mediaType,
+            @PathParam("filename") String filename)
+            throws GuacamoleException {
+
+        return new StreamResource(tunnel, streamIndex, mediaType);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b189f5fe/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/package-info.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/package-info.java b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/package-info.java
new file mode 100644
index 0000000..d4f07a7
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/tunnel/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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 the manipulation of Guacamole tunnels and underlying
+ * streams.
+ */
+package org.apache.guacamole.rest.tunnel;


[10/24] incubator-guacamole-client git commit: GUACAMOLE-5: Move permission management to own resource.

Posted by jm...@apache.org.
GUACAMOLE-5: Move permission management to own resource.


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

Branch: refs/heads/master
Commit: 86d94d18d4c9eca32a653a006d9949f37a7f2642
Parents: 374ad3e
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 13:19:19 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:46 2016 -0700

----------------------------------------------------------------------
 .../rest/permission/PermissionSetPatch.java     |  95 +++++++
 .../rest/permission/PermissionSetResource.java  | 261 +++++++++++++++++++
 .../guacamole/rest/user/PermissionSetPatch.java |  95 -------
 .../guacamole/rest/user/UserResource.java       | 178 +------------
 4 files changed, 363 insertions(+), 266 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/86d94d18/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetPatch.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetPatch.java b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetPatch.java
new file mode 100644
index 0000000..b08d2ba
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetPatch.java
@@ -0,0 +1,95 @@
+/*
+ * 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.permission;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.permission.Permission;
+import org.apache.guacamole.net.auth.permission.PermissionSet;
+
+/**
+ * A set of changes to be applied to a PermissionSet, describing the set of
+ * permissions being added and removed.
+ * 
+ * @author Michael Jumper
+ * @param <PermissionType>
+ *     The type of permissions being added and removed.
+ */
+public class PermissionSetPatch<PermissionType extends Permission> {
+
+    /**
+     * The set of all permissions being added.
+     */
+    private final Set<PermissionType> addedPermissions =
+            new HashSet<PermissionType>();
+    
+    /**
+     * The set of all permissions being removed.
+     */
+    private final Set<PermissionType> removedPermissions =
+            new HashSet<PermissionType>();
+
+    /**
+     * Queues the given permission to be added. The add operation will be
+     * performed only when apply() is called.
+     *
+     * @param permission
+     *     The permission to add.
+     */
+    public void addPermission(PermissionType permission) {
+        addedPermissions.add(permission);
+    }
+    
+    /**
+     * Queues the given permission to be removed. The remove operation will be
+     * performed only when apply() is called.
+     *
+     * @param permission
+     *     The permission to remove.
+     */
+    public void removePermission(PermissionType permission) {
+        removedPermissions.add(permission);
+    }
+
+    /**
+     * Applies all queued changes to the given permission set.
+     *
+     * @param permissionSet
+     *     The permission set to add and remove permissions from.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while manipulating the permissions of the given
+     *     permission set.
+     */
+    public void apply(PermissionSet<PermissionType> permissionSet)
+        throws GuacamoleException {
+
+        // Add any added permissions
+        if (!addedPermissions.isEmpty())
+            permissionSet.addPermissions(addedPermissions);
+
+        // Remove any removed permissions
+        if (!removedPermissions.isEmpty())
+            permissionSet.removePermissions(removedPermissions);
+
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/86d94d18/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
new file mode 100644
index 0000000..e75460c
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java
@@ -0,0 +1,261 @@
+/*
+ * 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.permission;
+
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleClientException;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.User;
+import org.apache.guacamole.net.auth.permission.ObjectPermission;
+import org.apache.guacamole.net.auth.permission.Permission;
+import org.apache.guacamole.net.auth.permission.SystemPermission;
+import org.apache.guacamole.rest.APIPatch;
+import org.apache.guacamole.rest.PATCH;
+
+/**
+ * A REST resource which abstracts the operations available on the permissions
+ * granted to an existing User.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+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 connection.
+     */
+    private static final String CONNECTION_PERMISSION_PATCH_PATH_PREFIX = "/connectionPermissions/";
+
+    /**
+     * The prefix of any path within an operation of a JSON patch which
+     * modifies the permissions of a user regarding a specific connection group.
+     */
+    private static final String CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX = "/connectionGroupPermissions/";
+
+    /**
+     * 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/";
+
+    /**
+     * The prefix of any path within an operation of a JSON patch which
+     * modifies the permissions of a user regarding another, specific user.
+     */
+    private static final String USER_PERMISSION_PATCH_PATH_PREFIX = "/userPermissions/";
+
+    /**
+     * The path of any operation within a JSON patch which modifies the
+     * permissions of a user regarding the entire system.
+     */
+    private static final String SYSTEM_PERMISSION_PATCH_PATH = "/systemPermissions";
+
+    /**
+     * The User object whose permissions are represented by this
+     * PermissionSetResource.
+     */
+    private final User user;
+
+    /**
+     * Creates a new PermissionSetResource which exposes the operations and
+     * subresources available for permissions of the given User.
+     *
+     * @param user
+     *     The User whose permissions should be represented by this
+     *     PermissionSetResource.
+     */
+    public PermissionSetResource(User user) {
+        this.user = user;
+    }
+
+    /**
+     * Gets a list of permissions for the user with the given username.
+     *
+     * @return
+     *     A list of all permissions granted to the specified user.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving permissions.
+     */
+    @GET
+    public APIPermissionSet getPermissions() throws GuacamoleException {
+        return new APIPermissionSet(user);
+    }
+
+    /**
+     * Updates the given permission set patch by queuing an add or remove
+     * operation for the given permission based on the given patch operation.
+     *
+     * @param <PermissionType>
+     *     The type of permission stored within the permission set.
+     *
+     * @param operation
+     *     The patch operation to perform.
+     *
+     * @param permissionSetPatch
+     *     The permission set patch being modified.
+     *
+     * @param permission
+     *     The permission being added or removed from the set.
+     *
+     * @throws GuacamoleException
+     *     If the requested patch operation is not supported.
+     */
+    private <PermissionType extends Permission> void updatePermissionSet(
+            APIPatch.Operation operation,
+            PermissionSetPatch<PermissionType> permissionSetPatch,
+            PermissionType permission) throws GuacamoleException {
+
+        // Add or remove permission based on operation
+        switch (operation) {
+
+            // Add permission
+            case add:
+                permissionSetPatch.addPermission(permission);
+                break;
+
+            // Remove permission
+            case remove:
+                permissionSetPatch.removePermission(permission);
+                break;
+
+            // Unsupported patch operation
+            default:
+                throw new GuacamoleClientException("Unsupported patch operation: \"" + operation + "\"");
+
+        }
+
+    }
+
+    /**
+     * Applies a given list of permission patches. Each patch specifies either
+     * an "add" or a "remove" operation for a permission type, represented by
+     * a string. Valid permission types depend on the path of each patch
+     * operation, as the path dictates the permission being modified, such as
+     * "/connectionPermissions/42" or "/systemPermissions".
+     *
+     * @param patches
+     *     The permission patches to apply for this request.
+     *
+     * @throws GuacamoleException
+     *     If a problem is encountered while modifying permissions.
+     */
+    @PATCH
+    public void patchPermissions(List<APIPatch<String>> patches)
+            throws GuacamoleException {
+
+        // Permission patches for all types of permissions
+        PermissionSetPatch<ObjectPermission> connectionPermissionPatch       = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> connectionGroupPermissionPatch  = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> activeConnectionPermissionPatch = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> userPermissionPatch             = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<SystemPermission> systemPermissionPatch           = new PermissionSetPatch<SystemPermission>();
+
+        // Apply all patch operations individually
+        for (APIPatch<String> patch : patches) {
+
+            String path = patch.getPath();
+
+            // Create connection permission if path has connection prefix
+            if (path.startsWith(CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(CONNECTION_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(), connectionPermissionPatch, permission);
+
+            }
+
+            // Create connection group permission if path has connection group prefix
+            else if (path.startsWith(CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(CONNECTION_GROUP_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(), connectionGroupPermissionPatch, permission);
+
+            }
+
+            // Create active connection permission if path has active connection prefix
+            else if (path.startsWith(ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(ACTIVE_CONNECTION_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(), activeConnectionPermissionPatch, permission);
+
+            }
+
+            // Create user permission if path has user prefix
+            else if (path.startsWith(USER_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(USER_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(), userPermissionPatch, permission);
+
+            }
+
+            // Create system permission if path is system path
+            else if (path.equals(SYSTEM_PERMISSION_PATCH_PATH)) {
+
+                // Get identifier and type from patch operation
+                SystemPermission.Type type = SystemPermission.Type.valueOf(patch.getValue());
+
+                // Create and update corresponding permission
+                SystemPermission permission = new SystemPermission(type);
+                updatePermissionSet(patch.getOp(), systemPermissionPatch, permission);
+
+            }
+
+            // Otherwise, the path is not supported
+            else
+                throw new GuacamoleClientException("Unsupported patch path: \"" + path + "\"");
+
+        } // end for each patch operation
+
+        // Save the permission changes
+        connectionPermissionPatch.apply(user.getConnectionPermissions());
+        connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions());
+        activeConnectionPermissionPatch.apply(user.getActiveConnectionPermissions());
+        userPermissionPatch.apply(user.getUserPermissions());
+        systemPermissionPatch.apply(user.getSystemPermissions());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/86d94d18/guacamole/src/main/java/org/apache/guacamole/rest/user/PermissionSetPatch.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/PermissionSetPatch.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/PermissionSetPatch.java
deleted file mode 100644
index 653f424..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/user/PermissionSetPatch.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.user;
-
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.net.auth.permission.Permission;
-import org.apache.guacamole.net.auth.permission.PermissionSet;
-
-/**
- * A set of changes to be applied to a PermissionSet, describing the set of
- * permissions being added and removed.
- * 
- * @author Michael Jumper
- * @param <PermissionType>
- *     The type of permissions being added and removed.
- */
-public class PermissionSetPatch<PermissionType extends Permission> {
-
-    /**
-     * The set of all permissions being added.
-     */
-    private final Set<PermissionType> addedPermissions =
-            new HashSet<PermissionType>();
-    
-    /**
-     * The set of all permissions being removed.
-     */
-    private final Set<PermissionType> removedPermissions =
-            new HashSet<PermissionType>();
-
-    /**
-     * Queues the given permission to be added. The add operation will be
-     * performed only when apply() is called.
-     *
-     * @param permission
-     *     The permission to add.
-     */
-    public void addPermission(PermissionType permission) {
-        addedPermissions.add(permission);
-    }
-    
-    /**
-     * Queues the given permission to be removed. The remove operation will be
-     * performed only when apply() is called.
-     *
-     * @param permission
-     *     The permission to remove.
-     */
-    public void removePermission(PermissionType permission) {
-        removedPermissions.add(permission);
-    }
-
-    /**
-     * Applies all queued changes to the given permission set.
-     *
-     * @param permissionSet
-     *     The permission set to add and remove permissions from.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while manipulating the permissions of the given
-     *     permission set.
-     */
-    public void apply(PermissionSet<PermissionType> permissionSet)
-        throws GuacamoleException {
-
-        // Add any added permissions
-        if (!addedPermissions.isEmpty())
-            permissionSet.addPermissions(addedPermissions);
-
-        // Remove any removed permissions
-        if (!removedPermissions.isEmpty())
-            permissionSet.removePermissions(removedPermissions);
-
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/86d94d18/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
index 77009b6..7329a02 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
@@ -21,16 +21,13 @@ package org.apache.guacamole.rest.user;
 
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
-import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleClientException;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.GuacamoleSecurityException;
 import org.apache.guacamole.net.auth.AuthenticationProvider;
@@ -39,14 +36,9 @@ import org.apache.guacamole.net.auth.User;
 import org.apache.guacamole.net.auth.Directory;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException;
-import org.apache.guacamole.net.auth.permission.ObjectPermission;
-import org.apache.guacamole.net.auth.permission.Permission;
-import org.apache.guacamole.net.auth.permission.SystemPermission;
-import org.apache.guacamole.rest.APIPatch;
-import org.apache.guacamole.rest.PATCH;
 import org.apache.guacamole.rest.directory.DirectoryObjectResource;
 import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
-import org.apache.guacamole.rest.permission.APIPermissionSet;
+import org.apache.guacamole.rest.permission.PermissionSetResource;
 
 /**
  * A REST resource which abstracts the operations available on an existing
@@ -158,172 +150,16 @@ public class UserResource
     }
 
     /**
-     * Gets a list of permissions for the user with the given username.
+     * Returns a resource which abstracts operations available on the overall
+     * permissions granted to the User represented by this UserResource.
      *
      * @return
-     *     A list of all permissions granted to the specified user.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving permissions.
-     */
-    @GET
-    @Path("permissions")
-    public APIPermissionSet getPermissions() throws GuacamoleException {
-        return new APIPermissionSet(user);
-    }
-
-    /**
-     * Updates the given permission set patch by queuing an add or remove
-     * operation for the given permission based on the given patch operation.
-     *
-     * @param <PermissionType>
-     *     The type of permission stored within the permission set.
-     *
-     * @param operation
-     *     The patch operation to perform.
-     *
-     * @param permissionSetPatch
-     *     The permission set patch being modified.
-     *
-     * @param permission
-     *     The permission being added or removed from the set.
-     *
-     * @throws GuacamoleException
-     *     If the requested patch operation is not supported.
-     */
-    private <PermissionType extends Permission> void updatePermissionSet(
-            APIPatch.Operation operation,
-            PermissionSetPatch<PermissionType> permissionSetPatch,
-            PermissionType permission) throws GuacamoleException {
-
-        // Add or remove permission based on operation
-        switch (operation) {
-
-            // Add permission
-            case add:
-                permissionSetPatch.addPermission(permission);
-                break;
-
-            // Remove permission
-            case remove:
-                permissionSetPatch.removePermission(permission);
-                break;
-
-            // Unsupported patch operation
-            default:
-                throw new GuacamoleClientException("Unsupported patch operation: \"" + operation + "\"");
-
-        }
-
-    }
-
-    /**
-     * Applies a given list of permission patches. Each patch specifies either
-     * an "add" or a "remove" operation for a permission type, represented by
-     * a string. Valid permission types depend on the path of each patch
-     * operation, as the path dictates the permission being modified, such as
-     * "/connectionPermissions/42" or "/systemPermissions".
-     *
-     * @param patches
-     *     The permission patches to apply for this request.
-     *
-     * @throws GuacamoleException
-     *     If a problem is encountered while modifying permissions.
+     *     A resource which representing the permissions granted to the User
+     *     represented by this UserResource.
      */
-    @PATCH
     @Path("permissions")
-    public void patchPermissions(List<APIPatch<String>> patches)
-            throws GuacamoleException {
-
-        // Permission patches for all types of permissions
-        PermissionSetPatch<ObjectPermission> connectionPermissionPatch       = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<ObjectPermission> connectionGroupPermissionPatch  = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<ObjectPermission> activeConnectionPermissionPatch = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<ObjectPermission> userPermissionPatch             = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<SystemPermission> systemPermissionPatch           = new PermissionSetPatch<SystemPermission>();
-
-        // Apply all patch operations individually
-        for (APIPatch<String> patch : patches) {
-
-            String path = patch.getPath();
-
-            // Create connection permission if path has connection prefix
-            if (path.startsWith(CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(CONNECTION_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(), connectionPermissionPatch, permission);
-
-            }
-
-            // Create connection group permission if path has connection group prefix
-            else if (path.startsWith(CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(CONNECTION_GROUP_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(), connectionGroupPermissionPatch, permission);
-
-            }
-
-            // Create active connection permission if path has active connection prefix
-            else if (path.startsWith(ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(ACTIVE_CONNECTION_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(), activeConnectionPermissionPatch, permission);
-
-            }
-
-            // Create user permission if path has user prefix
-            else if (path.startsWith(USER_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(USER_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(), userPermissionPatch, permission);
-
-            }
-
-            // Create system permission if path is system path
-            else if (path.equals(SYSTEM_PERMISSION_PATCH_PATH)) {
-
-                // Get identifier and type from patch operation
-                SystemPermission.Type type = SystemPermission.Type.valueOf(patch.getValue());
-
-                // Create and update corresponding permission
-                SystemPermission permission = new SystemPermission(type);
-                updatePermissionSet(patch.getOp(), systemPermissionPatch, permission);
-
-            }
-
-            // Otherwise, the path is not supported
-            else
-                throw new GuacamoleClientException("Unsupported patch path: \"" + path + "\"");
-
-        } // end for each patch operation
-
-        // Save the permission changes
-        connectionPermissionPatch.apply(user.getConnectionPermissions());
-        connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions());
-        activeConnectionPermissionPatch.apply(user.getActiveConnectionPermissions());
-        userPermissionPatch.apply(user.getUserPermissions());
-        systemPermissionPatch.apply(user.getSystemPermissions());
-
+    public PermissionSetResource getPermissions() {
+        return new PermissionSetResource(user);
     }
 
 }


[19/24] incubator-guacamole-client git commit: GUACAMOLE-5: Consider methods annotated with @Path to be REST methods as well.

Posted by jm...@apache.org.
GUACAMOLE-5: Consider methods annotated with @Path to be REST methods as well.


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

Branch: refs/heads/master
Commit: fa286f549a3bc7c69ac03b5945bac1f51e728a23
Parents: c586d18
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 18:52:26 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/guacamole/rest/RESTMethodMatcher.java     | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fa286f54/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
index c80750c..623932f 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTMethodMatcher.java
@@ -23,6 +23,7 @@ import com.google.inject.matcher.AbstractMatcher;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import javax.ws.rs.HttpMethod;
+import javax.ws.rs.Path;
 import org.apache.guacamole.GuacamoleException;
 
 /**
@@ -67,7 +68,7 @@ public class RESTMethodMatcher extends AbstractMatcher<Method> {
     /**
      * Returns whether the given method is annotated as a REST method. A REST
      * method is annotated with an annotation which is annotated with
-     * <code>@HttpMethod</code>.
+     * <code>@HttpMethod</code> or <code>@Path</code>.
      *
      * @param method
      *     The method to test.
@@ -86,6 +87,10 @@ public class RESTMethodMatcher extends AbstractMatcher<Method> {
             if (annotationType.isAnnotationPresent(HttpMethod.class))
                 return true;
 
+            // A method is a REST method if it is annotated with @Path
+            if (Path.class.isAssignableFrom(annotationType))
+                return true;
+
         }
 
         // A method is also REST method if it overrides a REST method within


[15/24] incubator-guacamole-client git commit: GUACAMOLE-5: Rename SessionResource to SessionDataRESTService for consistency.

Posted by jm...@apache.org.
GUACAMOLE-5: Rename SessionResource to SessionDataRESTService for consistency.


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

Branch: refs/heads/master
Commit: 3c9da92e9ce7c918907405fbeab8d031c3a47b04
Parents: 89eabc1
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 14:02:34 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:47 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   4 +-
 .../rest/session/SessionDataRESTService.java    | 100 +++++++++++++++++++
 .../guacamole/rest/session/SessionResource.java | 100 -------------------
 3 files changed, 102 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3c9da92e/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 88551b3..a94f836 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -20,7 +20,7 @@
 package org.apache.guacamole.rest;
 
 import org.apache.guacamole.rest.session.UserContextResourceFactory;
-import org.apache.guacamole.rest.session.SessionResource;
+import org.apache.guacamole.rest.session.SessionDataRESTService;
 import com.google.inject.Scopes;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.matcher.Matchers;
@@ -92,7 +92,7 @@ public class RESTServiceModule extends ServletModule {
         bind(TunnelRESTService.class);
 
         // Root-level resources
-        bind(SessionResource.class);
+        bind(SessionDataRESTService.class);
         install(new FactoryModuleBuilder().build(UserContextResourceFactory.class));
 
         // Resources below root

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3c9da92e/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java
new file mode 100644
index 0000000..e21eaa4
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java
@@ -0,0 +1,100 @@
+/*
+ * 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.session;
+
+import com.google.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSession;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.ObjectRetrievalService;
+import org.apache.guacamole.rest.auth.AuthenticationService;
+
+/**
+ * A REST service which exposes all data associated with a Guacamole user's
+ * session via the underlying UserContexts.
+ *
+ * @author Michael Jumper
+ */
+@Path("/data")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SessionDataRESTService {
+
+    /**
+     * A service for authenticating users from auth tokens.
+     */
+    @Inject
+    private AuthenticationService authenticationService;
+
+    /**
+     * Service for convenient retrieval of objects.
+     */
+    @Inject
+    private ObjectRetrievalService retrievalService;
+
+    /**
+     * Factory for creating UserContextResources which expose a given
+     * UserContext.
+     */
+    @Inject
+    private UserContextResourceFactory userContextResourceFactory;
+
+    /**
+     * Retrieves a resource representing the UserContext associated with the
+     * AuthenticationProvider having the given identifier.
+     *
+     * @param authToken
+     *     The authentication token that is used to authenticate the user
+     *     performing the operation.
+     *
+     * @param authProviderIdentifier
+     *     The unique identifier of the AuthenticationProvider associated with
+     *     the UserContext being retrieved.
+     *
+     * @return
+     *     A resource representing the UserContext associated with the
+     *     AuthenticationProvider having the given identifier.
+     *
+     * @throws GuacamoleException
+     *     If the authentication token or AuthenticationProvider identifier are
+     *     invalid.
+     */
+    @Path("{dataSource}")
+    public UserContextResource getUserContextResource(
+            @QueryParam("token") String authToken,
+            @PathParam("dataSource") String authProviderIdentifier)
+            throws GuacamoleException {
+
+        // Pull UserContext defined by the given auth provider identifier
+        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
+        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
+
+        // Return a resource exposing the retrieved UserContext
+        return userContextResourceFactory.create(userContext);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/3c9da92e/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
deleted file mode 100644
index 7c98a65..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.session;
-
-import com.google.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-
-/**
- * A REST resource which exposes all UserContexts within a Guacamole user's
- * session.
- *
- * @author mjumper
- */
-@Path("/data")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class SessionResource {
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
-     * Factory for creating UserContextResources which expose a given
-     * UserContext.
-     */
-    @Inject
-    private UserContextResourceFactory userContextResourceFactory;
-
-    /**
-     * Retrieves a resource representing the UserContext associated with the
-     * AuthenticationProvider having the given identifier.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext being retrieved.
-     *
-     * @return
-     *     A resource representing the UserContext associated with the
-     *     AuthenticationProvider having the given identifier.
-     *
-     * @throws GuacamoleException
-     *     If the authentication token or AuthenticationProvider identifier are
-     *     invalid.
-     */
-    @Path("{dataSource}")
-    public UserContextResource getUserContextResource(
-            @QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier)
-            throws GuacamoleException {
-
-        // Pull UserContext defined by the given auth provider identifier
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Return a resource exposing the retrieved UserContext
-        return userContextResourceFactory.create(userContext);
-
-    }
-
-}


[11/24] incubator-guacamole-client git commit: GUACAMOLE-5: Replace UserRESTService with new resource-driven implementation.

Posted by jm...@apache.org.
GUACAMOLE-5: Replace UserRESTService with new resource-driven implementation.


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

Branch: refs/heads/master
Commit: 374ad3eb232e43a0aa52a06ad1df34781e18b909
Parents: 61d581e
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 13:01:42 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 21:23:46 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   4 +-
 .../rest/session/UserContextResource.java       |  27 +
 .../rest/user/UserDirectoryResource.java        | 104 +++
 .../apache/guacamole/rest/user/UserModule.java  |  65 ++
 .../rest/user/UserObjectTranslator.java         |  59 ++
 .../guacamole/rest/user/UserRESTService.java    | 644 -------------------
 .../guacamole/rest/user/UserResource.java       | 329 ++++++++++
 .../webapp/app/rest/services/userService.js     |   7 +-
 .../settings/directives/guacSettingsUsers.js    |   4 +-
 9 files changed, 592 insertions(+), 651 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/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 d0c9bd6..dbdcaba 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -41,7 +41,7 @@ import org.apache.guacamole.rest.language.LanguageRESTService;
 import org.apache.guacamole.rest.patch.PatchRESTService;
 import org.apache.guacamole.rest.schema.SchemaRESTService;
 import org.apache.guacamole.rest.tunnel.TunnelRESTService;
-import org.apache.guacamole.rest.user.UserRESTService;
+import org.apache.guacamole.rest.user.UserModule;
 
 /**
  * A Guice Module to set up the servlet mappings and authentication-specific
@@ -94,7 +94,6 @@ public class RESTServiceModule extends ServletModule {
         bind(SchemaRESTService.class);
         bind(TokenRESTService.class);
         bind(TunnelRESTService.class);
-        bind(UserRESTService.class);
 
         // Root-level resources
         bind(SessionResource.class);
@@ -104,6 +103,7 @@ public class RESTServiceModule extends ServletModule {
         install(new ActiveConnectionModule());
         install(new ConnectionModule());
         install(new ConnectionGroupModule());
+        install(new UserModule());
 
         // Set up the servlet and JSON mappings
         bind(GuiceContainer.class);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/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 9091e99..c9ff670 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,10 +32,12 @@ 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.User;
 import org.apache.guacamole.net.auth.UserContext;
 import org.apache.guacamole.rest.activeconnection.APIActiveConnection;
 import org.apache.guacamole.rest.connection.APIConnection;
 import org.apache.guacamole.rest.connectiongroup.APIConnectionGroup;
+import org.apache.guacamole.rest.user.APIUser;
 
 /**
  * A REST resource which exposes the contents of a particular UserContext.
@@ -76,6 +78,13 @@ public class UserContextResource {
             connectionGroupDirectoryResourceFactory;
 
     /**
+     * Factory for creating DirectoryResources which expose a given
+     * User Directory.
+     */
+    @Inject
+    private DirectoryResourceFactory<User, APIUser> userDirectoryResourceFactory;
+
+    /**
      * Creates a new UserContextResource which exposes the data within the
      * given UserContext.
      *
@@ -142,4 +151,22 @@ public class UserContextResource {
                 userContext.getConnectionGroupDirectory());
     }
 
+    /**
+     * Returns a new resource which represents the User Directory contained
+     * within the UserContext exposed by this UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the User Directory contained within
+     *     the UserContext exposed by this UserContextResource.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the User Directory.
+     */
+    @Path("users")
+    public DirectoryResource<User, APIUser> getUserDirectoryResource()
+            throws GuacamoleException {
+        return userDirectoryResourceFactory.create(userContext,
+                userContext.getUserDirectory());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
new file mode 100644
index 0000000..a61bf05
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserDirectoryResource.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.rest.user;
+
+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.GuacamoleException;
+import org.apache.guacamole.net.auth.User;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.directory.DirectoryObjectResource;
+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
+ * Users.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class UserDirectoryResource extends DirectoryResource<User, APIUser> {
+
+    /**
+     * The UserContext associated with the Directory which contains the
+     * User exposed by this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The Directory exposed by this resource.
+     */
+    private final Directory<User> directory;
+
+    /**
+     * A factory which can be used to create instances of resources representing
+     * Users.
+     */
+    private final DirectoryObjectResourceFactory<User, APIUser> resourceFactory;
+
+    /**
+     * Creates a new UserDirectoryResource which exposes the operations and
+     * subresources available for the given User Directory.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory being exposed.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles
+     *     Users.
+     *
+     * @param resourceFactory
+     *     A factory which can be used to create instances of resources
+     *     representing Users.
+     */
+    @AssistedInject
+    public UserDirectoryResource(@Assisted UserContext userContext,
+            @Assisted Directory<User> directory,
+            DirectoryObjectTranslator<User, APIUser> translator,
+            DirectoryObjectResourceFactory<User, APIUser> resourceFactory) {
+        super(userContext, directory, translator, resourceFactory);
+        this.userContext = userContext;
+        this.directory = directory;
+        this.resourceFactory = resourceFactory;
+    }
+
+    @Override
+    public DirectoryObjectResource<User, APIUser>
+        getObjectResource(String identifier) throws GuacamoleException {
+
+        // If username is own username, just use self - might not have query permissions
+        if (userContext.self().getIdentifier().equals(identifier))
+            return resourceFactory.create(userContext, directory, userContext.self());
+
+        return super.getObjectResource(identifier);
+
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/guacamole/src/main/java/org/apache/guacamole/rest/user/UserObjectTranslator.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserObjectTranslator.java
new file mode 100644
index 0000000..5098c35
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserObjectTranslator.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.rest.user;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.User;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+
+/**
+ * Translator which converts between User objects and APIUser objects.
+ *
+ * @author Michael Jumper
+ */
+public class UserObjectTranslator
+        implements DirectoryObjectTranslator<User, APIUser> {
+
+    @Override
+    public APIUser toExternalObject(User object)
+            throws GuacamoleException {
+        return new APIUser(object);
+    }
+
+    @Override
+    public User toInternalObject(APIUser object)
+            throws GuacamoleException {
+        return new APIUserWrapper(object);
+    }
+
+    @Override
+    public void applyExternalChanges(User existingObject,
+            APIUser object) throws GuacamoleException {
+
+        // Do not update the user password if no password was provided
+        if (object.getPassword() != null)
+            existingObject.setPassword(object.getPassword());
+
+        // Update user attributes
+        existingObject.setAttributes(object.getAttributes());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/guacamole/src/main/java/org/apache/guacamole/rest/user/UserRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserRESTService.java
deleted file mode 100644
index c446ddf..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserRESTService.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * 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.user;
-
-import com.google.inject.Inject;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleClientException;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleResourceNotFoundException;
-import org.apache.guacamole.GuacamoleSecurityException;
-import org.apache.guacamole.net.auth.AuthenticationProvider;
-import org.apache.guacamole.net.auth.Credentials;
-import org.apache.guacamole.net.auth.Directory;
-import org.apache.guacamole.net.auth.User;
-import org.apache.guacamole.net.auth.UserContext;
-import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException;
-import org.apache.guacamole.net.auth.permission.ObjectPermission;
-import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
-import org.apache.guacamole.net.auth.permission.Permission;
-import org.apache.guacamole.net.auth.permission.SystemPermission;
-import org.apache.guacamole.net.auth.permission.SystemPermissionSet;
-import org.apache.guacamole.GuacamoleSession;
-import org.apache.guacamole.rest.APIPatch;
-import static org.apache.guacamole.rest.APIPatch.Operation.add;
-import static org.apache.guacamole.rest.APIPatch.Operation.remove;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.PATCH;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.apache.guacamole.rest.permission.APIPermissionSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A REST Service for handling user CRUD operations.
- * 
- * @author James Muehlner
- * @author Michael Jumper
- */
-@Path("/data/{dataSource}/users")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class UserRESTService {
-
-    /**
-     * Logger for this class.
-     */
-    private static final Logger logger = LoggerFactory.getLogger(UserRESTService.class);
-
-    /**
-     * The prefix of any path within an operation of a JSON patch which
-     * modifies the permissions of a user regarding a specific connection.
-     */
-    private static final String CONNECTION_PERMISSION_PATCH_PATH_PREFIX = "/connectionPermissions/";
-    
-    /**
-     * The prefix of any path within an operation of a JSON patch which
-     * modifies the permissions of a user regarding a specific connection group.
-     */
-    private static final String CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX = "/connectionGroupPermissions/";
-
-    /**
-     * 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/";
-
-    /**
-     * The prefix of any path within an operation of a JSON patch which
-     * modifies the permissions of a user regarding another, specific user.
-     */
-    private static final String USER_PERMISSION_PATCH_PATH_PREFIX = "/userPermissions/";
-
-    /**
-     * The path of any operation within a JSON patch which modifies the
-     * permissions of a user regarding the entire system.
-     */
-    private static final String SYSTEM_PERMISSION_PATCH_PATH = "/systemPermissions";
-    
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-    
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
-     * Gets a list of users in the given data source (UserContext), filtering
-     * the returned list by the given permission, if specified.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext from which the users are to be retrieved.
-     *
-     * @param permissions
-     *     The set of permissions to filter with. A user must have one or more
-     *     of these permissions for a user to appear in the result.
-     *     If null, no filtering will be performed.
-     *
-     * @return
-     *     A list of all visible users. If a permission was specified, this
-     *     list will contain only those users for whom the current user has
-     *     that permission.
-     *
-     * @throws GuacamoleException
-     *     If an error is encountered while retrieving users.
-     */
-    @GET
-    public List<APIUser> getUsers(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @QueryParam("permission") List<ObjectPermission.Type> permissions)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // An admin user has access to any user
-        User self = userContext.self();
-        SystemPermissionSet systemPermissions = self.getSystemPermissions();
-        boolean isAdmin = systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER);
-
-        // Get the directory
-        Directory<User> userDirectory = userContext.getUserDirectory();
-
-        // Filter users, if requested
-        Collection<String> userIdentifiers = userDirectory.getIdentifiers();
-        if (!isAdmin && permissions != null && !permissions.isEmpty()) {
-            ObjectPermissionSet userPermissions = self.getUserPermissions();
-            userIdentifiers = userPermissions.getAccessibleObjects(permissions, userIdentifiers);
-        }
-            
-        // Retrieve all users, converting to API users
-        List<APIUser> apiUsers = new ArrayList<APIUser>();
-        for (User user : userDirectory.getAll(userIdentifiers))
-            apiUsers.add(new APIUser(user));
-
-        return apiUsers;
-
-    }
-    
-    /**
-     * Retrieves an individual user.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext from which the requested user is to be retrieved.
-     *
-     * @param username
-     *     The username of the user to retrieve.
-     *
-     * @return user
-     *     The user having the given username.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving the user.
-     */
-    @GET
-    @Path("/{username}")
-    public APIUser getUser(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("username") String username)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-
-        // Retrieve the requested user
-        User user = retrievalService.retrieveUser(session, authProviderIdentifier, username);
-        return new APIUser(user);
-
-    }
-    
-    /**
-     * Creates a new user and returns the user that was created.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the requested user is to be created.
-     *
-     * @param user
-     *     The new user to create.
-     *
-     * @throws GuacamoleException
-     *     If a problem is encountered while creating the user.
-     *
-     * @return
-     *     The newly created user.
-     */
-    @POST
-    public APIUser createUser(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier, APIUser user)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get the directory
-        Directory<User> userDirectory = userContext.getUserDirectory();
-        
-        // Randomly set the password if it wasn't provided
-        if (user.getPassword() == null)
-            user.setPassword(UUID.randomUUID().toString());
-
-        // Create the user
-        userDirectory.add(new APIUserWrapper(user));
-
-        return user;
-
-    }
-    
-    /**
-     * Updates an individual existing user.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the requested user is to be updated.
-     *
-     * @param username
-     *     The username of the user to update.
-     *
-     * @param user
-     *     The data to update the user with.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while updating the user.
-     */
-    @PUT
-    @Path("/{username}")
-    public void updateUser(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("username") String username, APIUser user) 
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get the directory
-        Directory<User> userDirectory = userContext.getUserDirectory();
-
-        // Validate data and path are sane
-        if (!user.getUsername().equals(username))
-            throw new GuacamoleClientException("Username in path does not match username provided JSON data.");
-        
-        // A user may not use this endpoint to modify himself
-        if (userContext.self().getIdentifier().equals(user.getUsername()))
-            throw new GuacamoleSecurityException("Permission denied.");
-
-        // Get the user
-        User existingUser = retrievalService.retrieveUser(userContext, username);
-
-        // Do not update the user password if no password was provided
-        if (user.getPassword() != null)
-            existingUser.setPassword(user.getPassword());
-
-        // Update user attributes
-        existingUser.setAttributes(user.getAttributes());
-
-        // Update the user
-        userDirectory.update(existingUser);
-
-    }
-    
-    /**
-     * Updates the password for an individual existing user.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the requested user is to be updated.
-     *
-     * @param username
-     *     The username of the user to update.
-     *
-     * @param userPasswordUpdate
-     *     The object containing the old password for the user, as well as the
-     *     new password to set for that user.
-     *
-     * @param request
-     *     The HttpServletRequest associated with the password update attempt.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while updating the user's password.
-     */
-    @PUT
-    @Path("/{username}/password")
-    public void updatePassword(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("username") String username,
-            APIUserPasswordUpdate userPasswordUpdate,
-            @Context HttpServletRequest request) throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Build credentials
-        Credentials credentials = new Credentials();
-        credentials.setUsername(username);
-        credentials.setPassword(userPasswordUpdate.getOldPassword());
-        credentials.setRequest(request);
-        credentials.setSession(request.getSession(true));
-        
-        // Verify that the old password was correct
-        try {
-            AuthenticationProvider authProvider = userContext.getAuthenticationProvider();
-            if (authProvider.authenticateUser(credentials) == null)
-                throw new GuacamoleSecurityException("Permission denied.");
-        }
-
-        // Pass through any credentials exceptions as simple permission denied
-        catch (GuacamoleCredentialsException e) {
-            throw new GuacamoleSecurityException("Permission denied.");
-        }
-
-        // Get the user directory
-        Directory<User> userDirectory = userContext.getUserDirectory();
-        
-        // Get the user that we want to updates
-        User user = retrievalService.retrieveUser(userContext, username);
-        
-        // Set password to the newly provided one
-        user.setPassword(userPasswordUpdate.getNewPassword());
-        
-        // Update the user
-        userDirectory.update(user);
-        
-    }
-    
-    /**
-     * Deletes an individual existing user.
-     *
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext from which the requested user is to be deleted.
-     *
-     * @param username
-     *     The username of the user to delete.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while deleting the user.
-     */
-    @DELETE
-    @Path("/{username}")
-    public void deleteUser(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("username") String username) 
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get the directory
-        Directory<User> userDirectory = userContext.getUserDirectory();
-
-        // Get the user
-        User existingUser = userDirectory.get(username);
-        if (existingUser == null)
-            throw new GuacamoleResourceNotFoundException("No such user: \"" + username + "\"");
-
-        // Delete the user
-        userDirectory.remove(username);
-
-    }
-
-    /**
-     * Gets a list of permissions for the user with the given username.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the requested user is to be found.
-     *
-     * @param username
-     *     The username of the user to retrieve permissions for.
-     *
-     * @return
-     *     A list of all permissions granted to the specified user.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while retrieving permissions.
-     */
-    @GET
-    @Path("/{username}/permissions")
-    public APIPermissionSet getPermissions(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("username") String username) 
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        User user;
-
-        // If username is own username, just use self - might not have query permissions
-        if (userContext.self().getIdentifier().equals(username))
-            user = userContext.self();
-
-        // If not self, query corresponding user from directory
-        else {
-            user = userContext.getUserDirectory().get(username);
-            if (user == null)
-                throw new GuacamoleResourceNotFoundException("No such user: \"" + username + "\"");
-        }
-
-        return new APIPermissionSet(user);
-
-    }
-
-    /**
-     * Updates the given permission set patch by queuing an add or remove
-     * operation for the given permission based on the given patch operation.
-     *
-     * @param <PermissionType>
-     *     The type of permission stored within the permission set.
-     *
-     * @param operation
-     *     The patch operation to perform.
-     *
-     * @param permissionSetPatch
-     *     The permission set patch being modified.
-     *
-     * @param permission
-     *     The permission being added or removed from the set.
-     *
-     * @throws GuacamoleException
-     *     If the requested patch operation is not supported.
-     */
-    private <PermissionType extends Permission> void updatePermissionSet(
-            APIPatch.Operation operation,
-            PermissionSetPatch<PermissionType> permissionSetPatch,
-            PermissionType permission) throws GuacamoleException {
-
-        // Add or remove permission based on operation
-        switch (operation) {
-
-            // Add permission
-            case add:
-                permissionSetPatch.addPermission(permission);
-                break;
-
-            // Remove permission
-            case remove:
-                permissionSetPatch.removePermission(permission);
-                break;
-
-            // Unsupported patch operation
-            default:
-                throw new GuacamoleClientException("Unsupported patch operation: \"" + operation + "\"");
-
-        }
-
-    }
-    
-    /**
-     * Applies a given list of permission patches. Each patch specifies either
-     * an "add" or a "remove" operation for a permission type, represented by
-     * a string. Valid permission types depend on the path of each patch
-     * operation, as the path dictates the permission being modified, such as
-     * "/connectionPermissions/42" or "/systemPermissions".
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext in which the requested user is to be found.
-     *
-     * @param username
-     *     The username of the user to modify the permissions of.
-     *
-     * @param patches
-     *     The permission patches to apply for this request.
-     *
-     * @throws GuacamoleException
-     *     If a problem is encountered while modifying permissions.
-     */
-    @PATCH
-    @Path("/{username}/permissions")
-    public void patchPermissions(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @PathParam("username") String username,
-            List<APIPatch<String>> patches) throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get the user
-        User user = userContext.getUserDirectory().get(username);
-        if (user == null)
-            throw new GuacamoleResourceNotFoundException("No such user: \"" + username + "\"");
-
-        // Permission patches for all types of permissions
-        PermissionSetPatch<ObjectPermission> connectionPermissionPatch       = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<ObjectPermission> connectionGroupPermissionPatch  = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<ObjectPermission> activeConnectionPermissionPatch = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<ObjectPermission> userPermissionPatch             = new PermissionSetPatch<ObjectPermission>();
-        PermissionSetPatch<SystemPermission> systemPermissionPatch           = new PermissionSetPatch<SystemPermission>();
-        
-        // Apply all patch operations individually
-        for (APIPatch<String> patch : patches) {
-
-            String path = patch.getPath();
-
-            // Create connection permission if path has connection prefix
-            if (path.startsWith(CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(CONNECTION_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(), connectionPermissionPatch, permission);
-                
-            }
-
-            // Create connection group permission if path has connection group prefix
-            else if (path.startsWith(CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(CONNECTION_GROUP_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(), connectionGroupPermissionPatch, permission);
-                
-            }
-
-            // Create active connection permission if path has active connection prefix
-            else if (path.startsWith(ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(ACTIVE_CONNECTION_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(), activeConnectionPermissionPatch, permission);
-                
-            }
-
-            // Create user permission if path has user prefix
-            else if (path.startsWith(USER_PERMISSION_PATCH_PATH_PREFIX)) {
-
-                // Get identifier and type from patch operation
-                String identifier = path.substring(USER_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(), userPermissionPatch, permission);
-
-            }
-
-            // Create system permission if path is system path
-            else if (path.equals(SYSTEM_PERMISSION_PATCH_PATH)) {
-
-                // Get identifier and type from patch operation
-                SystemPermission.Type type = SystemPermission.Type.valueOf(patch.getValue());
-
-                // Create and update corresponding permission
-                SystemPermission permission = new SystemPermission(type);
-                updatePermissionSet(patch.getOp(), systemPermissionPatch, permission);
-                
-            }
-
-            // Otherwise, the path is not supported
-            else
-                throw new GuacamoleClientException("Unsupported patch path: \"" + path + "\"");
-
-        } // end for each patch operation
-        
-        // Save the permission changes
-        connectionPermissionPatch.apply(user.getConnectionPermissions());
-        connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions());
-        activeConnectionPermissionPatch.apply(user.getActiveConnectionPermissions());
-        userPermissionPatch.apply(user.getUserPermissions());
-        systemPermissionPatch.apply(user.getSystemPermissions());
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
new file mode 100644
index 0000000..77009b6
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/UserResource.java
@@ -0,0 +1,329 @@
+/*
+ * 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.user;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import org.apache.guacamole.GuacamoleClientException;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleSecurityException;
+import org.apache.guacamole.net.auth.AuthenticationProvider;
+import org.apache.guacamole.net.auth.Credentials;
+import org.apache.guacamole.net.auth.User;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException;
+import org.apache.guacamole.net.auth.permission.ObjectPermission;
+import org.apache.guacamole.net.auth.permission.Permission;
+import org.apache.guacamole.net.auth.permission.SystemPermission;
+import org.apache.guacamole.rest.APIPatch;
+import org.apache.guacamole.rest.PATCH;
+import org.apache.guacamole.rest.directory.DirectoryObjectResource;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+import org.apache.guacamole.rest.permission.APIPermissionSet;
+
+/**
+ * A REST resource which abstracts the operations available on an existing
+ * User.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class UserResource
+        extends DirectoryObjectResource<User, APIUser> {
+
+    /**
+     * The UserContext associated with the Directory which contains the User
+     * exposed by this resource.
+     */
+    private final UserContext userContext;
+
+    /**
+     * The Directory which contains the User object represented by this
+     * UserResource.
+     */
+    private final Directory<User> directory;
+
+    /**
+     * The User object represented by this UserResource.
+     */
+    private final User user;
+
+    /**
+     * Creates a new UserResource which exposes the operations and subresources
+     * available for the given User.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory which contains the given User.
+     *
+     * @param user
+     *     The User that this UserResource should represent.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles Users.
+     */
+    @AssistedInject
+    public UserResource(@Assisted UserContext userContext,
+            @Assisted Directory<User> directory,
+            @Assisted User user,
+            DirectoryObjectTranslator<User, APIUser> translator) {
+        super(directory, user, translator);
+        this.userContext = userContext;
+        this.directory = directory;
+        this.user = user;
+    }
+
+    @Override
+    public void updateObject(APIUser modifiedObject) throws GuacamoleException {
+
+        // A user may not use this endpoint to modify himself
+        if (userContext.self().getIdentifier().equals(modifiedObject.getUsername()))
+            throw new GuacamoleSecurityException("Permission denied.");
+
+        super.updateObject(modifiedObject);
+
+    }
+
+    /**
+     * Updates the password for an individual existing user.
+     *
+     * @param userPasswordUpdate
+     *     The object containing the old password for the user, as well as the
+     *     new password to set for that user.
+     *
+     * @param request
+     *     The HttpServletRequest associated with the password update attempt.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while updating the user's password.
+     */
+    @PUT
+    @Path("password")
+    public void updatePassword(APIUserPasswordUpdate userPasswordUpdate,
+            @Context HttpServletRequest request) throws GuacamoleException {
+
+        // Build credentials
+        Credentials credentials = new Credentials();
+        credentials.setUsername(user.getIdentifier());
+        credentials.setPassword(userPasswordUpdate.getOldPassword());
+        credentials.setRequest(request);
+        credentials.setSession(request.getSession(true));
+
+        // Verify that the old password was correct
+        try {
+            AuthenticationProvider authProvider = userContext.getAuthenticationProvider();
+            if (authProvider.authenticateUser(credentials) == null)
+                throw new GuacamoleSecurityException("Permission denied.");
+        }
+
+        // Pass through any credentials exceptions as simple permission denied
+        catch (GuacamoleCredentialsException e) {
+            throw new GuacamoleSecurityException("Permission denied.");
+        }
+
+        // Set password to the newly provided one
+        user.setPassword(userPasswordUpdate.getNewPassword());
+        directory.update(user);
+
+    }
+
+    /**
+     * Gets a list of permissions for the user with the given username.
+     *
+     * @return
+     *     A list of all permissions granted to the specified user.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving permissions.
+     */
+    @GET
+    @Path("permissions")
+    public APIPermissionSet getPermissions() throws GuacamoleException {
+        return new APIPermissionSet(user);
+    }
+
+    /**
+     * Updates the given permission set patch by queuing an add or remove
+     * operation for the given permission based on the given patch operation.
+     *
+     * @param <PermissionType>
+     *     The type of permission stored within the permission set.
+     *
+     * @param operation
+     *     The patch operation to perform.
+     *
+     * @param permissionSetPatch
+     *     The permission set patch being modified.
+     *
+     * @param permission
+     *     The permission being added or removed from the set.
+     *
+     * @throws GuacamoleException
+     *     If the requested patch operation is not supported.
+     */
+    private <PermissionType extends Permission> void updatePermissionSet(
+            APIPatch.Operation operation,
+            PermissionSetPatch<PermissionType> permissionSetPatch,
+            PermissionType permission) throws GuacamoleException {
+
+        // Add or remove permission based on operation
+        switch (operation) {
+
+            // Add permission
+            case add:
+                permissionSetPatch.addPermission(permission);
+                break;
+
+            // Remove permission
+            case remove:
+                permissionSetPatch.removePermission(permission);
+                break;
+
+            // Unsupported patch operation
+            default:
+                throw new GuacamoleClientException("Unsupported patch operation: \"" + operation + "\"");
+
+        }
+
+    }
+
+    /**
+     * Applies a given list of permission patches. Each patch specifies either
+     * an "add" or a "remove" operation for a permission type, represented by
+     * a string. Valid permission types depend on the path of each patch
+     * operation, as the path dictates the permission being modified, such as
+     * "/connectionPermissions/42" or "/systemPermissions".
+     *
+     * @param patches
+     *     The permission patches to apply for this request.
+     *
+     * @throws GuacamoleException
+     *     If a problem is encountered while modifying permissions.
+     */
+    @PATCH
+    @Path("permissions")
+    public void patchPermissions(List<APIPatch<String>> patches)
+            throws GuacamoleException {
+
+        // Permission patches for all types of permissions
+        PermissionSetPatch<ObjectPermission> connectionPermissionPatch       = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> connectionGroupPermissionPatch  = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> activeConnectionPermissionPatch = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<ObjectPermission> userPermissionPatch             = new PermissionSetPatch<ObjectPermission>();
+        PermissionSetPatch<SystemPermission> systemPermissionPatch           = new PermissionSetPatch<SystemPermission>();
+
+        // Apply all patch operations individually
+        for (APIPatch<String> patch : patches) {
+
+            String path = patch.getPath();
+
+            // Create connection permission if path has connection prefix
+            if (path.startsWith(CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(CONNECTION_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(), connectionPermissionPatch, permission);
+
+            }
+
+            // Create connection group permission if path has connection group prefix
+            else if (path.startsWith(CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(CONNECTION_GROUP_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(), connectionGroupPermissionPatch, permission);
+
+            }
+
+            // Create active connection permission if path has active connection prefix
+            else if (path.startsWith(ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(ACTIVE_CONNECTION_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(), activeConnectionPermissionPatch, permission);
+
+            }
+
+            // Create user permission if path has user prefix
+            else if (path.startsWith(USER_PERMISSION_PATCH_PATH_PREFIX)) {
+
+                // Get identifier and type from patch operation
+                String identifier = path.substring(USER_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(), userPermissionPatch, permission);
+
+            }
+
+            // Create system permission if path is system path
+            else if (path.equals(SYSTEM_PERMISSION_PATCH_PATH)) {
+
+                // Get identifier and type from patch operation
+                SystemPermission.Type type = SystemPermission.Type.valueOf(patch.getValue());
+
+                // Create and update corresponding permission
+                SystemPermission permission = new SystemPermission(type);
+                updatePermissionSet(patch.getOp(), systemPermissionPatch, permission);
+
+            }
+
+            // Otherwise, the path is not supported
+            else
+                throw new GuacamoleClientException("Unsupported patch path: \"" + path + "\"");
+
+        } // end for each patch operation
+
+        // Save the permission changes
+        connectionPermissionPatch.apply(user.getConnectionPermissions());
+        connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions());
+        activeConnectionPermissionPatch.apply(user.getActiveConnectionPermissions());
+        userPermissionPatch.apply(user.getUserPermissions());
+        systemPermissionPatch.apply(user.getSystemPermissions());
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/guacamole/src/main/webapp/app/rest/services/userService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js
index bd12462..3953f89 100644
--- a/guacamole/src/main/webapp/app/rest/services/userService.js
+++ b/guacamole/src/main/webapp/app/rest/services/userService.js
@@ -50,9 +50,10 @@ angular.module('rest').factory('userService', ['$injector',
      *     If null, no filtering will be performed. Valid values are listed
      *     within PermissionSet.ObjectType.
      *                          
-     * @returns {Promise.<User[]>}
-     *     A promise which will resolve with an array of @link{User} objects
-     *     upon success.
+     * @returns {Promise.<Object.<String, User>>}
+     *     A promise which will resolve with a map of @link{User} objects
+     *     where each key is the identifier (username) of the corresponding
+     *     user.
      */
     service.getUsers = function getUsers(dataSource, permissionTypes) {
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/374ad3eb/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
index fe15b14..cc134fa 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
@@ -227,14 +227,14 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
                         PermissionSet.ObjectPermissionType.DELETE
                     ]);
 
-                userPromise.then(function usersReceived(userArrays) {
+                userPromise.then(function usersReceived(allUsers) {
 
                     var addedUsers = {};
                     $scope.manageableUsers = [];
 
                     // For each user in each data source
                     angular.forEach(dataSources, function addUserList(dataSource) {
-                        angular.forEach(userArrays[dataSource], function addUser(user) {
+                        angular.forEach(allUsers[dataSource], function addUser(user) {
 
                             // Do not add the same user twice
                             if (addedUsers[user.username])


[06/24] incubator-guacamole-client git commit: GUACAMOLE-5: Replace ActiveConnectionRESTService with new resource-driven implementation.

Posted by jm...@apache.org.
GUACAMOLE-5: Replace ActiveConnectionRESTService with new resource-driven implementation.


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

Branch: refs/heads/master
Commit: 61d581ef0dced3ec1bf13d15de26a1980cc30413
Parents: 71c2b4e
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Jul 12 12:25:24 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jul 12 14:53:24 2016 -0700

----------------------------------------------------------------------
 .../guacamole/rest/RESTServiceModule.java       |   4 +-
 .../ActiveConnectionModule.java                 |  60 ++++++
 .../ActiveConnectionObjectTranslator.java       |  61 ++++++
 .../ActiveConnectionRESTService.java            | 193 -------------------
 .../ActiveConnectionResource.java               |  70 +++++++
 .../rest/activeconnection/package-info.java     |  24 +++
 .../rest/session/UserContextResource.java       |  28 +++
 7 files changed, 245 insertions(+), 195 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/61d581ef/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 c40224e..d0c9bd6 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java
@@ -27,9 +27,9 @@ import com.google.inject.matcher.Matchers;
 import com.google.inject.servlet.ServletModule;
 import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
 import org.aopalliance.intercept.MethodInterceptor;
+import org.apache.guacamole.rest.activeconnection.ActiveConnectionModule;
 import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
 import org.apache.guacamole.rest.auth.TokenRESTService;
-import org.apache.guacamole.rest.activeconnection.ActiveConnectionRESTService;
 import org.apache.guacamole.rest.auth.AuthTokenGenerator;
 import org.apache.guacamole.rest.auth.AuthenticationService;
 import org.apache.guacamole.rest.auth.SecureRandomAuthTokenGenerator;
@@ -88,7 +88,6 @@ public class RESTServiceModule extends ServletModule {
         bind(ObjectRetrievalService.class);
 
         // Set up the API endpoints
-        bind(ActiveConnectionRESTService.class);
         bind(HistoryRESTService.class);
         bind(LanguageRESTService.class);
         bind(PatchRESTService.class);
@@ -102,6 +101,7 @@ public class RESTServiceModule extends ServletModule {
         install(new FactoryModuleBuilder().build(UserContextResourceFactory.class));
 
         // Resources below root
+        install(new ActiveConnectionModule());
         install(new ConnectionModule());
         install(new ConnectionGroupModule());
 

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

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/61d581ef/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionObjectTranslator.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionObjectTranslator.java
new file mode 100644
index 0000000..f0f9ed3
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionObjectTranslator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.activeconnection;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleUnsupportedException;
+import org.apache.guacamole.net.auth.ActiveConnection;
+import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
+
+/**
+ * Translator which converts between ActiveConnection objects and
+ * APIActiveConnection objects. As ActiveConnection objects are read-only, only
+ * toExternalObject() is implemented here.
+ *
+ * @author Michael Jumper
+ */
+public class ActiveConnectionObjectTranslator
+        implements DirectoryObjectTranslator<ActiveConnection, APIActiveConnection> {
+
+    @Override
+    public APIActiveConnection toExternalObject(ActiveConnection object)
+            throws GuacamoleException {
+        return new APIActiveConnection(object);
+    }
+
+    @Override
+    public ActiveConnection toInternalObject(APIActiveConnection object)
+            throws GuacamoleException {
+
+        // ActiveConnection objects are read-only
+        throw new GuacamoleUnsupportedException("Active connection records are read-only.");
+
+    }
+
+    @Override
+    public void applyExternalChanges(ActiveConnection existingObject,
+            APIActiveConnection object) throws GuacamoleException {
+
+        // Modification not supported for ActiveConnection
+        throw new GuacamoleUnsupportedException("Active connection records are read-only.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/61d581ef/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionRESTService.java
deleted file mode 100644
index dd73916..0000000
--- a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionRESTService.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.activeconnection;
-
-import com.google.inject.Inject;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.GuacamoleClientException;
-import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleUnsupportedException;
-import org.apache.guacamole.net.auth.ActiveConnection;
-import org.apache.guacamole.net.auth.Directory;
-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.GuacamoleSession;
-import org.apache.guacamole.rest.APIPatch;
-import org.apache.guacamole.rest.ObjectRetrievalService;
-import org.apache.guacamole.rest.PATCH;
-import org.apache.guacamole.rest.auth.AuthenticationService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A REST Service for retrieving and managing the tunnels of active connections.
- * 
- * @author Michael Jumper
- */
-@Path("/data/{dataSource}/activeConnections")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class ActiveConnectionRESTService {
-
-    /**
-     * Logger for this class.
-     */
-    private static final Logger logger = LoggerFactory.getLogger(ActiveConnectionRESTService.class);
-
-    /**
-     * A service for authenticating users from auth tokens.
-     */
-    @Inject
-    private AuthenticationService authenticationService;
-
-    /**
-     * Service for convenient retrieval of objects.
-     */
-    @Inject
-    private ObjectRetrievalService retrievalService;
-
-    /**
-     * Gets a list of active connections in the system, filtering the returned
-     * list by the given permissions, if specified.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the active connections to be retrieved.
-     *
-     * @param permissions
-     *     The set of permissions to filter with. A user must have one or more
-     *     of these permissions for a user to appear in the result. 
-     *     If null, no filtering will be performed.
-     * 
-     * @return
-     *     A list of all active connections. If a permission was specified,
-     *     this list will contain only those active connections for which the
-     *     current user has that permission.
-     * 
-     * @throws GuacamoleException
-     *     If an error is encountered while retrieving active connections.
-     */
-    @GET
-    public Map<String, APIActiveConnection> getActiveConnections(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            @QueryParam("permission") List<ObjectPermission.Type> permissions)
-            throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-        User self = userContext.self();
-        
-        // Do not filter on permissions if no permissions are specified
-        if (permissions != null && permissions.isEmpty())
-            permissions = null;
-
-        // An admin user has access to any connection
-        SystemPermissionSet systemPermissions = self.getSystemPermissions();
-        boolean isAdmin = systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER);
-
-        // Get the directory
-        Directory<ActiveConnection> activeConnectionDirectory = userContext.getActiveConnectionDirectory();
-
-        // Filter connections, if requested
-        Collection<String> activeConnectionIdentifiers = activeConnectionDirectory.getIdentifiers();
-        if (!isAdmin && permissions != null) {
-            ObjectPermissionSet activeConnectionPermissions = self.getActiveConnectionPermissions();
-            activeConnectionIdentifiers = activeConnectionPermissions.getAccessibleObjects(permissions, activeConnectionIdentifiers);
-        }
-            
-        // Retrieve all active connections , converting to API active connections
-        Map<String, APIActiveConnection> apiActiveConnections = new HashMap<String, APIActiveConnection>();
-        for (ActiveConnection activeConnection : activeConnectionDirectory.getAll(activeConnectionIdentifiers))
-            apiActiveConnections.put(activeConnection.getIdentifier(), new APIActiveConnection(activeConnection));
-
-        return apiActiveConnections;
-
-    }
-
-    /**
-     * Applies the given active connection patches. This operation currently
-     * only supports deletion of active connections through the "remove" patch
-     * operation. Deleting an active connection effectively kills the
-     * connection. The path of each patch operation is of the form "/ID"
-     * where ID is the identifier of the active connection being modified.
-     * 
-     * @param authToken
-     *     The authentication token that is used to authenticate the user
-     *     performing the operation.
-     *
-     * @param authProviderIdentifier
-     *     The unique identifier of the AuthenticationProvider associated with
-     *     the UserContext containing the active connections to be deleted.
-     *
-     * @param patches
-     *     The active connection patches to apply for this request.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while deleting the active connections.
-     */
-    @PATCH
-    public void patchTunnels(@QueryParam("token") String authToken,
-            @PathParam("dataSource") String authProviderIdentifier,
-            List<APIPatch<String>> patches) throws GuacamoleException {
-
-        GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
-        UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
-
-        // Get the directory
-        Directory<ActiveConnection> activeConnectionDirectory = userContext.getActiveConnectionDirectory();
-
-        // Close each connection listed for removal
-        for (APIPatch<String> patch : patches) {
-
-            // Only remove is supported
-            if (patch.getOp() != APIPatch.Operation.remove)
-                throw new GuacamoleUnsupportedException("Only the \"remove\" operation is supported when patching active connections.");
-
-            // Retrieve and validate path
-            String path = patch.getPath();
-            if (!path.startsWith("/"))
-                throw new GuacamoleClientException("Patch paths must start with \"/\".");
-
-            // Close connection 
-            activeConnectionDirectory.remove(path.substring(1));
-            
-        }
-        
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/61d581ef/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionResource.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionResource.java
new file mode 100644
index 0000000..d006416
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/ActiveConnectionResource.java
@@ -0,0 +1,70 @@
+/*
+ * 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.activeconnection;
+
+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.ActiveConnection;
+import org.apache.guacamole.net.auth.Directory;
+import org.apache.guacamole.net.auth.UserContext;
+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
+ * ActiveConnection.
+ *
+ * @author Michael Jumper
+ */
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class ActiveConnectionResource
+        extends DirectoryObjectResource<ActiveConnection, APIActiveConnection> {
+
+    /**
+     * Creates a new ActiveConnectionResource which exposes the operations and
+     * subresources available for the given ActiveConnection.
+     *
+     * @param userContext
+     *     The UserContext associated with the given Directory.
+     *
+     * @param directory
+     *     The Directory which contains the given ActiveConnection.
+     *
+     * @param connection
+     *     The ActiveConnection that this ActiveConnectionResource should
+     *     represent.
+     *
+     * @param translator
+     *     A DirectoryObjectTranslator implementation which handles
+     *     ActiveConnections.
+     */
+    @AssistedInject
+    public ActiveConnectionResource(@Assisted UserContext userContext,
+            @Assisted Directory<ActiveConnection> directory,
+            @Assisted ActiveConnection connection,
+            DirectoryObjectTranslator<ActiveConnection, APIActiveConnection> translator) {
+        super(directory, connection, translator);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/61d581ef/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/package-info.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/package-info.java b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/package-info.java
new file mode 100644
index 0000000..f5483db
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/activeconnection/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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 the manipulation of active connections via the Guacamole
+ * REST API.
+ */
+package org.apache.guacamole.rest.activeconnection;

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/61d581ef/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 e5d5cb5..9091e99 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
@@ -29,9 +29,11 @@ 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.net.auth.ActiveConnection;
 import org.apache.guacamole.net.auth.Connection;
 import org.apache.guacamole.net.auth.ConnectionGroup;
 import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.activeconnection.APIActiveConnection;
 import org.apache.guacamole.rest.connection.APIConnection;
 import org.apache.guacamole.rest.connectiongroup.APIConnectionGroup;
 
@@ -51,6 +53,14 @@ public class UserContextResource {
 
     /**
      * Factory for creating DirectoryResources which expose a given
+     * ActiveConnection Directory.
+     */
+    @Inject
+    private DirectoryResourceFactory<ActiveConnection, APIActiveConnection>
+            activeConnectionDirectoryResourceFactory;
+
+    /**
+     * Factory for creating DirectoryResources which expose a given
      * Connection Directory.
      */
     @Inject
@@ -79,6 +89,24 @@ public class UserContextResource {
     }
 
     /**
+     * Returns a new resource which represents the ActiveConnection Directory
+     * contained within the UserContext exposed by this UserContextResource.
+     *
+     * @return
+     *     A new resource which represents the ActiveConnection Directory
+     *     contained within the UserContext exposed by this UserContextResource.
+     *
+     * @throws GuacamoleException
+     *     If an error occurs while retrieving the ActiveConnection Directory.
+     */
+    @Path("activeConnections")
+    public DirectoryResource<ActiveConnection, APIActiveConnection>
+        getActiveConnectionDirectoryResource() throws GuacamoleException {
+        return activeConnectionDirectoryResourceFactory.create(userContext,
+                userContext.getActiveConnectionDirectory());
+    }
+
+    /**
      * Returns a new resource which represents the Connection Directory
      * contained within the UserContext exposed by this UserContextResource.
      *