mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-220: Define base interfaces for mapping RelatedObjectSets to the database.
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.jdbc.base;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import org.apache.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for the relations represented by a particular RelatedObjectSet
|
||||
* implementation.
|
||||
*
|
||||
* @param <ParentModelType>
|
||||
* The underlying database model of the object on the parent side of the
|
||||
* one-to-many relationship represented by the RelatedObjectSet mapped by
|
||||
* this ObjectRelationMapper.
|
||||
*/
|
||||
public interface ObjectRelationMapper<ParentModelType extends ObjectModel> {
|
||||
|
||||
/**
|
||||
* Inserts rows as necessary to establish the one-to-many relationship
|
||||
* represented by the RelatedObjectSet between the given parent and
|
||||
* children. If the relation for any parent/child pair is already present,
|
||||
* no attempt is made to insert a new row for that relation.
|
||||
*
|
||||
* @param parent
|
||||
* The model of the object on the parent side of the one-to-many
|
||||
* relationship represented by the RelatedObjectSet.
|
||||
*
|
||||
* @param children
|
||||
* The identifiers of the objects on the child side of the one-to-many
|
||||
* relationship represented by the RelatedObjectSet.
|
||||
*
|
||||
* @return
|
||||
* The number of rows inserted.
|
||||
*/
|
||||
int insert(@Param("parent") ParentModelType parent,
|
||||
@Param("children") Collection<String> children);
|
||||
|
||||
/**
|
||||
* Deletes rows as necessary to establish the one-to-many relationship
|
||||
* represented by the RelatedObjectSet between the given parent and
|
||||
* children. If the relation for any parent/child pair does not exist,
|
||||
* that specific relation is ignored, and deletion proceeds with the
|
||||
* remaining relations.
|
||||
*
|
||||
* @param parent
|
||||
* The model of the object on the parent side of the one-to-many
|
||||
* relationship represented by the RelatedObjectSet.
|
||||
*
|
||||
* @param children
|
||||
* The identifiers of the objects on the child side of the one-to-many
|
||||
* relationship represented by the RelatedObjectSet.
|
||||
*
|
||||
* @return
|
||||
* The number of rows deleted.
|
||||
*/
|
||||
int delete(@Param("parent") ParentModelType parent,
|
||||
@Param("children") Collection<String> children);
|
||||
|
||||
/**
|
||||
* Retrieves the identifiers of all objects on the child side of the
|
||||
* one-to-many relationship represented by the RelatedObjectSet mapped by
|
||||
* this ObjectRelationMapper. This should only be called on behalf of a
|
||||
* system administrator. If identifiers are needed by a non-administrative
|
||||
* user who must have explicit read rights, use
|
||||
* selectReadableChildIdentifiers() instead.
|
||||
*
|
||||
* @param parent
|
||||
* The model of the object on the parent side of the one-to-many
|
||||
* relationship represented by the RelatedObjectSet.
|
||||
*
|
||||
* @return
|
||||
* A Set containing the identifiers of all objects on the child side
|
||||
* of the one-to-many relationship.
|
||||
*/
|
||||
Set<String> selectChildIdentifiers(@Param("parent") ParentModelType parent);
|
||||
|
||||
/**
|
||||
* Retrieves the identifiers of all objects on the child side of the
|
||||
* one-to-many relationship represented by the RelatedObjectSet mapped by
|
||||
* this ObjectRelationMapper, including only those objects which are
|
||||
* explicitly readable by the given user. If identifiers are needed by a
|
||||
* system administrator (who, by definition, does not need explicit read
|
||||
* rights), use selectChildIdentifiers() instead.
|
||||
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions should determine whether an identifier
|
||||
* is returned.
|
||||
*
|
||||
* @param effectiveGroups
|
||||
* The identifiers of any known effective groups that should be taken
|
||||
* into account, such as those defined externally to the database.
|
||||
*
|
||||
* @param parent
|
||||
* The model of the object on the parent side of the one-to-many
|
||||
* relationship represented by the RelatedObjectSet.
|
||||
*
|
||||
* @return
|
||||
* A Set containing the identifiers of all readable objects on the
|
||||
* child side of the one-to-many relationship.
|
||||
*/
|
||||
Set<String> selectReadableChildIdentifiers(@Param("user") UserModel user,
|
||||
@Param("effectiveGroups") Collection<String> effectiveGroups,
|
||||
@Param("parent") ParentModelType parent);
|
||||
|
||||
}
|
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.jdbc.base;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.GuacamoleSecurityException;
|
||||
import org.apache.guacamole.net.auth.permission.ObjectPermission;
|
||||
import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
|
||||
/**
|
||||
* A database implementation of RelatedObjectSet which provides access to a
|
||||
* parent object and corresponding set of objects related to the parent, subject
|
||||
* to object-level permissions. Though the parent and child objects have
|
||||
* specific types, only the parent object's type is enforced through type
|
||||
* parameters, as child objects are represented by identifiers only.
|
||||
*
|
||||
* @param <ParentObjectType>
|
||||
* The type of object that represents the parent side of the relation.
|
||||
*
|
||||
* @param <ParentModelType>
|
||||
* The underlying database model of the parent object.
|
||||
*/
|
||||
public abstract class RelatedObjectSet<ParentObjectType extends ModeledDirectoryObject<ParentModelType>, ParentModelType extends ObjectModel>
|
||||
extends RestrictedObject implements org.apache.guacamole.net.auth.RelatedObjectSet {
|
||||
|
||||
/**
|
||||
* The parent object which shares some arbitrary relation with the objects
|
||||
* within this set.
|
||||
*/
|
||||
private ParentObjectType parent;
|
||||
|
||||
/**
|
||||
* Creates a new RelatedObjectSet. The resulting object set must still be
|
||||
* initialized by a call to init().
|
||||
*/
|
||||
public RelatedObjectSet() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this RelatedObjectSet with the current user and the single
|
||||
* object on the parent side of the one-to-many relation represented by the
|
||||
* set.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user who queried this RelatedObjectSet, and whose permissions
|
||||
* dictate the access level of all operations performed on this set.
|
||||
*
|
||||
* @param parent
|
||||
* The parent object which shares some arbitrary relation with the
|
||||
* objects within this set.
|
||||
*/
|
||||
public void init(ModeledAuthenticatedUser currentUser, ParentObjectType parent) {
|
||||
super.init(currentUser);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapper which provides low-level access to the the database
|
||||
* models which drive the relation represented by this RelatedObjectSet.
|
||||
*
|
||||
* @return
|
||||
* The mapper which provides low-level access to the the database
|
||||
* models which drive the relation represented by this
|
||||
* RelatedObjectSet.
|
||||
*/
|
||||
protected abstract ObjectRelationMapper<ParentModelType> getObjectRelationMapper();
|
||||
|
||||
/**
|
||||
* Returns the permission set which exposes the effective permissions
|
||||
* available to the current user regarding the objects on the parent side
|
||||
* of the one-to-many relationship represented by this RelatedObjectSet.
|
||||
* Permission inheritance through user groups is taken into account.
|
||||
*
|
||||
* @return
|
||||
* The permission set which exposes the effective permissions
|
||||
* available to the current user regarding the objects on the parent
|
||||
* side of the one-to-many relationship represented by this
|
||||
* RelatedObjectSet.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to query permission status is denied.
|
||||
*/
|
||||
protected abstract ObjectPermissionSet getParentObjectEffectivePermissionSet()
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns the permission set which exposes the effective permissions
|
||||
* available to the current user regarding the objects on the child side
|
||||
* of the one-to-many relationship represented by this RelatedObjectSet.
|
||||
* Permission inheritance through user groups is taken into account.
|
||||
*
|
||||
* @return
|
||||
* The permission set which exposes the effective permissions
|
||||
* available to the current user regarding the objects on the child
|
||||
* side of the one-to-many relationship represented by this
|
||||
* RelatedObjectSet.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to query permission status is denied.
|
||||
*/
|
||||
protected abstract ObjectPermissionSet getChildObjectEffectivePermissionSet()
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns whether the current user has permission to alter that status of
|
||||
* the relation between the parent object and the given child objects.
|
||||
*
|
||||
* @param identifiers
|
||||
* The identifiers of all objects on the child side of the one-to-many
|
||||
* relation being changed.
|
||||
*
|
||||
* @return
|
||||
* true if the user has permission to make the described changes,
|
||||
* false otherwise.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to query permission status is denied.
|
||||
*/
|
||||
private boolean canAlterRelation(Collection<String> identifiers)
|
||||
throws GuacamoleException {
|
||||
|
||||
// System administrators may alter any relations
|
||||
if (getCurrentUser().getUser().isAdministrator())
|
||||
return true;
|
||||
|
||||
// Non-admin users require UPDATE permission on the parent object ...
|
||||
if (!getParentObjectEffectivePermissionSet().hasPermission(
|
||||
ObjectPermission.Type.UPDATE, parent.getIdentifier()))
|
||||
return false;
|
||||
|
||||
// ... as well as UPDATE permission on all child objects being changed
|
||||
Collection<String> accessibleIdentifiers =
|
||||
getChildObjectEffectivePermissionSet().getAccessibleObjects(
|
||||
Collections.singleton(ObjectPermission.Type.UPDATE),
|
||||
identifiers);
|
||||
|
||||
return accessibleIdentifiers.size() == identifiers.size();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getObjects() throws GuacamoleException {
|
||||
|
||||
// Bypass permission checks if the user is a system admin
|
||||
ModeledAuthenticatedUser user = getCurrentUser();
|
||||
if (user.getUser().isAdministrator())
|
||||
return getObjectRelationMapper().selectChildIdentifiers(parent.getModel());
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
return getObjectRelationMapper().selectReadableChildIdentifiers(
|
||||
user.getUser().getModel(), user.getEffectiveUserGroups(),
|
||||
parent.getModel());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addObjects(Set<String> identifiers) throws GuacamoleException {
|
||||
|
||||
// Nothing to do if nothing provided
|
||||
if (identifiers.isEmpty())
|
||||
return;
|
||||
|
||||
// Create relations only if permission is granted
|
||||
if (canAlterRelation(identifiers))
|
||||
getObjectRelationMapper().insert(parent.getModel(), identifiers);
|
||||
|
||||
// User lacks permission to add user groups
|
||||
else
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObjects(Set<String> identifiers) throws GuacamoleException {
|
||||
|
||||
// Nothing to do if nothing provided
|
||||
if (identifiers.isEmpty())
|
||||
return;
|
||||
|
||||
// Delete relations only if permission is granted
|
||||
if (canAlterRelation(identifiers))
|
||||
getObjectRelationMapper().delete(parent.getModel(), identifiers);
|
||||
|
||||
// User lacks permission to remove user groups
|
||||
else
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user