GUAC-1100: Implement patching of permissions with batch operations.

This commit is contained in:
Michael Jumper
2015-02-11 20:19:53 -08:00
parent 433d55d245
commit 514aafbd6d
2 changed files with 120 additions and 21 deletions

View File

@@ -0,0 +1,98 @@
/*
* 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 org.glyptodon.guacamole.net.basic.rest.user;
import java.util.HashSet;
import java.util.Set;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.permission.Permission;
import org.glyptodon.guacamole.net.auth.permission.PermissionSet;
/**
* A set of changes to be applied to a PermissionSet, describing the set of
* permissions being added and removed.
*
* @author Michael Jumper
* @param <PermissionType>
* The type of permissions being added and removed.
*/
public class PermissionSetPatch<PermissionType extends Permission> {
/**
* The set of all permissions being added.
*/
private final Set<PermissionType> addedPermissions =
new HashSet<PermissionType>();
/**
* The set of all permissions being removed.
*/
private final Set<PermissionType> removedPermissions =
new HashSet<PermissionType>();
/**
* Queues the given permission to be added. The add operation will be
* performed only when apply() is called.
*
* @param permission
* The permission to add.
*/
public void addPermission(PermissionType permission) {
addedPermissions.add(permission);
}
/**
* Queues the given permission to be removed. The remove operation will be
* performed only when apply() is called.
*
* @param permission
* The permission to remove.
*/
public void removePermission(PermissionType permission) {
removedPermissions.add(permission);
}
/**
* Applies all queued changes to the given permission set.
*
* @param permissionSet
* The permission set to add and remove permissions from.
*
* @throws GuacamoleException
* If an error occurs while manipulating the permissions of the given
* permission set.
*/
public void apply(PermissionSet<PermissionType> permissionSet)
throws GuacamoleException {
// Add any added permissions
if (!addedPermissions.isEmpty())
permissionSet.addPermissions(addedPermissions);
// Remove any removed permissions
if (!removedPermissions.isEmpty())
permissionSet.removePermissions(removedPermissions);
}
}

View File

@@ -25,7 +25,6 @@ package org.glyptodon.guacamole.net.basic.rest.user;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import javax.ws.rs.Consumes;
@@ -48,7 +47,6 @@ import org.glyptodon.guacamole.net.auth.UserContext;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.Permission;
import org.glyptodon.guacamole.net.auth.permission.PermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
import org.glyptodon.guacamole.net.basic.rest.APIPatch;
@@ -355,8 +353,8 @@ public class UserRESTService {
}
/**
* Updates the given permission set by adding or removing the given
* permission based on the given patch operation.
* Updates the given permission set patch by queuing an add or remove
* operation for the given permission based on the given patch operation.
*
* @param <PermissionType>
* The type of permission stored within the permission set.
@@ -364,31 +362,28 @@ public class UserRESTService {
* @param operation
* The patch operation to perform.
*
* @param permissionSet
* The permission set being modified.
* @param permissionSetPatch
* The permission set patch being modified.
*
* @param permission
* The permission being added or removed from the set.
*
* @throws GuacamoleException
* If an error occurs while modifying the permission set.
*/
private <PermissionType extends Permission> void updatePermissionSet(
APIPatch.Operation operation,
PermissionSet<PermissionType> permissionSet,
PermissionType permission) throws GuacamoleException {
PermissionSetPatch<PermissionType> permissionSetPatch,
PermissionType permission) {
// Add or remove permission based on operation
switch (operation) {
// Add permission
case add:
permissionSet.addPermissions(Collections.singleton(permission));
permissionSetPatch.addPermission(permission);
break;
// Remove permission
case remove:
permissionSet.removePermissions(Collections.singleton(permission));
permissionSetPatch.removePermission(permission);
break;
// Unsupported patch operation
@@ -429,14 +424,17 @@ public class UserRESTService {
UserContext userContext = authenticationService.getUserContext(authToken);
// Get the user directory
Directory<String, User> userDirectory = userContext.getUserDirectory();
// Get the user
User user = userContext.getUserDirectory().get(username);
if (user == null)
throw new GuacamoleResourceNotFoundException("No such user: \"" + username + "\"");
// Permission patches for all types of permissions
PermissionSetPatch<ObjectPermission<String>> connectionPermissionPatch = new PermissionSetPatch<ObjectPermission<String>>();
PermissionSetPatch<ObjectPermission<String>> connectionGroupPermissionPatch = new PermissionSetPatch<ObjectPermission<String>>();
PermissionSetPatch<ObjectPermission<String>> userPermissionPatch = new PermissionSetPatch<ObjectPermission<String>>();
PermissionSetPatch<SystemPermission> systemPermissionPatch = new PermissionSetPatch<SystemPermission>();
// Apply all patch operations individually
for (APIPatch<String> patch : patches) {
@@ -451,7 +449,7 @@ public class UserRESTService {
// Create and update corresponding permission
ObjectPermission<String> permission = new ObjectPermission<String>(type, identifier);
updatePermissionSet(patch.getOp(), user.getConnectionPermissions(), permission);
updatePermissionSet(patch.getOp(), connectionPermissionPatch, permission);
}
@@ -464,7 +462,7 @@ public class UserRESTService {
// Create and update corresponding permission
ObjectPermission<String> permission = new ObjectPermission<String>(type, identifier);
updatePermissionSet(patch.getOp(), user.getConnectionGroupPermissions(), permission);
updatePermissionSet(patch.getOp(), connectionGroupPermissionPatch, permission);
}
@@ -477,7 +475,7 @@ public class UserRESTService {
// Create and update corresponding permission
ObjectPermission<String> permission = new ObjectPermission<String>(type, identifier);
updatePermissionSet(patch.getOp(), user.getUserPermissions(), permission);
updatePermissionSet(patch.getOp(), userPermissionPatch, permission);
}
@@ -489,7 +487,7 @@ public class UserRESTService {
// Create and update corresponding permission
SystemPermission permission = new SystemPermission(type);
updatePermissionSet(patch.getOp(), user.getSystemPermissions(), permission);
updatePermissionSet(patch.getOp(), systemPermissionPatch, permission);
}
@@ -500,7 +498,10 @@ public class UserRESTService {
} // end for each patch operation
// Save the permission changes
userDirectory.update(user);
connectionPermissionPatch.apply(user.getConnectionPermissions());
connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions());
userPermissionPatch.apply(user.getUserPermissions());
systemPermissionPatch.apply(user.getSystemPermissions());
}