mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-5: Merge REST resource refactor.
This commit is contained in:
@@ -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>
|
||||
|
@@ -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;
|
||||
@@ -126,6 +127,44 @@ public class GuacamoleSession {
|
||||
return Collections.unmodifiableList(userContexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,277 +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.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.
|
||||
*/
|
||||
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 + "\".");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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,9 +87,32 @@ 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;
|
||||
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
@@ -19,26 +19,27 @@
|
||||
|
||||
package org.apache.guacamole.rest;
|
||||
|
||||
import org.apache.guacamole.rest.session.UserContextResourceFactory;
|
||||
import org.apache.guacamole.rest.session.SessionRESTService;
|
||||
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;
|
||||
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.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.history.HistoryRESTService;
|
||||
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.UserRESTService;
|
||||
import org.apache.guacamole.rest.session.SessionResourceFactory;
|
||||
import org.apache.guacamole.rest.user.UserModule;
|
||||
|
||||
/**
|
||||
* A Guice Module to set up the servlet mappings and authentication-specific
|
||||
@@ -81,20 +82,21 @@ 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(ActiveConnectionRESTService.class);
|
||||
bind(ConnectionGroupRESTService.class);
|
||||
bind(ConnectionRESTService.class);
|
||||
bind(HistoryRESTService.class);
|
||||
bind(LanguageRESTService.class);
|
||||
bind(PatchRESTService.class);
|
||||
bind(SchemaRESTService.class);
|
||||
bind(TokenRESTService.class);
|
||||
bind(TunnelRESTService.class);
|
||||
bind(UserRESTService.class);
|
||||
|
||||
// Root-level resources
|
||||
bind(SessionRESTService.class);
|
||||
install(new FactoryModuleBuilder().build(SessionResourceFactory.class));
|
||||
install(new FactoryModuleBuilder().build(UserContextResourceFactory.class));
|
||||
|
||||
// Resources below root
|
||||
install(new ActiveConnectionModule());
|
||||
install(new ConnectionModule());
|
||||
install(new ConnectionGroupModule());
|
||||
install(new UserModule());
|
||||
|
||||
// Set up the servlet and JSON mappings
|
||||
bind(GuiceContainer.class);
|
||||
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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.");
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.GuacamoleClientException;
|
||||
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 {
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
@@ -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.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
|
||||
* 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 userContext
|
||||
* The UserContext which contains the given Directory.
|
||||
*
|
||||
* @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(UserContext userContext, Directory<InternalType> directory,
|
||||
InternalType object);
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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 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
|
||||
* 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);
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
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 {
|
||||
|
||||
// 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));
|
||||
|
||||
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(userContext, directory, object);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
@@ -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;
|
@@ -19,13 +19,11 @@
|
||||
|
||||
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;
|
||||
@@ -33,27 +31,16 @@ 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
|
||||
* A REST resource 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);
|
||||
public class HistoryResource {
|
||||
|
||||
/**
|
||||
* The maximum number of history records to return in any one response.
|
||||
@@ -61,30 +48,25 @@ public class HistoryRESTService {
|
||||
private static final int MAXIMUM_HISTORY_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* A service for authenticating users from auth tokens.
|
||||
* The UserContext whose associated connection history is being exposed.
|
||||
*/
|
||||
@Inject
|
||||
private AuthenticationService authenticationService;
|
||||
private final UserContext userContext;
|
||||
|
||||
/**
|
||||
* Service for convenient retrieval of objects.
|
||||
* Creates a new HistoryResource which exposes the connection history
|
||||
* associated with the given UserContext.
|
||||
*
|
||||
* @param userContext
|
||||
* The UserContext whose connection history should be exposed.
|
||||
*/
|
||||
@Inject
|
||||
private ObjectRetrievalService retrievalService;
|
||||
public HistoryResource(UserContext userContext) {
|
||||
this.userContext = userContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@@ -105,16 +87,12 @@ public class HistoryRESTService {
|
||||
* If an error occurs while retrieving the connection history.
|
||||
*/
|
||||
@GET
|
||||
@Path("/connections")
|
||||
public List<APIConnectionRecord> getConnectionHistory(@QueryParam("token") String authToken,
|
||||
@PathParam("dataSource") String authProviderIdentifier,
|
||||
@Path("connections")
|
||||
public List<APIConnectionRecord> getConnectionHistory(
|
||||
@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();
|
||||
|
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.rest.user;
|
||||
package org.apache.guacamole.rest.permission;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.tunnel.TunnelCollectionResource;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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 = session.getUserContext(authProviderIdentifier);
|
||||
|
||||
// Return a resource exposing the retrieved UserContext
|
||||
return userContextResourceFactory.create(userContext);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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.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.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.history.HistoryResource;
|
||||
import org.apache.guacamole.rest.schema.SchemaResource;
|
||||
import org.apache.guacamole.rest.user.APIUser;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
private DirectoryResourceFactory<Connection, APIConnection>
|
||||
connectionDirectoryResourceFactory;
|
||||
|
||||
/**
|
||||
* Factory for creating DirectoryResources which expose a given
|
||||
* ConnectionGroup Directory.
|
||||
*/
|
||||
@Inject
|
||||
private DirectoryResourceFactory<ConnectionGroup, APIConnectionGroup>
|
||||
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.
|
||||
*
|
||||
* @param userContext
|
||||
* The UserContext which should be exposed through this
|
||||
* UserContextResource.
|
||||
*/
|
||||
@AssistedInject
|
||||
public UserContextResource(@Assisted UserContext userContext) {
|
||||
this.userContext = userContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
@@ -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;
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.UUID;
|
||||
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 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 {
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
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.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.rest.directory.DirectoryObjectResource;
|
||||
import org.apache.guacamole.rest.directory.DirectoryObjectTranslator;
|
||||
import org.apache.guacamole.rest.permission.PermissionSetResource;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a resource which abstracts operations available on the overall
|
||||
* permissions granted to the User represented by this UserResource.
|
||||
*
|
||||
* @return
|
||||
* A resource which representing the permissions granted to the User
|
||||
* represented by this UserResource.
|
||||
*/
|
||||
@Path("permissions")
|
||||
public PermissionSetResource getPermissions() {
|
||||
return new PermissionSetResource(user);
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
@@ -61,12 +60,6 @@ public class TunnelRequestService {
|
||||
@Inject
|
||||
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 {
|
||||
|
||||
|
@@ -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
|
||||
});
|
||||
|
@@ -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
|
||||
})
|
||||
|
||||
|
@@ -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
|
||||
})
|
||||
|
||||
|
@@ -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
|
||||
});
|
||||
|
||||
|
@@ -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
|
||||
})
|
||||
|
@@ -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/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/schema/' + encodeURIComponent(dataSource) + '/connections/attributes',
|
||||
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/schema/' + encodeURIComponent(dataSource) + '/connectionGroups/attributes',
|
||||
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/schema/' + encodeURIComponent(dataSource) + '/protocols',
|
||||
url : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/protocols',
|
||||
params : httpParameters
|
||||
});
|
||||
|
||||
|
@@ -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());
|
||||
|
@@ -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) {
|
||||
|
||||
@@ -69,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
|
||||
});
|
||||
|
||||
@@ -102,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
|
||||
});
|
||||
|
||||
@@ -134,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
|
||||
})
|
||||
|
||||
@@ -172,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
|
||||
})
|
||||
@@ -210,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
|
||||
})
|
||||
@@ -255,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,
|
||||
|
@@ -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])
|
||||
|
Reference in New Issue
Block a user