mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
GUAC-1101: Allow implementations to validate objects prior to create/update.
This commit is contained in:
@@ -159,6 +159,55 @@ public abstract class DirectoryObjectService<InternalType extends DirectoryObjec
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given object is valid and can be created as-is. The
|
||||||
|
* object does not yet exist in the database, but the user desires to
|
||||||
|
* create a new object with the given values. This function will be called
|
||||||
|
* prior to any creation operation, and provides a means for the
|
||||||
|
* implementation to abort prior to completion. The default implementation
|
||||||
|
* does nothing.
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* The user creating the object.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* The object to validate.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the object is invalid, or an error prevents validating the given
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
protected void validateNewObject(AuthenticatedUser user,
|
||||||
|
ExternalType object) throws GuacamoleException {
|
||||||
|
|
||||||
|
// By default, do nothing.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given object is valid and can updated as-is. The
|
||||||
|
* object already exists in the database, but the user desires to update
|
||||||
|
* the object to the given values. This function will be called prior to
|
||||||
|
* update operation, and provides a means for the implementation to abort
|
||||||
|
* prior to completion. The default implementation does nothing.
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* The user updating the existing object.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* The object to validate.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the object is invalid, or an error prevents validating the given
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
protected void validateExistingObject(AuthenticatedUser user,
|
||||||
|
InternalType object) throws GuacamoleException {
|
||||||
|
|
||||||
|
// By default, do nothing.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the single object that has the given identifier, if it exists
|
* Retrieves the single object that has the given identifier, if it exists
|
||||||
* and the user has permission to read it.
|
* and the user has permission to read it.
|
||||||
@@ -253,7 +302,13 @@ public abstract class DirectoryObjectService<InternalType extends DirectoryObjec
|
|||||||
|
|
||||||
// Only create object if user has permission to do so
|
// Only create object if user has permission to do so
|
||||||
if (user.getUser().isAdministrator() || hasCreatePermission(user)) {
|
if (user.getUser().isAdministrator() || hasCreatePermission(user)) {
|
||||||
|
|
||||||
|
// Validate object prior to creation
|
||||||
|
validateNewObject(user, object);
|
||||||
|
|
||||||
|
// Create object
|
||||||
getObjectMapper().insert(getModelInstance(user, object));
|
getObjectMapper().insert(getModelInstance(user, object));
|
||||||
|
|
||||||
// FIXME: Insert implicit object permissions, too.
|
// FIXME: Insert implicit object permissions, too.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -318,6 +373,11 @@ public abstract class DirectoryObjectService<InternalType extends DirectoryObjec
|
|||||||
// Only update object if user has permission to do so
|
// Only update object if user has permission to do so
|
||||||
if (user.getUser().isAdministrator()
|
if (user.getUser().isAdministrator()
|
||||||
|| permissionSet.hasPermission(ObjectPermission.Type.UPDATE, object.getIdentifier())) {
|
|| permissionSet.hasPermission(ObjectPermission.Type.UPDATE, object.getIdentifier())) {
|
||||||
|
|
||||||
|
// Validate object prior to creation
|
||||||
|
validateExistingObject(user, object);
|
||||||
|
|
||||||
|
// Update object
|
||||||
getObjectMapper().update(object.getModel());
|
getObjectMapper().update(object.getModel());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -24,12 +24,15 @@ package net.sourceforge.guacamole.net.auth.mysql.service;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
|
import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
|
||||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
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.DirectoryObjectMapper;
|
||||||
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.model.UserModel;
|
import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||||
import org.glyptodon.guacamole.GuacamoleException;
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
import org.glyptodon.guacamole.net.auth.User;
|
import org.glyptodon.guacamole.net.auth.User;
|
||||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||||
@@ -104,6 +107,44 @@ public class UserService extends DirectoryObjectService<MySQLUser, User, UserMod
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void validateNewObject(AuthenticatedUser user, User object)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Username must not be blank
|
||||||
|
if (object.getIdentifier().trim().isEmpty())
|
||||||
|
throw new GuacamoleClientException("The username must not be blank.");
|
||||||
|
|
||||||
|
// Do not create duplicate users
|
||||||
|
Collection<UserModel> existing = userMapper.select(Collections.singleton(object.getIdentifier()));
|
||||||
|
if (!existing.isEmpty())
|
||||||
|
throw new GuacamoleClientException("User \"" + object.getIdentifier() + "\" already exists.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void validateExistingObject(AuthenticatedUser user,
|
||||||
|
MySQLUser object) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Username must not be blank
|
||||||
|
if (object.getIdentifier().trim().isEmpty())
|
||||||
|
throw new GuacamoleClientException("The username must not be blank.");
|
||||||
|
|
||||||
|
// Check whether such a user is already present
|
||||||
|
MySQLUser existing = retrieveObject(user, object.getIdentifier());
|
||||||
|
if (existing != null) {
|
||||||
|
|
||||||
|
UserModel existingModel = existing.getModel();
|
||||||
|
UserModel updatedModel = object.getModel();
|
||||||
|
|
||||||
|
// Do not rename to existing user
|
||||||
|
if (!existingModel.getUserID().equals(updatedModel.getUserID()))
|
||||||
|
throw new GuacamoleClientException("User \"" + object.getIdentifier() + "\" already exists.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the user corresponding to the given credentials from the
|
* Retrieves the user corresponding to the given credentials from the
|
||||||
* database.
|
* database.
|
||||||
|
Reference in New Issue
Block a user