GUACAMOLE-708: Replace isAdministrator() checks with more generic isPrivileged().

This commit is contained in:
Michael Jumper
2020-06-16 16:35:34 -07:00
parent 4e8c9e1cb7
commit 6f37e5d07d
14 changed files with 53 additions and 31 deletions

View File

@@ -82,21 +82,22 @@ public class ActiveConnectionPermissionService
// Retrieve permissions only if allowed // Retrieve permissions only if allowed
if (canReadPermissions(user, targetEntity)) { if (canReadPermissions(user, targetEntity)) {
// Only administrators may access active connections // Administrators may always access active connections
boolean isAdmin = targetEntity.isAdministrator(); boolean isAdmin = targetEntity.isPrivileged();
// Get all active connections // Get all active connections
Collection<ActiveConnectionRecord> records = tunnelService.getActiveConnections(user); Collection<ActiveConnectionRecord> records = tunnelService.getActiveConnections(user);
// We have READ, and possibly DELETE, on all active connections // We have READ, and possibly DELETE, on all active connections
Set<ObjectPermission> permissions = new HashSet<ObjectPermission>(); Set<ObjectPermission> permissions = new HashSet<>();
for (ActiveConnectionRecord record : records) { for (ActiveConnectionRecord record : records) {
// Add implicit READ // Add implicit READ
String identifier = record.getUUID().toString(); String identifier = record.getUUID().toString();
permissions.add(new ObjectPermission(ObjectPermission.Type.READ, identifier)); permissions.add(new ObjectPermission(ObjectPermission.Type.READ, identifier));
// If we're an admin, or the connection is ours, then we can DELETE // If the target use is an admin, or the connection belongs to
// the target user, then they can DELETE
if (isAdmin || targetEntity.isUser(record.getUsername())) if (isAdmin || targetEntity.isUser(record.getUsername()))
permissions.add(new ObjectPermission(ObjectPermission.Type.DELETE, identifier)); permissions.add(new ObjectPermission(ObjectPermission.Type.DELETE, identifier));

View File

@@ -81,7 +81,7 @@ public class ActiveConnectionService
Collection<String> identifiers) throws GuacamoleException { Collection<String> identifiers) throws GuacamoleException {
String username = user.getIdentifier(); String username = user.getIdentifier();
boolean isAdmin = user.getUser().isAdministrator(); boolean isAdmin = user.isPrivileged();
Set<String> identifierSet = new HashSet<String>(identifiers); Set<String> identifierSet = new HashSet<String>(identifiers);
// Retrieve all visible connections (permissions enforced by tunnel service) // Retrieve all visible connections (permissions enforced by tunnel service)
@@ -211,7 +211,7 @@ public class ActiveConnectionService
ObjectPermissionSet permissionSet = getPermissionSet(user); ObjectPermissionSet permissionSet = getPermissionSet(user);
return user.getUser().isAdministrator() return user.isPrivileged()
|| permissionSet.hasPermission(type, identifier); || permissionSet.hasPermission(type, identifier);
} }

View File

@@ -149,7 +149,7 @@ public abstract class ModeledChildDirectoryObjectService<InternalType extends Mo
String identifier, ModelType model) throws GuacamoleException { String identifier, ModelType model) throws GuacamoleException {
// If user is an administrator, no need to check // If user is an administrator, no need to check
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return true; return true;
// Verify that we have permission to modify any modified parents // Verify that we have permission to modify any modified parents

View File

@@ -171,7 +171,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
ObjectPermissionSet permissionSet = getEffectivePermissionSet(user); ObjectPermissionSet permissionSet = getEffectivePermissionSet(user);
// Return whether permission is granted // Return whether permission is granted
return user.getUser().isAdministrator() return user.isPrivileged()
|| permissionSet.hasPermission(type, identifier); || permissionSet.hasPermission(type, identifier);
} }
@@ -248,7 +248,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
ExternalType object, ModelType model) throws GuacamoleException { ExternalType object, ModelType model) throws GuacamoleException {
// Verify permission to create objects // Verify permission to create objects
if (!user.getUser().isAdministrator() && !hasCreatePermission(user)) if (!user.isPrivileged() && !hasCreatePermission(user))
throw new GuacamoleSecurityException("Permission denied."); throw new GuacamoleSecurityException("Permission denied.");
} }
@@ -396,7 +396,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
Collection<ModelType> objects; Collection<ModelType> objects;
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
if (user.getUser().isAdministrator()) if (user.isPrivileged())
objects = getObjectMapper().select(identifiers); objects = getObjectMapper().select(identifiers);
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers
@@ -508,7 +508,7 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
throws GuacamoleException { throws GuacamoleException {
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return getObjectMapper().selectIdentifiers(); return getObjectMapper().selectIdentifiers();
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers

View File

@@ -132,18 +132,20 @@ public abstract class ModeledPermissions<ModelType extends EntityModel>
} }
/** /**
* Returns whether this entity is a system administrator, and thus is not * Returns whether this entity is effectively unrestricted by permissions,
* restricted by permissions, taking into account permission inheritance * such as a system administrator or an internal user operating via a
* via user groups. * privileged UserContext. Permission inheritance via user groups is taken
* into account.
* *
* @return * @return
* true if this entity is a system administrator, false otherwise. * true if this entity should be unrestricted by permissions, false
* otherwise.
* *
* @throws GuacamoleException * @throws GuacamoleException
* If an error occurs while determining the entity's system administrator * If an error occurs while determining whether permission restrictions
* status. * apply to the entity.
*/ */
public boolean isAdministrator() throws GuacamoleException { public boolean isPrivileged() throws GuacamoleException {
SystemPermissionSet systemPermissionSet = getEffective().getSystemPermissions(); SystemPermissionSet systemPermissionSet = getEffective().getSystemPermissions();
return systemPermissionSet.hasPermission(SystemPermission.Type.ADMINISTER); return systemPermissionSet.hasPermission(SystemPermission.Type.ADMINISTER);
} }

View File

@@ -141,7 +141,7 @@ public abstract class RelatedObjectSet<ParentObjectType extends ModeledDirectory
throws GuacamoleException { throws GuacamoleException {
// System administrators may alter any relations // System administrators may alter any relations
if (getCurrentUser().getUser().isAdministrator()) if (getCurrentUser().isPrivileged())
return true; return true;
// Non-admin users require UPDATE permission on the parent object ... // Non-admin users require UPDATE permission on the parent object ...
@@ -164,7 +164,7 @@ public abstract class RelatedObjectSet<ParentObjectType extends ModeledDirectory
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
ModeledAuthenticatedUser user = getCurrentUser(); ModeledAuthenticatedUser user = getCurrentUser();
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return getObjectRelationMapper().selectChildIdentifiers(parent.getModel()); return getObjectRelationMapper().selectChildIdentifiers(parent.getModel());
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers

View File

@@ -298,7 +298,7 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
throws GuacamoleException { throws GuacamoleException {
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return connectionMapper.selectIdentifiersWithin(identifier); return connectionMapper.selectIdentifiersWithin(identifier);
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers
@@ -471,7 +471,7 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
List<ConnectionRecordModel> searchResults; List<ConnectionRecordModel> searchResults;
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
if (user.getUser().isAdministrator()) if (user.isPrivileged())
searchResults = connectionRecordMapper.search(requiredContents, searchResults = connectionRecordMapper.search(requiredContents,
sortPredicates, limit); sortPredicates, limit);

View File

@@ -219,7 +219,7 @@ public class ConnectionGroupService extends ModeledChildDirectoryObjectService<M
throws GuacamoleException { throws GuacamoleException {
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return connectionGroupMapper.selectIdentifiersWithin(identifier); return connectionGroupMapper.selectIdentifiersWithin(identifier);
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers

View File

@@ -105,7 +105,7 @@ public abstract class AbstractPermissionService<PermissionSetType extends Permis
return true; return true;
// A system adminstrator can do anything // A system adminstrator can do anything
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return true; return true;
// Can read permissions on target entity if explicit READ is granted // Can read permissions on target entity if explicit READ is granted

View File

@@ -96,7 +96,7 @@ public abstract class ModeledObjectPermissionService
throws GuacamoleException { throws GuacamoleException {
// A system adminstrator can do anything // A system adminstrator can do anything
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return true; return true;
// Verify user has update permission on the target entity // Verify user has update permission on the target entity
@@ -188,7 +188,7 @@ public abstract class ModeledObjectPermissionService
return identifiers; return identifiers;
// If user is an admin, everything is accessible // If user is an admin, everything is accessible
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return identifiers; return identifiers;
// Otherwise, return explicitly-retrievable identifiers only if allowed // Otherwise, return explicitly-retrievable identifiers only if allowed

View File

@@ -95,7 +95,7 @@ public class SystemPermissionService
Collection<SystemPermission> permissions) throws GuacamoleException { Collection<SystemPermission> permissions) throws GuacamoleException {
// Only an admin can create system permissions // Only an admin can create system permissions
if (user.getUser().isAdministrator()) { if (user.isPrivileged()) {
Collection<SystemPermissionModel> models = getModelInstances(targetEntity, permissions); Collection<SystemPermissionModel> models = getModelInstances(targetEntity, permissions);
systemPermissionMapper.insert(models); systemPermissionMapper.insert(models);
return; return;
@@ -112,7 +112,7 @@ public class SystemPermissionService
Collection<SystemPermission> permissions) throws GuacamoleException { Collection<SystemPermission> permissions) throws GuacamoleException {
// Only an admin can delete system permissions // Only an admin can delete system permissions
if (user.getUser().isAdministrator()) { if (user.isPrivileged()) {
// 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()))

View File

@@ -629,7 +629,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
return Collections.<ActiveConnectionRecord>emptyList(); return Collections.<ActiveConnectionRecord>emptyList();
// A system administrator can view all connections; no need to filter // A system administrator can view all connections; no need to filter
if (user.getUser().isAdministrator()) if (user.isPrivileged())
return records; return records;
// Build set of all connection identifiers associated with active tunnels // Build set of all connection identifiers associated with active tunnels

View File

@@ -23,6 +23,7 @@ import com.google.common.collect.Sets;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.Credentials;
@@ -176,4 +177,22 @@ public class ModeledAuthenticatedUser extends RemoteAuthenticatedUser {
super.getEffectiveUserGroups()); super.getEffectiveUserGroups());
} }
/**
* Returns whether this user is effectively unrestricted by permissions,
* such as a system administrator or an internal user operating via a
* privileged UserContext. Permission inheritance via user groups is taken
* into account.
*
* @return
* true if this user should be unrestricted by permissions, false
* otherwise.
*
* @throws GuacamoleException
* If an error occurs while determining whether permission restrictions
* apply to the user.
*/
public boolean isPrivileged() throws GuacamoleException {
return getUser().isPrivileged();
}
} }

View File

@@ -279,7 +279,7 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
if (object.getPassword() != null) { if (object.getPassword() != null) {
// Enforce password age only for non-adminstrators // Enforce password age only for non-adminstrators
if (!user.getUser().isAdministrator()) if (!user.isPrivileged())
passwordPolicyService.verifyPasswordAge(object); passwordPolicyService.verifyPasswordAge(object);
// Always verify password complexity // Always verify password complexity
@@ -627,7 +627,7 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
List<ActivityRecordModel> searchResults; List<ActivityRecordModel> searchResults;
// Bypass permission checks if the user is a system admin // Bypass permission checks if the user is a system admin
if (user.getUser().isAdministrator()) if (user.isPrivileged())
searchResults = userRecordMapper.search(requiredContents, searchResults = userRecordMapper.search(requiredContents,
sortPredicates, limit); sortPredicates, limit);