GUAC-1101: Implement querying of connection permissions.

This commit is contained in:
Michael Jumper
2015-02-28 18:53:07 -08:00
parent 7d399a0fbe
commit 820ffed959
9 changed files with 287 additions and 53 deletions

View File

@@ -49,6 +49,9 @@ import org.glyptodon.guacamole.auth.jdbc.permission.SystemPermissionService;
import org.glyptodon.guacamole.auth.jdbc.socket.UnrestrictedGuacamoleSocketService;
import org.glyptodon.guacamole.auth.jdbc.user.UserService;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionMapper;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionSet;
import org.glyptodon.guacamole.environment.Environment;
import org.mybatis.guice.MyBatisModule;
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
@@ -91,6 +94,7 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
// Add MyBatis mappers
addMapperClass(ConnectionMapper.class);
addMapperClass(ConnectionGroupMapper.class);
addMapperClass(ConnectionPermissionMapper.class);
addMapperClass(ConnectionRecordMapper.class);
addMapperClass(ParameterMapper.class);
addMapperClass(SystemPermissionMapper.class);
@@ -105,11 +109,13 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
bind(ModeledGuacamoleConfiguration.class);
bind(ModeledUser.class);
bind(RootConnectionGroup.class);
bind(ConnectionPermissionSet.class);
bind(SystemPermissionSet.class);
bind(UserContext.class);
bind(UserDirectory.class);
// Bind services
bind(ConnectionPermissionService.class);
bind(ConnectionService.class);
bind(ConnectionGroupService.class);
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);

View File

@@ -0,0 +1,30 @@
/*
* 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.auth.jdbc.permission;
/**
* Mapper for connection permissions.
*
* @author Michael Jumper
*/
public interface ConnectionPermissionMapper extends ObjectPermissionMapper {}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2013 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.auth.jdbc.permission;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser;
/**
* Service which provides convenience methods for creating, retrieving, and
* deleting connection permissions. This service will automatically enforce the
* permissions of the current user.
*
* @author Michael Jumper
*/
public class ConnectionPermissionService extends ObjectPermissionService {
/**
* Mapper for connection permissions.
*/
@Inject
private ConnectionPermissionMapper connectionPermissionMapper;
/**
* Provider for connection permission sets.
*/
@Inject
private Provider<ConnectionPermissionSet> connectionPermissionSetProvider;
@Override
protected ObjectPermissionMapper getPermissionMapper() {
return connectionPermissionMapper;
}
@Override
public ObjectPermissionSet getPermissionSet(AuthenticatedUser user,
ModeledUser targetUser) throws GuacamoleException {
// Create permission set for requested user
ObjectPermissionSet permissionSet = connectionPermissionSetProvider.get();
permissionSet.init(user, targetUser);
return permissionSet;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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.auth.jdbc.permission;
import com.google.inject.Inject;
/**
* A database implementation of ObjectPermissionSet which uses an injected
* service to query and manipulate the connection permissions associated with
* a particular user.
*
* @author Michael Jumper
*/
public class ConnectionPermissionSet extends ObjectPermissionSet {
/**
* Service for querying and manipulating connection permissions.
*/
@Inject
private ConnectionPermissionService connectionPermissionService;
@Override
protected ObjectPermissionService getObjectPermissionService() {
return connectionPermissionService;
}
}

View File

@@ -32,15 +32,10 @@ import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
*/
public class ObjectPermissionModel extends PermissionModel<ObjectPermission.Type> {
/**
* The database ID of the object affected by this permission.
*/
private Integer affectedID;
/**
* The unique identifier of the object affected by this permission.
*/
private String affectedIdentifier;
private String objectIdentifier;
/**
* Creates a new, empty object permission.
@@ -48,44 +43,24 @@ public class ObjectPermissionModel extends PermissionModel<ObjectPermission.Type
public ObjectPermissionModel() {
}
/**
* Returns the database ID of the object affected by this permission.
*
* @return
* The database ID of the object affected by this permission.
*/
public Integer getAffectedID() {
return affectedID;
}
/**
* Sets the database ID of the object affected by this permission.
*
* @param affectedID
* The database ID of the object affected by this permission.
*/
public void setAffectedID(Integer affectedID) {
this.affectedID = affectedID;
}
/**
* Returns the unique identifier of the object affected by this permission.
*
* @return
* The unique identifier of the object affected by this permission.
*/
public String getAffectedIdentifier() {
return affectedIdentifier;
public String getObjectIdentifier() {
return objectIdentifier;
}
/**
* Sets the unique identifier of the object affected by this permission.
*
* @param affectedIdentifier
* @param objectIdentifier
* The unique identifier of the object affected by this permission.
*/
public void setAffectedIdentifier(String affectedIdentifier) {
this.affectedIdentifier = affectedIdentifier;
public void setObjectIdentifier(String objectIdentifier) {
this.objectIdentifier = objectIdentifier;
}
}

View File

@@ -45,24 +45,26 @@ public abstract class ObjectPermissionService
@Override
protected abstract ObjectPermissionMapper getPermissionMapper();
/**
* Returns the permission set associated with the given user and related
* to the type of objects affected the permissions handled by this
* permission 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 handled by this
* directory object service.
*
* @throws GuacamoleException
* If permission to read the user's permissions is denied.
*/
protected abstract ObjectPermissionSet getAffectedPermissionSet(AuthenticatedUser user)
throws GuacamoleException;
@Override
protected ObjectPermission getPermissionInstance(ObjectPermissionModel model) {
return new ObjectPermission(model.getType(), model.getObjectIdentifier());
}
@Override
protected ObjectPermissionModel getModelInstance(ModeledUser targetUser,
ObjectPermission permission) {
ObjectPermissionModel model = new ObjectPermissionModel();
// Populate model object with data from user and permission
model.setUserID(targetUser.getModel().getObjectID());
model.setUsername(targetUser.getModel().getIdentifier());
model.setType(permission.getType());
model.setObjectIdentifier(permission.getObjectIdentifier());
return model;
}
/**
* Determines whether the current user has permission to update the given
@@ -108,7 +110,7 @@ public abstract class ObjectPermissionService
affectedIdentifiers.add(permission.getObjectIdentifier());
// Determine subset of affected identifiers that we have admin access to
ObjectPermissionSet affectedPermissionSet = getAffectedPermissionSet(user);
ObjectPermissionSet affectedPermissionSet = getPermissionSet(user, user.getUser());
Collection<String> allowedSubset = affectedPermissionSet.getAccessibleObjects(
Collections.singleton(ObjectPermission.Type.ADMINISTER),
affectedIdentifiers

View File

@@ -28,6 +28,7 @@ import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
import org.glyptodon.guacamole.auth.jdbc.security.SaltService;
import org.glyptodon.guacamole.auth.jdbc.permission.SystemPermissionService;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService;
import org.glyptodon.guacamole.net.auth.User;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
@@ -59,6 +60,12 @@ public class ModeledUser extends DirectoryObject<UserModel> implements User {
*/
@Inject
private SystemPermissionService systemPermissionService;
/**
* Service for retrieving connection permissions.
*/
@Inject
private ConnectionPermissionService connectionPermissionService;
/**
* The plaintext password previously set by a call to setPassword(), if
@@ -131,8 +138,7 @@ public class ModeledUser extends DirectoryObject<UserModel> implements User {
@Override
public ObjectPermissionSet getConnectionPermissions()
throws GuacamoleException {
// STUB
return new SimpleObjectPermissionSet();
return connectionPermissionService.getPermissionSet(getCurrentUser(), this);
}
@Override