mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 09:03:21 +00:00 
			
		
		
		
	GUACAMOLE-1796: Merge batching of updates to permissions.
This commit is contained in:
		| @@ -132,11 +132,16 @@ public abstract class ModeledObjectPermissionService | |||||||
|  |  | ||||||
|         // Create permissions only if user has permission to do so |         // Create permissions only if user has permission to do so | ||||||
|         if (canAlterPermissions(user, targetEntity, permissions)) { |         if (canAlterPermissions(user, targetEntity, permissions)) { | ||||||
|             Collection<ObjectPermissionModel> models = getModelInstances(targetEntity, permissions); |  | ||||||
|             getPermissionMapper().insert(models); |             batchPermissionUpdates(permissions, permissionSubset -> { | ||||||
|  |                 Collection<ObjectPermissionModel> models = getModelInstances( | ||||||
|  |                         targetEntity, permissionSubset); | ||||||
|  |                 getPermissionMapper().insert(models); | ||||||
|  |             }); | ||||||
|  |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|          |  | ||||||
|         // User lacks permission to create object permissions |         // User lacks permission to create object permissions | ||||||
|         throw new GuacamoleSecurityException("Permission denied."); |         throw new GuacamoleSecurityException("Permission denied."); | ||||||
|  |  | ||||||
| @@ -150,8 +155,13 @@ public abstract class ModeledObjectPermissionService | |||||||
|  |  | ||||||
|         // Delete permissions only if user has permission to do so |         // Delete permissions only if user has permission to do so | ||||||
|         if (canAlterPermissions(user, targetEntity, permissions)) { |         if (canAlterPermissions(user, targetEntity, permissions)) { | ||||||
|             Collection<ObjectPermissionModel> models = getModelInstances(targetEntity, permissions); |  | ||||||
|             getPermissionMapper().delete(models); |             batchPermissionUpdates(permissions, permissionSubset -> { | ||||||
|  |                 Collection<ObjectPermissionModel> models = getModelInstances( | ||||||
|  |                         targetEntity, permissionSubset); | ||||||
|  |                 getPermissionMapper().delete(models); | ||||||
|  |             }); | ||||||
|  |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|          |          | ||||||
|   | |||||||
| @@ -23,14 +23,20 @@ import java.util.ArrayList; | |||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  | import java.util.function.Consumer; | ||||||
|  |  | ||||||
| import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; | import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; | ||||||
| import org.apache.guacamole.GuacamoleException; | import org.apache.guacamole.GuacamoleException; | ||||||
| import org.apache.guacamole.GuacamoleSecurityException; | import org.apache.guacamole.GuacamoleSecurityException; | ||||||
|  | import org.apache.guacamole.auth.jdbc.JDBCEnvironment; | ||||||
| import org.apache.guacamole.auth.jdbc.base.EntityModel; | import org.apache.guacamole.auth.jdbc.base.EntityModel; | ||||||
| import org.apache.guacamole.auth.jdbc.base.ModeledPermissions; | import org.apache.guacamole.auth.jdbc.base.ModeledPermissions; | ||||||
| import org.apache.guacamole.net.auth.permission.Permission; | import org.apache.guacamole.net.auth.permission.Permission; | ||||||
| import org.apache.guacamole.net.auth.permission.PermissionSet; | import org.apache.guacamole.net.auth.permission.PermissionSet; | ||||||
|  |  | ||||||
|  | import com.google.common.collect.Iterables; | ||||||
|  | import com.google.inject.Inject; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Service which provides convenience methods for creating, retrieving, and |  * Service which provides convenience methods for creating, retrieving, and | ||||||
|  * deleting permissions within a backend database model, and for obtaining the |  * deleting permissions within a backend database model, and for obtaining the | ||||||
| @@ -51,6 +57,12 @@ public abstract class ModeledPermissionService<PermissionSetType extends Permiss | |||||||
|         PermissionType extends Permission, ModelType> |         PermissionType extends Permission, ModelType> | ||||||
|     extends AbstractPermissionService<PermissionSetType, PermissionType> { |     extends AbstractPermissionService<PermissionSetType, PermissionType> { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The environment of the Guacamole server. | ||||||
|  |      */ | ||||||
|  |     @Inject | ||||||
|  |     private JDBCEnvironment environment; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns an instance of a mapper for the type of permission used by this |      * Returns an instance of a mapper for the type of permission used by this | ||||||
|      * service. |      * service. | ||||||
| @@ -141,6 +153,38 @@ public abstract class ModeledPermissionService<PermissionSetType extends Permiss | |||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Runs the provided consumer function on subsets of the original collection | ||||||
|  |      * of objects, with each subset being no larger than the maximum batch size | ||||||
|  |      * configured for the JDBC environment. Any permission update that involves | ||||||
|  |      * passing potentially-large lists of models to a mapper should use this | ||||||
|  |      * method to perform the update to ensure that the maximum number of | ||||||
|  |      * parameters for an individual query is not exceeded. | ||||||
|  |      * | ||||||
|  |      * @param <T> | ||||||
|  |      *     The type of object stored in the provided objects list, and consumed | ||||||
|  |      *     by the provided consumer. | ||||||
|  |      * | ||||||
|  |      * @param objects | ||||||
|  |      *     A collection of objects to be partitioned. | ||||||
|  |      * | ||||||
|  |      * @param consumer | ||||||
|  |      *     A function that will consume subsets of the objects from the provided | ||||||
|  |      *     collection of objects, performing any update as needed. | ||||||
|  |      * | ||||||
|  |      * @throws GuacamoleException | ||||||
|  |      *     If the batch size cannot be determined for the JDBC environment. | ||||||
|  |      */ | ||||||
|  |     protected <T> void batchPermissionUpdates( | ||||||
|  |             Collection<T> objects, Consumer<Collection<T>> consumer) | ||||||
|  |             throws GuacamoleException { | ||||||
|  |  | ||||||
|  |         // Split the original collection into views, each no larger than the | ||||||
|  |         // configured batch size, and call the collector function with each | ||||||
|  |         Iterables.partition(objects, environment.getBatchSize()) | ||||||
|  |                 .forEach(batch -> consumer.accept(batch)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Set<PermissionType> retrievePermissions(ModeledAuthenticatedUser user, |     public Set<PermissionType> retrievePermissions(ModeledAuthenticatedUser user, | ||||||
|             ModeledPermissions<? extends EntityModel> targetEntity, |             ModeledPermissions<? extends EntityModel> targetEntity, | ||||||
|   | |||||||
| @@ -97,8 +97,13 @@ public class SystemPermissionService | |||||||
|         // Only privileged users (such as system administrators) can create |         // Only privileged users (such as system administrators) can create | ||||||
|         // system permissions |         // system permissions | ||||||
|         if (user.isPrivileged()) { |         if (user.isPrivileged()) { | ||||||
|             Collection<SystemPermissionModel> models = getModelInstances(targetEntity, permissions); |  | ||||||
|             systemPermissionMapper.insert(models); |             batchPermissionUpdates(permissions, permissionSubset -> { | ||||||
|  |                 Collection<SystemPermissionModel> models = getModelInstances( | ||||||
|  |                         targetEntity, permissionSubset); | ||||||
|  |                 systemPermissionMapper.insert(models); | ||||||
|  |             }); | ||||||
|  |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -119,9 +124,13 @@ public class SystemPermissionService | |||||||
|             // Do not allow users to remove their own admin powers |             // Do not allow users to remove their own admin powers | ||||||
|             if (user.getUser().getIdentifier().equals(targetEntity.getIdentifier())) |             if (user.getUser().getIdentifier().equals(targetEntity.getIdentifier())) | ||||||
|                 throw new GuacamoleUnsupportedException("Removing your own administrative permissions is not allowed."); |                 throw new GuacamoleUnsupportedException("Removing your own administrative permissions is not allowed."); | ||||||
|              |  | ||||||
|             Collection<SystemPermissionModel> models = getModelInstances(targetEntity, permissions); |             batchPermissionUpdates(permissions, permissionSubset -> { | ||||||
|             systemPermissionMapper.delete(models); |                 Collection<SystemPermissionModel> models = getModelInstances( | ||||||
|  |                         targetEntity, permissionSubset); | ||||||
|  |                 systemPermissionMapper.delete(models); | ||||||
|  |             }); | ||||||
|  |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user