mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
Ticket #269: Refactor all user access into UserService, remove usage of UserMapper outside UserService.
This commit is contained in:
@@ -42,7 +42,6 @@ import com.google.inject.Guice;
|
|||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.name.Names;
|
import com.google.inject.name.Names;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import net.sourceforge.guacamole.GuacamoleException;
|
import net.sourceforge.guacamole.GuacamoleException;
|
||||||
import net.sourceforge.guacamole.net.auth.AuthenticationProvider;
|
import net.sourceforge.guacamole.net.auth.AuthenticationProvider;
|
||||||
@@ -55,8 +54,6 @@ 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.SystemPermissionMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
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.dao.UserPermissionMapper;
|
||||||
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.properties.MySQLGuacamoleProperties;
|
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConfigurationTranslationService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.ConfigurationTranslationService;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
|
||||||
@@ -65,6 +62,7 @@ import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService;
|
|||||||
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.Sha256PasswordEncryptionService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.Sha256PasswordEncryptionService;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||||
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
||||||
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||||
import org.mybatis.guice.MyBatisModule;
|
import org.mybatis.guice.MyBatisModule;
|
||||||
@@ -93,43 +91,19 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
|||||||
@Override
|
@Override
|
||||||
public UserContext getUserContext(Credentials credentials) throws GuacamoleException {
|
public UserContext getUserContext(Credentials credentials) throws GuacamoleException {
|
||||||
|
|
||||||
// No null users in database
|
// Get user service
|
||||||
if (credentials.getUsername() == null)
|
UserService userService = injector.getInstance(UserService.class);
|
||||||
return null;
|
|
||||||
|
// Get user
|
||||||
|
MySQLUser authenticatedUser = userService.retrieveUser(credentials);
|
||||||
|
if (authenticatedUser != null) {
|
||||||
|
MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
|
||||||
|
context.init(authenticatedUser.getUserID());
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
// Get user DAO
|
// Otherwise, unauthorized
|
||||||
UserMapper userDAO = injector.getInstance(UserMapper.class);
|
return null;
|
||||||
|
|
||||||
// Query user
|
|
||||||
UserExample userExample = new UserExample();
|
|
||||||
userExample.createCriteria().andUsernameEqualTo(credentials.getUsername());
|
|
||||||
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(userExample);
|
|
||||||
|
|
||||||
// The unique constraint on the table should prevent this.
|
|
||||||
if (users.size() > 1)
|
|
||||||
throw new GuacamoleException(
|
|
||||||
"Multiple users found with the same username: "
|
|
||||||
+ credentials.getUsername());
|
|
||||||
|
|
||||||
// Check that a user was found
|
|
||||||
if (users.isEmpty())
|
|
||||||
throw new GuacamoleException("No user found with the supplied credentials");
|
|
||||||
|
|
||||||
// Get first (and only) user
|
|
||||||
UserWithBLOBs user = users.get(0);
|
|
||||||
|
|
||||||
// Get password service
|
|
||||||
PasswordEncryptionService passwordService =
|
|
||||||
injector.getInstance(PasswordEncryptionService.class);
|
|
||||||
|
|
||||||
// Check password, if invalid return null
|
|
||||||
if (!passwordService.checkPassword(credentials.getPassword(),
|
|
||||||
user.getPassword_hash(), user.getPassword_salt()))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
|
|
||||||
context.init(user.getUser_id());
|
|
||||||
return context;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +166,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
|||||||
bind(PasswordEncryptionService.class).to(Sha256PasswordEncryptionService.class);
|
bind(PasswordEncryptionService.class).to(Sha256PasswordEncryptionService.class);
|
||||||
bind(PermissionCheckService.class);
|
bind(PermissionCheckService.class);
|
||||||
bind(ProviderService.class);
|
bind(ProviderService.class);
|
||||||
|
bind(UserService.class);
|
||||||
bind(ConfigurationTranslationService.class);
|
bind(ConfigurationTranslationService.class);
|
||||||
bind(ActiveConnectionSet.class).toInstance(activeConnectionSet);
|
bind(ActiveConnectionSet.class).toInstance(activeConnectionSet);
|
||||||
|
|
||||||
|
@@ -42,10 +42,9 @@ import java.util.Date;
|
|||||||
import net.sourceforge.guacamole.net.auth.Connection;
|
import net.sourceforge.guacamole.net.auth.Connection;
|
||||||
import net.sourceforge.guacamole.net.auth.ConnectionRecord;
|
import net.sourceforge.guacamole.net.auth.ConnectionRecord;
|
||||||
import net.sourceforge.guacamole.net.auth.User;
|
import net.sourceforge.guacamole.net.auth.User;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ConnectionRecord which is based on data stored in MySQL.
|
* A ConnectionRecord which is based on data stored in MySQL.
|
||||||
@@ -60,16 +59,10 @@ public class MySQLConnectionRecord implements ConnectionRecord {
|
|||||||
private ConnectionHistory connectionHistory;
|
private ConnectionHistory connectionHistory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DAO for accessing users.
|
* Service for accessing users.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private UserMapper userDAO;
|
private UserService userService;
|
||||||
|
|
||||||
/**
|
|
||||||
* DAO for accessing connections.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private ConnectionMapper connectionDAO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for creating and retrieving objects.
|
* Service for creating and retrieving objects.
|
||||||
@@ -100,7 +93,9 @@ public class MySQLConnectionRecord implements ConnectionRecord {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User getUser() {
|
public User getUser() {
|
||||||
return providerService.getExistingMySQLUser(connectionHistory.getUser_id());
|
// FIXME: This will be SLOW - history is queried in bulk. When listed
|
||||||
|
// to the user in the webapp, this will result in one query per record.
|
||||||
|
return userService.retrieveUser(connectionHistory.getUser_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -43,7 +43,7 @@ import net.sourceforge.guacamole.net.auth.Connection;
|
|||||||
import net.sourceforge.guacamole.net.auth.Directory;
|
import net.sourceforge.guacamole.net.auth.Directory;
|
||||||
import net.sourceforge.guacamole.net.auth.User;
|
import net.sourceforge.guacamole.net.auth.User;
|
||||||
import net.sourceforge.guacamole.net.auth.UserContext;
|
import net.sourceforge.guacamole.net.auth.UserContext;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MySQL representation of a UserContext.
|
* The MySQL representation of a UserContext.
|
||||||
@@ -72,10 +72,10 @@ public class MySQLUserContext implements UserContext {
|
|||||||
private ConnectionDirectory connectionDirectory;
|
private ConnectionDirectory connectionDirectory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for retrieving existing objects or creating new ones.
|
* Service for accessing users.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private ProviderService providerService;
|
private UserService userService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the user and directories associated with this context.
|
* Initializes the user and directories associated with this context.
|
||||||
@@ -90,7 +90,7 @@ public class MySQLUserContext implements UserContext {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User self() {
|
public User self() {
|
||||||
return providerService.getExistingMySQLUser(user_id);
|
return userService.retrieveUser(user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -52,7 +52,6 @@ import net.sourceforge.guacamole.net.auth.Directory;
|
|||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
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.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.dao.UserPermissionMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.Connection;
|
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;
|
||||||
@@ -60,15 +59,12 @@ import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExampl
|
|||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
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.SystemPermissionExample;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||||
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.UserPermissionExample;
|
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.model.UserPermissionKey;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
|
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.PermissionCheckService;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||||
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
||||||
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
||||||
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
||||||
@@ -88,10 +84,10 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
private int user_id;
|
private int user_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DAO for accessing users, which will be injected.
|
* Service for accessing users.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private UserMapper userDAO;
|
private UserService userService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DAO for accessing connections, which will be injected.
|
* DAO for accessing connections, which will be injected.
|
||||||
@@ -123,13 +119,6 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
@Inject
|
@Inject
|
||||||
private PermissionCheckService permissionCheckService;
|
private PermissionCheckService permissionCheckService;
|
||||||
|
|
||||||
/**
|
|
||||||
* Service providing convenient access to object creation and
|
|
||||||
* retrieval functions.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private ProviderService providerService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for encrypting passwords.
|
* Service for encrypting passwords.
|
||||||
*/
|
*/
|
||||||
@@ -157,7 +146,7 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
public net.sourceforge.guacamole.net.auth.User get(String identifier)
|
public net.sourceforge.guacamole.net.auth.User get(String identifier)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
permissionCheckService.verifyUserReadAccess(this.user_id, identifier);
|
permissionCheckService.verifyUserReadAccess(this.user_id, identifier);
|
||||||
return providerService.getExistingMySQLUser(identifier);
|
return userService.retrieveUser(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -184,27 +173,17 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
permissionCheckService.verifyCreateUserPermission(this.user_id);
|
permissionCheckService.verifyCreateUserPermission(this.user_id);
|
||||||
Preconditions.checkNotNull(object);
|
Preconditions.checkNotNull(object);
|
||||||
|
|
||||||
// Create user in database
|
// Create new user
|
||||||
UserWithBLOBs user = new UserWithBLOBs();
|
MySQLUser user = userService.createUser(object.getUsername(),
|
||||||
user.setUsername(object.getUsername());
|
object.getPassword());
|
||||||
|
|
||||||
// Set password if specified
|
|
||||||
if (object.getPassword() != null) {
|
|
||||||
byte[] salt = saltService.generateSalt();
|
|
||||||
user.setPassword_salt(salt);
|
|
||||||
user.setPassword_hash(
|
|
||||||
passwordService.createPasswordHash(object.getPassword(), salt));
|
|
||||||
}
|
|
||||||
|
|
||||||
userDAO.insert(user);
|
|
||||||
|
|
||||||
// Create permissions of new user in database
|
// Create permissions of new user in database
|
||||||
createPermissions(user.getUser_id(), object.getPermissions());
|
createPermissions(user.getUserID(), object.getPermissions());
|
||||||
|
|
||||||
// Give the current user full access to the newly created user.
|
// Give the current user full access to the newly created user.
|
||||||
UserPermissionKey newUserPermission = new UserPermissionKey();
|
UserPermissionKey newUserPermission = new UserPermissionKey();
|
||||||
newUserPermission.setUser_id(this.user_id);
|
newUserPermission.setUser_id(this.user_id);
|
||||||
newUserPermission.setAffected_user_id(user.getUser_id());
|
newUserPermission.setAffected_user_id(user.getUserID());
|
||||||
|
|
||||||
// READ permission on new user
|
// READ permission on new user
|
||||||
newUserPermission.setPermission(MySQLConstants.USER_READ);
|
newUserPermission.setPermission(MySQLConstants.USER_READ);
|
||||||
@@ -321,36 +300,34 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
usernames.add(permission.getObjectIdentifier());
|
usernames.add(permission.getObjectIdentifier());
|
||||||
|
|
||||||
// Find all the users by username
|
// Find all the users by username
|
||||||
UserExample userExample = new UserExample();
|
List<MySQLUser> users = userService.retrieveUsersByUsername(usernames);
|
||||||
userExample.createCriteria().andUsernameIn(usernames);
|
|
||||||
List<User> dbUsers = userDAO.selectByExample(userExample);
|
|
||||||
|
|
||||||
// Build map of found users, indexed by username
|
// Build map of found users, indexed by username
|
||||||
Map<String, User> dbUserMap = new HashMap<String, User>();
|
Map<String, MySQLUser> userMap = new HashMap<String, MySQLUser>();
|
||||||
for (User dbUser : dbUsers) {
|
for (MySQLUser user : users)
|
||||||
dbUserMap.put(dbUser.getUsername(), dbUser);
|
userMap.put(user.getUsername(), user);
|
||||||
}
|
|
||||||
|
|
||||||
for (UserPermission permission : permissions) {
|
for (UserPermission permission : permissions) {
|
||||||
|
|
||||||
// Get user
|
// Get user
|
||||||
User dbAffectedUser = dbUserMap.get(permission.getObjectIdentifier());
|
MySQLUser affectedUser =
|
||||||
if (dbAffectedUser == null)
|
userMap.get(permission.getObjectIdentifier());
|
||||||
|
if (affectedUser == null)
|
||||||
throw new GuacamoleException(
|
throw new GuacamoleException(
|
||||||
"User '" + permission.getObjectIdentifier()
|
"User '" + permission.getObjectIdentifier()
|
||||||
+ "' not found.");
|
+ "' not found.");
|
||||||
|
|
||||||
// Verify that the user actually has permission to administrate
|
// Verify that the user actually has permission to administrate
|
||||||
// every one of these users
|
// every one of these users
|
||||||
if (!administerableUsers.contains(dbAffectedUser.getUser_id()))
|
if (!administerableUsers.contains(affectedUser.getUserID()))
|
||||||
throw new GuacamoleSecurityException(
|
throw new GuacamoleSecurityException(
|
||||||
"User #" + this.user_id
|
"User #" + this.user_id
|
||||||
+ " does not have permission to administrate user "
|
+ " does not have permission to administrate user "
|
||||||
+ dbAffectedUser.getUser_id());
|
+ affectedUser.getUsername());
|
||||||
|
|
||||||
// Create new permission
|
// Create new permission
|
||||||
UserPermissionKey newPermission = new UserPermissionKey();
|
UserPermissionKey newPermission = new UserPermissionKey();
|
||||||
newPermission.setAffected_user_id(dbAffectedUser.getUser_id());
|
newPermission.setAffected_user_id(affectedUser.getUserID());
|
||||||
newPermission.setPermission(permission.getType().name());
|
newPermission.setPermission(permission.getType().name());
|
||||||
newPermission.setUser_id(user_id);
|
newPermission.setUser_id(user_id);
|
||||||
userPermissionDAO.insert(newPermission);
|
userPermissionDAO.insert(newPermission);
|
||||||
@@ -383,35 +360,33 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
usernames.add(permission.getObjectIdentifier());
|
usernames.add(permission.getObjectIdentifier());
|
||||||
|
|
||||||
// Find all the users by username
|
// Find all the users by username
|
||||||
UserExample userExample = new UserExample();
|
List<MySQLUser> users = userService.retrieveUsersByUsername(usernames);
|
||||||
userExample.createCriteria().andUsernameIn(usernames);
|
|
||||||
List<User> dbUsers = userDAO.selectByExample(userExample);
|
|
||||||
List<Integer> userIDs = new ArrayList<Integer>();
|
List<Integer> userIDs = new ArrayList<Integer>();
|
||||||
|
|
||||||
// Build map of found users, indexed by username
|
// Build map of found users, indexed by username
|
||||||
Map<String, User> dbUserMap = new HashMap<String, User>();
|
Map<String, MySQLUser> userMap = new HashMap<String, MySQLUser>();
|
||||||
for (User dbUser : dbUsers) {
|
for (MySQLUser user : users) {
|
||||||
dbUserMap.put(dbUser.getUsername(), dbUser);
|
userMap.put(user.getUsername(), user);
|
||||||
userIDs.add(dbUser.getUser_id());
|
userIDs.add(user.getUserID());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify we have permission to delete each user permission.
|
// Verify we have permission to delete each user permission.
|
||||||
for (UserPermission permission : permissions) {
|
for (UserPermission permission : permissions) {
|
||||||
|
|
||||||
// Get user
|
// Get user
|
||||||
User dbAffectedUser = dbUserMap.get(permission.getObjectIdentifier());
|
MySQLUser affectedUser = userMap.get(permission.getObjectIdentifier());
|
||||||
if (dbAffectedUser == null)
|
if (affectedUser == null)
|
||||||
throw new GuacamoleException(
|
throw new GuacamoleException(
|
||||||
"User '" + permission.getObjectIdentifier()
|
"User '" + permission.getObjectIdentifier()
|
||||||
+ "' not found.");
|
+ "' not found.");
|
||||||
|
|
||||||
// Verify that the user actually has permission to administrate
|
// Verify that the user actually has permission to administrate
|
||||||
// every one of these users
|
// every one of these users
|
||||||
if (!administerableUsers.contains(dbAffectedUser.getUser_id()))
|
if (!administerableUsers.contains(affectedUser.getUserID()))
|
||||||
throw new GuacamoleSecurityException(
|
throw new GuacamoleSecurityException(
|
||||||
"User #" + this.user_id
|
"User #" + this.user_id
|
||||||
+ " does not have permission to administrate user "
|
+ " does not have permission to administrate user "
|
||||||
+ dbAffectedUser.getUser_id());
|
+ affectedUser.getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!userIDs.isEmpty()) {
|
if(!userIDs.isEmpty()) {
|
||||||
@@ -663,22 +638,9 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
permissionCheckService.verifyUserUpdateAccess(this.user_id,
|
permissionCheckService.verifyUserUpdateAccess(this.user_id,
|
||||||
object.getUsername());
|
object.getUsername());
|
||||||
|
|
||||||
// Build database user from non-database structure
|
|
||||||
MySQLUser mySQLUser = (MySQLUser) object;
|
|
||||||
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
|
// Update the user in the database
|
||||||
userDAO.updateByPrimaryKeySelective(user);
|
MySQLUser mySQLUser = (MySQLUser) object;
|
||||||
|
userService.updateUser(mySQLUser);
|
||||||
|
|
||||||
// Update permissions in database
|
// Update permissions in database
|
||||||
createPermissions(mySQLUser.getUserID(), mySQLUser.getNewPermissions());
|
createPermissions(mySQLUser.getUserID(), mySQLUser.getNewPermissions());
|
||||||
@@ -694,48 +656,17 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
|
|||||||
@Transactional
|
@Transactional
|
||||||
public void remove(String identifier) throws GuacamoleException {
|
public void remove(String identifier) throws GuacamoleException {
|
||||||
|
|
||||||
|
// FIXME: Querying permissions here will query the user to determine
|
||||||
|
// its ID, and that same user will be queried AGAIN later when
|
||||||
|
// deleted, again - to determine its ID. Perhaps we want cascading
|
||||||
|
// deletes in the schema?
|
||||||
|
|
||||||
// Validate current user has permission to remove the specified user
|
// Validate current user has permission to remove the specified user
|
||||||
permissionCheckService.verifyUserDeleteAccess(this.user_id,
|
permissionCheckService.verifyUserDeleteAccess(this.user_id,
|
||||||
identifier);
|
identifier);
|
||||||
|
|
||||||
// Get specified user
|
// Delete specified user
|
||||||
MySQLUser mySQLUser = providerService.getExistingMySQLUser(identifier);
|
userService.deleteUser(identifier);
|
||||||
|
|
||||||
// Delete all the user permissions in the database
|
|
||||||
deleteAllPermissions(mySQLUser.getUserID());
|
|
||||||
|
|
||||||
// Delete the user in the database
|
|
||||||
userDAO.deleteByPrimaryKey(mySQLUser.getUserID());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all permissions associated with the provided user. This is only
|
|
||||||
* used when deleting a user.
|
|
||||||
*
|
|
||||||
* @param user_id The ID of the user to delete all permissions of.
|
|
||||||
*/
|
|
||||||
private void deleteAllPermissions(int user_id) {
|
|
||||||
|
|
||||||
// Delete all user permissions
|
|
||||||
UserPermissionExample userPermissionExample = new UserPermissionExample();
|
|
||||||
userPermissionExample.createCriteria().andUser_idEqualTo(user_id);
|
|
||||||
userPermissionDAO.deleteByExample(userPermissionExample);
|
|
||||||
|
|
||||||
// Delete all connection permissions
|
|
||||||
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
|
||||||
connectionPermissionExample.createCriteria().andUser_idEqualTo(user_id);
|
|
||||||
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
|
|
||||||
|
|
||||||
// Delete all system permissions
|
|
||||||
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
|
||||||
systemPermissionExample.createCriteria().andUser_idEqualTo(user_id);
|
|
||||||
systemPermissionDAO.deleteByExample(systemPermissionExample);
|
|
||||||
|
|
||||||
// Delete all permissions that refer to this user
|
|
||||||
userPermissionExample.clear();
|
|
||||||
userPermissionExample.createCriteria().andAffected_user_idEqualTo(user_id);
|
|
||||||
userPermissionDAO.deleteByExample(userPermissionExample);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,7 +52,6 @@ import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
|||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
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.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.dao.UserPermissionMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.Connection;
|
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;
|
||||||
@@ -60,11 +59,8 @@ import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExampl
|
|||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
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.SystemPermissionExample;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||||
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.UserPermissionExample;
|
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.model.UserPermissionKey;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
|
||||||
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
||||||
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
||||||
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
||||||
@@ -78,7 +74,7 @@ import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
|||||||
public class PermissionCheckService {
|
public class PermissionCheckService {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserMapper userDAO;
|
private UserService userService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ConnectionMapper connectionDAO;
|
private ConnectionMapper connectionDAO;
|
||||||
@@ -274,9 +270,9 @@ public class PermissionCheckService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean checkUserAccess(int userID, String affectedUsername, String permissionType) {
|
private boolean checkUserAccess(int userID, String affectedUsername, String permissionType) {
|
||||||
User affectedUser = getUser(affectedUsername);
|
MySQLUser affectedUser = userService.retrieveUser(affectedUsername);
|
||||||
if(affectedUser != null)
|
if(affectedUser != null)
|
||||||
return checkUserAccess(userID, affectedUser.getUser_id(), permissionType);
|
return checkUserAccess(userID, affectedUser.getUserID(), permissionType);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -386,19 +382,8 @@ public class PermissionCheckService {
|
|||||||
return Collections.EMPTY_SET;
|
return Collections.EMPTY_SET;
|
||||||
|
|
||||||
// Query corresponding user data for each retrieved ID
|
// Query corresponding user data for each retrieved ID
|
||||||
UserExample example = new UserExample();
|
return new HashSet<MySQLUser>(userService.retrieveUsersByID(
|
||||||
example.createCriteria().andUser_idIn(Lists.newArrayList(affectedUserIDs));
|
Lists.newArrayList(affectedUserIDs)));
|
||||||
List<UserWithBLOBs> userDBOjects = userDAO.selectByExampleWithBLOBs(example);
|
|
||||||
|
|
||||||
// Build set of MySQLUsers from retrieved user data
|
|
||||||
Set<MySQLUser> affectedUsers = new HashSet<MySQLUser>();
|
|
||||||
for(UserWithBLOBs affectedUser : userDBOjects) {
|
|
||||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
|
||||||
mySQLUser.init(affectedUser.getUsername());
|
|
||||||
affectedUsers.add(mySQLUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
return affectedUsers;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,21 +788,6 @@ public class PermissionCheckService {
|
|||||||
return connections.get(0);
|
return connections.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a user object by username.
|
|
||||||
* @param userName
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private User getUser(String username) {
|
|
||||||
UserExample example = new UserExample();
|
|
||||||
example.createCriteria().andUsernameEqualTo(username);
|
|
||||||
List<User> users = userDAO.selectByExample(example);
|
|
||||||
if(users.isEmpty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return users.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all permissions a given user has.
|
* Get all permissions a given user has.
|
||||||
* @param userID
|
* @param userID
|
||||||
@@ -841,16 +811,14 @@ public class PermissionCheckService {
|
|||||||
affectedUserIDs.add(userPermission.getAffected_user_id());
|
affectedUserIDs.add(userPermission.getAffected_user_id());
|
||||||
|
|
||||||
// Query all affected users, store in map indexed by user ID
|
// Query all affected users, store in map indexed by user ID
|
||||||
UserExample userExample = new UserExample();
|
List<MySQLUser> users = userService.retrieveUsersByID(affectedUserIDs);
|
||||||
userExample.createCriteria().andUser_idIn(affectedUserIDs);
|
Map<Integer, MySQLUser> userMap = new HashMap<Integer, MySQLUser>();
|
||||||
List<User> users = userDAO.selectByExample(userExample);
|
for (MySQLUser user : users)
|
||||||
Map<Integer, User> userMap = new HashMap<Integer, User>();
|
userMap.put(user.getUserID(), user);
|
||||||
for(User user : users)
|
|
||||||
userMap.put(user.getUser_id(), user);
|
|
||||||
|
|
||||||
// Add user permissions
|
// Add user permissions
|
||||||
for(UserPermissionKey userPermission : userPermissions) {
|
for(UserPermissionKey userPermission : userPermissions) {
|
||||||
User affectedUser = userMap.get(userPermission.getAffected_user_id());
|
MySQLUser affectedUser = userMap.get(userPermission.getAffected_user_id());
|
||||||
UserPermission newPermission = new UserPermission(
|
UserPermission newPermission = new UserPermission(
|
||||||
UserPermission.Type.valueOf(userPermission.getPermission()),
|
UserPermission.Type.valueOf(userPermission.getPermission()),
|
||||||
affectedUser.getUsername()
|
affectedUser.getUsername()
|
||||||
|
@@ -42,22 +42,17 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.sourceforge.guacamole.GuacamoleException;
|
import net.sourceforge.guacamole.GuacamoleException;
|
||||||
import net.sourceforge.guacamole.net.auth.Connection;
|
import net.sourceforge.guacamole.net.auth.Connection;
|
||||||
import net.sourceforge.guacamole.net.auth.User;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
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.ConnectionParameterMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
|
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
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.ConnectionHistoryExample;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter;
|
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.ConnectionParameterExample;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserExample;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
|
||||||
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
|
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||||
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||||
|
|
||||||
@@ -67,9 +62,6 @@ import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
|||||||
*/
|
*/
|
||||||
public class ProviderService {
|
public class ProviderService {
|
||||||
|
|
||||||
@Inject
|
|
||||||
private UserMapper userDAO;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ConnectionMapper connectionDAO;
|
private ConnectionMapper connectionDAO;
|
||||||
|
|
||||||
@@ -79,9 +71,6 @@ public class ProviderService {
|
|||||||
@Inject
|
@Inject
|
||||||
private ConnectionHistoryMapper connectionHistoryDAO;
|
private ConnectionHistoryMapper connectionHistoryDAO;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Provider<MySQLUser> mySQLUserProvider;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Provider<MySQLConnection> mySQLConnectionProvider;
|
private Provider<MySQLConnection> mySQLConnectionProvider;
|
||||||
|
|
||||||
@@ -91,92 +80,6 @@ public class ProviderService {
|
|||||||
@Inject
|
@Inject
|
||||||
private Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
private Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
||||||
|
|
||||||
/**
|
|
||||||
* Service for checking permissions.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private PermissionCheckService permissionCheckService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new user based on the provided object.
|
|
||||||
* @param user
|
|
||||||
* @return the new MySQLUser object.
|
|
||||||
* @throws GuacamoleException
|
|
||||||
*/
|
|
||||||
public MySQLUser getNewMySQLUser(User user) throws GuacamoleException {
|
|
||||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
|
||||||
mySQLUser.init(user);
|
|
||||||
return mySQLUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the user based on the username of the provided object.
|
|
||||||
* @param user
|
|
||||||
* @return the new MySQLUser object.
|
|
||||||
* @throws GuacamoleException
|
|
||||||
*/
|
|
||||||
public MySQLUser getExistingMySQLUser(User user) throws GuacamoleException {
|
|
||||||
return getExistingMySQLUser(user.getUsername());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the user based on the username of the provided object.
|
|
||||||
* @param name
|
|
||||||
* @return the new MySQLUser object.
|
|
||||||
* @throws GuacamoleException
|
|
||||||
*/
|
|
||||||
public MySQLUser getExistingMySQLUser(String name) throws GuacamoleException {
|
|
||||||
|
|
||||||
// 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 getExistingMySQLUser(users.get(0));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an existing MySQLUser from a user database record.
|
|
||||||
* @param user
|
|
||||||
* @return the existing MySQLUser object.
|
|
||||||
*/
|
|
||||||
public MySQLUser getExistingMySQLUser(UserWithBLOBs user) {
|
|
||||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
|
||||||
mySQLUser.init(
|
|
||||||
user.getUser_id(),
|
|
||||||
user.getUsername(),
|
|
||||||
null,
|
|
||||||
permissionCheckService.getAllPermissions(user.getUser_id())
|
|
||||||
);
|
|
||||||
|
|
||||||
return mySQLUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an existing MySQLUser from a user ID.
|
|
||||||
* @param id
|
|
||||||
* @return the existing MySQLUser object if found, null if not.
|
|
||||||
*/
|
|
||||||
public MySQLUser getExistingMySQLUser(Integer 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 getExistingMySQLUser(user);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the connection based on the connection name of the provided object.
|
* Get the connection based on the connection name of the provided object.
|
||||||
* @param connection
|
* @param connection
|
||||||
|
@@ -0,0 +1,382 @@
|
|||||||
|
|
||||||
|
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||||
|
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is guacamole-auth-mysql.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* James Muehlner.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import net.sourceforge.guacamole.GuacamoleException;
|
||||||
|
import net.sourceforge.guacamole.net.auth.Credentials;
|
||||||
|
import net.sourceforge.guacamole.net.auth.User;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
||||||
|
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.model.ConnectionPermissionExample;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionExample;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.model.UserExample;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service which provides convenience methods for creating, retrieving, and
|
||||||
|
* manipulating users.
|
||||||
|
*
|
||||||
|
* @author Michael Jumper, James Muehlner
|
||||||
|
*/
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DAO for accessing users.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private UserMapper userDAO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 system permissions, which will be injected.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private SystemPermissionMapper systemPermissionDAO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider for creating users.
|
||||||
|
*/
|
||||||
|
@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(User user) throws GuacamoleException {
|
||||||
|
MySQLUser mySQLUser = mySQLUserProvider.get();
|
||||||
|
mySQLUser.init(user);
|
||||||
|
return mySQLUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.getAllPermissions(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(Integer 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 users having the given IDs from the database.
|
||||||
|
*
|
||||||
|
* @param ids The IDs of the users to retrieve.
|
||||||
|
* @return A list of existing MySQLUser objects.
|
||||||
|
*/
|
||||||
|
public List<MySQLUser> retrieveUsersByID(List<Integer> ids) {
|
||||||
|
|
||||||
|
// If no IDs given, just return empty list
|
||||||
|
if (ids.isEmpty())
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
|
||||||
|
// Query users by ID
|
||||||
|
UserExample example = new UserExample();
|
||||||
|
example.createCriteria().andUser_idIn(ids);
|
||||||
|
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(example);
|
||||||
|
|
||||||
|
// Convert to MySQLUser list
|
||||||
|
List<MySQLUser> mySQLUsers = new ArrayList<MySQLUser>(users.size());
|
||||||
|
for (UserWithBLOBs user : users)
|
||||||
|
mySQLUsers.add(toMySQLUser(user));
|
||||||
|
|
||||||
|
// Return found users
|
||||||
|
return mySQLUsers;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the users having the given usernames from the database.
|
||||||
|
*
|
||||||
|
* @param names The usernames of the users to retrieve.
|
||||||
|
* @return A list of existing MySQLUser objects.
|
||||||
|
*/
|
||||||
|
public List<MySQLUser> retrieveUsersByUsername(List<String> names) {
|
||||||
|
|
||||||
|
// If no names given, just return empty list
|
||||||
|
if (names.isEmpty())
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
|
||||||
|
// Query users by ID
|
||||||
|
UserExample example = new UserExample();
|
||||||
|
example.createCriteria().andUsernameIn(names);
|
||||||
|
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(example);
|
||||||
|
|
||||||
|
// Convert to MySQLUser list
|
||||||
|
List<MySQLUser> mySQLUsers = new ArrayList<MySQLUser>(users.size());
|
||||||
|
for (UserWithBLOBs user : users)
|
||||||
|
mySQLUsers.add(toMySQLUser(user));
|
||||||
|
|
||||||
|
// Return found users
|
||||||
|
return mySQLUsers;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the user corresponding to the given credentials from the
|
||||||
|
* database.
|
||||||
|
*
|
||||||
|
* @param credentials The credentials to use when locating the user.
|
||||||
|
* @return The existing MySQLUser object if the credentials given are
|
||||||
|
* valid, null otherwise.
|
||||||
|
*/
|
||||||
|
public MySQLUser retrieveUser(Credentials credentials) {
|
||||||
|
|
||||||
|
// No null users in database
|
||||||
|
if (credentials.getUsername() == 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 username from the database
|
||||||
|
* @param username The username of the user to delete.
|
||||||
|
*/
|
||||||
|
public void deleteUser(String username) {
|
||||||
|
|
||||||
|
// Get specified user
|
||||||
|
MySQLUser mySQLUser = retrieveUser(username);
|
||||||
|
int user_id = mySQLUser.getUserID();
|
||||||
|
|
||||||
|
// Delete all user permissions
|
||||||
|
UserPermissionExample userPermissionExample = new UserPermissionExample();
|
||||||
|
userPermissionExample.createCriteria().andUser_idEqualTo(user_id);
|
||||||
|
userPermissionDAO.deleteByExample(userPermissionExample);
|
||||||
|
|
||||||
|
// Delete all connection permissions
|
||||||
|
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
||||||
|
connectionPermissionExample.createCriteria().andUser_idEqualTo(user_id);
|
||||||
|
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
|
||||||
|
|
||||||
|
// Delete all system permissions
|
||||||
|
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
||||||
|
systemPermissionExample.createCriteria().andUser_idEqualTo(user_id);
|
||||||
|
systemPermissionDAO.deleteByExample(systemPermissionExample);
|
||||||
|
|
||||||
|
// Delete all permissions that refer to this user
|
||||||
|
userPermissionExample.clear();
|
||||||
|
userPermissionExample.createCriteria().andAffected_user_idEqualTo(user_id);
|
||||||
|
userPermissionDAO.deleteByExample(userPermissionExample);
|
||||||
|
|
||||||
|
// Delete the user in the database
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user