mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Ticket #269: Connection implementation completed. Testing and styling remain.
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -51,6 +51,7 @@ import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.PermissionCheckUtility;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.ProviderUtility;
|
||||
@@ -113,7 +114,6 @@ public class ConnectionDirectory implements Directory<String, Connection>{
|
||||
@Transactional
|
||||
@Override
|
||||
public void add(Connection object) throws GuacamoleException {
|
||||
Preconditions.checkNotNull(object);
|
||||
permissionCheckUtility.verifyCreateConnectionPermission(this.user.getUserID());
|
||||
|
||||
MySQLConnection mySQLConnection = providerUtility.getNewMySQLConnection(object);
|
||||
@@ -143,6 +143,7 @@ public class ConnectionDirectory implements Directory<String, Connection>{
|
||||
GuacamoleConfiguration configuration = mySQLConnection.getConfiguration();
|
||||
Map<String, String> existingConfiguration = new HashMap<String, String>();
|
||||
ConnectionParameterExample example = new ConnectionParameterExample();
|
||||
example.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
|
||||
List<ConnectionParameter> connectionParameters = connectionParameterDAO.selectByExample(example);
|
||||
for(ConnectionParameter parameter : connectionParameters)
|
||||
existingConfiguration.put(parameter.getParameter_name(), parameter.getParameter_value());
|
||||
@@ -153,20 +154,84 @@ public class ConnectionDirectory implements Directory<String, Connection>{
|
||||
Set<String> parameterNames = configuration.getParameterNames();
|
||||
|
||||
for(String parameterName : parameterNames) {
|
||||
String parameterValue = configuration.getParameter(parameterName);
|
||||
if(existingConfiguration.containsKey(parameterName)) {
|
||||
String existingValue = existingConfiguration.get(parameterName);
|
||||
// the value is different; we'll have to update this one in the database
|
||||
if(!parameterValue.equals(existingValue)) {
|
||||
ConnectionParameter parameterToUpdate = new ConnectionParameter();
|
||||
parameterToUpdate.setConnection_id(mySQLConnection.getConnectionID());
|
||||
parameterToUpdate.setParameter_name(parameterName);
|
||||
parameterToUpdate.setParameter_value(parameterValue);
|
||||
parametersToUpdate.add(parameterToUpdate);
|
||||
}
|
||||
} else {
|
||||
// the value is new, we need to insert it
|
||||
ConnectionParameter parameterToInsert = new ConnectionParameter();
|
||||
parameterToInsert.setConnection_id(mySQLConnection.getConnectionID());
|
||||
parameterToInsert.setParameter_name(parameterName);
|
||||
parameterToInsert.setParameter_value(parameterValue);
|
||||
parametersToInsert.add(parameterToInsert);
|
||||
}
|
||||
}
|
||||
|
||||
// First, delete all parameters that are not in the new configuration.
|
||||
example.clear();
|
||||
example.createCriteria().
|
||||
andConnection_idEqualTo(mySQLConnection.getConnectionID()).
|
||||
andParameter_nameNotIn(Lists.newArrayList(existingConfiguration.keySet()));
|
||||
|
||||
//Second, update all the parameters that need to be modified.
|
||||
for(ConnectionParameter parameter : parametersToUpdate) {
|
||||
example.clear();
|
||||
example.createCriteria().
|
||||
andConnection_idEqualTo(mySQLConnection.getConnectionID()).
|
||||
andParameter_nameEqualTo(parameter.getParameter_name());
|
||||
|
||||
connectionParameterDAO.updateByExample(parameter, example);
|
||||
}
|
||||
|
||||
//Finally, insert any new parameters.
|
||||
for(ConnectionParameter parameter : parametersToInsert) {
|
||||
example.clear();
|
||||
example.createCriteria().
|
||||
andConnection_idEqualTo(mySQLConnection.getConnectionID()).
|
||||
andParameter_nameEqualTo(parameter.getParameter_name());
|
||||
|
||||
connectionParameterDAO.insert(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void update(Connection object) throws GuacamoleException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
permissionCheckUtility.verifyConnectionUpdateAccess(this.user.getUserID(), object.getIdentifier());
|
||||
|
||||
MySQLConnection mySQLConnection = providerUtility.getExistingMySQLConnection(object);
|
||||
connectionDAO.updateByPrimaryKey(mySQLConnection.getConnection());
|
||||
|
||||
updateConfigurationValues(mySQLConnection);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
permissionCheckUtility.verifyConnectionDeleteAccess(this.user.getUserID(), identifier);
|
||||
|
||||
MySQLConnection mySQLConnection = providerUtility.getExistingMySQLConnection(identifier);
|
||||
|
||||
// delete all configuration values
|
||||
ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
|
||||
connectionParameterExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
|
||||
connectionParameterDAO.deleteByExample(connectionParameterExample);
|
||||
|
||||
// delete all permissions that refer to this connection
|
||||
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
||||
connectionPermissionExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
|
||||
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
|
||||
|
||||
// delete the connection itself
|
||||
connectionDAO.deleteByPrimaryKey(mySQLConnection.getConnectionID());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -52,6 +52,7 @@ import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.ConfigurationTranslationUtility;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.PasswordEncryptionUtility;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.PermissionCheckUtility;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.ProviderUtility;
|
||||
@@ -74,6 +75,8 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(MySQLUserContext.class);
|
||||
|
||||
private ActiveConnectionSet activeConnectionSet = new ActiveConnectionSet();
|
||||
|
||||
private Injector injector;
|
||||
|
||||
@Override
|
||||
@@ -85,6 +88,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
public MySQLAuthenticationProvider() throws GuacamoleException {
|
||||
final Properties myBatisProperties = new Properties();
|
||||
//set the mysql properties for MyBatis.
|
||||
myBatisProperties.setProperty("mybatis.environment.id", "guacamole");
|
||||
myBatisProperties.setProperty("JDBC.host", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_HOSTNAME));
|
||||
myBatisProperties.setProperty("JDBC.port", String.valueOf(GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PORT)));
|
||||
@@ -93,6 +97,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
myBatisProperties.setProperty("JDBC.password", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PASSWORD));
|
||||
myBatisProperties.setProperty("JDBC.autoCommit", "false");
|
||||
|
||||
// Set up Guice injector.
|
||||
injector = Guice.createInjector(
|
||||
JdbcHelper.MySQL,
|
||||
new Module() {
|
||||
@@ -117,6 +122,8 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
bind(PasswordEncryptionUtility.class).to(Sha256PasswordEncryptionUtility.class);
|
||||
bind(PermissionCheckUtility.class);
|
||||
bind(ProviderUtility.class);
|
||||
bind(ConfigurationTranslationUtility.class);
|
||||
bind(ActiveConnectionSet.class).toInstance(activeConnectionSet);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@@ -39,11 +39,19 @@ import com.google.inject.Inject;
|
||||
import java.util.List;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.ConnectionRecord;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.ConfigurationTranslationUtility;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.utility.ProviderUtility;
|
||||
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
||||
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||
|
||||
@@ -56,9 +64,18 @@ public class MySQLConnection implements Connection {
|
||||
@Inject
|
||||
ConnectionMapper connectionDAO;
|
||||
|
||||
@Inject
|
||||
ConnectionParameterMapper connectionParameterDAO;
|
||||
|
||||
@Inject
|
||||
ProviderUtility providerUtility;
|
||||
|
||||
@Inject
|
||||
ActiveConnectionSet activeConnectionSet;
|
||||
|
||||
@Inject
|
||||
ConfigurationTranslationUtility configurationTranslationUtility;
|
||||
|
||||
private net.sourceforge.guacamole.net.auth.mysql.model.Connection connection;
|
||||
|
||||
private GuacamoleConfiguration configuration;
|
||||
@@ -68,6 +85,7 @@ public class MySQLConnection implements Connection {
|
||||
*/
|
||||
MySQLConnection() {
|
||||
connection = new net.sourceforge.guacamole.net.auth.mysql.model.Connection();
|
||||
configuration = new GuacamoleConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,6 +113,18 @@ public class MySQLConnection implements Connection {
|
||||
this.configuration = connection.getConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the GuacamoleConfiguration based on the ConnectionParameter values in the database.
|
||||
*/
|
||||
private void initConfiguration() {
|
||||
ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
|
||||
connectionParameterExample.createCriteria().andConnection_idEqualTo(connection.getConnection_id());
|
||||
|
||||
List<ConnectionParameter> connectionParameters = connectionParameterDAO.selectByExample(connectionParameterExample);
|
||||
|
||||
configuration = configurationTranslationUtility.getConfiguration(connection.getProtocol(), connectionParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an existing connection by name.
|
||||
* @param connectionName
|
||||
@@ -110,14 +140,17 @@ public class MySQLConnection implements Connection {
|
||||
throw new GuacamoleException("No connection found named '" + connectionName + "'.");
|
||||
|
||||
connection = connections.get(0);
|
||||
|
||||
initConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize from a database record.
|
||||
* Initialize from a database record. This also initializes the configuration values.
|
||||
* @param connection
|
||||
*/
|
||||
public void init(net.sourceforge.guacamole.net.auth.mysql.model.Connection connection) {
|
||||
this.connection = connection;
|
||||
initConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,11 +171,28 @@ public class MySQLConnection implements Connection {
|
||||
@Override
|
||||
public void setConfiguration(GuacamoleConfiguration config) {
|
||||
this.configuration = config;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
// If the current connection is active, and multiple simultaneous connections are not allowed.
|
||||
if(GuacamoleProperties.getProperty(MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
||||
&& activeConnectionSet.contains(getConnectionID()))
|
||||
throw new GuacamoleException("Cannot connect. This connection is in use.");
|
||||
|
||||
String host = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME);
|
||||
int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT);
|
||||
|
||||
InetGuacamoleSocket inetSocket = new InetGuacamoleSocket(host, port);
|
||||
ConfiguredGuacamoleSocket configuredSocket = new ConfiguredGuacamoleSocket(inetSocket, configuration);
|
||||
|
||||
MySQLGuacamoleSocket mySQLSocket = providerUtility.getMySQLGuacamoleSocket(configuredSocket, getConnectionID());
|
||||
|
||||
// mark this connection as active
|
||||
activeConnectionSet.add(getConnectionID());
|
||||
|
||||
return mySQLSocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -411,5 +411,10 @@ public class UserDirectory implements Directory<String, User> {
|
||||
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
||||
systemPermissionExample.createCriteria().andUser_idEqualTo(user.getUserID());
|
||||
systemPermissionDAO.deleteByExample(systemPermissionExample);
|
||||
|
||||
//delete all permissions that refer to this user
|
||||
userPermissionExample.createCriteria();
|
||||
userPermissionExample.createCriteria().andAffected_user_idEqualTo(user.getUserID());
|
||||
userPermissionDAO.deleteByExample(userPermissionExample);
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql.properties;
|
||||
|
||||
import net.sourceforge.guacamole.properties.BooleanGuacamoleProperty;
|
||||
import net.sourceforge.guacamole.properties.IntegerGuacamoleProperty;
|
||||
import net.sourceforge.guacamole.properties.StringGuacamoleProperty;
|
||||
|
||||
@@ -98,4 +99,14 @@ public class MySQLGuacamoleProperties {
|
||||
public String getName() { return "mysql-password"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not multiple users accessing the same connection at the same time should be disallowed.
|
||||
*/
|
||||
public static final BooleanGuacamoleProperty MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS = new BooleanGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-disallow-simultaneous-connections"; }
|
||||
|
||||
};
|
||||
}
|
||||
|
@@ -44,6 +44,7 @@ import net.sourceforge.guacamole.net.auth.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.User;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
||||
@@ -53,9 +54,10 @@ import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistoryExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
||||
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||
|
||||
/**
|
||||
* Provides convenient provider methods for MySQLUser, MySQLConnection, and MySQLConnctionRecord objects.
|
||||
* Provides convenient provider methods for MySQL specific implementations.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ProviderUtility {
|
||||
@@ -77,6 +79,9 @@ public class ProviderUtility {
|
||||
@Inject
|
||||
Provider<MySQLConnectionRecord> mySQLConnectionRecordProvider;
|
||||
|
||||
@Inject
|
||||
Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
||||
|
||||
/**
|
||||
* Create a new user based on the provided object.
|
||||
* @param user
|
||||
@@ -205,6 +210,8 @@ public class ProviderUtility {
|
||||
public List<MySQLConnectionRecord> getExistingMySQLConnectionRecords(Integer connectionID) {
|
||||
ConnectionHistoryExample example = new ConnectionHistoryExample();
|
||||
example.createCriteria().andConnection_idEqualTo(connectionID);
|
||||
// we want to return the newest records first
|
||||
example.setOrderByClause("start_date DESC");
|
||||
List<ConnectionHistory> connectionHistories = connectionHistoryDAO.selectByExample(example);
|
||||
List<MySQLConnectionRecord> connectionRecords = new ArrayList<MySQLConnectionRecord>();
|
||||
for(ConnectionHistory history : connectionHistories) {
|
||||
@@ -223,4 +230,16 @@ public class ProviderUtility {
|
||||
record.init(history);
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MySQLGuacamoleSocket using the provided ConfiguredGuacamoleSocket and connection ID.
|
||||
* @param socket
|
||||
* @param connectionID
|
||||
* @return
|
||||
*/
|
||||
public MySQLGuacamoleSocket getMySQLGuacamoleSocket(ConfiguredGuacamoleSocket socket, int connectionID) {
|
||||
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
|
||||
mySQLGuacamoleSocket.init(socket, connectionID);
|
||||
return mySQLGuacamoleSocket;
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,6 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql.utility;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -51,18 +50,12 @@ public class Sha256PasswordEncryptionUtility implements PasswordEncryptionUtilit
|
||||
|
||||
@Override
|
||||
public boolean checkCredentials(Credentials credentials, byte[] dbPasswordHash, String dbUsername, byte[] dbSalt) {
|
||||
Preconditions.checkNotNull(credentials);
|
||||
Preconditions.checkNotNull(dbPasswordHash);
|
||||
Preconditions.checkNotNull(dbUsername);
|
||||
Preconditions.checkNotNull(dbSalt);
|
||||
byte[] passwordBytes = createPasswordHash(credentials.getPassword(), dbSalt);
|
||||
return Arrays.equals(passwordBytes, dbPasswordHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] createPasswordHash(String password, byte[] salt) {
|
||||
Preconditions.checkNotNull(password);
|
||||
Preconditions.checkNotNull(salt);
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
|
Reference in New Issue
Block a user