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 a94f83642..37086403e 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 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 000000000..e8c4d7509 --- /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); + + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java similarity index 77% rename from guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java rename to guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java index e21eaa41a..c9e9834f1 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionDataRESTService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/SessionResource.java @@ -20,34 +20,32 @@ 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.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 + * A REST resource 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 { +public class SessionResource { /** - * A service for authenticating users from auth tokens. + * The GuacamoleSession being exposed by this SessionResource. */ - @Inject - private AuthenticationService authenticationService; + private final GuacamoleSession session; /** * Service for convenient retrieval of objects. @@ -62,14 +60,23 @@ public class SessionDataRESTService { @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 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. @@ -79,17 +86,14 @@ public class SessionDataRESTService { * AuthenticationProvider having the given identifier. * * @throws GuacamoleException - * If the authentication token or AuthenticationProvider identifier are - * invalid. + * If the AuthenticationProvider identifier is invalid. */ - @Path("{dataSource}") + @Path("data/{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 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 000000000..eaa839451 --- /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); + +} diff --git a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js index 4ebb131f4..9c967be32 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 }); diff --git a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js index 3283102d2..0662e4d6e 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 }) diff --git a/guacamole/src/main/webapp/app/rest/services/connectionService.js b/guacamole/src/main/webapp/app/rest/services/connectionService.js index 7629cd141..7b63a7e21 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 }) diff --git a/guacamole/src/main/webapp/app/rest/services/historyService.js b/guacamole/src/main/webapp/app/rest/services/historyService.js index 717389ddb..c77c4ab80 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 }); diff --git a/guacamole/src/main/webapp/app/rest/services/permissionService.js b/guacamole/src/main/webapp/app/rest/services/permissionService.js index d398447e7..8a4184526 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 }) diff --git a/guacamole/src/main/webapp/app/rest/services/schemaService.js b/guacamole/src/main/webapp/app/rest/services/schemaService.js index 2c874ed28..f0db23fe0 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 }); diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js index 3953f89f8..659aed7b6 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,