Merge 1.2.0 changes back to master.

This commit is contained in:
Michael Jumper
2020-06-20 19:59:39 -07:00
15 changed files with 123 additions and 21 deletions

View File

@@ -27,6 +27,7 @@ import org.apache.guacamole.auth.jdbc.sharing.user.SharedAuthenticatedUser;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
import org.apache.guacamole.auth.jdbc.user.ModeledUserContext; import org.apache.guacamole.auth.jdbc.user.ModeledUserContext;
import org.apache.guacamole.auth.jdbc.user.PrivilegedModeledAuthenticatedUser;
import org.apache.guacamole.auth.jdbc.user.UserService; import org.apache.guacamole.auth.jdbc.user.UserService;
import org.apache.guacamole.language.TranslatableGuacamoleClientException; import org.apache.guacamole.language.TranslatableGuacamoleClientException;
import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticatedUser;
@@ -126,9 +127,15 @@ public class JDBCAuthenticationProviderService implements AuthenticationProvider
} }
// If no user account is found, and database-specific account // If no user account is found, and database-specific account
// restrictions do not apply, get an empty user. // restrictions do not apply, get a skeleton user.
else if (!databaseRestrictionsApplicable) { else if (!databaseRestrictionsApplicable) {
user = userService.retrieveSkeletonUser(authenticationProvider, authenticatedUser); user = userService.retrieveSkeletonUser(authenticationProvider, authenticatedUser);
// If auto account creation is enabled, add user to DB.
if (environment.autoCreateAbsentAccounts()) {
userService.createObject(new PrivilegedModeledAuthenticatedUser(user.getCurrentUser()), user);
}
} }
// Veto authentication result only if database-specific account // Veto authentication result only if database-specific account

View File

@@ -152,4 +152,20 @@ public abstract class JDBCEnvironment extends LocalEnvironment {
*/ */
public abstract boolean isRecursiveQuerySupported(SqlSession session); public abstract boolean isRecursiveQuerySupported(SqlSession session);
/**
* Returns a boolean value representing whether or not the JDBC module
* should automatically create accounts within the database for users that
* are successfully authenticated via other extensions. Returns true if
* accounts should be auto-created, otherwise returns false.
*
* @return
* true if user accounts should be automatically created within the
* database when authentication succeeds from another extension;
* otherwise false.
*
* @throws GuacamoleException
* If guacamole.properties cannot be parsed.
*/
public abstract boolean autoCreateAbsentAccounts() throws GuacamoleException;
} }

View File

@@ -410,9 +410,9 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
} }
/** /**
* Returns a collection of permissions that should be granted due to the * Returns an immutable collection of permissions that should be granted due
* creation of the given object. These permissions need not be granted * to the creation of the given object. These permissions need not be
* solely to the user creating the object. * granted solely to the user creating the object.
* *
* @param user * @param user
* The user creating the object. * The user creating the object.
@@ -427,11 +427,19 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
protected Collection<ObjectPermissionModel> getImplicitPermissions(ModeledAuthenticatedUser user, protected Collection<ObjectPermissionModel> getImplicitPermissions(ModeledAuthenticatedUser user,
ModelType model) { ModelType model) {
// Check to see if the user granting permissions is a skeleton user,
// thus lacking database backing.
if (user.getUser().isSkeleton())
return Collections.emptyList();
// Get the user model and check for an entity ID.
UserModel userModel = user.getUser().getModel();
// Build list of implicit permissions // Build list of implicit permissions
Collection<ObjectPermissionModel> implicitPermissions = Collection<ObjectPermissionModel> implicitPermissions =
new ArrayList<ObjectPermissionModel>(IMPLICIT_OBJECT_PERMISSIONS.length); new ArrayList<>(IMPLICIT_OBJECT_PERMISSIONS.length);
UserModel userModel = user.getUser().getModel();
for (ObjectPermission.Type permission : IMPLICIT_OBJECT_PERMISSIONS) { for (ObjectPermission.Type permission : IMPLICIT_OBJECT_PERMISSIONS) {
// Create model which grants this permission to the current user // Create model which grants this permission to the current user
@@ -445,7 +453,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
} }
return implicitPermissions; return Collections.unmodifiableCollection(implicitPermissions);
} }
@@ -464,7 +472,9 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
object.setIdentifier(model.getIdentifier()); object.setIdentifier(model.getIdentifier());
// Add implicit permissions // Add implicit permissions
getPermissionMapper().insert(getImplicitPermissions(user, model)); Collection<ObjectPermissionModel> implicitPermissions = getImplicitPermissions(user, model);
if (!implicitPermissions.isEmpty())
getPermissionMapper().insert(implicitPermissions);
// Add any arbitrary attributes // Add any arbitrary attributes
if (model.hasArbitraryAttributes()) if (model.hasArbitraryAttributes())

View File

@@ -764,4 +764,15 @@ public class ModeledUser extends ModeledPermissions<UserModel> implements User {
return super.getEffective(); return super.getEffective();
} }
/**
* Returns true if this user is a skeleton user, lacking a database entity
* entry.
*
* @return
* True if this user is a skeleton user, otherwise false.
*/
public boolean isSkeleton() {
return (getModel().getEntityID() == null);
}
} }

View File

@@ -296,8 +296,9 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
protected Collection<ObjectPermissionModel> protected Collection<ObjectPermissionModel>
getImplicitPermissions(ModeledAuthenticatedUser user, UserModel model) { getImplicitPermissions(ModeledAuthenticatedUser user, UserModel model) {
// Get original set of implicit permissions // Get original set of implicit permissions and make a copy
Collection<ObjectPermissionModel> implicitPermissions = super.getImplicitPermissions(user, model); Collection<ObjectPermissionModel> implicitPermissions =
new ArrayList<>(super.getImplicitPermissions(user, model));
// Grant implicit permissions to the new user // Grant implicit permissions to the new user
for (ObjectPermission.Type permissionType : IMPLICIT_USER_PERMISSIONS) { for (ObjectPermission.Type permissionType : IMPLICIT_USER_PERMISSIONS) {
@@ -312,7 +313,7 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
} }
return implicitPermissions; return Collections.unmodifiableCollection(implicitPermissions);
} }
@Override @Override
@@ -407,11 +408,8 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
if (authenticatedUser instanceof ModeledAuthenticatedUser) if (authenticatedUser instanceof ModeledAuthenticatedUser)
return ((ModeledAuthenticatedUser) authenticatedUser).getUser(); return ((ModeledAuthenticatedUser) authenticatedUser).getUser();
// Get username
String username = authenticatedUser.getIdentifier();
// Retrieve corresponding user model, if such a user exists // Retrieve corresponding user model, if such a user exists
UserModel userModel = userMapper.selectOne(username); UserModel userModel = userMapper.selectOne(authenticatedUser.getIdentifier());
if (userModel == null) if (userModel == null)
return null; return null;

View File

@@ -387,4 +387,10 @@ public class MySQLEnvironment extends JDBCEnvironment {
return getProperty(MySQLGuacamoleProperties.MYSQL_SSL_TRUST_PASSWORD); return getProperty(MySQLGuacamoleProperties.MYSQL_SSL_TRUST_PASSWORD);
} }
@Override
public boolean autoCreateAbsentAccounts() throws GuacamoleException {
return getProperty(MySQLGuacamoleProperties.MYSQL_AUTO_CREATE_ACCOUNTS,
false);
}
} }

View File

@@ -241,4 +241,17 @@ public class MySQLGuacamoleProperties {
}; };
/**
* Whether or not to automatically create accounts in the MySQL database for
* users who successfully authenticate through another extension. By default
* users will not be automatically created.
*/
public static final BooleanGuacamoleProperty MYSQL_AUTO_CREATE_ACCOUNTS =
new BooleanGuacamoleProperty() {
@Override
public String getName() { return "mysql-auto-create-accounts"; }
};
} }

View File

@@ -328,4 +328,10 @@ public class PostgreSQLEnvironment extends JDBCEnvironment {
return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_KEY_PASSWORD); return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_KEY_PASSWORD);
} }
@Override
public boolean autoCreateAbsentAccounts() throws GuacamoleException {
return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_AUTO_CREATE_ACCOUNTS,
false);
}
} }

View File

@@ -233,4 +233,17 @@ public class PostgreSQLGuacamoleProperties {
}; };
/**
* Whether or not to automatically create accounts in the PostgreSQL
* database for users who successfully authenticate through another
* extension. By default users will not be automatically created.
*/
public static final BooleanGuacamoleProperty POSTGRESQL_AUTO_CREATE_ACCOUNTS =
new BooleanGuacamoleProperty() {
@Override
public String getName() { return "postgresql-auto-create-accounts"; }
};
} }

View File

@@ -25,6 +25,8 @@ import com.google.inject.name.Names;
import java.lang.UnsupportedOperationException; import java.lang.UnsupportedOperationException;
import java.util.Properties; import java.util.Properties;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.sqlserver.conf.SQLServerDriver;
import org.apache.guacamole.auth.sqlserver.conf.SQLServerEnvironment;
import org.mybatis.guice.datasource.helper.JdbcHelper; import org.mybatis.guice.datasource.helper.JdbcHelper;
/** /**
@@ -45,7 +47,7 @@ public class SQLServerAuthenticationProviderModule implements Module {
/** /**
* Which SQL Server driver should be used. * Which SQL Server driver should be used.
*/ */
private SQLServerDriver sqlServerDriver; private final SQLServerDriver sqlServerDriver;
/** /**
* Creates a new SQLServer authentication provider module that configures * Creates a new SQLServer authentication provider module that configures

View File

@@ -24,6 +24,7 @@ import com.google.inject.Injector;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderModule; import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderModule;
import org.apache.guacamole.auth.jdbc.JDBCInjectorProvider; import org.apache.guacamole.auth.jdbc.JDBCInjectorProvider;
import org.apache.guacamole.auth.sqlserver.conf.SQLServerEnvironment;
/** /**
* JDBCInjectorProvider implementation which configures Guice injections for * JDBCInjectorProvider implementation which configures Guice injections for

View File

@@ -17,7 +17,7 @@
* under the License. * under the License.
*/ */
package org.apache.guacamole.auth.sqlserver; package org.apache.guacamole.auth.sqlserver.conf;
import org.apache.guacamole.properties.EnumGuacamoleProperty.PropertyValue; import org.apache.guacamole.properties.EnumGuacamoleProperty.PropertyValue;

View File

@@ -17,7 +17,7 @@
* under the License. * under the License.
*/ */
package org.apache.guacamole.auth.sqlserver; package org.apache.guacamole.auth.sqlserver.conf;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
@@ -274,4 +274,10 @@ public class SQLServerEnvironment extends JDBCEnvironment {
return true; // All versions of SQL Server support recursive queries through CTEs return true; // All versions of SQL Server support recursive queries through CTEs
} }
@Override
public boolean autoCreateAbsentAccounts() throws GuacamoleException {
return getProperty(SQLServerGuacamoleProperties.SQLSERVER_AUTO_CREATE_ACCOUNTS,
false);
}
} }

View File

@@ -17,7 +17,7 @@
* under the License. * under the License.
*/ */
package org.apache.guacamole.auth.sqlserver; package org.apache.guacamole.auth.sqlserver.conf;
import org.apache.guacamole.properties.BooleanGuacamoleProperty; import org.apache.guacamole.properties.BooleanGuacamoleProperty;
import org.apache.guacamole.properties.EnumGuacamoleProperty; import org.apache.guacamole.properties.EnumGuacamoleProperty;
@@ -194,4 +194,17 @@ public class SQLServerGuacamoleProperties {
}; };
/**
* Whether or not to automatically create accounts in the SQL Server
* database for users who successfully authenticate through another
* extension. By default users will not be automatically created.
*/
public static final BooleanGuacamoleProperty SQLSERVER_AUTO_CREATE_ACCOUNTS =
new BooleanGuacamoleProperty() {
@Override
public String getName() { return "sqlserver-auto-create-accounts"; }
};
} }

View File

@@ -17,7 +17,7 @@
* under the License. * under the License.
*/ */
package org.apache.guacamole.auth.sqlserver; package org.apache.guacamole.auth.sqlserver.conf;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.JDBCEnvironment;