From 4e3212f9fda500223f8b24f43f403d4bf540eb43 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 28 Jul 2016 17:16:03 -0700 Subject: [PATCH] GUACAMOLE-5: Use AuthenticationProviderService as the means of defining AuthenticationProvider behavior. --- .../AuthenticationProviderService.java | 78 ++--------------- ...va => InjectedAuthenticationProvider.java} | 54 ++++++------ .../JDBCAuthenticationProviderService.java | 85 +++++++++++++++++++ .../mysql/MySQLAuthenticationProvider.java | 14 ++- .../PostgreSQLAuthenticationProvider.java | 14 ++- 5 files changed, 140 insertions(+), 105 deletions(-) rename extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/{user => }/AuthenticationProviderService.java (51%) rename extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/{JDBCAuthenticationProvider.java => InjectedAuthenticationProvider.java} (62%) create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/AuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java similarity index 51% rename from extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/AuthenticationProviderService.java rename to extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java index 3e61cf536..a821bfa2d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java @@ -17,19 +17,13 @@ * under the License. */ -package org.apache.guacamole.auth.jdbc.user; +package org.apache.guacamole.auth.jdbc; -import com.google.inject.Inject; -import com.google.inject.Provider; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.auth.jdbc.sharing.ConnectionSharingService; -import org.apache.guacamole.auth.jdbc.sharing.SharedConnectionUser; -import org.apache.guacamole.auth.jdbc.sharing.SharedConnectionUserContext; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Credentials; -import org.apache.guacamole.net.auth.credentials.CredentialsInfo; -import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; +import org.apache.guacamole.net.auth.UserContext; /** * Service which authenticates users based on credentials and provides for @@ -38,31 +32,7 @@ import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsExce * * @author Michael Jumper */ -public class AuthenticationProviderService { - - /** - * Service for accessing users. - */ - @Inject - private UserService userService; - - /** - * Provider for retrieving UserContext instances. - */ - @Inject - private Provider userContextProvider; - - /** - * Provider for retrieving SharedConnectionUserContext instances. - */ - @Inject - private Provider sharedUserContextProvider; - - /** - * Service for sharing active connections. - */ - @Inject - private ConnectionSharingService sharingService; +public interface AuthenticationProviderService { /** * Authenticates the user having the given credentials, returning a new @@ -86,24 +56,7 @@ public class AuthenticationProviderService { * credentials are invalid or expired. */ public AuthenticatedUser authenticateUser(AuthenticationProvider authenticationProvider, - Credentials credentials) throws GuacamoleException { - - AuthenticatedUser user; - - // Check whether user is authenticating with a valid sharing key - user = sharingService.retrieveSharedConnectionUser(authenticationProvider, credentials); - if (user != null) - return user; - - // Authenticate user - user = userService.retrieveAuthenticatedUser(authenticationProvider, credentials); - if (user != null) - return user; - - // Otherwise, unauthorized - throw new GuacamoleInvalidCredentialsException("Invalid login", CredentialsInfo.USERNAME_PASSWORD); - - } + Credentials credentials) throws GuacamoleException; /** * Returning a new UserContext instance for the given already-authenticated @@ -121,26 +74,7 @@ public class AuthenticationProviderService { * If an error occurs during authentication, or if the given * credentials are invalid or expired. */ - public org.apache.guacamole.net.auth.UserContext getUserContext( - AuthenticatedUser authenticatedUser) throws GuacamoleException { - - // Produce sharing-specific user context if this is the user of a shared connection - if (authenticatedUser instanceof SharedConnectionUser) { - SharedConnectionUserContext context = sharedUserContextProvider.get(); - context.init((SharedConnectionUser) authenticatedUser); - return context; - } - - // Retrieve user account for already-authenticated user - ModeledUser user = userService.retrieveUser(authenticatedUser); - if (user == null) - return null; - - // Link to user context - UserContext context = userContextProvider.get(); - context.init(user.getCurrentUser()); - return context; - - } + public UserContext getUserContext(AuthenticatedUser authenticatedUser) + throws GuacamoleException; } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java similarity index 62% rename from extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProvider.java rename to extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java index ebacd13ce..cc25e4ac5 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProvider.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java @@ -24,48 +24,58 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.UserContext; -import org.apache.guacamole.auth.jdbc.user.AuthenticationProviderService; import org.apache.guacamole.net.auth.AuthenticatedUser; /** - * Provides a base implementation of an AuthenticationProvider which is backed - * by an arbitrary underlying database. It is up to the subclass implementation - * to configure the underlying database appropriately via Guice. + * Provides a base implementation of an AuthenticationProvider which delegates + * the various function calls to an underlying AuthenticationProviderService + * implementation. As such a service is injectable by Guice, this provides a + * means for Guice to (effectively) apply dependency injection to an + * AuthenticationProvider, even though it is the AuthenticationProvider that + * serves as the entry point. * - * @author James Muehlner * @author Michael Jumper */ -public abstract class JDBCAuthenticationProvider implements AuthenticationProvider { +public abstract class InjectedAuthenticationProvider implements AuthenticationProvider { /** - * Provider of the singleton Injector instance which will manage the object - * graph of this authentication provider. + * The AuthenticationProviderService to which all AuthenticationProvider + * calls will be delegated. */ - private final JDBCInjectorProvider injectorProvider; + private final AuthenticationProviderService authProviderService; /** - * Creates a new AuthenticationProvider that is backed by an arbitrary - * underlying database. + * Creates a new AuthenticationProvider that delegates all calls to an + * underlying AuthenticationProviderService. The behavior of the + * AuthenticationProvider is defined by the given + * AuthenticationProviderService implementation, which will be injected by + * the Guice Injector provided by the given JDBCInjectorProvider. * * @param injectorProvider * A JDBCInjectorProvider instance which provides singleton instances * of a Guice Injector, pre-configured to set up all injections and * access to the underlying database via MyBatis. + * + * @param authProviderServiceClass + * The AuthenticationProviderService implementation which defines the + * behavior of this AuthenticationProvider. + * + * @throws GuacamoleException + * If the Injector cannot be created due to an error. */ - public JDBCAuthenticationProvider(JDBCInjectorProvider injectorProvider) { - this.injectorProvider = injectorProvider; + public InjectedAuthenticationProvider(JDBCInjectorProvider injectorProvider, + Class authProviderServiceClass) + throws GuacamoleException { + + Injector injector = injectorProvider.get(); + authProviderService = injector.getInstance(authProviderServiceClass); + } @Override public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { - - Injector injector = injectorProvider.get(); - - // Create AuthenticatedUser based on credentials, if valid - AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class); return authProviderService.authenticateUser(this, credentials); - } @Override @@ -80,13 +90,7 @@ public abstract class JDBCAuthenticationProvider implements AuthenticationProvid @Override public UserContext getUserContext(AuthenticatedUser authenticatedUser) throws GuacamoleException { - - Injector injector = injectorProvider.get(); - - // Create UserContext based on credentials, if valid - AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class); return authProviderService.getUserContext(authenticatedUser); - } @Override diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java new file mode 100644 index 000000000..07b7382bb --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.auth.jdbc; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.user.ModeledUser; +import org.apache.guacamole.auth.jdbc.user.UserContext; +import org.apache.guacamole.auth.jdbc.user.UserService; +import org.apache.guacamole.net.auth.AuthenticatedUser; +import org.apache.guacamole.net.auth.AuthenticationProvider; +import org.apache.guacamole.net.auth.Credentials; +import org.apache.guacamole.net.auth.credentials.CredentialsInfo; +import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; + +/** + * AuthenticationProviderService implementation which authenticates users with + * a username/password pair, producing new UserContext objects which are backed + * by an underlying, arbitrary database. + * + * @author Michael Jumper + */ +public class JDBCAuthenticationProviderService implements AuthenticationProviderService { + + /** + * Service for accessing users. + */ + @Inject + private UserService userService; + + /** + * Provider for retrieving UserContext instances. + */ + @Inject + private Provider userContextProvider; + + @Override + public AuthenticatedUser authenticateUser(AuthenticationProvider authenticationProvider, + Credentials credentials) throws GuacamoleException { + + // Authenticate user + AuthenticatedUser user = userService.retrieveAuthenticatedUser(authenticationProvider, credentials); + if (user != null) + return user; + + // Otherwise, unauthorized + throw new GuacamoleInvalidCredentialsException("Invalid login", CredentialsInfo.USERNAME_PASSWORD); + + } + + @Override + public org.apache.guacamole.net.auth.UserContext getUserContext( + AuthenticatedUser authenticatedUser) throws GuacamoleException { + + // Retrieve user account for already-authenticated user + ModeledUser user = userService.retrieveUser(authenticatedUser); + if (user == null) + return null; + + // Link to user context + UserContext context = userContextProvider.get(); + context.init(user.getCurrentUser()); + return context; + + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProvider.java index e7521633b..e8ba3073b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProvider.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProvider.java @@ -19,7 +19,9 @@ package org.apache.guacamole.auth.mysql; -import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProvider; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.InjectedAuthenticationProvider; +import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderService; /** * Provides a MySQL based implementation of the AuthenticationProvider @@ -28,15 +30,19 @@ import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProvider; * @author James Muehlner * @author Michael Jumper */ -public class MySQLAuthenticationProvider extends JDBCAuthenticationProvider { +public class MySQLAuthenticationProvider extends InjectedAuthenticationProvider { /** * Creates a new MySQLAuthenticationProvider that reads and writes * authentication data to a MySQL database defined by properties in * guacamole.properties. + * + * @throws GuacamoleException + * If a required property is missing, or an error occurs while parsing + * a property. */ - public MySQLAuthenticationProvider() { - super(new MySQLInjectorProvider()); + public MySQLAuthenticationProvider() throws GuacamoleException { + super(new MySQLInjectorProvider(), JDBCAuthenticationProviderService.class); } @Override diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java index 1c4b816ca..f8ef00d9e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java @@ -19,7 +19,9 @@ package org.apache.guacamole.auth.postgresql; -import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProvider; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.InjectedAuthenticationProvider; +import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderService; /** * Provides a PostgreSQL-based implementation of the AuthenticationProvider @@ -28,15 +30,19 @@ import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProvider; * @author James Muehlner * @author Michael Jumper */ -public class PostgreSQLAuthenticationProvider extends JDBCAuthenticationProvider { +public class PostgreSQLAuthenticationProvider extends InjectedAuthenticationProvider { /** * Creates a new PostgreSQLAuthenticationProvider that reads and writes * authentication data to a PostgreSQL database defined by properties in * guacamole.properties. + * + * @throws GuacamoleException + * If a required property is missing, or an error occurs while parsing + * a property. */ - public PostgreSQLAuthenticationProvider() { - super(new PostgreSQLInjectorProvider()); + public PostgreSQLAuthenticationProvider() throws GuacamoleException { + super(new PostgreSQLInjectorProvider(), JDBCAuthenticationProviderService.class); } @Override