mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-1101: Remove use of mybatis-generator. Temporarily remove all but users. Add common interfaces and simple queries.
This commit is contained in:
@@ -48,32 +48,6 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- MyBatis Generator plugin -->
|
||||
<plugin>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
||||
<version>1.3.2</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>Generate MyBatis Artifacts</id>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
<!-- MySQL Connector -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.23</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -104,22 +78,31 @@
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.2.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis Guice -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-guice</artifactId>
|
||||
<version>3.2</version>
|
||||
<version>3.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Guice -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Google Collections -->
|
||||
<dependency>
|
||||
<groupId>com.google.collections</groupId>
|
||||
<artifactId>google-collections</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@@ -1,502 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* Represents the map of currently active Connections to the count of the number
|
||||
* of current users. Whenever a socket is opened, the connection count should be
|
||||
* incremented, and whenever a socket is closed, the connection count should be
|
||||
* decremented.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ActiveConnectionMap {
|
||||
|
||||
/**
|
||||
* Represents the count of users currently using a MySQL connection.
|
||||
*/
|
||||
public class Connection {
|
||||
|
||||
/**
|
||||
* The ID of the MySQL connection that this Connection represents.
|
||||
*/
|
||||
private int connectionID;
|
||||
|
||||
/**
|
||||
* The number of users currently using this connection.
|
||||
*/
|
||||
private int currentUserCount;
|
||||
|
||||
/**
|
||||
* Returns the ID of the MySQL connection that this Connection
|
||||
* represents.
|
||||
*
|
||||
* @return the ID of the MySQL connection that this Connection
|
||||
* represents.
|
||||
*/
|
||||
public int getConnectionID() {
|
||||
return connectionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of users currently using this connection.
|
||||
*
|
||||
* @return the number of users currently using this connection.
|
||||
*/
|
||||
public int getCurrentUserCount() {
|
||||
return currentUserCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current user count for this connection.
|
||||
*
|
||||
* @param currentUserCount The new user count for this Connection.
|
||||
*/
|
||||
public void setCurrentUserCount(int currentUserCount) {
|
||||
this.currentUserCount = currentUserCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Connection for the given connectionID with a zero
|
||||
* current user count.
|
||||
*
|
||||
* @param connectionID The ID of the MySQL connection that this
|
||||
* Connection represents.
|
||||
*/
|
||||
public Connection(int connectionID) {
|
||||
this.connectionID = connectionID;
|
||||
this.currentUserCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents a user connected to a connection or BALANCING connection group.
|
||||
*/
|
||||
public class ConnectionUser {
|
||||
/**
|
||||
* The ID of the connection or connection group that this ConnectionUser refers to.
|
||||
*/
|
||||
private int identifier;
|
||||
|
||||
/**
|
||||
* The user that this ConnectionUser refers to.
|
||||
*/
|
||||
private int userID;
|
||||
|
||||
/**
|
||||
* Returns ID of the connection or connection group that this ConnectionUser refers to.
|
||||
* @return ID of the connection or connection group that this ConnectionUser refers to.
|
||||
*/
|
||||
public int getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user ID that this ConnectionUser refers to.
|
||||
* @return the user ID that this ConnectionUser refers to.
|
||||
*/
|
||||
public int getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ConnectionUser with the given connection or connection group
|
||||
* ID and user ID.
|
||||
*
|
||||
* @param identifier The connection or connection group ID that this
|
||||
* ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*/
|
||||
public ConnectionUser(int identifier, int userID) {
|
||||
this.identifier = identifier;
|
||||
this.userID = userID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
// Only another ConnectionUser can equal this ConnectionUser
|
||||
if(!(other instanceof ConnectionUser))
|
||||
return false;
|
||||
|
||||
ConnectionUser otherConnectionGroupUser =
|
||||
(ConnectionUser)other;
|
||||
|
||||
/*
|
||||
* Two ConnectionGroupUsers are equal iff they represent the exact
|
||||
* same pairing of connection or connection group and user.
|
||||
*/
|
||||
return this.identifier == otherConnectionGroupUser.identifier
|
||||
&& this.userID == otherConnectionGroupUser.userID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 23 * hash + this.identifier;
|
||||
hash = 23 * hash + this.userID;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DAO for accessing connection history.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionHistoryMapper connectionHistoryDAO;
|
||||
|
||||
/**
|
||||
* Map of all the connections that are currently active to the
|
||||
* count of current users.
|
||||
*/
|
||||
private Map<Integer, Connection> activeConnectionMap =
|
||||
new HashMap<Integer, Connection>();
|
||||
|
||||
/**
|
||||
* Map of all the connection group users to the count of current usages.
|
||||
*/
|
||||
private Map<ConnectionUser, Integer> activeConnectionGroupUserMap =
|
||||
new HashMap<ConnectionUser, Integer>();
|
||||
|
||||
/**
|
||||
* Map of all the connection users to the count of current usages.
|
||||
*/
|
||||
private Map<ConnectionUser, Integer> activeConnectionUserMap =
|
||||
new HashMap<ConnectionUser, Integer>();
|
||||
|
||||
/**
|
||||
* Returns the number of connections opened by the given user using
|
||||
* the given ConnectionGroup.
|
||||
*
|
||||
* @param connectionGroupID The connection group ID that this
|
||||
* ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*
|
||||
* @return The number of connections opened by the given user to the given
|
||||
* ConnectionGroup.
|
||||
*/
|
||||
public int getConnectionGroupUserCount(int connectionGroupID, int userID) {
|
||||
Integer count = activeConnectionGroupUserMap.get
|
||||
(new ConnectionUser(connectionGroupID, userID));
|
||||
|
||||
// No ConnectionUser found means this combination was never used
|
||||
if(count == null)
|
||||
return 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given user is currently connected to the given BALANCING
|
||||
* connection group.
|
||||
*
|
||||
* @param connectionGroupID The connection group ID that this
|
||||
* ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*
|
||||
* @return True if the given user is currently connected to the given
|
||||
* BALANCING connection group, false otherwise.
|
||||
*/
|
||||
public boolean isConnectionGroupUserActive(int connectionGroupID, int userID) {
|
||||
Integer count = activeConnectionGroupUserMap.get
|
||||
(new ConnectionUser(connectionGroupID, userID));
|
||||
|
||||
// The connection group is in use if the ConnectionUser count > 0
|
||||
return count != null && count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the count of the number of connections opened by the given user
|
||||
* to the given ConnectionGroup.
|
||||
*
|
||||
* @param connectionGroupID The connection group ID that this
|
||||
* ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*/
|
||||
private void incrementConnectionGroupUserCount(int connectionGroupID, int userID) {
|
||||
int currentCount = getConnectionGroupUserCount(connectionGroupID, userID);
|
||||
|
||||
activeConnectionGroupUserMap.put
|
||||
(new ConnectionUser(connectionGroupID, userID), currentCount + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the count of the number of connections opened by the given user
|
||||
* to the given ConnectionGroup.
|
||||
*
|
||||
* @param connectionGroupID The connection group ID that this
|
||||
* ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*/
|
||||
private void decrementConnectionGroupUserCount(int connectionGroupID, int userID) {
|
||||
int currentCount = getConnectionGroupUserCount(connectionGroupID, userID);
|
||||
|
||||
activeConnectionGroupUserMap.put
|
||||
(new ConnectionUser(connectionGroupID, userID), currentCount - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of connections opened by the given user using
|
||||
* the given Connection.
|
||||
*
|
||||
* @param connectionID The connection ID that this ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*
|
||||
* @return The number of connections opened by the given user to the given
|
||||
* connection.
|
||||
*/
|
||||
public int getConnectionUserCount(int connectionID, int userID) {
|
||||
Integer count = activeConnectionUserMap.get
|
||||
(new ConnectionUser(connectionID, userID));
|
||||
|
||||
// No ConnectionUser found means this combination was never used
|
||||
if(count == null)
|
||||
return 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given user is currently connected to the given connection.
|
||||
*
|
||||
* @param connectionID The connection ID that this ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*
|
||||
* @return True if the given user is currently connected to the given
|
||||
* connection, false otherwise.
|
||||
*/
|
||||
public boolean isConnectionUserActive(int connectionID, int userID) {
|
||||
Integer count = activeConnectionUserMap.get
|
||||
(new ConnectionUser(connectionID, userID));
|
||||
|
||||
// The connection is in use if the ConnectionUser count > 0
|
||||
return count != null && count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the count of the number of connections opened by the given user
|
||||
* to the given Connection.
|
||||
*
|
||||
* @param connectionID The connection ID that this ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*/
|
||||
private void incrementConnectionUserCount(int connectionID, int userID) {
|
||||
int currentCount = getConnectionUserCount(connectionID, userID);
|
||||
|
||||
activeConnectionUserMap.put
|
||||
(new ConnectionUser(connectionID, userID), currentCount + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the count of the number of connections opened by the given user
|
||||
* to the given Connection.
|
||||
*
|
||||
* @param connectionID The connection ID that this ConnectionUser refers to.
|
||||
* @param userID The user ID that this ConnectionUser refers to.
|
||||
*/
|
||||
private void decrementConnectionUserCount(int connectionID, int userID) {
|
||||
int currentCount = getConnectionUserCount(connectionID, userID);
|
||||
|
||||
activeConnectionUserMap.put
|
||||
(new ConnectionUser(connectionID, userID), currentCount - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the connection with the lowest number of current
|
||||
* active users, if found.
|
||||
*
|
||||
* @param connectionIDs The subset of connection IDs to find the least
|
||||
* used connection within.
|
||||
*
|
||||
* @return The ID of the connection with the lowest number of current
|
||||
* active users, if found.
|
||||
*/
|
||||
public Integer getLeastUsedConnection(Collection<Integer> connectionIDs) {
|
||||
|
||||
if(connectionIDs.isEmpty())
|
||||
return null;
|
||||
|
||||
int minUserCount = Integer.MAX_VALUE;
|
||||
Integer minConnectionID = null;
|
||||
|
||||
for(Integer connectionID : connectionIDs) {
|
||||
Connection connection = activeConnectionMap.get(connectionID);
|
||||
|
||||
/*
|
||||
* If the connection is not found in the map, it has not been used,
|
||||
* and therefore will be count 0.
|
||||
*/
|
||||
if(connection == null) {
|
||||
minUserCount = 0;
|
||||
minConnectionID = connectionID;
|
||||
}
|
||||
// If this is the least active connection
|
||||
else if(connection.getCurrentUserCount() < minUserCount) {
|
||||
minUserCount = connection.getCurrentUserCount();
|
||||
minConnectionID = connection.getConnectionID();
|
||||
}
|
||||
}
|
||||
|
||||
return minConnectionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of currently active users for the given connectionID.
|
||||
* @return the count of currently active users for the given connectionID.
|
||||
*/
|
||||
public int getCurrentUserCount(int connectionID) {
|
||||
Connection connection = activeConnectionMap.get(connectionID);
|
||||
|
||||
if(connection == null)
|
||||
return 0;
|
||||
|
||||
return connection.getCurrentUserCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the current user count for this Connection.
|
||||
*
|
||||
* @param connectionID The ID of the MySQL connection that this
|
||||
* Connection represents.
|
||||
*
|
||||
* @throws GuacamoleException If the connection is not found.
|
||||
*/
|
||||
private void decrementUserCount(int connectionID)
|
||||
throws GuacamoleException {
|
||||
Connection connection = activeConnectionMap.get(connectionID);
|
||||
|
||||
if(connection == null)
|
||||
throw new GuacamoleResourceNotFoundException
|
||||
("Connection to decrement does not exist.");
|
||||
|
||||
// Decrement the current user count
|
||||
connection.setCurrentUserCount(connection.getCurrentUserCount() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the current user count for this Connection.
|
||||
*
|
||||
* @param connectionID The ID of the MySQL connection that this
|
||||
* Connection represents.
|
||||
*
|
||||
* @throws GuacamoleException If the connection is not found.
|
||||
*/
|
||||
private void incrementUserCount(int connectionID) {
|
||||
Connection connection = activeConnectionMap.get(connectionID);
|
||||
|
||||
// If the Connection does not exist, it should be created
|
||||
if(connection == null) {
|
||||
connection = new Connection(connectionID);
|
||||
activeConnectionMap.put(connectionID, connection);
|
||||
}
|
||||
|
||||
// Increment the current user count
|
||||
connection.setCurrentUserCount(connection.getCurrentUserCount() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a connection is currently in use.
|
||||
* @param connectionID The connection to check the status of.
|
||||
* @return true if the connection is currently in use.
|
||||
*/
|
||||
public boolean isActive(int connectionID) {
|
||||
return getCurrentUserCount(connectionID) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a connection as open.
|
||||
* @param connectionID The ID of the connection that is being opened.
|
||||
* @param userID The ID of the user who is opening the connection.
|
||||
* @param connectionGroupID The ID of the BALANCING connection group that is
|
||||
* being connected to; null if not used.
|
||||
* @return The ID of the history record created for this open connection.
|
||||
*/
|
||||
public int openConnection(int connectionID, int userID, Integer connectionGroupID) {
|
||||
|
||||
// Create the connection history record
|
||||
ConnectionHistory connectionHistory = new ConnectionHistory();
|
||||
connectionHistory.setConnection_id(connectionID);
|
||||
connectionHistory.setUser_id(userID);
|
||||
connectionHistory.setStart_date(new Date());
|
||||
connectionHistoryDAO.insert(connectionHistory);
|
||||
|
||||
// Increment the user count
|
||||
incrementUserCount(connectionID);
|
||||
|
||||
// Increment the connection user count
|
||||
incrementConnectionUserCount(connectionID, userID);
|
||||
|
||||
// If this is a connection to a BALANCING ConnectionGroup, increment the count
|
||||
if(connectionGroupID != null)
|
||||
incrementConnectionGroupUserCount(connectionGroupID, userID);
|
||||
|
||||
return connectionHistory.getHistory_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a connection as closed.
|
||||
* @param historyID The ID of the history record about the open connection.
|
||||
* @param connectionGroupID The ID of the BALANCING connection group that is
|
||||
* being connected to; null if not used.
|
||||
* @throws GuacamoleException If the open connection history is not found.
|
||||
*/
|
||||
public void closeConnection(int historyID, Integer connectionGroupID)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get the existing history record
|
||||
ConnectionHistory connectionHistory =
|
||||
connectionHistoryDAO.selectByPrimaryKey(historyID);
|
||||
|
||||
if(connectionHistory == null)
|
||||
throw new GuacamoleResourceNotFoundException("History record not found.");
|
||||
|
||||
// Get the connection and user IDs
|
||||
int connectionID = connectionHistory.getConnection_id();
|
||||
int userID = connectionHistory.getUser_id();
|
||||
|
||||
// Update the connection history record to mark that it is now closed
|
||||
connectionHistory.setEnd_date(new Date());
|
||||
connectionHistoryDAO.updateByPrimaryKey(connectionHistory);
|
||||
|
||||
// Decrement the user count.
|
||||
decrementUserCount(connectionID);
|
||||
|
||||
// Decrement the connection user count
|
||||
decrementConnectionUserCount(connectionID, userID);
|
||||
|
||||
// If this is a connection to a BALANCING ConnectionGroup, decrement the count
|
||||
if(connectionGroupID != null)
|
||||
decrementConnectionGroupUserCount(connectionGroupID, userID);
|
||||
}
|
||||
}
|
@@ -1,336 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
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.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||
import org.glyptodon.guacamole.GuacamoleUnsupportedException;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL-based implementation of the connection directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ConnectionDirectory implements Directory<String, Connection>{
|
||||
|
||||
/**
|
||||
* The user who this connection directory belongs to. Access is based on
|
||||
* his/her permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* The ID of the parent connection group.
|
||||
*/
|
||||
private Integer parentID;
|
||||
|
||||
/**
|
||||
* Service for checking permissions.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Service managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service managing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Service for manipulating connection permissions in the database.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* Service for manipulating connection parameters in the database.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionParameterMapper connectionParameterDAO;
|
||||
|
||||
/**
|
||||
* Set the user and parentID for this directory.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user owning this connection directory.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser, Integer parentID) {
|
||||
this.currentUser = currentUser;
|
||||
this.parentID = parentID;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Connection get(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get connection
|
||||
MySQLConnection connection =
|
||||
connectionService.retrieveConnection(identifier, currentUser);
|
||||
|
||||
if(connection == null)
|
||||
return null;
|
||||
|
||||
// Verify permission to use the parent connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(connection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify access is granted
|
||||
permissionCheckService.verifyConnectionAccess(
|
||||
currentUser,
|
||||
connection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_READ);
|
||||
|
||||
// Return connection
|
||||
return connection;
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
|
||||
// Verify permission to use the connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
return permissionCheckService.retrieveConnectionIdentifiers(currentUser,
|
||||
parentID, MySQLConstants.CONNECTION_READ);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void add(Connection object) throws GuacamoleException {
|
||||
|
||||
String name = object.getName().trim();
|
||||
if(name.isEmpty())
|
||||
throw new GuacamoleClientException("The connection name cannot be blank.");
|
||||
|
||||
// Verify permission to create
|
||||
permissionCheckService.verifySystemAccess(currentUser,
|
||||
MySQLConstants.SYSTEM_CONNECTION_CREATE);
|
||||
|
||||
// Verify permission to edit the connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
this.parentID, MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify permission to use the connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify that no connection already exists with this name.
|
||||
MySQLConnection previousConnection =
|
||||
connectionService.retrieveConnection(name, parentID, currentUser);
|
||||
if(previousConnection != null)
|
||||
throw new GuacamoleClientException("That connection name is already in use.");
|
||||
|
||||
// Create connection
|
||||
MySQLConnection connection = connectionService.createConnection(
|
||||
name, object.getConfiguration().getProtocol(), currentUser, parentID);
|
||||
|
||||
// Set the connection ID
|
||||
object.setIdentifier(connection.getIdentifier());
|
||||
|
||||
// Add connection parameters
|
||||
createConfigurationValues(connection.getConnectionID(),
|
||||
object.getConfiguration());
|
||||
|
||||
// Finally, give the current user full access to the newly created
|
||||
// connection.
|
||||
ConnectionPermissionKey newConnectionPermission = new ConnectionPermissionKey();
|
||||
newConnectionPermission.setUser_id(currentUser.getUserID());
|
||||
newConnectionPermission.setConnection_id(connection.getConnectionID());
|
||||
|
||||
// Read permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_READ);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
// Update permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_UPDATE);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
// Delete permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_DELETE);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
// Administer permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_ADMINISTER);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts all parameter values from the given configuration into the
|
||||
* database, associating them with the connection having the givenID.
|
||||
*
|
||||
* @param connection_id The ID of the connection to associate all
|
||||
* parameters with.
|
||||
* @param config The GuacamoleConfiguration to read parameters from.
|
||||
*/
|
||||
private void createConfigurationValues(int connection_id,
|
||||
GuacamoleConfiguration config) {
|
||||
|
||||
// Insert new parameters for each parameter in the config
|
||||
for (String name : config.getParameterNames()) {
|
||||
|
||||
// Create a ConnectionParameter based on the current parameter
|
||||
ConnectionParameter parameter = new ConnectionParameter();
|
||||
parameter.setConnection_id(connection_id);
|
||||
parameter.setParameter_name(name);
|
||||
parameter.setParameter_value(config.getParameter(name));
|
||||
|
||||
// Insert connection parameter
|
||||
connectionParameterDAO.insert(parameter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void update(Connection object) throws GuacamoleException {
|
||||
|
||||
// If connection not actually from this auth provider, we can't handle
|
||||
// the update
|
||||
if (!(object instanceof MySQLConnection))
|
||||
throw new GuacamoleUnsupportedException("Connection not from database.");
|
||||
|
||||
MySQLConnection mySQLConnection = (MySQLConnection) object;
|
||||
|
||||
// Verify permission to update
|
||||
permissionCheckService.verifyConnectionAccess(currentUser,
|
||||
mySQLConnection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_UPDATE);
|
||||
|
||||
// Perform update
|
||||
connectionService.updateConnection(mySQLConnection);
|
||||
|
||||
// Delete old connection parameters
|
||||
ConnectionParameterExample parameterExample = new ConnectionParameterExample();
|
||||
parameterExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
|
||||
connectionParameterDAO.deleteByExample(parameterExample);
|
||||
|
||||
// Add connection parameters
|
||||
createConfigurationValues(mySQLConnection.getConnectionID(),
|
||||
object.getConfiguration());
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get connection
|
||||
MySQLConnection mySQLConnection =
|
||||
connectionService.retrieveConnection(identifier, currentUser);
|
||||
|
||||
if(mySQLConnection == null)
|
||||
throw new GuacamoleResourceNotFoundException("Connection not found.");
|
||||
|
||||
// Verify permission to use the parent connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(mySQLConnection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify permission to delete
|
||||
permissionCheckService.verifyConnectionAccess(currentUser,
|
||||
mySQLConnection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_DELETE);
|
||||
|
||||
// Delete the connection itself
|
||||
connectionService.deleteConnection(mySQLConnection.getConnectionID());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(String identifier, Directory<String, Connection> directory)
|
||||
throws GuacamoleException {
|
||||
|
||||
if(!(directory instanceof ConnectionDirectory))
|
||||
throw new GuacamoleUnsupportedException("Directory not from database");
|
||||
|
||||
Integer toConnectionGroupID = ((ConnectionDirectory)directory).parentID;
|
||||
|
||||
// Get connection
|
||||
MySQLConnection mySQLConnection =
|
||||
connectionService.retrieveConnection(identifier, currentUser);
|
||||
|
||||
if(mySQLConnection == null)
|
||||
throw new GuacamoleResourceNotFoundException("Connection not found.");
|
||||
|
||||
// Verify permission to update the connection
|
||||
permissionCheckService.verifyConnectionAccess(currentUser,
|
||||
mySQLConnection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_UPDATE);
|
||||
|
||||
// Verify permission to use the from connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(mySQLConnection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify permission to update the from connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
mySQLConnection.getParentID(), MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify permission to use the to connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(toConnectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify permission to update the to connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
toConnectionGroupID, MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify that no connection already exists with this name.
|
||||
MySQLConnection previousConnection =
|
||||
connectionService.retrieveConnection(mySQLConnection.getName(),
|
||||
toConnectionGroupID, currentUser);
|
||||
if(previousConnection != null)
|
||||
throw new GuacamoleClientException("That connection name is already in use.");
|
||||
|
||||
// Update the connection
|
||||
mySQLConnection.setParentID(toConnectionGroupID);
|
||||
connectionService.updateConnection(mySQLConnection);
|
||||
}
|
||||
|
||||
}
|
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup.Type;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||
import org.glyptodon.guacamole.GuacamoleUnsupportedException;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL-based implementation of the connection group directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ConnectionGroupDirectory implements Directory<String, ConnectionGroup>{
|
||||
|
||||
/**
|
||||
* The user who this connection directory belongs to. Access is based on
|
||||
* his/her permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* The ID of the parent connection group.
|
||||
*/
|
||||
private Integer parentID;
|
||||
|
||||
/**
|
||||
* Service for checking permissions.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Service managing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Service for manipulating connection group permissions in the database.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
|
||||
|
||||
/**
|
||||
* Set the user and parentID for this directory.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user owning this connection group directory.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser, Integer parentID) {
|
||||
this.parentID = parentID;
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public ConnectionGroup get(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get connection
|
||||
MySQLConnectionGroup connectionGroup =
|
||||
connectionGroupService.retrieveConnectionGroup(identifier, currentUser);
|
||||
|
||||
if(connectionGroup == null)
|
||||
return null;
|
||||
|
||||
// Verify permission to use the parent connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(connectionGroup.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify access is granted
|
||||
permissionCheckService.verifyConnectionGroupAccess(
|
||||
currentUser,
|
||||
connectionGroup.getConnectionGroupID(),
|
||||
MySQLConstants.CONNECTION_GROUP_READ);
|
||||
|
||||
// Return connection group
|
||||
return connectionGroup;
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
|
||||
// Verify permission to use the connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
return permissionCheckService.retrieveConnectionGroupIdentifiers(currentUser,
|
||||
parentID, MySQLConstants.CONNECTION_GROUP_READ);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void add(ConnectionGroup object) throws GuacamoleException {
|
||||
|
||||
String name = object.getName().trim();
|
||||
if(name.isEmpty())
|
||||
throw new GuacamoleClientException("The connection group name cannot be blank.");
|
||||
|
||||
Type type = object.getType();
|
||||
|
||||
String mySQLType = MySQLConstants.getConnectionGroupTypeConstant(type);
|
||||
|
||||
// Verify permission to create
|
||||
permissionCheckService.verifySystemAccess(currentUser,
|
||||
MySQLConstants.SYSTEM_CONNECTION_GROUP_CREATE);
|
||||
|
||||
// Verify permission to edit the parent connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
this.parentID, MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify permission to use the parent connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify that no connection already exists with this name.
|
||||
MySQLConnectionGroup previousConnectionGroup =
|
||||
connectionGroupService.retrieveConnectionGroup(name, parentID, currentUser);
|
||||
if(previousConnectionGroup != null)
|
||||
throw new GuacamoleClientException("That connection group name is already in use.");
|
||||
|
||||
// Create connection group
|
||||
MySQLConnectionGroup connectionGroup = connectionGroupService
|
||||
.createConnectionGroup(name, currentUser, parentID, mySQLType);
|
||||
|
||||
// Set the connection group ID
|
||||
object.setIdentifier(connectionGroup.getIdentifier());
|
||||
|
||||
// Finally, give the current user full access to the newly created
|
||||
// connection group.
|
||||
ConnectionGroupPermissionKey newConnectionGroupPermission = new ConnectionGroupPermissionKey();
|
||||
newConnectionGroupPermission.setUser_id(currentUser.getUserID());
|
||||
newConnectionGroupPermission.setConnection_group_id(connectionGroup.getConnectionGroupID());
|
||||
|
||||
// Read permission
|
||||
newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_READ);
|
||||
connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
|
||||
|
||||
// Update permission
|
||||
newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
|
||||
|
||||
// Delete permission
|
||||
newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_DELETE);
|
||||
connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
|
||||
|
||||
// Administer permission
|
||||
newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_ADMINISTER);
|
||||
connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void update(ConnectionGroup object) throws GuacamoleException {
|
||||
|
||||
// If connection not actually from this auth provider, we can't handle
|
||||
// the update
|
||||
if (!(object instanceof MySQLConnectionGroup))
|
||||
throw new GuacamoleUnsupportedException("Connection not from database.");
|
||||
|
||||
MySQLConnectionGroup mySQLConnectionGroup = (MySQLConnectionGroup) object;
|
||||
|
||||
// Verify permission to update
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
mySQLConnectionGroup.getConnectionGroupID(),
|
||||
MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Perform update
|
||||
connectionGroupService.updateConnectionGroup(mySQLConnectionGroup);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get connection
|
||||
MySQLConnectionGroup mySQLConnectionGroup =
|
||||
connectionGroupService.retrieveConnectionGroup(identifier, currentUser);
|
||||
|
||||
if(mySQLConnectionGroup == null)
|
||||
throw new GuacamoleResourceNotFoundException("Connection group not found.");
|
||||
|
||||
// Verify permission to use the parent connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(mySQLConnectionGroup.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify permission to delete
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
mySQLConnectionGroup.getConnectionGroupID(),
|
||||
MySQLConstants.CONNECTION_GROUP_DELETE);
|
||||
|
||||
// Delete the connection group itself
|
||||
connectionGroupService.deleteConnectionGroup
|
||||
(mySQLConnectionGroup.getConnectionGroupID());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(String identifier, Directory<String, ConnectionGroup> directory)
|
||||
throws GuacamoleException {
|
||||
|
||||
if(MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER.equals(identifier))
|
||||
throw new GuacamoleUnsupportedException("The root connection group cannot be moved.");
|
||||
|
||||
if(!(directory instanceof ConnectionGroupDirectory))
|
||||
throw new GuacamoleUnsupportedException("Directory not from database");
|
||||
|
||||
Integer toConnectionGroupID = ((ConnectionGroupDirectory)directory).parentID;
|
||||
|
||||
// Get connection group
|
||||
MySQLConnectionGroup mySQLConnectionGroup =
|
||||
connectionGroupService.retrieveConnectionGroup(identifier, currentUser);
|
||||
|
||||
if(mySQLConnectionGroup == null)
|
||||
throw new GuacamoleResourceNotFoundException("Connection group not found.");
|
||||
|
||||
// Verify permission to update the connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
mySQLConnectionGroup.getConnectionGroupID(),
|
||||
MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify permission to use the from connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(mySQLConnectionGroup.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify permission to update the from connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
mySQLConnectionGroup.getParentID(), MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify permission to use the to connection group for organizational purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(toConnectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
|
||||
// Verify permission to update the to connection group
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
toConnectionGroupID, MySQLConstants.CONNECTION_GROUP_UPDATE);
|
||||
|
||||
// Verify that no connection already exists with this name.
|
||||
MySQLConnectionGroup previousConnectionGroup =
|
||||
connectionGroupService.retrieveConnectionGroup(mySQLConnectionGroup.getName(),
|
||||
toConnectionGroupID, currentUser);
|
||||
if(previousConnectionGroup != null)
|
||||
throw new GuacamoleClientException("That connection group name is already in use.");
|
||||
|
||||
// Verify that moving this connectionGroup would not cause a cycle
|
||||
Integer relativeParentID = toConnectionGroupID;
|
||||
while(relativeParentID != null) {
|
||||
if(relativeParentID == mySQLConnectionGroup.getConnectionGroupID())
|
||||
throw new GuacamoleUnsupportedException("Connection group cycle detected.");
|
||||
|
||||
MySQLConnectionGroup relativeParentGroup = connectionGroupService.
|
||||
retrieveConnectionGroup(relativeParentID, currentUser);
|
||||
|
||||
relativeParentID = relativeParentGroup.getParentID();
|
||||
}
|
||||
|
||||
// Update the connection
|
||||
mySQLConnectionGroup.setParentID(toConnectionGroupID);
|
||||
connectionGroupService.updateConnectionGroup(mySQLConnectionGroup);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/**
|
||||
* Common interface for objects that will ultimately be made available through
|
||||
* the Directory class. All such objects will need the same base set of queries
|
||||
* to fulfill the needs of the Directory class.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <ModelType>
|
||||
* The type of object contained within the directory whose objects are
|
||||
* mapped by this mapper.
|
||||
*/
|
||||
public interface DirectoryObject<ModelType> {
|
||||
|
||||
/**
|
||||
* Returns the backing model object. Changes to the model object will
|
||||
* affect this object, and changes to this object will affect the model
|
||||
* object.
|
||||
*
|
||||
* @return
|
||||
* The user model object backing this MySQLUser.
|
||||
*/
|
||||
public ModelType getModel();
|
||||
|
||||
/**
|
||||
* Sets the backing model object. This will effectively replace all data
|
||||
* contained within this object.
|
||||
*
|
||||
* @param model
|
||||
* The backing model object.
|
||||
*/
|
||||
public void setModel(ModelType model);
|
||||
|
||||
}
|
@@ -33,20 +33,9 @@ import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||
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.dao.ConnectionPermissionMapper;
|
||||
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.service.ConnectionGroupService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SHA256PasswordEncryptionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService;
|
||||
@@ -65,16 +54,11 @@ import org.mybatis.guice.datasource.helper.JdbcHelper;
|
||||
*/
|
||||
public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Set of all active connections.
|
||||
*/
|
||||
private ActiveConnectionMap activeConnectionMap = new ActiveConnectionMap();
|
||||
|
||||
/**
|
||||
* Injector which will manage the object graph of this authentication
|
||||
* provider.
|
||||
*/
|
||||
private Injector injector;
|
||||
private final Injector injector;
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(Credentials credentials) throws GuacamoleException {
|
||||
@@ -83,10 +67,10 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
UserService userService = injector.getInstance(UserService.class);
|
||||
|
||||
// Get user
|
||||
MySQLUser authenticatedUser = userService.retrieveUser(credentials);
|
||||
if (authenticatedUser != null) {
|
||||
MySQLUser user = userService.retrieveUser(credentials);
|
||||
if (user != null) {
|
||||
MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
|
||||
context.init(new AuthenticatedUser(authenticatedUser.getUserID(), credentials));
|
||||
context.init(user);
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -145,27 +129,15 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
bindTransactionFactoryType(JdbcTransactionFactory.class);
|
||||
|
||||
// Add MyBatis mappers
|
||||
addMapperClass(ConnectionHistoryMapper.class);
|
||||
addMapperClass(ConnectionMapper.class);
|
||||
addMapperClass(ConnectionGroupMapper.class);
|
||||
addMapperClass(ConnectionGroupPermissionMapper.class);
|
||||
addMapperClass(ConnectionParameterMapper.class);
|
||||
addMapperClass(ConnectionPermissionMapper.class);
|
||||
addMapperClass(SystemPermissionMapper.class);
|
||||
addMapperClass(UserMapper.class);
|
||||
addMapperClass(UserPermissionMapper.class);
|
||||
|
||||
// Bind interfaces
|
||||
bind(MySQLUserContext.class);
|
||||
bind(UserDirectory.class);
|
||||
bind(MySQLUser.class);
|
||||
bind(SaltService.class).to(SecureRandomSaltService.class);
|
||||
bind(MySQLUserContext.class);
|
||||
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
|
||||
bind(PermissionCheckService.class);
|
||||
bind(ConnectionService.class);
|
||||
bind(ConnectionGroupService.class);
|
||||
bind(SaltService.class).to(SecureRandomSaltService.class);
|
||||
bind(UserDirectory.class);
|
||||
bind(UserService.class);
|
||||
bind(ActiveConnectionMap.class).toInstance(activeConnectionMap);
|
||||
|
||||
}
|
||||
} // end of mybatis module
|
||||
|
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.AbstractConnection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the Connection object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLConnection extends AbstractConnection {
|
||||
|
||||
/**
|
||||
* The ID associated with this connection in the database.
|
||||
*/
|
||||
private Integer connectionID;
|
||||
|
||||
/**
|
||||
* The ID of the parent connection group for this connection.
|
||||
*/
|
||||
private Integer parentID;
|
||||
|
||||
/**
|
||||
* The user who queried or created this connection.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* History of this connection.
|
||||
*/
|
||||
private List<ConnectionRecord> history = new ArrayList<ConnectionRecord>();
|
||||
|
||||
/**
|
||||
* Service for managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Create a default, empty connection.
|
||||
*/
|
||||
public MySQLConnection() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the corresponding connection record.
|
||||
* @return The ID of the corresponding connection, if any.
|
||||
*/
|
||||
public Integer getConnectionID() {
|
||||
return connectionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the corresponding connection record.
|
||||
* @param connectionID The ID to assign to this connection.
|
||||
*/
|
||||
public void setConnectionID(Integer connectionID) {
|
||||
this.connectionID = connectionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the parent connection group for this connection, if any.
|
||||
* @return The ID of the parent connection group for this connection, if any.
|
||||
*/
|
||||
public Integer getParentID() {
|
||||
return parentID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the parent connection group for this connection.
|
||||
* @param parentID The ID of the parent connection group for this connection.
|
||||
*/
|
||||
public void setParentID(Integer parentID) {
|
||||
this.parentID = parentID;
|
||||
|
||||
// Translate to string identifier
|
||||
if (parentID != null)
|
||||
this.setParentIdentifier(String.valueOf(parentID));
|
||||
else
|
||||
this.setParentIdentifier(MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize from explicit values.
|
||||
*
|
||||
* @param connectionID
|
||||
* The ID of the associated database record, if any.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group for this connection, if any.
|
||||
*
|
||||
* @param name
|
||||
* The human-readable name associated with this connection.
|
||||
*
|
||||
* @param identifier
|
||||
* The unique identifier associated with this connection.
|
||||
*
|
||||
* @param config
|
||||
* The GuacamoleConfiguration associated with this connection.
|
||||
*
|
||||
* @param history
|
||||
* All ConnectionRecords associated with this connection.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*/
|
||||
public void init(Integer connectionID, Integer parentID, String name,
|
||||
String identifier, GuacamoleConfiguration config,
|
||||
List<? extends ConnectionRecord> history,
|
||||
AuthenticatedUser currentUser) {
|
||||
|
||||
this.connectionID = connectionID;
|
||||
this.setParentID(parentID);
|
||||
setName(name);
|
||||
setIdentifier(identifier);
|
||||
setConfiguration(config);
|
||||
this.history.addAll(history);
|
||||
this.currentUser = currentUser;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
|
||||
return connectionService.connect(this, info, currentUser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends ConnectionRecord> getHistory() throws GuacamoleException {
|
||||
return Collections.unmodifiableList(history);
|
||||
}
|
||||
|
||||
}
|
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.AbstractConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the ConnectionGroup object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLConnectionGroup extends AbstractConnectionGroup {
|
||||
|
||||
/**
|
||||
* The ID associated with this connection group in the database.
|
||||
*/
|
||||
private Integer connectionGroupID;
|
||||
|
||||
/**
|
||||
* The ID of the parent connection group for this connection group.
|
||||
*/
|
||||
private Integer parentID;
|
||||
|
||||
/**
|
||||
* The user who queried or created this connection group.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* A Directory of connections that have this connection group as a parent.
|
||||
*/
|
||||
private ConnectionDirectory connectionDirectory = null;
|
||||
|
||||
/**
|
||||
* A Directory of connection groups that have this connection group as a parent.
|
||||
*/
|
||||
private ConnectionGroupDirectory connectionGroupDirectory = null;
|
||||
|
||||
/**
|
||||
* Service managing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Service for checking permissions.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Service for creating new ConnectionDirectory objects.
|
||||
*/
|
||||
@Inject Provider<ConnectionDirectory> connectionDirectoryProvider;
|
||||
|
||||
/**
|
||||
* Service for creating new ConnectionGroupDirectory objects.
|
||||
*/
|
||||
@Inject Provider<ConnectionGroupDirectory> connectionGroupDirectoryProvider;
|
||||
|
||||
/**
|
||||
* Create a default, empty connection group.
|
||||
*/
|
||||
public MySQLConnectionGroup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the corresponding connection group record.
|
||||
* @return The ID of the corresponding connection group, if any.
|
||||
*/
|
||||
public Integer getConnectionGroupID() {
|
||||
return connectionGroupID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the corresponding connection group record.
|
||||
* @param connectionGroupID The ID to assign to this connection group.
|
||||
*/
|
||||
public void setConnectionID(Integer connectionGroupID) {
|
||||
this.connectionGroupID = connectionGroupID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the parent connection group for this connection group, if any.
|
||||
* @return The ID of the parent connection group for this connection group, if any.
|
||||
*/
|
||||
public Integer getParentID() {
|
||||
return parentID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the parent connection group for this connection group.
|
||||
* @param parentID The ID of the parent connection group for this connection group.
|
||||
*/
|
||||
public void setParentID(Integer parentID) {
|
||||
this.parentID = parentID;
|
||||
|
||||
// Translate to string identifier
|
||||
if (parentID != null)
|
||||
this.setParentIdentifier(String.valueOf(parentID));
|
||||
else
|
||||
this.setParentIdentifier(MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize from explicit values.
|
||||
*
|
||||
* @param connectionGroupID
|
||||
* The ID of the associated database record, if any.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group for this connection group, if
|
||||
* any.
|
||||
*
|
||||
* @param name
|
||||
* The name of this connection group.
|
||||
*
|
||||
* @param identifier
|
||||
* The unique identifier associated with this connection group.
|
||||
*
|
||||
* @param type
|
||||
* The type of this connection group.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*/
|
||||
public void init(Integer connectionGroupID, Integer parentID, String name,
|
||||
String identifier, ConnectionGroup.Type type, AuthenticatedUser currentUser) {
|
||||
this.connectionGroupID = connectionGroupID;
|
||||
this.setParentID(parentID);
|
||||
setName(name);
|
||||
setIdentifier(identifier);
|
||||
setType(type);
|
||||
this.currentUser = currentUser;
|
||||
|
||||
connectionDirectory = connectionDirectoryProvider.get();
|
||||
connectionDirectory.init(currentUser, connectionGroupID);
|
||||
|
||||
connectionGroupDirectory = connectionGroupDirectoryProvider.get();
|
||||
connectionGroupDirectory.init(currentUser, connectionGroupID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
|
||||
|
||||
// Verify permission to use the connection group for balancing purposes
|
||||
permissionCheckService.verifyConnectionGroupUsageAccess
|
||||
(this.connectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_BALANCING);
|
||||
|
||||
// Verify permission to delete
|
||||
permissionCheckService.verifyConnectionGroupAccess(currentUser,
|
||||
this.connectionGroupID,
|
||||
MySQLConstants.CONNECTION_GROUP_READ);
|
||||
|
||||
return connectionGroupService.connect(this, info, currentUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<String, Connection> getConnectionDirectory() throws GuacamoleException {
|
||||
return connectionDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<String, ConnectionGroup> getConnectionGroupDirectory() throws GuacamoleException {
|
||||
return connectionGroupDirectory;
|
||||
}
|
||||
|
||||
}
|
@@ -23,7 +23,6 @@
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.io.GuacamoleReader;
|
||||
import org.glyptodon.guacamole.io.GuacamoleWriter;
|
||||
@@ -35,12 +34,6 @@ import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
*/
|
||||
public class MySQLGuacamoleSocket implements GuacamoleSocket {
|
||||
|
||||
/**
|
||||
* Injected ActiveConnectionMap which will contain all active connections.
|
||||
*/
|
||||
@Inject
|
||||
private ActiveConnectionMap activeConnectionMap;
|
||||
|
||||
/**
|
||||
* The wrapped socket.
|
||||
*/
|
||||
@@ -86,18 +79,7 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket {
|
||||
|
||||
@Override
|
||||
public void close() throws GuacamoleException {
|
||||
|
||||
// Mark this connection as inactive
|
||||
synchronized (activeConnectionMap) {
|
||||
|
||||
if (isOpen())
|
||||
activeConnectionMap.closeConnection(historyID, connectionGroupID);
|
||||
|
||||
// Close socket
|
||||
socket.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -22,39 +22,49 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import com.google.inject.Inject;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.AbstractUser;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.glyptodon.guacamole.net.auth.permission.Permission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.simple.SimpleObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.simple.SimpleSystemPermissionSet;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the User object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLUser extends AbstractUser {
|
||||
public class MySQLUser implements User, DirectoryObject<UserModel> {
|
||||
|
||||
/**
|
||||
* The ID of this user in the database, if any.
|
||||
* Service for hashing passwords.
|
||||
*/
|
||||
private Integer userID;
|
||||
@Inject
|
||||
private PasswordEncryptionService encryptionService;
|
||||
|
||||
/**
|
||||
* The set of current permissions a user has.
|
||||
* Service for providing secure, random salts.
|
||||
*/
|
||||
private Set<Permission> permissions = new HashSet<Permission>();
|
||||
@Inject
|
||||
private SaltService saltService;
|
||||
|
||||
/**
|
||||
* Any newly added permissions that have yet to be committed.
|
||||
* The internal model object containing the values which represent this
|
||||
* user in the database.
|
||||
*/
|
||||
private Set<Permission> newPermissions = new HashSet<Permission>();
|
||||
private UserModel userModel;
|
||||
|
||||
/**
|
||||
* Any newly deleted permissions that have yet to be deleted.
|
||||
* The plaintext password previously set by a call to setPassword(), if
|
||||
* any. The password of a user cannot be retrieved once saved into the
|
||||
* database, so this serves to ensure getPassword() returns a reasonable
|
||||
* value if setPassword() is called. If no password has been set, or the
|
||||
* user was retrieved from the database, this will be null.
|
||||
*/
|
||||
private Set<Permission> removedPermissions = new HashSet<Permission>();
|
||||
private String password = null;
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLUser.
|
||||
@@ -63,118 +73,85 @@ public class MySQLUser extends AbstractUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new MySQLUser having the given username.
|
||||
* Creates a new MySQLUser backed by the given user model object. Changes
|
||||
* to this model object will affect the new MySQLUser even after creation,
|
||||
* and changes to the new MySQLUser will affect this model object.
|
||||
*
|
||||
* @param name The name to assign to this MySQLUser.
|
||||
* @param userModel
|
||||
* The user model object to use to back this MySQLUser.
|
||||
*/
|
||||
public void init(String name) {
|
||||
init(null, name, null, Collections.EMPTY_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new MySQLUser, copying all data from the given user
|
||||
* object.
|
||||
*
|
||||
* @param user The user object to copy.
|
||||
* @throws GuacamoleException If an error occurs while reading the user
|
||||
* data in the given object.
|
||||
*/
|
||||
public void init(User user) throws GuacamoleException {
|
||||
init(null, user.getUsername(), user.getPassword(), user.getPermissions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new MySQLUser initialized from the given data from the
|
||||
* database.
|
||||
*
|
||||
* @param userID The ID of the user in the database, if any.
|
||||
* @param username The username of this user.
|
||||
* @param password The password to assign to this user.
|
||||
* @param permissions The permissions to assign to this user, as
|
||||
* retrieved from the database.
|
||||
*/
|
||||
public void init(Integer userID, String username, String password,
|
||||
Set<Permission> permissions) {
|
||||
this.userID = userID;
|
||||
setUsername(username);
|
||||
setPassword(password);
|
||||
this.permissions.addAll(permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current set of permissions this user has.
|
||||
* @return the current set of permissions.
|
||||
*/
|
||||
public Set<Permission> getCurrentPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any new permissions that have yet to be inserted.
|
||||
* @return the new set of permissions.
|
||||
*/
|
||||
public Set<Permission> getNewPermissions() {
|
||||
return newPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any permissions that have not yet been deleted.
|
||||
* @return the permissions that need to be deleted.
|
||||
*/
|
||||
public Set<Permission> getRemovedPermissions() {
|
||||
return removedPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the new and removed permission sets after they are
|
||||
* no longer needed.
|
||||
*/
|
||||
public void resetPermissions() {
|
||||
newPermissions.clear();
|
||||
removedPermissions.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of this user in the database, if it exists.
|
||||
*
|
||||
* @return The ID of this user in the database, or null if this user
|
||||
* was not retrieved from the database.
|
||||
*/
|
||||
public Integer getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of this user to the given value.
|
||||
*
|
||||
* @param userID The ID to assign to this user.
|
||||
*/
|
||||
public void setUserID(Integer userID) {
|
||||
this.userID = userID;
|
||||
public MySQLUser(UserModel userModel) {
|
||||
this.userModel = userModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Permission> getPermissions() throws GuacamoleException {
|
||||
return Collections.unmodifiableSet(permissions);
|
||||
public UserModel getModel() {
|
||||
return userModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Permission permission) throws GuacamoleException {
|
||||
return permissions.contains(permission);
|
||||
public void setModel(UserModel userModel) {
|
||||
this.userModel = userModel;
|
||||
this.password = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPermission(Permission permission) throws GuacamoleException {
|
||||
permissions.add(permission);
|
||||
newPermissions.add(permission);
|
||||
removedPermissions.remove(permission);
|
||||
public String getUsername() {
|
||||
return userModel.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePermission(Permission permission) throws GuacamoleException {
|
||||
permissions.remove(permission);
|
||||
newPermissions.remove(permission);
|
||||
removedPermissions.add(permission);
|
||||
public void setUsername(String username) {
|
||||
userModel.setUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPassword(String password) {
|
||||
|
||||
// Store plaintext password internally
|
||||
this.password = password;
|
||||
|
||||
// Generate new salt and hash given password using newly-generated salt
|
||||
byte[] salt = saltService.generateSalt();
|
||||
byte[] hash = encryptionService.createPasswordHash(password, salt);
|
||||
|
||||
// Set stored salt and hash
|
||||
userModel.setPasswordSalt(salt);
|
||||
userModel.setPasswordHash(hash);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemPermissionSet getSystemPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleSystemPermissionSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermissionSet<String> getConnectionPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleObjectPermissionSet<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermissionSet<String> getConnectionGroupPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleObjectPermissionSet<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermissionSet<String> getUserPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleObjectPermissionSet<String>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -24,13 +24,15 @@ package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.simple.SimpleConnectionDirectory;
|
||||
import org.glyptodon.guacamole.net.auth.simple.SimpleConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.simple.SimpleConnectionGroupDirectory;
|
||||
|
||||
/**
|
||||
* The MySQL representation of a UserContext.
|
||||
@@ -39,10 +41,9 @@ import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
public class MySQLUserContext implements UserContext {
|
||||
|
||||
/**
|
||||
* The the user owning this context. The permissions of this user dictate
|
||||
* the access given via the user and connection directories.
|
||||
* The the user owning this context.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
private MySQLUser currentUser;
|
||||
|
||||
/**
|
||||
* User directory restricted by the permissions of the user associated
|
||||
@@ -51,36 +52,19 @@ public class MySQLUserContext implements UserContext {
|
||||
@Inject
|
||||
private UserDirectory userDirectory;
|
||||
|
||||
/**
|
||||
* The root connection group.
|
||||
*/
|
||||
@Inject
|
||||
private MySQLConnectionGroup rootConnectionGroup;
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Initializes the user and directories associated with this context.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user owning this context.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
public void init(MySQLUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
userDirectory.init(currentUser);
|
||||
rootConnectionGroup.init(null, null,
|
||||
MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
|
||||
MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
|
||||
ConnectionGroup.Type.ORGANIZATIONAL, currentUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User self() {
|
||||
return userService.retrieveUser(currentUser.getUserID());
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,7 +74,11 @@ public class MySQLUserContext implements UserContext {
|
||||
|
||||
@Override
|
||||
public ConnectionGroup getRootConnectionGroup() throws GuacamoleException {
|
||||
return rootConnectionGroup;
|
||||
/* STUB */
|
||||
return new SimpleConnectionGroup("ROOT", "ROOT",
|
||||
new SimpleConnectionDirectory(Collections.EMPTY_MAP),
|
||||
new SimpleConnectionGroupDirectory(Collections.EMPTY_LIST)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -23,686 +23,76 @@
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
|
||||
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.model.SystemPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||
import org.glyptodon.guacamole.GuacamoleUnsupportedException;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ConnectionGroupPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ConnectionPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.Permission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.UserPermission;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the User Directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class UserDirectory implements Directory<String, User> {
|
||||
|
||||
/**
|
||||
* The user this user directory belongs to. Access is based on his/her
|
||||
* permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
* Service for managing user objects.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Service for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for accessing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* DAO for accessing user permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private UserPermissionMapper userPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection group permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing system permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private SystemPermissionMapper systemPermissionDAO;
|
||||
|
||||
/**
|
||||
* Service for checking various permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Set the user for this directory.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions define the visibility of other users in
|
||||
* this directory.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public org.glyptodon.guacamole.net.auth.User get(String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get user
|
||||
MySQLUser user = userService.retrieveUser(identifier);
|
||||
|
||||
if(user == null)
|
||||
return null;
|
||||
|
||||
// Verify access is granted
|
||||
permissionCheckService.verifyUserAccess(currentUser,
|
||||
user.getUserID(),
|
||||
MySQLConstants.USER_READ);
|
||||
|
||||
// Return user
|
||||
return user;
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
return permissionCheckService.retrieveUsernames(currentUser,
|
||||
MySQLConstants.USER_READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void add(org.glyptodon.guacamole.net.auth.User object)
|
||||
throws GuacamoleException {
|
||||
|
||||
String username = object.getUsername().trim();
|
||||
if(username.isEmpty())
|
||||
throw new GuacamoleClientException("The username cannot be blank.");
|
||||
|
||||
// Verify current user has permission to create users
|
||||
permissionCheckService.verifySystemAccess(currentUser,
|
||||
MySQLConstants.SYSTEM_USER_CREATE);
|
||||
Preconditions.checkNotNull(object);
|
||||
|
||||
// Verify that no user already exists with this username.
|
||||
MySQLUser previousUser = userService.retrieveUser(username);
|
||||
if(previousUser != null)
|
||||
throw new GuacamoleClientException("That username is already in use.");
|
||||
|
||||
// Create new user
|
||||
MySQLUser user = userService.createUser(username, object.getPassword());
|
||||
|
||||
// Create permissions of new user in database
|
||||
createPermissions(user.getUserID(), object.getPermissions());
|
||||
|
||||
// Give the current user full access to the newly created user.
|
||||
UserPermissionKey newUserPermission = new UserPermissionKey();
|
||||
newUserPermission.setUser_id(currentUser.getUserID());
|
||||
newUserPermission.setAffected_user_id(user.getUserID());
|
||||
|
||||
// READ permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_READ);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
// UPDATE permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_UPDATE);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
// DELETE permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_DELETE);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
// ADMINISTER permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_ADMINISTER);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given permissions to the given user.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The permissions to add.
|
||||
* @throws GuacamoleException If an error occurs while updating the
|
||||
* permissions of the given user.
|
||||
*/
|
||||
private void createPermissions(int user_id, Set<Permission> permissions) throws GuacamoleException {
|
||||
|
||||
// Partition given permissions by permission type
|
||||
List<UserPermission> newUserPermissions = new ArrayList<UserPermission>();
|
||||
List<ConnectionPermission> newConnectionPermissions = new ArrayList<ConnectionPermission>();
|
||||
List<ConnectionGroupPermission> newConnectionGroupPermissions = new ArrayList<ConnectionGroupPermission>();
|
||||
List<SystemPermission> newSystemPermissions = new ArrayList<SystemPermission>();
|
||||
|
||||
for (Permission permission : permissions) {
|
||||
|
||||
if (permission instanceof UserPermission)
|
||||
newUserPermissions.add((UserPermission) permission);
|
||||
|
||||
else if (permission instanceof ConnectionPermission)
|
||||
newConnectionPermissions.add((ConnectionPermission) permission);
|
||||
|
||||
else if (permission instanceof ConnectionGroupPermission)
|
||||
newConnectionGroupPermissions.add((ConnectionGroupPermission) permission);
|
||||
|
||||
else if (permission instanceof SystemPermission)
|
||||
newSystemPermissions.add((SystemPermission) permission);
|
||||
}
|
||||
|
||||
// Create the new permissions
|
||||
createUserPermissions(user_id, newUserPermissions);
|
||||
createConnectionPermissions(user_id, newConnectionPermissions);
|
||||
createConnectionGroupPermissions(user_id, newConnectionGroupPermissions);
|
||||
createSystemPermissions(user_id, newSystemPermissions);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given permissions from the given user.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The permissions to remove.
|
||||
* @throws GuacamoleException If an error occurs while updating the
|
||||
* permissions of the given user.
|
||||
*/
|
||||
private void removePermissions(int user_id, Set<Permission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Partition given permissions by permission type
|
||||
List<UserPermission> removedUserPermissions = new ArrayList<UserPermission>();
|
||||
List<ConnectionPermission> removedConnectionPermissions = new ArrayList<ConnectionPermission>();
|
||||
List<ConnectionGroupPermission> removedConnectionGroupPermissions = new ArrayList<ConnectionGroupPermission>();
|
||||
List<SystemPermission> removedSystemPermissions = new ArrayList<SystemPermission>();
|
||||
|
||||
for (Permission permission : permissions) {
|
||||
|
||||
if (permission instanceof UserPermission)
|
||||
removedUserPermissions.add((UserPermission) permission);
|
||||
|
||||
else if (permission instanceof ConnectionPermission)
|
||||
removedConnectionPermissions.add((ConnectionPermission) permission);
|
||||
|
||||
else if (permission instanceof ConnectionGroupPermission)
|
||||
removedConnectionGroupPermissions.add((ConnectionGroupPermission) permission);
|
||||
|
||||
else if (permission instanceof SystemPermission)
|
||||
removedSystemPermissions.add((SystemPermission) permission);
|
||||
}
|
||||
|
||||
// Delete the removed permissions.
|
||||
deleteUserPermissions(user_id, removedUserPermissions);
|
||||
deleteConnectionPermissions(user_id, removedConnectionPermissions);
|
||||
deleteConnectionGroupPermissions(user_id, removedConnectionGroupPermissions);
|
||||
deleteSystemPermissions(user_id, removedSystemPermissions);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the given user permissions for the given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The new permissions the given user should have when
|
||||
* this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void createUserPermissions(int user_id,
|
||||
Collection<UserPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable user IDs
|
||||
List<Integer> administerableUserIDs =
|
||||
permissionCheckService.retrieveUserIDs(currentUser,
|
||||
MySQLConstants.USER_ADMINISTER);
|
||||
|
||||
// Get set of usernames corresponding to administerable users
|
||||
Map<String, Integer> administerableUsers =
|
||||
userService.translateUsernames(administerableUserIDs);
|
||||
|
||||
// Insert all given permissions
|
||||
for (UserPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer affected_id =
|
||||
administerableUsers.get(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these users
|
||||
if (affected_id == null)
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + currentUser.getUserID()
|
||||
+ " does not have permission to administrate user "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
// Create new permission
|
||||
UserPermissionKey newPermission = new UserPermissionKey();
|
||||
newPermission.setUser_id(currentUser.getUserID());
|
||||
newPermission.setPermission(MySQLConstants.getUserConstant(permission.getType()));
|
||||
newPermission.setAffected_user_id(affected_id);
|
||||
userPermissionDAO.insert(newPermission);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permissions having to do with users for a given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void deleteUserPermissions(int user_id,
|
||||
Collection<UserPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable user IDs
|
||||
List<Integer> administerableUserIDs =
|
||||
permissionCheckService.retrieveUserIDs(currentUser,
|
||||
MySQLConstants.USER_ADMINISTER);
|
||||
|
||||
// Get set of usernames corresponding to administerable users
|
||||
Map<String, Integer> administerableUsers =
|
||||
userService.translateUsernames(administerableUserIDs);
|
||||
|
||||
// Delete requested permissions
|
||||
for (UserPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer affected_id =
|
||||
administerableUsers.get(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these users
|
||||
if (affected_id == null)
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + currentUser.getUserID()
|
||||
+ " does not have permission to administrate user "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
// Delete requested permission
|
||||
UserPermissionExample userPermissionExample = new UserPermissionExample();
|
||||
userPermissionExample.createCriteria()
|
||||
.andUser_idEqualTo(user_id)
|
||||
.andPermissionEqualTo(MySQLConstants.getUserConstant(permission.getType()))
|
||||
.andAffected_user_idEqualTo(affected_id);
|
||||
userPermissionDAO.deleteByExample(userPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create any new permissions having to do with connections for a given
|
||||
* user.
|
||||
*
|
||||
* @param user_id The ID of the user to assign or remove permissions from.
|
||||
* @param permissions The new permissions the user should have after this
|
||||
* operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is deniedD
|
||||
*/
|
||||
private void createConnectionPermissions(int user_id,
|
||||
Collection<ConnectionPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable connection IDs
|
||||
Set<Integer> administerableConnectionIDs = Sets.<Integer>newHashSet(
|
||||
permissionCheckService.retrieveConnectionIDs(currentUser,
|
||||
MySQLConstants.CONNECTION_ADMINISTER));
|
||||
|
||||
// Insert all given permissions
|
||||
for (ConnectionPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer connection_id = Integer.valueOf(permission.getObjectIdentifier());
|
||||
|
||||
// Throw exception if permission to administer this connection
|
||||
// is not granted
|
||||
if (!administerableConnectionIDs.contains(connection_id))
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + currentUser.getUserID()
|
||||
+ " does not have permission to administrate connection "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
// Create new permission
|
||||
ConnectionPermissionKey newPermission = new ConnectionPermissionKey();
|
||||
newPermission.setUser_id(user_id);
|
||||
newPermission.setPermission(MySQLConstants.getConnectionConstant(permission.getType()));
|
||||
newPermission.setConnection_id(connection_id);
|
||||
connectionPermissionDAO.insert(newPermission);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create any new permissions having to do with connection groups
|
||||
* for a given user.
|
||||
*
|
||||
* @param user_id The ID of the user to assign or remove permissions from.
|
||||
* @param permissions The new permissions the user should have after this
|
||||
* operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is deniedD
|
||||
*/
|
||||
private void createConnectionGroupPermissions(int user_id,
|
||||
Collection<ConnectionGroupPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable connection group IDs
|
||||
Set<Integer> administerableConnectionGroupIDs = Sets.<Integer>newHashSet(
|
||||
permissionCheckService.retrieveConnectionGroupIDs(currentUser,
|
||||
MySQLConstants.CONNECTION_GROUP_ADMINISTER));
|
||||
|
||||
// Insert all given permissions
|
||||
for (ConnectionGroupPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer connection_group_id = Integer.valueOf(permission.getObjectIdentifier());
|
||||
|
||||
// Throw exception if permission to administer this connection group
|
||||
// is not granted
|
||||
if (!administerableConnectionGroupIDs.contains(connection_group_id))
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + currentUser.getUserID()
|
||||
+ " does not have permission to administrate connection group"
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
// Create new permission
|
||||
ConnectionGroupPermissionKey newPermission = new ConnectionGroupPermissionKey();
|
||||
newPermission.setUser_id(user_id);
|
||||
newPermission.setPermission(MySQLConstants.getConnectionGroupConstant(permission.getType()));
|
||||
newPermission.setConnection_group_id(connection_group_id);
|
||||
connectionGroupPermissionDAO.insert(newPermission);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permissions having to do with connections for a given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void deleteConnectionPermissions(int user_id,
|
||||
Collection<ConnectionPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable connection IDs
|
||||
Set<Integer> administerableConnectionIDs = Sets.<Integer>newHashSet(
|
||||
permissionCheckService.retrieveConnectionIDs(currentUser,
|
||||
MySQLConstants.CONNECTION_ADMINISTER));
|
||||
|
||||
// Delete requested permissions
|
||||
for (ConnectionPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer connection_id = Integer.valueOf(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these connections
|
||||
if (!administerableConnectionIDs.contains(connection_id))
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + currentUser.getUserID()
|
||||
+ " does not have permission to administrate connection "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
||||
connectionPermissionExample.createCriteria()
|
||||
.andUser_idEqualTo(user_id)
|
||||
.andPermissionEqualTo(MySQLConstants.getConnectionConstant(permission.getType()))
|
||||
.andConnection_idEqualTo(connection_id);
|
||||
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permissions having to do with connection groups for a given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void deleteConnectionGroupPermissions(int user_id,
|
||||
Collection<ConnectionGroupPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable connection group IDs
|
||||
Set<Integer> administerableConnectionGroupIDs = Sets.<Integer>newHashSet(
|
||||
permissionCheckService.retrieveConnectionGroupIDs(currentUser,
|
||||
MySQLConstants.CONNECTION_GROUP_ADMINISTER));
|
||||
|
||||
// Delete requested permissions
|
||||
for (ConnectionGroupPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer connection_group_id = Integer.valueOf(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these connection groups
|
||||
if (!administerableConnectionGroupIDs.contains(connection_group_id))
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + currentUser.getUserID()
|
||||
+ " does not have permission to administrate connection group"
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
ConnectionGroupPermissionExample connectionGroupPermissionExample = new ConnectionGroupPermissionExample();
|
||||
connectionGroupPermissionExample.createCriteria()
|
||||
.andUser_idEqualTo(user_id)
|
||||
.andPermissionEqualTo(MySQLConstants.getConnectionGroupConstant(permission.getType()))
|
||||
.andConnection_group_idEqualTo(connection_group_id);
|
||||
connectionGroupPermissionDAO.deleteByExample(connectionGroupPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create any new system permissions for a given user. All permissions in
|
||||
* the given list will be inserted.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The new system permissions that the given user should
|
||||
* have when this operation completes.
|
||||
* @throws GuacamoleException If permission to administer system permissions
|
||||
* is denied.
|
||||
*/
|
||||
private void createSystemPermissions(int user_id,
|
||||
Collection<SystemPermission> permissions) throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Only a system administrator can add system permissions.
|
||||
permissionCheckService.verifySystemAccess(
|
||||
currentUser, SystemPermission.Type.ADMINISTER.name());
|
||||
|
||||
// Insert all requested permissions
|
||||
for (SystemPermission permission : permissions) {
|
||||
|
||||
// Insert permission
|
||||
SystemPermissionKey newSystemPermission = new SystemPermissionKey();
|
||||
newSystemPermission.setUser_id(user_id);
|
||||
newSystemPermission.setPermission(MySQLConstants.getSystemConstant(permission.getType()));
|
||||
systemPermissionDAO.insert(newSystemPermission);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete system permissions for a given user. All permissions in
|
||||
* the given list will be removed from the user.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If the permissions specified could not be
|
||||
* removed due to system restrictions.
|
||||
*/
|
||||
private void deleteSystemPermissions(int user_id,
|
||||
Collection<SystemPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if (permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Prevent self-de-adminifying
|
||||
if (user_id == currentUser.getUserID())
|
||||
throw new GuacamoleUnsupportedException("Removing your own administrative permissions is not allowed.");
|
||||
|
||||
// Build list of requested system permissions
|
||||
List<String> systemPermissionTypes = new ArrayList<String>();
|
||||
for (SystemPermission permission : permissions)
|
||||
systemPermissionTypes.add(MySQLConstants.getSystemConstant(permission.getType()));
|
||||
|
||||
// Delete the requested system permissions for this user
|
||||
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
||||
systemPermissionExample.createCriteria().andUser_idEqualTo(user_id)
|
||||
.andPermissionIn(systemPermissionTypes);
|
||||
systemPermissionDAO.deleteByExample(systemPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void update(org.glyptodon.guacamole.net.auth.User object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If user not actually from this auth provider, we can't handle updated
|
||||
// permissions.
|
||||
if (!(object instanceof MySQLUser))
|
||||
throw new GuacamoleUnsupportedException("User not from database.");
|
||||
|
||||
MySQLUser mySQLUser = (MySQLUser) object;
|
||||
|
||||
// Validate permission to update this user is granted
|
||||
permissionCheckService.verifyUserAccess(currentUser,
|
||||
mySQLUser.getUserID(),
|
||||
MySQLConstants.USER_UPDATE);
|
||||
|
||||
// Update the user in the database
|
||||
userService.updateUser(mySQLUser);
|
||||
|
||||
// Update permissions in database
|
||||
createPermissions(mySQLUser.getUserID(), mySQLUser.getNewPermissions());
|
||||
removePermissions(mySQLUser.getUserID(), mySQLUser.getRemovedPermissions());
|
||||
|
||||
// The appropriate permissions have been inserted and deleted, so
|
||||
// reset the new and removed permission sets.
|
||||
mySQLUser.resetPermissions();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get user pending deletion
|
||||
MySQLUser user = userService.retrieveUser(identifier);
|
||||
|
||||
// Prevent self-deletion
|
||||
if (user.getUserID() == currentUser.getUserID())
|
||||
throw new GuacamoleUnsupportedException("Deleting your own user is not allowed.");
|
||||
|
||||
// Validate current user has permission to remove the specified user
|
||||
permissionCheckService.verifyUserAccess(currentUser,
|
||||
user.getUserID(),
|
||||
MySQLConstants.USER_DELETE);
|
||||
|
||||
// Delete specified user
|
||||
userService.deleteUser(user.getUserID());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(String identifier, Directory<String, User> groupIdentifier)
|
||||
throws GuacamoleException {
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public User get(String identifier) throws GuacamoleException {
|
||||
return userService.retrieveObject(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<User> getAll(Collection<String> identifiers) throws GuacamoleException {
|
||||
return Collections.<User>unmodifiableCollection(userService.retrieveObjects(identifiers));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
// STUB
|
||||
return userService.getIdentifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void add(User object) throws GuacamoleException {
|
||||
// STUB
|
||||
MySQLUser user = (MySQLUser) object;
|
||||
userService.createObject(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void update(User object) throws GuacamoleException {
|
||||
// STUB
|
||||
MySQLUser user = (MySQLUser) object;
|
||||
userService.updateObject(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
// STUB
|
||||
userService.deleteObject(identifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.dao;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Common interface for objects that will ultimately be made available through
|
||||
* the Directory class. All such objects will need the same base set of queries
|
||||
* to fulfill the needs of the Directory class.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <T>
|
||||
* The type of object contained within the directory whose objects are
|
||||
* mapped by this mapper.
|
||||
*/
|
||||
public interface DirectoryObjectMapper<T> {
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all objects.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all objects.
|
||||
*/
|
||||
Set<String> selectIdentifiers();
|
||||
|
||||
/**
|
||||
* Selects all objects which have the given identifiers. If an identifier
|
||||
* has no corresponding object, it will be ignored.
|
||||
*
|
||||
* @param identifiers
|
||||
* The identifiers of the objects to return.
|
||||
*
|
||||
* @return
|
||||
* A Collection of all objects having the given identifiers.
|
||||
*/
|
||||
Collection<T> select(@Param("identifiers") Collection<String> identifiers);
|
||||
|
||||
/**
|
||||
* Inserts the given object into the database. If the object already
|
||||
* exists, this will result in an error.
|
||||
*
|
||||
* @param object
|
||||
* The object to insert.
|
||||
*
|
||||
* @return
|
||||
* The number of rows inserted.
|
||||
*/
|
||||
int insert(@Param("object") T object);
|
||||
|
||||
/**
|
||||
* Deletes the given object into the database. If the object does not
|
||||
* exist, this operation has no effect.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to delete.
|
||||
*
|
||||
* @return
|
||||
* The number of rows deleted.
|
||||
*/
|
||||
int delete(@Param("identifier") String identifier);
|
||||
|
||||
/**
|
||||
* Updates the given existing object in the database. If the object does
|
||||
* not actually exist, this operation has no effect.
|
||||
*
|
||||
* @param object
|
||||
* The object to update.
|
||||
*
|
||||
* @return
|
||||
* The number of rows updated.
|
||||
*/
|
||||
int update(@Param("object") T object);
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.dao;
|
||||
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for user objects.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface UserMapper extends DirectoryObjectMapper<UserModel> {
|
||||
|
||||
/**
|
||||
* Returns the user having the given username and password, if any. If no
|
||||
* such user exists, null is returned.
|
||||
*
|
||||
* @param username
|
||||
* The username of the user to return.
|
||||
*
|
||||
* @param password
|
||||
* The password of the user to return.
|
||||
*
|
||||
* @return
|
||||
* The user having the given username and password, or null if no such
|
||||
* user exists.
|
||||
*/
|
||||
UserModel selectByCredentials(@Param("username") String username,
|
||||
@Param("password") String password);
|
||||
|
||||
}
|
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.model;
|
||||
|
||||
/**
|
||||
* Object representation of a Guacamole user, as represented in the database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class UserModel {
|
||||
|
||||
/**
|
||||
* The ID of this user in the database, if any.
|
||||
*/
|
||||
private Integer userID;
|
||||
|
||||
/**
|
||||
* The unique username which identifies this user.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* The SHA-256 hash of the password and salt.
|
||||
*/
|
||||
private byte[] passwordHash;
|
||||
|
||||
/**
|
||||
* The 32-byte random binary password salt that was appended to the
|
||||
* password prior to hashing.
|
||||
*/
|
||||
private byte[] passwordSalt;
|
||||
|
||||
/**
|
||||
* Creates a new, empty user.
|
||||
*/
|
||||
public UserModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username that uniquely identifies this user.
|
||||
*
|
||||
* @return
|
||||
* The username that uniquely identifies this user.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username that uniquely identifies this user.
|
||||
*
|
||||
* @param username
|
||||
* The username that uniquely identifies this user.
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of this user in the database, if it exists.
|
||||
*
|
||||
* @return
|
||||
* The ID of this user in the database, or null if this user was not
|
||||
* retrieved from the database.
|
||||
*/
|
||||
public Integer getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of this user to the given value.
|
||||
*
|
||||
* @param userID
|
||||
* The ID to assign to this user.
|
||||
*/
|
||||
public void setUserID(Integer userID) {
|
||||
this.userID = userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash of this user's password and password salt. This may be
|
||||
* null if the user was not retrieved from the database, and setPassword()
|
||||
* has not yet been called.
|
||||
*
|
||||
* @return
|
||||
* The hash of this user's password and password salt.
|
||||
*/
|
||||
public byte[] getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash of this user's password and password salt. This is
|
||||
* normally only set upon retrieval from the database, or through a call
|
||||
* to the higher-level setPassword() function.
|
||||
*
|
||||
* @param passwordHash
|
||||
* The hash of this user's password and password salt.
|
||||
*/
|
||||
public void setPasswordHash(byte[] passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the random salt that was used when generating this user's
|
||||
* password hash. This may be null if the user was not retrieved from the
|
||||
* database, and setPassword() has not yet been called.
|
||||
*
|
||||
* @return
|
||||
* The random salt that was used when generating this user's password
|
||||
* hash.
|
||||
*/
|
||||
public byte[] getPasswordSalt() {
|
||||
return passwordSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the random salt that was used when generating this user's password
|
||||
* hash. This is normally only set upon retrieval from the database, or
|
||||
* through a call to the higher-level setPassword() function.
|
||||
*
|
||||
* @param passwordSalt
|
||||
* The random salt used when generating this user's password hash.
|
||||
*/
|
||||
public void setPasswordSalt(byte[] passwordSalt) {
|
||||
this.passwordSalt = passwordSalt;
|
||||
}
|
||||
|
||||
}
|
@@ -1,446 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroup;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample.Criteria;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||
import org.glyptodon.guacamole.GuacamoleClientTooManyException;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||
import org.glyptodon.guacamole.GuacamoleServerBusyException;
|
||||
import org.glyptodon.guacamole.properties.GuacamoleProperties;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating connection groups.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ConnectionGroupService {
|
||||
|
||||
/**
|
||||
* Service for managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupMapper connectionGroupDAO;
|
||||
|
||||
/**
|
||||
* Provider which creates MySQLConnectionGroups.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLConnectionGroup> mysqlConnectionGroupProvider;
|
||||
|
||||
/**
|
||||
* The map of all active connections.
|
||||
*/
|
||||
@Inject
|
||||
private ActiveConnectionMap activeConnectionMap;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the connection group having the given
|
||||
* name from the database.
|
||||
*
|
||||
* @param name
|
||||
* The name of the connection to return.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection group.
|
||||
*
|
||||
* @return
|
||||
* The connection having the given name, or null if no such connection
|
||||
* group could be found.
|
||||
*/
|
||||
public MySQLConnectionGroup retrieveConnectionGroup(String name, Integer parentID,
|
||||
AuthenticatedUser currentUser) {
|
||||
|
||||
// Create criteria
|
||||
ConnectionGroupExample example = new ConnectionGroupExample();
|
||||
Criteria criteria = example.createCriteria().andConnection_group_nameEqualTo(name);
|
||||
if(parentID != null)
|
||||
criteria.andParent_idEqualTo(parentID);
|
||||
else
|
||||
criteria.andParent_idIsNull();
|
||||
|
||||
// Query connection group by name and parentID
|
||||
List<ConnectionGroup> connectionGroups =
|
||||
connectionGroupDAO.selectByExample(example);
|
||||
|
||||
// If no connection group found, return null
|
||||
if(connectionGroups.isEmpty())
|
||||
return null;
|
||||
|
||||
// Otherwise, return found connection
|
||||
return toMySQLConnectionGroup(connectionGroups.get(0), currentUser);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the connection group having the given unique identifier
|
||||
* from the database.
|
||||
*
|
||||
* @param uniqueIdentifier
|
||||
* The unique identifier of the connection group to retrieve.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection group.
|
||||
*
|
||||
* @return
|
||||
* The connection group having the given unique identifier, or null if
|
||||
* no such connection group was found.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the connection group.
|
||||
*/
|
||||
public MySQLConnectionGroup retrieveConnectionGroup(String uniqueIdentifier,
|
||||
AuthenticatedUser currentUser) throws GuacamoleException {
|
||||
|
||||
// The unique identifier for a MySQLConnectionGroup is the database ID
|
||||
Integer connectionGroupID = null;
|
||||
|
||||
// Try to parse the connectionID if it's not the root group
|
||||
if(!MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER.equals(uniqueIdentifier)) {
|
||||
try {
|
||||
connectionGroupID = Integer.parseInt(uniqueIdentifier);
|
||||
} catch(NumberFormatException e) {
|
||||
throw new GuacamoleResourceNotFoundException("Invalid connection group ID.");
|
||||
}
|
||||
}
|
||||
|
||||
return retrieveConnectionGroup(connectionGroupID, currentUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the connection group having the given ID from the database.
|
||||
*
|
||||
* @param id
|
||||
* The ID of the connection group to retrieve.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*
|
||||
* @return
|
||||
* The connection group having the given ID, or null if no such
|
||||
* connection was found.
|
||||
*/
|
||||
public MySQLConnectionGroup retrieveConnectionGroup(Integer id, AuthenticatedUser currentUser) {
|
||||
|
||||
// This is the root connection group, so just create it here
|
||||
if(id == null) {
|
||||
MySQLConnectionGroup connectionGroup = mysqlConnectionGroupProvider.get();
|
||||
connectionGroup.init(null, null,
|
||||
MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
|
||||
MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
|
||||
org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.ORGANIZATIONAL,
|
||||
currentUser);
|
||||
|
||||
return connectionGroup;
|
||||
}
|
||||
|
||||
// Query connection by ID
|
||||
ConnectionGroup connectionGroup = connectionGroupDAO.selectByPrimaryKey(id);
|
||||
|
||||
// If no connection found, return null
|
||||
if(connectionGroup == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, return found connection
|
||||
return toMySQLConnectionGroup(connectionGroup, currentUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the connection within the given group with the lowest number
|
||||
* of currently active users.
|
||||
*
|
||||
* @param group
|
||||
* The group to load balance across.
|
||||
*
|
||||
* @param info
|
||||
* The information to use when performing the connection handshake.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who is connecting to the socket.
|
||||
*
|
||||
* @return
|
||||
* The connected socket.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while connecting the socket.
|
||||
*/
|
||||
public GuacamoleSocket connect(MySQLConnectionGroup group,
|
||||
GuacamoleClientInformation info, AuthenticatedUser currentUser)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get all connections in the group.
|
||||
List<Integer> connectionIDs = connectionService.getAllConnectionIDs
|
||||
(group.getConnectionGroupID());
|
||||
|
||||
synchronized (activeConnectionMap) {
|
||||
|
||||
// Get the least used connection.
|
||||
Integer leastUsedConnectionID =
|
||||
activeConnectionMap.getLeastUsedConnection(connectionIDs);
|
||||
|
||||
if(leastUsedConnectionID == null)
|
||||
throw new GuacamoleResourceNotFoundException("No connections found in group.");
|
||||
|
||||
if(GuacamoleProperties.getProperty(
|
||||
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
||||
&& activeConnectionMap.isActive(leastUsedConnectionID))
|
||||
throw new GuacamoleServerBusyException
|
||||
("Cannot connect. All connections are in use.");
|
||||
|
||||
if(GuacamoleProperties.getProperty(
|
||||
MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true)
|
||||
&& activeConnectionMap.isConnectionGroupUserActive(group.getConnectionGroupID(), currentUser.getUserID()))
|
||||
throw new GuacamoleClientTooManyException
|
||||
("Cannot connect. Connection group already in use by this user.");
|
||||
|
||||
// Get the connection
|
||||
MySQLConnection connection = connectionService
|
||||
.retrieveConnection(leastUsedConnectionID, currentUser);
|
||||
|
||||
// Connect to the connection
|
||||
return connectionService.connect(connection, info, currentUser, group.getConnectionGroupID());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the IDs of all connection groups with a given parent ID.
|
||||
* @param parentID The ID of the parent for all the queried connection groups.
|
||||
* @return a list of the IDs of all connection groups with a given parent ID.
|
||||
*/
|
||||
public List<Integer> getAllConnectionGroupIDs(Integer parentID) {
|
||||
|
||||
// Create criteria
|
||||
ConnectionGroupExample example = new ConnectionGroupExample();
|
||||
Criteria criteria = example.createCriteria();
|
||||
|
||||
if(parentID != null)
|
||||
criteria.andParent_idEqualTo(parentID);
|
||||
else
|
||||
criteria.andParent_idIsNull();
|
||||
|
||||
// Query the connections
|
||||
List<ConnectionGroup> connectionGroups = connectionGroupDAO.selectByExample(example);
|
||||
|
||||
// List of IDs of connections with the given parent
|
||||
List<Integer> connectionGroupIDs = new ArrayList<Integer>();
|
||||
|
||||
for(ConnectionGroup connectionGroup : connectionGroups) {
|
||||
connectionGroupIDs.add(connectionGroup.getConnection_group_id());
|
||||
}
|
||||
|
||||
return connectionGroupIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the identifiers of all the connection groups defined in the system
|
||||
* with a certain parentID.
|
||||
*
|
||||
* @return A Set of identifiers of all the connection groups defined
|
||||
* in the system with the given parentID.
|
||||
*/
|
||||
public Set<String> getAllConnectionGroupIdentifiers(Integer parentID) {
|
||||
|
||||
// Set of all present connection identifiers
|
||||
Set<String> identifiers = new HashSet<String>();
|
||||
|
||||
// Set up Criteria
|
||||
ConnectionGroupExample example = new ConnectionGroupExample();
|
||||
Criteria criteria = example.createCriteria();
|
||||
if(parentID != null)
|
||||
criteria.andParent_idEqualTo(parentID);
|
||||
else
|
||||
criteria.andParent_idIsNull();
|
||||
|
||||
// Query connection identifiers
|
||||
List<ConnectionGroup> connectionGroups =
|
||||
connectionGroupDAO.selectByExample(example);
|
||||
for (ConnectionGroup connectionGroup : connectionGroups)
|
||||
identifiers.add(String.valueOf(connectionGroup.getConnection_group_id()));
|
||||
|
||||
return identifiers;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given database-retrieved Connection into a MySQLConnection.
|
||||
* The parameters of the given connection will be read and added to the
|
||||
* MySQLConnection in the process.
|
||||
*
|
||||
* @param connection
|
||||
* The connection to convert.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*
|
||||
* @return
|
||||
* A new MySQLConnection containing all data associated with the
|
||||
* specified connection.
|
||||
*/
|
||||
private MySQLConnectionGroup toMySQLConnectionGroup(ConnectionGroup connectionGroup,
|
||||
AuthenticatedUser currentUser) {
|
||||
|
||||
// Create new MySQLConnection from retrieved data
|
||||
MySQLConnectionGroup mySQLConnectionGroup = mysqlConnectionGroupProvider.get();
|
||||
|
||||
String mySqlType = connectionGroup.getType();
|
||||
org.glyptodon.guacamole.net.auth.ConnectionGroup.Type authType;
|
||||
|
||||
if(mySqlType.equals(MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL))
|
||||
authType = org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.ORGANIZATIONAL;
|
||||
else
|
||||
authType = org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.BALANCING;
|
||||
|
||||
mySQLConnectionGroup.init(
|
||||
connectionGroup.getConnection_group_id(),
|
||||
connectionGroup.getParent_id(),
|
||||
connectionGroup.getConnection_group_name(),
|
||||
Integer.toString(connectionGroup.getConnection_group_id()),
|
||||
authType,
|
||||
currentUser
|
||||
);
|
||||
|
||||
return mySQLConnectionGroup;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection group IDs of all the connection groups defined in the system.
|
||||
*
|
||||
* @return A list of connection group IDs of all the connection groups defined in the system.
|
||||
*/
|
||||
public List<Integer> getAllConnectionGroupIDs() {
|
||||
|
||||
// Set of all present connection group IDs
|
||||
List<Integer> connectionGroupIDs = new ArrayList<Integer>();
|
||||
|
||||
// Query all connection IDs
|
||||
List<ConnectionGroup> connections =
|
||||
connectionGroupDAO.selectByExample(new ConnectionGroupExample());
|
||||
for (ConnectionGroup connection : connections)
|
||||
connectionGroupIDs.add(connection.getConnection_group_id());
|
||||
|
||||
return connectionGroupIDs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection group having the given name and type.
|
||||
*
|
||||
* @param name
|
||||
* The name to assign to the new connection group.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who created this connection group.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent of the new connection group, if any.
|
||||
*
|
||||
* @param type
|
||||
* The type of the new connection group.
|
||||
*
|
||||
* @return A new MySQLConnectionGroup containing the data of the newly created
|
||||
* connection group.
|
||||
*/
|
||||
public MySQLConnectionGroup createConnectionGroup(String name, AuthenticatedUser currentUser,
|
||||
Integer parentID, String type) {
|
||||
|
||||
// Initialize database connection
|
||||
ConnectionGroup connectionGroup = new ConnectionGroup();
|
||||
connectionGroup.setConnection_group_name(name);
|
||||
connectionGroup.setParent_id(parentID);
|
||||
connectionGroup.setType(type);
|
||||
|
||||
// Create connection
|
||||
connectionGroupDAO.insert(connectionGroup);
|
||||
return toMySQLConnectionGroup(connectionGroup, currentUser);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the connection group in the database corresponding to the given
|
||||
* MySQLConnectionGroup.
|
||||
*
|
||||
* @param mySQLConnectionGroup The MySQLConnectionGroup to update (save)
|
||||
* to the database.
|
||||
* This connection must already exist.
|
||||
*/
|
||||
public void updateConnectionGroup(MySQLConnectionGroup mySQLConnectionGroup) {
|
||||
|
||||
// Populate connection
|
||||
ConnectionGroup connectionGroup = new ConnectionGroup();
|
||||
connectionGroup.setConnection_group_id(mySQLConnectionGroup.getConnectionGroupID());
|
||||
connectionGroup.setParent_id(mySQLConnectionGroup.getParentID());
|
||||
connectionGroup.setConnection_group_name(mySQLConnectionGroup.getName());
|
||||
|
||||
switch(mySQLConnectionGroup.getType()) {
|
||||
case BALANCING :
|
||||
connectionGroup.setType(MySQLConstants.CONNECTION_GROUP_BALANCING);
|
||||
break;
|
||||
case ORGANIZATIONAL:
|
||||
connectionGroup.setType(MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the connection group in the database
|
||||
connectionGroupDAO.updateByPrimaryKey(connectionGroup);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the connection group having the given ID from the database.
|
||||
* @param id The ID of the connection group to delete.
|
||||
*/
|
||||
public void deleteConnectionGroup(int id) {
|
||||
connectionGroupDAO.deleteByPrimaryKey(id);
|
||||
}
|
||||
}
|
@@ -1,548 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.InetGuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.SSLGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
|
||||
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.dao.ConnectionHistoryMapper;
|
||||
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.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample.Criteria;
|
||||
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.ConnectionParameter;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||
import org.glyptodon.guacamole.properties.GuacamoleProperties;
|
||||
import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.glyptodon.guacamole.GuacamoleClientTooManyException;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceConflictException;
|
||||
import org.glyptodon.guacamole.token.StandardTokens;
|
||||
import org.glyptodon.guacamole.token.TokenFilter;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating connections.
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class ConnectionService {
|
||||
|
||||
/**
|
||||
* DAO for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionMapper connectionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection parameters.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionParameterMapper connectionParameterDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection history.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionHistoryMapper connectionHistoryDAO;
|
||||
|
||||
/**
|
||||
* Provider which creates MySQLConnections.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLConnection> mySQLConnectionProvider;
|
||||
|
||||
/**
|
||||
* Provider which creates MySQLGuacamoleSockets.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
||||
|
||||
/**
|
||||
* Map of all currently active connections.
|
||||
*/
|
||||
@Inject
|
||||
private ActiveConnectionMap activeConnectionMap;
|
||||
|
||||
/**
|
||||
* Service managing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Retrieves the connection having the given name from the database.
|
||||
*
|
||||
* @param name
|
||||
* The name of the connection to return.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*
|
||||
* @return
|
||||
* The connection having the given name, or null if no such
|
||||
* connection could be found.
|
||||
*/
|
||||
public MySQLConnection retrieveConnection(String name, Integer parentID,
|
||||
AuthenticatedUser currentUser) {
|
||||
|
||||
// Create criteria
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
Criteria criteria = example.createCriteria().andConnection_nameEqualTo(name);
|
||||
if(parentID != null)
|
||||
criteria.andParent_idEqualTo(parentID);
|
||||
else
|
||||
criteria.andParent_idIsNull();
|
||||
|
||||
// Query connection by name and parentID
|
||||
List<Connection> connections =
|
||||
connectionDAO.selectByExample(example);
|
||||
|
||||
// If no connection found, return null
|
||||
if(connections.isEmpty())
|
||||
return null;
|
||||
|
||||
// Otherwise, return found connection
|
||||
return toMySQLConnection(connections.get(0), currentUser);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the connection having the given unique identifier
|
||||
* from the database.
|
||||
*
|
||||
* @param uniqueIdentifier
|
||||
* The unique identifier of the connection to retrieve.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*
|
||||
* @return
|
||||
* The connection having the given unique identifier, or null if no
|
||||
* such connection was found.
|
||||
*/
|
||||
public MySQLConnection retrieveConnection(String uniqueIdentifier, AuthenticatedUser currentUser) {
|
||||
|
||||
// The unique identifier for a MySQLConnection is the database ID
|
||||
int connectionID;
|
||||
try {
|
||||
connectionID = Integer.parseInt(uniqueIdentifier);
|
||||
} catch(NumberFormatException e) {
|
||||
// Invalid number means it can't be a DB record; not found
|
||||
return null;
|
||||
}
|
||||
|
||||
return retrieveConnection(connectionID, currentUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the connection having the given ID from the database.
|
||||
*
|
||||
* @param id
|
||||
* The ID of the connection to retrieve.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*
|
||||
* @return
|
||||
* The connection having the given ID, or null if no such connection
|
||||
* was found.
|
||||
*/
|
||||
public MySQLConnection retrieveConnection(int id, AuthenticatedUser currentUser) {
|
||||
|
||||
// Query connection by ID
|
||||
Connection connection = connectionDAO.selectByPrimaryKey(id);
|
||||
|
||||
// If no connection found, return null
|
||||
if(connection == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, return found connection
|
||||
return toMySQLConnection(connection, currentUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the IDs of all connections with a given parent ID.
|
||||
* @param parentID The ID of the parent for all the queried connections.
|
||||
* @return a list of the IDs of all connections with a given parent ID.
|
||||
*/
|
||||
public List<Integer> getAllConnectionIDs(Integer parentID) {
|
||||
|
||||
// Create criteria
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
Criteria criteria = example.createCriteria();
|
||||
|
||||
if(parentID != null)
|
||||
criteria.andParent_idEqualTo(parentID);
|
||||
else
|
||||
criteria.andParent_idIsNull();
|
||||
|
||||
// Query the connections
|
||||
List<Connection> connections = connectionDAO.selectByExample(example);
|
||||
|
||||
// List of IDs of connections with the given parent
|
||||
List<Integer> connectionIDs = new ArrayList<Integer>();
|
||||
|
||||
for(Connection connection : connections) {
|
||||
connectionIDs.add(connection.getConnection_id());
|
||||
}
|
||||
|
||||
return connectionIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given database-retrieved Connection into a MySQLConnection.
|
||||
* The parameters of the given connection will be read and added to the
|
||||
* MySQLConnection in the process.
|
||||
*
|
||||
* @param connection
|
||||
* The connection to convert.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this connection.
|
||||
*
|
||||
* @return A new MySQLConnection containing all data associated with the
|
||||
* specified connection.
|
||||
*/
|
||||
private MySQLConnection toMySQLConnection(Connection connection, AuthenticatedUser currentUser) {
|
||||
|
||||
// Build configuration
|
||||
GuacamoleConfiguration config = new GuacamoleConfiguration();
|
||||
|
||||
// Query parameters for configuration
|
||||
ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
|
||||
connectionParameterExample.createCriteria().andConnection_idEqualTo(connection.getConnection_id());
|
||||
List<ConnectionParameter> connectionParameters =
|
||||
connectionParameterDAO.selectByExample(connectionParameterExample);
|
||||
|
||||
// Set protocol
|
||||
config.setProtocol(connection.getProtocol());
|
||||
|
||||
// Set all values for all parameters
|
||||
for (ConnectionParameter parameter : connectionParameters)
|
||||
config.setParameter(parameter.getParameter_name(),
|
||||
parameter.getParameter_value());
|
||||
|
||||
// Create new MySQLConnection from retrieved data
|
||||
MySQLConnection mySQLConnection = mySQLConnectionProvider.get();
|
||||
mySQLConnection.init(
|
||||
connection.getConnection_id(),
|
||||
connection.getParent_id(),
|
||||
connection.getConnection_name(),
|
||||
Integer.toString(connection.getConnection_id()),
|
||||
config,
|
||||
retrieveHistory(connection.getConnection_id()),
|
||||
currentUser
|
||||
);
|
||||
|
||||
return mySQLConnection;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the history of the connection having the given ID.
|
||||
*
|
||||
* @param connectionID The ID of the connection to retrieve the history of.
|
||||
* @return A list of MySQLConnectionRecord documenting the history of this
|
||||
* connection.
|
||||
*/
|
||||
public List<MySQLConnectionRecord> retrieveHistory(int connectionID) {
|
||||
|
||||
// Retrieve history records relating to given connection ID
|
||||
ConnectionHistoryExample example = new ConnectionHistoryExample();
|
||||
example.createCriteria().andConnection_idEqualTo(connectionID);
|
||||
|
||||
// We want to return the newest records first
|
||||
example.setOrderByClause("start_date DESC");
|
||||
|
||||
// Set the maximum number of history records returned to 100
|
||||
RowBounds rowBounds = new RowBounds(0, 100);
|
||||
|
||||
// Retrieve all connection history entries
|
||||
List<ConnectionHistory> connectionHistories =
|
||||
connectionHistoryDAO.selectByExampleWithRowbounds(example, rowBounds);
|
||||
|
||||
// Convert history entries to connection records
|
||||
List<MySQLConnectionRecord> connectionRecords = new ArrayList<MySQLConnectionRecord>();
|
||||
Set<Integer> userIDSet = new HashSet<Integer>();
|
||||
for(ConnectionHistory history : connectionHistories) {
|
||||
userIDSet.add(history.getUser_id());
|
||||
}
|
||||
|
||||
// Determine whether connection is currently active
|
||||
int user_count = activeConnectionMap.getCurrentUserCount(connectionID);
|
||||
|
||||
// Get all the usernames for the users who are in the history
|
||||
Map<Integer, String> usernameMap = userService.retrieveUsernames(userIDSet);
|
||||
|
||||
// Create the new ConnectionRecords
|
||||
for(ConnectionHistory history : connectionHistories) {
|
||||
|
||||
Date startDate = history.getStart_date();
|
||||
Date endDate = history.getEnd_date();
|
||||
String username = usernameMap.get(history.getUser_id());
|
||||
|
||||
// If there are active users, list the top N not-ended connections
|
||||
// as active (best guess)
|
||||
MySQLConnectionRecord connectionRecord;
|
||||
if (user_count > 0 && endDate == null) {
|
||||
connectionRecord = new MySQLConnectionRecord(startDate, endDate, username, true);
|
||||
user_count--;
|
||||
}
|
||||
|
||||
// If no active users, or end date is recorded, connection is not
|
||||
// active.
|
||||
else
|
||||
connectionRecord = new MySQLConnectionRecord(startDate, endDate, username, false);
|
||||
|
||||
connectionRecords.add(connectionRecord);
|
||||
|
||||
}
|
||||
|
||||
return connectionRecords;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a MySQLGuacamoleSocket using the provided connection.
|
||||
*
|
||||
* @param connection
|
||||
* The connection to use when connecting the socket.
|
||||
*
|
||||
* @param info
|
||||
* The information to use when performing the connection handshake.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who is connecting to the socket.
|
||||
*
|
||||
* @param connectionGroupID
|
||||
* The ID of the balancing connection group that is being connected to;
|
||||
* null if not used.
|
||||
*
|
||||
* @return
|
||||
* The connected socket.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while connecting the socket.
|
||||
*/
|
||||
public MySQLGuacamoleSocket connect(MySQLConnection connection,
|
||||
GuacamoleClientInformation info, AuthenticatedUser currentUser,
|
||||
Integer connectionGroupID)
|
||||
throws GuacamoleException {
|
||||
|
||||
synchronized (activeConnectionMap) {
|
||||
|
||||
// If the given connection is active, and multiple simultaneous
|
||||
// connections are not allowed, disallow connection
|
||||
if(GuacamoleProperties.getProperty(
|
||||
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
||||
&& activeConnectionMap.isActive(connection.getConnectionID()))
|
||||
throw new GuacamoleResourceConflictException("Cannot connect. This connection is in use.");
|
||||
|
||||
if(GuacamoleProperties.getProperty(
|
||||
MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true)
|
||||
&& activeConnectionMap.isConnectionUserActive(connection.getConnectionID(), currentUser.getUserID()))
|
||||
throw new GuacamoleClientTooManyException
|
||||
("Cannot connect. Connection already in use by this user.");
|
||||
|
||||
// Get guacd connection information
|
||||
String host = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_HOSTNAME);
|
||||
int port = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_PORT);
|
||||
|
||||
// Build token filter containing credential tokens
|
||||
TokenFilter tokenFilter = new TokenFilter();
|
||||
StandardTokens.addStandardTokens(tokenFilter, currentUser.getCredentials());
|
||||
|
||||
// Filter the configuration
|
||||
GuacamoleConfiguration config = new GuacamoleConfiguration(connection.getConfiguration());
|
||||
tokenFilter.filterValues(config.getParameters());
|
||||
|
||||
// Get socket
|
||||
GuacamoleSocket socket;
|
||||
if (GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_SSL, false))
|
||||
socket = new ConfiguredGuacamoleSocket(
|
||||
new SSLGuacamoleSocket(host, port),
|
||||
config, info
|
||||
);
|
||||
else
|
||||
socket = new ConfiguredGuacamoleSocket(
|
||||
new InetGuacamoleSocket(host, port),
|
||||
config, info
|
||||
);
|
||||
|
||||
// Mark this connection as active
|
||||
int historyID = activeConnectionMap.openConnection(connection.getConnectionID(),
|
||||
currentUser.getUserID(), connectionGroupID);
|
||||
|
||||
// Return new MySQLGuacamoleSocket
|
||||
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
|
||||
mySQLGuacamoleSocket.init(socket, historyID, connectionGroupID);
|
||||
|
||||
return mySQLGuacamoleSocket;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection having the given name and protocol.
|
||||
*
|
||||
* @param name
|
||||
* The name to assign to the new connection.
|
||||
*
|
||||
* @param protocol
|
||||
* The protocol to assign to the new connection.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who created this connection.
|
||||
*
|
||||
* @param parentID
|
||||
* The ID of the parent connection group.
|
||||
*
|
||||
* @return
|
||||
* A new MySQLConnection containing the data of the newly created
|
||||
* connection.
|
||||
*/
|
||||
public MySQLConnection createConnection(String name, String protocol,
|
||||
AuthenticatedUser currentUser, Integer parentID) {
|
||||
|
||||
// Initialize database connection
|
||||
Connection connection = new Connection();
|
||||
connection.setConnection_name(name);
|
||||
connection.setProtocol(protocol);
|
||||
connection.setParent_id(parentID);
|
||||
|
||||
// Create connection
|
||||
connectionDAO.insert(connection);
|
||||
return toMySQLConnection(connection, currentUser);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the connection having the given ID from the database.
|
||||
* @param id The ID of the connection to delete.
|
||||
*/
|
||||
public void deleteConnection(int id) {
|
||||
connectionDAO.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the connection in the database corresponding to the given
|
||||
* MySQLConnection.
|
||||
*
|
||||
* @param mySQLConnection The MySQLConnection to update (save) to the
|
||||
* database. This connection must already exist.
|
||||
*/
|
||||
public void updateConnection(MySQLConnection mySQLConnection) {
|
||||
|
||||
// Populate connection
|
||||
Connection connection = new Connection();
|
||||
connection.setConnection_id(mySQLConnection.getConnectionID());
|
||||
connection.setParent_id(mySQLConnection.getParentID());
|
||||
connection.setConnection_name(mySQLConnection.getName());
|
||||
connection.setProtocol(mySQLConnection.getConfiguration().getProtocol());
|
||||
|
||||
// Update the connection in the database
|
||||
connectionDAO.updateByPrimaryKey(connection);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the identifiers of all the connections defined in the system
|
||||
* with a certain parentID.
|
||||
*
|
||||
* @return A Set of identifiers of all the connections defined in the system
|
||||
* with the given parentID.
|
||||
*/
|
||||
public Set<String> getAllConnectionIdentifiers(Integer parentID) {
|
||||
|
||||
// Set of all present connection identifiers
|
||||
Set<String> identifiers = new HashSet<String>();
|
||||
|
||||
// Set up Criteria
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
Criteria criteria = example.createCriteria();
|
||||
if(parentID != null)
|
||||
criteria.andParent_idEqualTo(parentID);
|
||||
else
|
||||
criteria.andParent_idIsNull();
|
||||
|
||||
// Query connection identifiers
|
||||
List<Connection> connections =
|
||||
connectionDAO.selectByExample(example);
|
||||
for (Connection connection : connections)
|
||||
identifiers.add(String.valueOf(connection.getConnection_id()));
|
||||
|
||||
return identifiers;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection IDs of all the connections defined in the system
|
||||
* with a certain parent connection group.
|
||||
*
|
||||
* @return A list of connection IDs of all the connections defined in the system.
|
||||
*/
|
||||
public List<Integer> getAllConnectionIDs() {
|
||||
|
||||
// Set of all present connection IDs
|
||||
List<Integer> connectionIDs = new ArrayList<Integer>();
|
||||
|
||||
// Create the criteria
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
|
||||
// Query the connections
|
||||
List<Connection> connections =
|
||||
connectionDAO.selectByExample(example);
|
||||
for (Connection connection : connections)
|
||||
connectionIDs.add(connection.getConnection_id());
|
||||
|
||||
return connectionIDs;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.DirectoryObject;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating users.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <ObjectType>
|
||||
* The type of object this service provides access to.
|
||||
*
|
||||
* @param <ModelType>
|
||||
* The underlying model object used to represent ObjectType in the
|
||||
* database.
|
||||
*/
|
||||
public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<ModelType>, ModelType> {
|
||||
|
||||
/**
|
||||
* Returns an instance of a mapper for the type of object used by this
|
||||
* service.
|
||||
*
|
||||
* @return
|
||||
* A mapper which provides access to the model objects associated with
|
||||
* the objects used by this service.
|
||||
*/
|
||||
protected abstract DirectoryObjectMapper<ModelType> getObjectMapper();
|
||||
|
||||
/**
|
||||
* Returns an instance of an object which is backed by the given model
|
||||
* object.
|
||||
*
|
||||
* @param model
|
||||
* The model object to use to back the returned object.
|
||||
*
|
||||
* @return
|
||||
* An object which is backed by the given model object.
|
||||
*/
|
||||
protected abstract ObjectType getObjectInstance(ModelType model);
|
||||
|
||||
/**
|
||||
* Returns a collection of objects which are backed by the models in the
|
||||
* given collection.
|
||||
*
|
||||
* @param models
|
||||
* The model objects to use to back the objects within the returned
|
||||
* collection.
|
||||
*
|
||||
* @return
|
||||
* A collection of objects which are backed by the models in the given
|
||||
* collection.
|
||||
*/
|
||||
protected Collection<ObjectType> getObjectInstances(Collection<ModelType> models) {
|
||||
|
||||
// Create new collection of objects by manually converting each model
|
||||
Collection<ObjectType> objects = new ArrayList<ObjectType>(models.size());
|
||||
for (ModelType model : models)
|
||||
objects.add(getObjectInstance(model));
|
||||
|
||||
return objects;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the single object that has the given identifier, if it exists.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to retrieve.
|
||||
*
|
||||
* @return
|
||||
* The object having the given identifier, or null if no such object
|
||||
* exists.
|
||||
*/
|
||||
public ObjectType retrieveObject(String identifier) {
|
||||
|
||||
// Pull objects having given identifier
|
||||
Collection<ObjectType> objects = retrieveObjects(Collections.singleton(identifier));
|
||||
|
||||
// If no such object, return null
|
||||
if (objects.isEmpty())
|
||||
return null;
|
||||
|
||||
// The object collection will have exactly one element unless the
|
||||
// database has seriously lost integrity
|
||||
assert(objects.size() == 1);
|
||||
|
||||
// Return first and only object
|
||||
return objects.iterator().next();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all objects that have the identifiers in the given collection.
|
||||
*
|
||||
* @param identifiers
|
||||
* The identifiers of the objects to retrieve.
|
||||
*
|
||||
* @return
|
||||
* The objects having the given identifiers.
|
||||
*/
|
||||
public Collection<ObjectType> retrieveObjects(Collection<String> identifiers) {
|
||||
|
||||
// Do not query if no identifiers given
|
||||
if (identifiers.isEmpty())
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
// Return collection of requested objects
|
||||
return getObjectInstances(getObjectMapper().select(identifiers));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given object within the database. If the object already
|
||||
* exists, an error will be thrown. The internal model object will be
|
||||
* updated appropriately to contain the new database ID.
|
||||
*
|
||||
* @param object
|
||||
* The object to create.
|
||||
*/
|
||||
public void createObject(ObjectType object) {
|
||||
getObjectMapper().insert(object.getModel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the object having the given identifier. If no such object
|
||||
* exists, this function has no effect.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to delete.
|
||||
*/
|
||||
public void deleteObject(String identifier) {
|
||||
getObjectMapper().delete(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the given object in the database, applying any changes that have
|
||||
* been made. If no such object exists, this function has no effect.
|
||||
*
|
||||
* @param object
|
||||
* The object to update.
|
||||
*/
|
||||
public void updateObject(ObjectType object) {
|
||||
getObjectMapper().update(object.getModel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of all identifiers for all objects in the database.
|
||||
*
|
||||
* @return
|
||||
* The set of all identifiers for all objects in the database.
|
||||
*/
|
||||
public Set<String> getIdentifiers() {
|
||||
return getObjectMapper().selectIdentifiers();
|
||||
}
|
||||
|
||||
}
|
@@ -22,27 +22,12 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
|
||||
/**
|
||||
* A service to perform password encryption and checking.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public interface PasswordEncryptionService {
|
||||
|
||||
/**
|
||||
* Checks whether the provided, unhashed password matches the given
|
||||
* hash/salt pair.
|
||||
*
|
||||
* @param password The unhashed password to validate.
|
||||
* @param hashedPassword The hashed password to compare the given password
|
||||
* against.
|
||||
* @param salt The salt used when the hashed password given was created.
|
||||
* @return true if the provided credentials match the values given, false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean checkPassword(String password, byte[] hashedPassword,
|
||||
byte[] salt);
|
||||
|
||||
/**
|
||||
* Creates a password hash based on the provided username, password, and
|
||||
* salt.
|
||||
@@ -52,4 +37,5 @@ public interface PasswordEncryptionService {
|
||||
* @return The generated password hash.
|
||||
*/
|
||||
public byte[] createPasswordHash(String password, byte[] salt);
|
||||
|
||||
}
|
||||
|
@@ -1,968 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample.Criteria;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ConnectionGroupPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ConnectionPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.Permission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.UserPermission;
|
||||
|
||||
/**
|
||||
* A service to retrieve information about what objects a user has permission to.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class PermissionCheckService {
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Service for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for accessing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to users.
|
||||
*/
|
||||
@Inject
|
||||
private UserPermissionMapper userPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to the system as a whole.
|
||||
*/
|
||||
@Inject
|
||||
private SystemPermissionMapper systemPermissionDAO;
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the given other
|
||||
* user. If permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param affectedUserID
|
||||
* The user that would be affected by the operation if permission is
|
||||
* granted.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @throws GuacamoleSecurityException
|
||||
* If the specified permission is not granted.
|
||||
*/
|
||||
public void verifyUserAccess(AuthenticatedUser currentUser, int affectedUserID,
|
||||
String permissionType) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkUserAccess(currentUser, affectedUserID, permissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the given connection.
|
||||
* If permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param affectedConnectionID
|
||||
* The connection that would be affected by the operation if permission
|
||||
* is granted.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @throws GuacamoleSecurityException
|
||||
* If the specified permission is not granted.
|
||||
*/
|
||||
public void verifyConnectionAccess(AuthenticatedUser currentUser,
|
||||
int affectedConnectionID, String permissionType) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkConnectionAccess(currentUser, affectedConnectionID, permissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the given connection group.
|
||||
* If permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param affectedConnectionGroupID
|
||||
* The connection group that would be affected by the operation if
|
||||
* permission is granted.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @throws GuacamoleSecurityException
|
||||
* If the specified permission is not granted.
|
||||
*/
|
||||
public void verifyConnectionGroupAccess(AuthenticatedUser currentUser,
|
||||
Integer affectedConnectionGroupID, String permissionType) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkConnectionGroupAccess(currentUser, affectedConnectionGroupID, permissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the system. If
|
||||
* permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param systemPermissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @throws GuacamoleSecurityException
|
||||
* If the specified permission is not granted.
|
||||
*/
|
||||
public void verifySystemAccess(AuthenticatedUser currentUser, String systemPermissionType)
|
||||
throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkSystemAccess(currentUser, systemPermissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the affected
|
||||
* user.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param affectedUserID
|
||||
* The user that would be affected by the operation if permission is
|
||||
* granted.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
public boolean checkUserAccess(AuthenticatedUser currentUser,
|
||||
Integer affectedUserID, String permissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
UserPermissionExample example = new UserPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andAffected_user_idEqualTo(affectedUserID).andPermissionEqualTo(permissionType);
|
||||
return userPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the affected
|
||||
* connection.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param affectedConnectionID
|
||||
* The connection that would be affected by the operation if permission
|
||||
* is granted.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
public boolean checkConnectionAccess(AuthenticatedUser currentUser,
|
||||
Integer affectedConnectionID, String permissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
ConnectionPermissionExample example = new ConnectionPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andConnection_idEqualTo(affectedConnectionID).andPermissionEqualTo(permissionType);
|
||||
return connectionPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the affected
|
||||
* connection group.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param affectedConnectionGroupID
|
||||
* The connection group that would be affected by the operation if
|
||||
* permission is granted.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
public boolean checkConnectionGroupAccess(AuthenticatedUser currentUser,
|
||||
Integer affectedConnectionGroupID, String permissionType) {
|
||||
|
||||
// All users have implicit permission to read and update the root connection group
|
||||
if(affectedConnectionGroupID == null &&
|
||||
MySQLConstants.CONNECTION_GROUP_READ.equals(permissionType) ||
|
||||
MySQLConstants.CONNECTION_GROUP_UPDATE.equals(permissionType))
|
||||
return true;
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andConnection_group_idEqualTo(affectedConnectionGroupID).andPermissionEqualTo(permissionType);
|
||||
return connectionGroupPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the system.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param systemPermissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
private boolean checkSystemAccess(AuthenticatedUser currentUser, String systemPermissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
SystemPermissionExample example = new SystemPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andPermissionEqualTo(systemPermissionType);
|
||||
return systemPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has system administrator access to the system.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @return
|
||||
* true if the system administrator access exists, false otherwise.
|
||||
*/
|
||||
private boolean checkSystemAdministratorAccess(AuthenticatedUser currentUser) {
|
||||
|
||||
// Check existence of system administrator permission
|
||||
SystemPermissionExample example = new SystemPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID())
|
||||
.andPermissionEqualTo(MySQLConstants.SYSTEM_ADMINISTER);
|
||||
return systemPermissionDAO.countByExample(example) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the specified group can be used for organization
|
||||
* by the given user.
|
||||
*
|
||||
* @param connectionGroupID
|
||||
* The ID of the affected ConnectionGroup.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param type
|
||||
* The desired usage.
|
||||
*
|
||||
* @throws GuacamoleSecurityException
|
||||
* If the connection group cannot be used for organization.
|
||||
*/
|
||||
public void verifyConnectionGroupUsageAccess(Integer connectionGroupID,
|
||||
AuthenticatedUser currentUser, String type) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkConnectionGroupUsageAccess(connectionGroupID, currentUser, type))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a user can use connectionGroup for the given usage.
|
||||
*
|
||||
* @param connectionGroupID
|
||||
* The ID of the affected connection group.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param usage
|
||||
* The desired usage.
|
||||
*
|
||||
* @return
|
||||
* true if the user can use the connection group for the given usage.
|
||||
*/
|
||||
private boolean checkConnectionGroupUsageAccess(
|
||||
Integer connectionGroupID, AuthenticatedUser currentUser, String usage) {
|
||||
|
||||
// The root level connection group can only be used for organization
|
||||
if(connectionGroupID == null)
|
||||
return MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL.equals(usage);
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return true;
|
||||
|
||||
// A connection group administrator can use the group either way.
|
||||
if(checkConnectionGroupAccess(currentUser, connectionGroupID,
|
||||
MySQLConstants.CONNECTION_GROUP_ADMINISTER))
|
||||
return true;
|
||||
|
||||
// Query the connection group
|
||||
MySQLConnectionGroup connectionGroup = connectionGroupService.
|
||||
retrieveConnectionGroup(connectionGroupID, currentUser);
|
||||
|
||||
// If the connection group is not found, it cannot be used.
|
||||
if(connectionGroup == null)
|
||||
return false;
|
||||
|
||||
// Verify that the desired usage matches the type.
|
||||
return MySQLConstants.getConnectionGroupTypeConstant(
|
||||
connectionGroup.getType()).equals(usage);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all users a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* A list of all user IDs this user has the specified access to.
|
||||
*/
|
||||
public List<Integer> retrieveUserIDs(AuthenticatedUser currentUser, String permissionType) {
|
||||
|
||||
// A system administrator has access to all users.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return userService.getAllUserIDs();
|
||||
|
||||
// Query all user permissions for the given user and permission type
|
||||
UserPermissionExample example = new UserPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andPermissionEqualTo(permissionType);
|
||||
example.setDistinct(true);
|
||||
List<UserPermissionKey> userPermissions =
|
||||
userPermissionDAO.selectByExample(example);
|
||||
|
||||
// Convert result into list of IDs
|
||||
List<Integer> currentUsers = new ArrayList<Integer>(userPermissions.size());
|
||||
for(UserPermissionKey permission : userPermissions)
|
||||
currentUsers.add(permission.getAffected_user_id());
|
||||
|
||||
return currentUsers;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connections a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* A list of all connection IDs this user has the specified access to.
|
||||
*/
|
||||
public List<Integer> retrieveConnectionIDs(AuthenticatedUser currentUser,
|
||||
String permissionType) {
|
||||
|
||||
return retrieveConnectionIDs(currentUser, null, permissionType, false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connections a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param parentID
|
||||
* The parent connection group.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* A list of all connection IDs this user has the specified access to.
|
||||
*/
|
||||
public List<Integer> retrieveConnectionIDs(AuthenticatedUser currentUser, Integer parentID,
|
||||
String permissionType) {
|
||||
|
||||
return retrieveConnectionIDs(currentUser, parentID, permissionType, true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connections a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param parentID
|
||||
* The parent connection group.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @param checkParentID
|
||||
* Whether the parentID should be checked or not.
|
||||
*
|
||||
* @return
|
||||
* A list of all connection IDs this user has the specified access to.
|
||||
*/
|
||||
private List<Integer> retrieveConnectionIDs(AuthenticatedUser currentUser, Integer parentID,
|
||||
String permissionType, boolean checkParentID) {
|
||||
|
||||
// A system administrator has access to all connections.
|
||||
if(checkSystemAdministratorAccess(currentUser)) {
|
||||
if(checkParentID)
|
||||
return connectionService.getAllConnectionIDs(parentID);
|
||||
else
|
||||
return connectionService.getAllConnectionIDs();
|
||||
}
|
||||
|
||||
// Query all connection permissions for the given user and permission type
|
||||
ConnectionPermissionExample example = new ConnectionPermissionExample();
|
||||
Criteria criteria = example.createCriteria().andUser_idEqualTo(currentUser.getUserID())
|
||||
.andPermissionEqualTo(permissionType);
|
||||
|
||||
// Ensure that the connections are all under the parent ID, if needed
|
||||
if(checkParentID) {
|
||||
// Get the IDs of all connections in the connection group
|
||||
List<Integer> allConnectionIDs = connectionService.getAllConnectionIDs(parentID);
|
||||
|
||||
if(allConnectionIDs.isEmpty())
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
criteria.andConnection_idIn(allConnectionIDs);
|
||||
}
|
||||
|
||||
example.setDistinct(true);
|
||||
List<ConnectionPermissionKey> connectionPermissions =
|
||||
connectionPermissionDAO.selectByExample(example);
|
||||
|
||||
// Convert result into list of IDs
|
||||
List<Integer> connectionIDs = new ArrayList<Integer>(connectionPermissions.size());
|
||||
for(ConnectionPermissionKey permission : connectionPermissions)
|
||||
connectionIDs.add(permission.getConnection_id());
|
||||
|
||||
return connectionIDs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connection groups a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* A list of all connection group IDs this user has the specified
|
||||
* access to.
|
||||
*/
|
||||
public List<Integer> retrieveConnectionGroupIDs(AuthenticatedUser currentUser,
|
||||
String permissionType) {
|
||||
|
||||
return retrieveConnectionGroupIDs(currentUser, null, permissionType, false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connection groups a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param parentID
|
||||
* The parent connection group.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @return
|
||||
* A list of all connection group IDs this user has the specified
|
||||
* access to.
|
||||
*/
|
||||
public List<Integer> retrieveConnectionGroupIDs(AuthenticatedUser currentUser, Integer parentID,
|
||||
String permissionType) {
|
||||
|
||||
return retrieveConnectionGroupIDs(currentUser, parentID, permissionType, true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connection groups a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user to check.
|
||||
*
|
||||
* @param parentID
|
||||
* The parent connection group.
|
||||
*
|
||||
* @param permissionType
|
||||
* The type of permission to check for.
|
||||
*
|
||||
* @param checkParentID
|
||||
* Whether the parentID should be checked or not.
|
||||
*
|
||||
* @return
|
||||
* A list of all connection group IDs this user has the specified
|
||||
* access to.
|
||||
*/
|
||||
private List<Integer> retrieveConnectionGroupIDs(AuthenticatedUser currentUser, Integer parentID,
|
||||
String permissionType, boolean checkParentID) {
|
||||
|
||||
// A system administrator has access to all connectionGroups .
|
||||
if(checkSystemAdministratorAccess(currentUser)) {
|
||||
if(checkParentID)
|
||||
return connectionGroupService.getAllConnectionGroupIDs(parentID);
|
||||
else
|
||||
return connectionGroupService.getAllConnectionGroupIDs();
|
||||
}
|
||||
|
||||
// Query all connection permissions for the given user and permission type
|
||||
ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample();
|
||||
ConnectionGroupPermissionExample.Criteria criteria =
|
||||
example.createCriteria().andUser_idEqualTo(currentUser.getUserID())
|
||||
.andPermissionEqualTo(permissionType);
|
||||
|
||||
// Ensure that the connection groups are all under the parent ID, if needed
|
||||
if(checkParentID) {
|
||||
// Get the IDs of all connection groups in the connection group
|
||||
List<Integer> allConnectionGroupIDs = connectionGroupService
|
||||
.getAllConnectionGroupIDs(parentID);
|
||||
|
||||
if(allConnectionGroupIDs.isEmpty())
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
criteria.andConnection_group_idIn(allConnectionGroupIDs);
|
||||
}
|
||||
|
||||
example.setDistinct(true);
|
||||
List<ConnectionGroupPermissionKey> connectionGroupPermissions =
|
||||
connectionGroupPermissionDAO.selectByExample(example);
|
||||
|
||||
// Convert result into list of IDs
|
||||
List<Integer> connectionGroupIDs = new ArrayList<Integer>(connectionGroupPermissions.size());
|
||||
for(ConnectionGroupPermissionKey permission : connectionGroupPermissions)
|
||||
connectionGroupIDs.add(permission.getConnection_group_id());
|
||||
|
||||
// All users have implicit access to read and update the root group
|
||||
if(MySQLConstants.CONNECTION_GROUP_READ.equals(permissionType)
|
||||
&& MySQLConstants.CONNECTION_GROUP_UPDATE.equals(permissionType)
|
||||
&& !checkParentID)
|
||||
connectionGroupIDs.add(null);
|
||||
|
||||
return connectionGroupIDs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all existing usernames that the given user has permission to
|
||||
* perform the given operation upon.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions should be checked.
|
||||
*
|
||||
* @param permissionType
|
||||
* The permission to check.
|
||||
*
|
||||
* @return
|
||||
* A set of all usernames for which the given user has the given
|
||||
* permission.
|
||||
*/
|
||||
public Set<String> retrieveUsernames(AuthenticatedUser currentUser, String permissionType) {
|
||||
|
||||
// A system administrator has access to all users.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return userService.getAllUsernames();
|
||||
|
||||
// List of all user IDs for which this user has read access
|
||||
List<Integer> currentUsers =
|
||||
retrieveUserIDs(currentUser, MySQLConstants.USER_READ);
|
||||
|
||||
// Query all associated users
|
||||
return userService.translateUsernames(currentUsers).keySet();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all existing connection identifiers that the given user has
|
||||
* permission to perform the given operation upon.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions should be checked.
|
||||
*
|
||||
* @param permissionType
|
||||
* The permission to check.
|
||||
*
|
||||
* @param parentID
|
||||
* The parent connection group.
|
||||
*
|
||||
* @return
|
||||
* A set of all connection identifiers for which the given user has the
|
||||
* given permission.
|
||||
*/
|
||||
public Set<String> retrieveConnectionIdentifiers(AuthenticatedUser currentUser, Integer parentID,
|
||||
String permissionType) {
|
||||
|
||||
// A system administrator has access to all connections.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return connectionService.getAllConnectionIdentifiers(parentID);
|
||||
|
||||
// List of all connection IDs for which this user has access
|
||||
List<Integer> connectionIDs =
|
||||
retrieveConnectionIDs(currentUser, parentID, permissionType);
|
||||
|
||||
// Unique Identifiers for MySQLConnections are the database IDs
|
||||
Set<String> connectionIdentifiers = new HashSet<String>();
|
||||
|
||||
for(Integer connectionID : connectionIDs)
|
||||
connectionIdentifiers.add(Integer.toString(connectionID));
|
||||
|
||||
return connectionIdentifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all existing connection group identifiers that the given user
|
||||
* has permission to perform the given operation upon.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions should be checked.
|
||||
*
|
||||
* @param permissionType
|
||||
* The permission to check.
|
||||
*
|
||||
* @param parentID
|
||||
* The parent connection group.
|
||||
*
|
||||
* @return
|
||||
* A set of all connection group identifiers for which the given user
|
||||
* has the given permission.
|
||||
*/
|
||||
public Set<String> retrieveConnectionGroupIdentifiers(AuthenticatedUser currentUser, Integer parentID,
|
||||
String permissionType) {
|
||||
|
||||
// A system administrator has access to all connections.
|
||||
if(checkSystemAdministratorAccess(currentUser))
|
||||
return connectionGroupService.getAllConnectionGroupIdentifiers(parentID);
|
||||
|
||||
// List of all connection group IDs for which this user has access
|
||||
List<Integer> connectionGroupIDs =
|
||||
retrieveConnectionGroupIDs(currentUser, parentID, permissionType);
|
||||
|
||||
// Unique Identifiers for MySQLConnectionGroups are the database IDs
|
||||
Set<String> connectionGroupIdentifiers = new HashSet<String>();
|
||||
|
||||
for(Integer connectionGroupID : connectionGroupIDs)
|
||||
connectionGroupIdentifiers.add(Integer.toString(connectionGroupID));
|
||||
|
||||
return connectionGroupIdentifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all user permissions granted to the user having the given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all user permissions granted to the user having the
|
||||
* given ID.
|
||||
*/
|
||||
public Set<UserPermission> retrieveUserPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<UserPermission> permissions = new HashSet<UserPermission>();
|
||||
|
||||
// Query all user permissions
|
||||
UserPermissionExample userPermissionExample = new UserPermissionExample();
|
||||
userPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<UserPermissionKey> userPermissions =
|
||||
userPermissionDAO.selectByExample(userPermissionExample);
|
||||
|
||||
// Get list of affected user IDs
|
||||
List<Integer> affectedUserIDs = new ArrayList<Integer>();
|
||||
for(UserPermissionKey userPermission : userPermissions)
|
||||
affectedUserIDs.add(userPermission.getAffected_user_id());
|
||||
|
||||
// Get corresponding usernames
|
||||
Map<Integer, String> affectedUsers =
|
||||
userService.retrieveUsernames(affectedUserIDs);
|
||||
|
||||
// Add user permissions
|
||||
for(UserPermissionKey userPermission : userPermissions) {
|
||||
|
||||
// Construct permission from data
|
||||
UserPermission permission = new UserPermission(
|
||||
UserPermission.Type.valueOf(userPermission.getPermission()),
|
||||
affectedUsers.get(userPermission.getAffected_user_id())
|
||||
);
|
||||
|
||||
// Add to set
|
||||
permissions.add(permission);
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all connection permissions granted to the user having the
|
||||
* given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all connection permissions granted to the user having
|
||||
* the given ID.
|
||||
*/
|
||||
public Set<ConnectionPermission> retrieveConnectionPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<ConnectionPermission> permissions = new HashSet<ConnectionPermission>();
|
||||
|
||||
// Query all connection permissions
|
||||
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
||||
connectionPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<ConnectionPermissionKey> connectionPermissions =
|
||||
connectionPermissionDAO.selectByExample(connectionPermissionExample);
|
||||
|
||||
// Add connection permissions
|
||||
for(ConnectionPermissionKey connectionPermission : connectionPermissions) {
|
||||
|
||||
// Construct permission from data
|
||||
ConnectionPermission permission = new ConnectionPermission(
|
||||
ConnectionPermission.Type.valueOf(connectionPermission.getPermission()),
|
||||
String.valueOf(connectionPermission.getConnection_id())
|
||||
);
|
||||
|
||||
// Add to set
|
||||
permissions.add(permission);
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all connection group permissions granted to the user having the
|
||||
* given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all connection group permissions granted to the user having
|
||||
* the given ID.
|
||||
*/
|
||||
public Set<ConnectionGroupPermission> retrieveConnectionGroupPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<ConnectionGroupPermission> permissions = new HashSet<ConnectionGroupPermission>();
|
||||
|
||||
// Query all connection permissions
|
||||
ConnectionGroupPermissionExample connectionGroupPermissionExample = new ConnectionGroupPermissionExample();
|
||||
connectionGroupPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<ConnectionGroupPermissionKey> connectionGroupPermissions =
|
||||
connectionGroupPermissionDAO.selectByExample(connectionGroupPermissionExample);
|
||||
|
||||
// Add connection permissions
|
||||
for(ConnectionGroupPermissionKey connectionGroupPermission : connectionGroupPermissions) {
|
||||
|
||||
// Construct permission from data
|
||||
ConnectionGroupPermission permission = new ConnectionGroupPermission(
|
||||
ConnectionGroupPermission.Type.valueOf(connectionGroupPermission.getPermission()),
|
||||
String.valueOf(connectionGroupPermission.getConnection_group_id())
|
||||
);
|
||||
|
||||
// Add to set
|
||||
permissions.add(permission);
|
||||
|
||||
}
|
||||
|
||||
// All users have implict access to read the root connection group
|
||||
permissions.add(new ConnectionGroupPermission(
|
||||
ConnectionGroupPermission.Type.READ,
|
||||
MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER
|
||||
));
|
||||
|
||||
// All users have implict access to update the root connection group
|
||||
permissions.add(new ConnectionGroupPermission(
|
||||
ConnectionGroupPermission.Type.UPDATE,
|
||||
MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER
|
||||
));
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all system permissions granted to the user having the
|
||||
* given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all system permissions granted to the user having the
|
||||
* given ID.
|
||||
*/
|
||||
public Set<SystemPermission> retrieveSystemPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<SystemPermission> permissions = new HashSet<SystemPermission>();
|
||||
|
||||
// And finally, system permissions
|
||||
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
||||
systemPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<SystemPermissionKey> systemPermissions =
|
||||
systemPermissionDAO.selectByExample(systemPermissionExample);
|
||||
for(SystemPermissionKey systemPermission : systemPermissions) {
|
||||
|
||||
// User creation permission
|
||||
if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_USER_CREATE))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.CREATE_USER));
|
||||
|
||||
// System creation permission
|
||||
else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_CONNECTION_CREATE))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.CREATE_CONNECTION));
|
||||
|
||||
// System creation permission
|
||||
else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_CONNECTION_GROUP_CREATE))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.CREATE_CONNECTION_GROUP));
|
||||
|
||||
// System administration permission
|
||||
else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_ADMINISTER))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.ADMINISTER));
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all permissions granted to the user having the given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all permissions granted to the user having the given
|
||||
* ID.
|
||||
*/
|
||||
public Set<Permission> retrieveAllPermissions(int userID) {
|
||||
|
||||
// Set which will contain all permissions
|
||||
Set<Permission> allPermissions = new HashSet<Permission>();
|
||||
|
||||
// Add user permissions
|
||||
allPermissions.addAll(retrieveUserPermissions(userID));
|
||||
|
||||
// Add connection permissions
|
||||
allPermissions.addAll(retrieveConnectionPermissions(userID));
|
||||
|
||||
// add connection group permissions
|
||||
allPermissions.addAll(retrieveConnectionGroupPermissions(userID));
|
||||
|
||||
// Add system permissions
|
||||
allPermissions.addAll(retrieveSystemPermissions(userID));
|
||||
|
||||
return allPermissions;
|
||||
}
|
||||
|
||||
}
|
@@ -25,7 +25,6 @@ package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/**
|
||||
@@ -34,16 +33,6 @@ import javax.xml.bind.DatatypeConverter;
|
||||
*/
|
||||
public class SHA256PasswordEncryptionService implements PasswordEncryptionService {
|
||||
|
||||
@Override
|
||||
public boolean checkPassword(String password, byte[] hashedPassword,
|
||||
byte[] salt) {
|
||||
|
||||
// Compare bytes of password in credentials against hashed password
|
||||
byte[] passwordBytes = createPasswordHash(password, salt);
|
||||
return Arrays.equals(passwordBytes, hashedPassword);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] createPasswordHash(String password, byte[] salt) {
|
||||
|
||||
@@ -72,4 +61,5 @@ public class SHA256PasswordEncryptionService implements PasswordEncryptionServic
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -22,24 +22,13 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.User;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
@@ -47,13 +36,13 @@ import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class UserService {
|
||||
public class UserService extends DirectoryObjectService<MySQLUser, UserModel> {
|
||||
|
||||
/**
|
||||
* DAO for accessing users.
|
||||
* Mapper for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserMapper userDAO;
|
||||
private UserMapper userMapper;
|
||||
|
||||
/**
|
||||
* Provider for creating users.
|
||||
@@ -61,106 +50,16 @@ public class UserService {
|
||||
@Inject
|
||||
private Provider<MySQLUser> mySQLUserProvider;
|
||||
|
||||
/**
|
||||
* Service for checking permissions.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Service for encrypting passwords.
|
||||
*/
|
||||
@Inject
|
||||
private PasswordEncryptionService passwordService;
|
||||
|
||||
/**
|
||||
* Service for generating random salts.
|
||||
*/
|
||||
@Inject
|
||||
private SaltService saltService;
|
||||
|
||||
/**
|
||||
* Create a new MySQLUser based on the provided User.
|
||||
*
|
||||
* @param user The User to use when populating the data of the given
|
||||
* MySQLUser.
|
||||
* @return A new MySQLUser object, populated with the data of the given
|
||||
* user.
|
||||
*
|
||||
* @throws GuacamoleException If an error occurs while reading the data
|
||||
* of the provided User.
|
||||
*/
|
||||
public MySQLUser toMySQLUser(org.glyptodon.guacamole.net.auth.User user) throws GuacamoleException {
|
||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
||||
mySQLUser.init(user);
|
||||
return mySQLUser;
|
||||
@Override
|
||||
protected DirectoryObjectMapper<UserModel> getObjectMapper() {
|
||||
return userMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MySQLUser based on the provided database record.
|
||||
*
|
||||
* @param user The database record describing the user.
|
||||
* @return A new MySQLUser object, populated with the data of the given
|
||||
* database record.
|
||||
*/
|
||||
private MySQLUser toMySQLUser(UserWithBLOBs user) {
|
||||
|
||||
// Retrieve user from provider
|
||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
||||
|
||||
// Init with data from given database user
|
||||
mySQLUser.init(
|
||||
user.getUser_id(),
|
||||
user.getUsername(),
|
||||
null,
|
||||
permissionCheckService.retrieveAllPermissions(user.getUser_id())
|
||||
);
|
||||
|
||||
// Return new user
|
||||
return mySQLUser;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the user having the given ID from the database.
|
||||
*
|
||||
* @param id The ID of the user to retrieve.
|
||||
* @return The existing MySQLUser object if found, null otherwise.
|
||||
*/
|
||||
public MySQLUser retrieveUser(int id) {
|
||||
|
||||
// Query user by ID
|
||||
UserWithBLOBs user = userDAO.selectByPrimaryKey(id);
|
||||
|
||||
// If no user found, return null
|
||||
if(user == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, return found user
|
||||
return toMySQLUser(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the user having the given username from the database.
|
||||
*
|
||||
* @param name The username of the user to retrieve.
|
||||
* @return The existing MySQLUser object if found, null otherwise.
|
||||
*/
|
||||
public MySQLUser retrieveUser(String name) {
|
||||
|
||||
// Query user by ID
|
||||
UserExample example = new UserExample();
|
||||
example.createCriteria().andUsernameEqualTo(name);
|
||||
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(example);
|
||||
|
||||
// If no user found, return null
|
||||
if(users.isEmpty())
|
||||
return null;
|
||||
|
||||
// Otherwise, return found user
|
||||
return toMySQLUser(users.get(0));
|
||||
|
||||
@Override
|
||||
protected MySQLUser getObjectInstance(UserModel model) {
|
||||
MySQLUser user = mySQLUserProvider.get();
|
||||
user.setModel(model);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,193 +72,17 @@ public class UserService {
|
||||
*/
|
||||
public MySQLUser retrieveUser(Credentials credentials) {
|
||||
|
||||
// No null users in database
|
||||
if (credentials.getUsername() == null)
|
||||
// Get username and password
|
||||
String username = credentials.getUsername();
|
||||
String password = credentials.getPassword();
|
||||
|
||||
// Retrieve user model, if the user exists
|
||||
UserModel userModel = userMapper.selectByCredentials(username, password);
|
||||
if (userModel == null)
|
||||
return null;
|
||||
|
||||
// Query user
|
||||
UserExample userExample = new UserExample();
|
||||
userExample.createCriteria().andUsernameEqualTo(credentials.getUsername());
|
||||
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(userExample);
|
||||
|
||||
// Check that a user was found
|
||||
if (users.isEmpty())
|
||||
return null;
|
||||
|
||||
// Assert only one user found
|
||||
assert users.size() == 1 : "Multiple users with same username.";
|
||||
|
||||
// Get first (and only) user
|
||||
UserWithBLOBs user = users.get(0);
|
||||
|
||||
// Check password, if invalid return null
|
||||
if (!passwordService.checkPassword(credentials.getPassword(),
|
||||
user.getPassword_hash(), user.getPassword_salt()))
|
||||
return null;
|
||||
|
||||
// Return found user
|
||||
return toMySQLUser(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a translation map of usernames to their corresponding IDs.
|
||||
*
|
||||
* @param ids The IDs of the users to retrieve the usernames of.
|
||||
* @return A map containing the names of all users and their corresponding
|
||||
* IDs.
|
||||
*/
|
||||
public Map<String, Integer> translateUsernames(List<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs
|
||||
Map<String, Integer> names = new HashMap<String, Integer>();
|
||||
|
||||
// Get all users having the given IDs
|
||||
UserExample example = new UserExample();
|
||||
example.createCriteria().andUser_idIn(ids);
|
||||
List<User> users =
|
||||
userDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (User user : users)
|
||||
names.put(user.getUsername(), user.getUser_id());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a map of all usernames for the given IDs.
|
||||
*
|
||||
* @param ids The IDs of the users to retrieve the usernames of.
|
||||
* @return A map containing the names of all users and their corresponding
|
||||
* IDs.
|
||||
*/
|
||||
public Map<Integer, String> retrieveUsernames(Collection<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs
|
||||
Map<Integer, String> names = new HashMap<Integer, String>();
|
||||
|
||||
// Get all users having the given IDs
|
||||
UserExample example = new UserExample();
|
||||
example.createCriteria().andUser_idIn(Lists.newArrayList(ids));
|
||||
List<User> users =
|
||||
userDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (User user : users)
|
||||
names.put(user.getUser_id(), user.getUsername());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user having the given username and password.
|
||||
*
|
||||
* @param username The username to assign to the new user.
|
||||
* @param password The password to assign to the new user.
|
||||
* @return A new MySQLUser containing the data of the newly created
|
||||
* user.
|
||||
*/
|
||||
public MySQLUser createUser(String username, String password) {
|
||||
|
||||
// Initialize database user
|
||||
UserWithBLOBs user = new UserWithBLOBs();
|
||||
user.setUsername(username);
|
||||
|
||||
// Set password if specified
|
||||
if (password != null) {
|
||||
byte[] salt = saltService.generateSalt();
|
||||
user.setPassword_salt(salt);
|
||||
user.setPassword_hash(
|
||||
passwordService.createPasswordHash(password, salt));
|
||||
}
|
||||
|
||||
// Create user
|
||||
userDAO.insert(user);
|
||||
return toMySQLUser(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the user having the given ID from the database.
|
||||
* @param user_id The ID of the user to delete.
|
||||
*/
|
||||
public void deleteUser(int user_id) {
|
||||
userDAO.deleteByPrimaryKey(user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user in the database corresponding to the given MySQLUser.
|
||||
*
|
||||
* @param mySQLUser The MySQLUser to update (save) to the database. This
|
||||
* user must already exist.
|
||||
*/
|
||||
public void updateUser(MySQLUser mySQLUser) {
|
||||
|
||||
UserWithBLOBs user = new UserWithBLOBs();
|
||||
user.setUser_id(mySQLUser.getUserID());
|
||||
user.setUsername(mySQLUser.getUsername());
|
||||
|
||||
// Set password if specified
|
||||
if (mySQLUser.getPassword() != null) {
|
||||
byte[] salt = saltService.generateSalt();
|
||||
user.setPassword_salt(salt);
|
||||
user.setPassword_hash(
|
||||
passwordService.createPasswordHash(mySQLUser.getPassword(), salt));
|
||||
}
|
||||
|
||||
// Update the user in the database
|
||||
userDAO.updateByPrimaryKeySelective(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the usernames of all the users defined in the system.
|
||||
*
|
||||
* @return A Set of usernames of all the users defined in the system.
|
||||
*/
|
||||
public Set<String> getAllUsernames() {
|
||||
|
||||
// Set of all present usernames
|
||||
Set<String> usernames = new HashSet<String>();
|
||||
|
||||
// Query all usernames
|
||||
List<User> users =
|
||||
userDAO.selectByExample(new UserExample());
|
||||
for (User user : users)
|
||||
usernames.add(user.getUsername());
|
||||
|
||||
return usernames;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user IDs of all the users defined in the system.
|
||||
*
|
||||
* @return A list of user IDs of all the users defined in the system.
|
||||
*/
|
||||
public List<Integer> getAllUserIDs() {
|
||||
|
||||
// Set of all present user IDs
|
||||
List<Integer> userIDs = new ArrayList<Integer>();
|
||||
|
||||
// Query all user IDs
|
||||
List<User> users =
|
||||
userDAO.selectByExample(new UserExample());
|
||||
for (User user : users)
|
||||
userIDs.add(user.getUser_id());
|
||||
|
||||
return userIDs;
|
||||
// Return corresponding user
|
||||
return getObjectInstance(userModel);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE generatorConfiguration
|
||||
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (C) 2013 Glyptodon LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<generatorConfiguration>
|
||||
<context id="guacamoleTables" targetRuntime="MyBatis3">
|
||||
|
||||
<!-- Allow selectByExample with RowBounds -->
|
||||
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>
|
||||
|
||||
<!-- MySQL JDBC driver class. -->
|
||||
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
|
||||
connectionURL="jdbc:mysql://127.0.0.1:3306"
|
||||
userId="${guacamole.database.user}"
|
||||
password="${guacamole.database.password}"/>
|
||||
|
||||
<javaModelGenerator
|
||||
targetPackage="net.sourceforge.guacamole.net.auth.mysql.model"
|
||||
targetProject="MAVEN"/>
|
||||
|
||||
<sqlMapGenerator
|
||||
targetPackage="net.sourceforge.guacamole.net.auth.mysql.dao"
|
||||
targetProject="MAVEN"/>
|
||||
|
||||
<javaClientGenerator type="XMLMAPPER"
|
||||
targetPackage="net.sourceforge.guacamole.net.auth.mysql.dao"
|
||||
targetProject="MAVEN"/>
|
||||
|
||||
<!-- TABLES -->
|
||||
|
||||
<table tableName="guacamole_connection"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="Connection" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="connection_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_group"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionGroup" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="connection_group_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_parameter"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionParameter" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_group_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionGroupPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_system_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="SystemPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_user"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="User" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="user_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_user_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="UserPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_history"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionHistory" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="history_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
</context>
|
||||
</generatorConfiguration>
|
||||
|
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
|
||||
<!--
|
||||
Copyright (C) 2015 Glyptodon LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<mapper namespace="net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper" >
|
||||
|
||||
<!-- Result mapper for user objects -->
|
||||
<resultMap id="UserResultMap" type="net.sourceforge.guacamole.net.auth.mysql.model.UserModel" >
|
||||
<id column="user_id" property="userID" jdbcType="INTEGER"/>
|
||||
<result column="username" property="username" jdbcType="VARCHAR"/>
|
||||
<result column="password_hash" property="passwordHash" jdbcType="BINARY"/>
|
||||
<result column="password_salt" property="passwordSalt" jdbcType="BINARY"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all usernames -->
|
||||
<select id="selectIdentifiers" resultType="string">
|
||||
SELECT username
|
||||
FROM guacamole_user
|
||||
</select>
|
||||
|
||||
<!-- Select multiple users by username -->
|
||||
<select id="select" resultMap="UserResultMap">
|
||||
|
||||
SELECT
|
||||
user_id,
|
||||
username,
|
||||
password_hash,
|
||||
password_salt
|
||||
FROM guacamole_user
|
||||
WHERE username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
|
||||
</select>
|
||||
|
||||
<select id="selectByCredentials" resultMap="UserResultMap">
|
||||
SELECT
|
||||
user_id,
|
||||
username,
|
||||
password_hash,
|
||||
password_salt
|
||||
FROM guacamole_user
|
||||
WHERE
|
||||
username = #{username,jdbcType=VARCHAR}
|
||||
AND password_hash = UNHEX(SHA2(CONCAT(#{password,jdbcType=VARCHAR}, HEX(password_salt)), 256))
|
||||
</select>
|
||||
|
||||
<!-- Delete single user by username -->
|
||||
<delete id="delete">
|
||||
DELETE FROM guacamole_user
|
||||
WHERE username = #{identifier,jdbcType=VARCHAR}
|
||||
</delete>
|
||||
|
||||
<!-- Insert single user -->
|
||||
<insert id="insert" parameterType="net.sourceforge.guacamole.net.auth.mysql.model.UserModel">
|
||||
|
||||
INSERT INTO guacamole_user (
|
||||
username,
|
||||
password_hash,
|
||||
password_salt
|
||||
)
|
||||
VALUES (
|
||||
#{username,jdbcType=VARCHAR},
|
||||
#{passwordHash,jdbcType=BINARY},
|
||||
#{passwordSalt,jdbcType=BINARY}
|
||||
)
|
||||
|
||||
<selectKey resultType="java.lang.Integer" keyProperty="userID" order="AFTER">
|
||||
SELECT LAST_INSERT_ID()
|
||||
</selectKey>
|
||||
|
||||
</insert>
|
||||
|
||||
<!-- Update single user -->
|
||||
<update id="update" parameterType="net.sourceforge.guacamole.net.auth.mysql.model.UserModel">
|
||||
UPDATE guacamole_user
|
||||
SET password_hash = #{passwordHash,jdbcType=BINARY},
|
||||
password_salt = #{passwordSalt,jdbcType=BINARY}
|
||||
WHERE user_id = #{userID,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
</mapper>
|
Reference in New Issue
Block a user