GUACAMOLE-81: Generalize permissions surrounding parent/child relationship.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/26d9dd85 Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/26d9dd85 Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/26d9dd85 Branch: refs/heads/master Commit: 26d9dd85935bd526b3ddb954709b7a10cbfea3cd Parents: 39a25db Author: Michael Jumper <[email protected]> Authored: Sat Aug 20 18:03:32 2016 -0700 Committer: Michael Jumper <[email protected]> Committed: Sat Aug 20 19:13:01 2016 -0700 ---------------------------------------------------------------------- .../auth/jdbc/base/ChildObjectModel.java | 65 ++++++ .../auth/jdbc/base/GroupedObjectModel.java | 64 ------ .../jdbc/base/ModeledChildDirectoryObject.java | 75 +++++++ .../ModeledChildDirectoryObjectService.java | 209 +++++++++++++++++++ .../base/ModeledGroupedDirectoryObject.java | 75 ------- .../ModeledGroupedDirectoryObjectService.java | 194 ----------------- .../auth/jdbc/connection/ConnectionModel.java | 4 +- .../auth/jdbc/connection/ConnectionService.java | 13 +- .../auth/jdbc/connection/ModeledConnection.java | 4 +- .../connectiongroup/ConnectionGroupModel.java | 4 +- .../connectiongroup/ConnectionGroupService.java | 13 +- .../connectiongroup/ModeledConnectionGroup.java | 4 +- 12 files changed, 379 insertions(+), 345 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ChildObjectModel.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ChildObjectModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ChildObjectModel.java new file mode 100644 index 0000000..5a458ca --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ChildObjectModel.java @@ -0,0 +1,65 @@ +/* + * 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; + +/** + * Object representation of a Guacamole object which can be the child of another + * object, such as a connection or sharing profile, as represented in the + * database. + * + * @author Michael Jumper + */ +public abstract class ChildObjectModel extends ObjectModel { + + /** + * The unique identifier which identifies the parent of this object. + */ + private String parentIdentifier; + + /** + * Creates a new, empty object. + */ + public ChildObjectModel() { + } + + /** + * Returns the identifier of the parent connection group, or null if the + * parent connection group is the root connection group. + * + * @return + * The identifier of the parent connection group, or null if the parent + * connection group is the root connection group. + */ + public String getParentIdentifier() { + return parentIdentifier; + } + + /** + * Sets the identifier of the parent connection group. + * + * @param parentIdentifier + * The identifier of the parent connection group, or null if the parent + * connection group is the root connection group. + */ + public void setParentIdentifier(String parentIdentifier) { + this.parentIdentifier = parentIdentifier; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/GroupedObjectModel.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/GroupedObjectModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/GroupedObjectModel.java deleted file mode 100644 index 18dffee..0000000 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/GroupedObjectModel.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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; - -/** - * Object representation of a Guacamole object, such as a user or connection, - * as represented in the database. - * - * @author Michael Jumper - */ -public abstract class GroupedObjectModel extends ObjectModel { - - /** - * The unique identifier which identifies the parent of this object. - */ - private String parentIdentifier; - - /** - * Creates a new, empty object. - */ - public GroupedObjectModel() { - } - - /** - * Returns the identifier of the parent connection group, or null if the - * parent connection group is the root connection group. - * - * @return - * The identifier of the parent connection group, or null if the parent - * connection group is the root connection group. - */ - public String getParentIdentifier() { - return parentIdentifier; - } - - /** - * Sets the identifier of the parent connection group. - * - * @param parentIdentifier - * The identifier of the parent connection group, or null if the parent - * connection group is the root connection group. - */ - public void setParentIdentifier(String parentIdentifier) { - this.parentIdentifier = parentIdentifier; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObject.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObject.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObject.java new file mode 100644 index 0000000..f086112 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObject.java @@ -0,0 +1,75 @@ +/* + * 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 org.apache.guacamole.auth.jdbc.connectiongroup.RootConnectionGroup; + +/** + * Common base class for objects that will ultimately be made available through + * the Directory class. All such objects will need the same base set of queries + * to fulfill the needs of the Directory class. + * + * @author Michael Jumper + * @param <ModelType> + * The type of model object that corresponds to this object. + */ +public abstract class ModeledChildDirectoryObject<ModelType extends ChildObjectModel> + extends ModeledDirectoryObject<ModelType> { + + /** + * Returns the identifier of the parent connection group, which cannot be + * null. If the parent is the root connection group, this will be + * RootConnectionGroup.IDENTIFIER. + * + * @return + * The identifier of the parent connection group. + */ + public String getParentIdentifier() { + + // Translate null parent to proper identifier + String parentIdentifier = getModel().getParentIdentifier(); + if (parentIdentifier == null) + return RootConnectionGroup.IDENTIFIER; + + return parentIdentifier; + + } + + /** + * Sets the identifier of the associated parent connection group. If the + * parent is the root connection group, this should be + * RootConnectionGroup.IDENTIFIER. + * + * @param parentIdentifier + * The identifier of the connection group to associate as this object's + * parent. + */ + public void setParentIdentifier(String parentIdentifier) { + + // Translate root identifier back into null + if (parentIdentifier != null + && parentIdentifier.equals(RootConnectionGroup.IDENTIFIER)) + parentIdentifier = null; + + getModel().setParentIdentifier(parentIdentifier); + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObjectService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObjectService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObjectService.java new file mode 100644 index 0000000..61f48d4 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledChildDirectoryObjectService.java @@ -0,0 +1,209 @@ +/* + * 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.ArrayList; +import java.util.Collection; +import java.util.Collections; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; +import org.apache.guacamole.net.auth.Identifiable; +import org.apache.guacamole.net.auth.permission.ObjectPermission; +import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; + +/** + * Service which provides convenience methods for creating, retrieving, and + * manipulating objects that can be children of other objects. This service will + * automatically enforce the permissions of the current user. + * + * @author Michael Jumper + * @param <InternalType> + * The specific internal implementation of the type of object this service + * provides access to. + * + * @param <ExternalType> + * The external interface or implementation of the type of object this + * service provides access to, as defined by the guacamole-ext API. + * + * @param <ModelType> + * The underlying model object used to represent InternalType in the + * database. + */ +public abstract class ModeledChildDirectoryObjectService<InternalType extends ModeledChildDirectoryObject<ModelType>, + ExternalType extends Identifiable, ModelType extends ChildObjectModel> + extends ModeledDirectoryObjectService<InternalType, ExternalType, ModelType> { + + /** + * Returns the permission set associated with the given user and related + * to the type of objects which can be parents of the child objects handled + * by this directory object service. + * + * @param user + * The user whose permissions are being retrieved. + * + * @return + * A permission set which contains the permissions associated with the + * given user and related to the type of objects which can be parents + * of the child objects handled by this directory object service. + * + * @throws GuacamoleException + * If permission to read the user's permissions is denied. + */ + protected abstract ObjectPermissionSet getParentPermissionSet( + ModeledAuthenticatedUser user) throws GuacamoleException; + + /** + * Returns the set of parent objects that are modified by the given model + * object (by virtue of the object changing parents). If the model is not + * changing parents, the resulting collection will be empty. + * + * @param user + * The user making the given changes to the model. + * + * @param identifier + * The identifier of the object that has been modified, if it exists. + * If the object is being created, this will be null. + * + * @param model + * The model that has been modified, if any. If the object is being + * deleted, this will be null. + * + * @return + * A collection of the identifiers of all parents that will be affected + * (updated) by the change. + * + * @throws GuacamoleException + * If an error occurs while determining which parents are affected. + */ + protected Collection<String> getModifiedParents(ModeledAuthenticatedUser user, + String identifier, ModelType model) throws GuacamoleException { + + // Get old parent identifier + String oldParentIdentifier = null; + if (identifier != null) { + ModelType current = retrieveObject(user, identifier).getModel(); + oldParentIdentifier = current.getParentIdentifier(); + } + + // Get new parent identifier + String parentIdentifier = null; + if (model != null) { + + parentIdentifier = model.getParentIdentifier(); + + // If both parents have the same identifier, nothing has changed + if (parentIdentifier != null && parentIdentifier.equals(oldParentIdentifier)) + return Collections.<String>emptyList(); + + } + + // Return collection of all non-root parents involved + Collection<String> parents = new ArrayList<String>(2); + if (oldParentIdentifier != null) parents.add(oldParentIdentifier); + if (parentIdentifier != null) parents.add(parentIdentifier); + return parents; + + } + + /** + * Returns whether the given user has permission to modify the parents + * affected by the modifications made to the given model object. + * + * @param user + * The user who changed the model object. + * + * @param identifier + * The identifier of the object that has been modified, if it exists. + * If the object is being created, this will be null. + * + * @param model + * The model that has been modified, if any. If the object is being + * deleted, this will be null. + * + * @return + * true if the user has update permission for all modified parents, + * false otherwise. + * + * @throws GuacamoleException + * If an error occurs while determining which parents are affected. + */ + protected boolean canUpdateModifiedParents(ModeledAuthenticatedUser user, + String identifier, ModelType model) throws GuacamoleException { + + // If user is an administrator, no need to check + if (user.getUser().isAdministrator()) + return true; + + // Verify that we have permission to modify any modified parents + Collection<String> modifiedParents = getModifiedParents(user, identifier, model); + if (!modifiedParents.isEmpty()) { + + ObjectPermissionSet permissionSet = getParentPermissionSet(user); + Collection<String> updateableParents = permissionSet.getAccessibleObjects( + Collections.singleton(ObjectPermission.Type.UPDATE), + modifiedParents + ); + + return updateableParents.size() == modifiedParents.size(); + + } + + return true; + + } + + @Override + protected void beforeCreate(ModeledAuthenticatedUser user, + ModelType model) throws GuacamoleException { + + super.beforeCreate(user, model); + + // Validate that we can update all applicable parents + if (!canUpdateModifiedParents(user, null, model)) + throw new GuacamoleSecurityException("Permission denied."); + + } + + @Override + protected void beforeUpdate(ModeledAuthenticatedUser user, + ModelType model) throws GuacamoleException { + + super.beforeUpdate(user, model); + + // Validate that we can update all applicable parents + if (!canUpdateModifiedParents(user, model.getIdentifier(), model)) + throw new GuacamoleSecurityException("Permission denied."); + + } + + @Override + protected void beforeDelete(ModeledAuthenticatedUser user, + String identifier) throws GuacamoleException { + + super.beforeDelete(user, identifier); + + // Validate that we can update all applicable parents + if (!canUpdateModifiedParents(user, identifier, null)) + throw new GuacamoleSecurityException("Permission denied."); + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObject.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObject.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObject.java deleted file mode 100644 index 6aca740..0000000 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObject.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 org.apache.guacamole.auth.jdbc.connectiongroup.RootConnectionGroup; - -/** - * Common base class for objects that will ultimately be made available through - * the Directory class. All such objects will need the same base set of queries - * to fulfill the needs of the Directory class. - * - * @author Michael Jumper - * @param <ModelType> - * The type of model object that corresponds to this object. - */ -public abstract class ModeledGroupedDirectoryObject<ModelType extends GroupedObjectModel> - extends ModeledDirectoryObject<ModelType> { - - /** - * Returns the identifier of the parent connection group, which cannot be - * null. If the parent is the root connection group, this will be - * RootConnectionGroup.IDENTIFIER. - * - * @return - * The identifier of the parent connection group. - */ - public String getParentIdentifier() { - - // Translate null parent to proper identifier - String parentIdentifier = getModel().getParentIdentifier(); - if (parentIdentifier == null) - return RootConnectionGroup.IDENTIFIER; - - return parentIdentifier; - - } - - /** - * Sets the identifier of the associated parent connection group. If the - * parent is the root connection group, this should be - * RootConnectionGroup.IDENTIFIER. - * - * @param parentIdentifier - * The identifier of the connection group to associate as this object's - * parent. - */ - public void setParentIdentifier(String parentIdentifier) { - - // Translate root identifier back into null - if (parentIdentifier != null - && parentIdentifier.equals(RootConnectionGroup.IDENTIFIER)) - parentIdentifier = null; - - getModel().setParentIdentifier(parentIdentifier); - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObjectService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObjectService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObjectService.java deleted file mode 100644 index 718def7..0000000 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledGroupedDirectoryObjectService.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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.ArrayList; -import java.util.Collection; -import java.util.Collections; -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.GuacamoleSecurityException; -import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; -import org.apache.guacamole.net.auth.Identifiable; -import org.apache.guacamole.net.auth.permission.ObjectPermission; -import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; - -/** - * Service which provides convenience methods for creating, retrieving, and - * manipulating objects that can be within connection groups. This service will - * automatically enforce the permissions of the current user. - * - * @author Michael Jumper - * @param <InternalType> - * The specific internal implementation of the type of object this service - * provides access to. - * - * @param <ExternalType> - * The external interface or implementation of the type of object this - * service provides access to, as defined by the guacamole-ext API. - * - * @param <ModelType> - * The underlying model object used to represent InternalType in the - * database. - */ -public abstract class ModeledGroupedDirectoryObjectService<InternalType extends ModeledGroupedDirectoryObject<ModelType>, - ExternalType extends Identifiable, ModelType extends GroupedObjectModel> - extends ModeledDirectoryObjectService<InternalType, ExternalType, ModelType> { - - /** - * Returns the set of parent connection groups that are modified by the - * given model object (by virtue of the object changing parent groups). If - * the model is not changing parents, the resulting collection will be - * empty. - * - * @param user - * The user making the given changes to the model. - * - * @param identifier - * The identifier of the object that has been modified, if it exists. - * If the object is being created, this will be null. - * - * @param model - * The model that has been modified, if any. If the object is being - * deleted, this will be null. - * - * @return - * A collection of the identifiers of all parent connection groups - * that will be affected (updated) by the change. - * - * @throws GuacamoleException - * If an error occurs while determining which parent connection groups - * are affected. - */ - protected Collection<String> getModifiedGroups(ModeledAuthenticatedUser user, - String identifier, ModelType model) throws GuacamoleException { - - // Get old parent identifier - String oldParentIdentifier = null; - if (identifier != null) { - ModelType current = retrieveObject(user, identifier).getModel(); - oldParentIdentifier = current.getParentIdentifier(); - } - - // Get new parent identifier - String parentIdentifier = null; - if (model != null) { - - parentIdentifier = model.getParentIdentifier(); - - // If both parents have the same identifier, nothing has changed - if (parentIdentifier != null && parentIdentifier.equals(oldParentIdentifier)) - return Collections.<String>emptyList(); - - } - - // Return collection of all non-root groups involved - Collection<String> groups = new ArrayList<String>(2); - if (oldParentIdentifier != null) groups.add(oldParentIdentifier); - if (parentIdentifier != null) groups.add(parentIdentifier); - return groups; - - } - - /** - * Returns whether the given user has permission to modify the parent - * connection groups affected by the modifications made to the given model - * object. - * - * @param user - * The user who changed the model object. - * - * @param identifier - * The identifier of the object that has been modified, if it exists. - * If the object is being created, this will be null. - * - * @param model - * The model that has been modified, if any. If the object is being - * deleted, this will be null. - * - * @return - * true if the user has update permission for all modified groups, - * false otherwise. - * - * @throws GuacamoleException - * If an error occurs while determining which parent connection groups - * are affected. - */ - protected boolean canUpdateModifiedGroups(ModeledAuthenticatedUser user, - String identifier, ModelType model) throws GuacamoleException { - - // If user is an administrator, no need to check - if (user.getUser().isAdministrator()) - return true; - - // Verify that we have permission to modify any modified groups - Collection<String> modifiedGroups = getModifiedGroups(user, identifier, model); - if (!modifiedGroups.isEmpty()) { - - ObjectPermissionSet permissionSet = user.getUser().getConnectionGroupPermissions(); - Collection<String> updateableGroups = permissionSet.getAccessibleObjects( - Collections.singleton(ObjectPermission.Type.UPDATE), - modifiedGroups - ); - - return updateableGroups.size() == modifiedGroups.size(); - - } - - return true; - - } - - @Override - protected void beforeCreate(ModeledAuthenticatedUser user, - ModelType model) throws GuacamoleException { - - super.beforeCreate(user, model); - - // Validate that we can update all applicable parent groups - if (!canUpdateModifiedGroups(user, null, model)) - throw new GuacamoleSecurityException("Permission denied."); - - } - - @Override - protected void beforeUpdate(ModeledAuthenticatedUser user, - ModelType model) throws GuacamoleException { - - super.beforeUpdate(user, model); - - // Validate that we can update all applicable parent groups - if (!canUpdateModifiedGroups(user, model.getIdentifier(), model)) - throw new GuacamoleSecurityException("Permission denied."); - - } - - @Override - protected void beforeDelete(ModeledAuthenticatedUser user, - String identifier) throws GuacamoleException { - - super.beforeDelete(user, identifier); - - // Validate that we can update all applicable parent groups - if (!canUpdateModifiedGroups(user, identifier, null)) - throw new GuacamoleSecurityException("Permission denied."); - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java index 0a1a475..5e8a8f3 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java @@ -21,7 +21,7 @@ package org.apache.guacamole.auth.jdbc.connection; import java.util.HashSet; import java.util.Set; -import org.apache.guacamole.auth.jdbc.base.GroupedObjectModel; +import org.apache.guacamole.auth.jdbc.base.ChildObjectModel; /** * Object representation of a Guacamole connection, as represented in the @@ -29,7 +29,7 @@ import org.apache.guacamole.auth.jdbc.base.GroupedObjectModel; * * @author Michael Jumper */ -public class ConnectionModel extends GroupedObjectModel { +public class ConnectionModel extends ChildObjectModel { /** * The human-readable name associated with this connection. http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java index cf64f8a..d6de326 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java @@ -34,7 +34,7 @@ import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.apache.guacamole.GuacamoleClientException; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; -import org.apache.guacamole.auth.jdbc.base.ModeledGroupedDirectoryObjectService; +import org.apache.guacamole.auth.jdbc.base.ModeledChildDirectoryObjectService; import org.apache.guacamole.auth.jdbc.permission.ConnectionPermissionMapper; import org.apache.guacamole.auth.jdbc.permission.ObjectPermissionMapper; import org.apache.guacamole.net.GuacamoleTunnel; @@ -52,7 +52,7 @@ import org.apache.guacamole.protocol.GuacamoleClientInformation; * * @author Michael Jumper, James Muehlner */ -public class ConnectionService extends ModeledGroupedDirectoryObjectService<ModeledConnection, Connection, ConnectionModel> { +public class ConnectionService extends ModeledChildDirectoryObjectService<ModeledConnection, Connection, ConnectionModel> { /** * Mapper for accessing connections. @@ -146,6 +146,15 @@ public class ConnectionService extends ModeledGroupedDirectoryObjectService<Mode } @Override + protected ObjectPermissionSet getParentPermissionSet(ModeledAuthenticatedUser user) + throws GuacamoleException { + + // Connections are contained by connection groups + return user.getUser().getConnectionGroupPermissions(); + + } + + @Override protected void beforeCreate(ModeledAuthenticatedUser user, ConnectionModel model) throws GuacamoleException { http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java index 1ee896a..ead81ec 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java @@ -31,7 +31,7 @@ import java.util.Set; import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.jdbc.JDBCEnvironment; -import org.apache.guacamole.auth.jdbc.base.ModeledGroupedDirectoryObject; +import org.apache.guacamole.auth.jdbc.base.ModeledChildDirectoryObject; import org.apache.guacamole.form.Field; import org.apache.guacamole.form.Form; import org.apache.guacamole.form.NumericField; @@ -50,7 +50,7 @@ import org.slf4j.LoggerFactory; * @author James Muehlner * @author Michael Jumper */ -public class ModeledConnection extends ModeledGroupedDirectoryObject<ConnectionModel> +public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionModel> implements Connection { /** http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupModel.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupModel.java index 1d938c9..3784578 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupModel.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupModel.java @@ -21,7 +21,7 @@ package org.apache.guacamole.auth.jdbc.connectiongroup; import java.util.HashSet; import java.util.Set; -import org.apache.guacamole.auth.jdbc.base.GroupedObjectModel; +import org.apache.guacamole.auth.jdbc.base.ChildObjectModel; import org.apache.guacamole.net.auth.ConnectionGroup; /** @@ -30,7 +30,7 @@ import org.apache.guacamole.net.auth.ConnectionGroup; * * @author Michael Jumper */ -public class ConnectionGroupModel extends GroupedObjectModel { +public class ConnectionGroupModel extends ChildObjectModel { /** * The human-readable name associated with this connection group. http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java index 68ebdae..0382c35 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupService.java @@ -29,7 +29,7 @@ import org.apache.guacamole.GuacamoleClientException; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleUnsupportedException; -import org.apache.guacamole.auth.jdbc.base.ModeledGroupedDirectoryObjectService; +import org.apache.guacamole.auth.jdbc.base.ModeledChildDirectoryObjectService; import org.apache.guacamole.auth.jdbc.permission.ConnectionGroupPermissionMapper; import org.apache.guacamole.auth.jdbc.permission.ObjectPermissionMapper; import org.apache.guacamole.net.GuacamoleTunnel; @@ -46,7 +46,7 @@ import org.apache.guacamole.protocol.GuacamoleClientInformation; * * @author Michael Jumper, James Muehlner */ -public class ConnectionGroupService extends ModeledGroupedDirectoryObjectService<ModeledConnectionGroup, +public class ConnectionGroupService extends ModeledChildDirectoryObjectService<ModeledConnectionGroup, ConnectionGroup, ConnectionGroupModel> { /** @@ -129,6 +129,15 @@ public class ConnectionGroupService extends ModeledGroupedDirectoryObjectService } @Override + protected ObjectPermissionSet getParentPermissionSet(ModeledAuthenticatedUser user) + throws GuacamoleException { + + // Connection groups are contained by other connection groups + return user.getUser().getConnectionGroupPermissions(); + + } + + @Override protected void beforeCreate(ModeledAuthenticatedUser user, ConnectionGroupModel model) throws GuacamoleException { http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/26d9dd85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java index 59a93ec..5fdf6f7 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connectiongroup/ModeledConnectionGroup.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.Set; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.jdbc.JDBCEnvironment; -import org.apache.guacamole.auth.jdbc.base.ModeledGroupedDirectoryObject; +import org.apache.guacamole.auth.jdbc.base.ModeledChildDirectoryObject; import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.apache.guacamole.form.BooleanField; import org.apache.guacamole.form.Field; @@ -47,7 +47,7 @@ import org.slf4j.LoggerFactory; * @author James Muehlner * @author Michael Jumper */ -public class ModeledConnectionGroup extends ModeledGroupedDirectoryObject<ConnectionGroupModel> +public class ModeledConnectionGroup extends ModeledChildDirectoryObject<ConnectionGroupModel> implements ConnectionGroup { /**
