mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
Ticket #263: Clarified permissioning.
This commit is contained in:
@@ -8,6 +8,8 @@ CREATE TABLE `guacamole_connection_group` (
|
||||
`connection_group_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`parent_group_id` int(11),
|
||||
`connection_group_name` varchar(128) NOT NULL,
|
||||
`type` enum('ORGANIZATIONAL',
|
||||
'BALANCING') NOT NULL DEFAULT 'ORGANIZATIONAL',
|
||||
|
||||
PRIMARY KEY (`connection_group_id`),
|
||||
UNIQUE KEY `connection_group_name` (`connection_group_name`),
|
||||
@@ -112,7 +114,6 @@ CREATE TABLE `guacamole_connection_group_permission` (
|
||||
`user_id` int(11) NOT NULL,
|
||||
`connection_group_id` int(11) NOT NULL,
|
||||
`permission` enum('READ',
|
||||
'EXECUTE',
|
||||
'UPDATE',
|
||||
'DELETE',
|
||||
'ADMINISTER') NOT NULL,
|
||||
|
@@ -8,6 +8,9 @@ CREATE TABLE `guacamole_connection_group` (
|
||||
`connection_group_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`parent_group_id` int(11),
|
||||
`connection_group_name` varchar(128) NOT NULL,
|
||||
`type` enum('ORGANIZATIONAL',
|
||||
'BALANCING') NOT NULL DEFAULT 'ORGANIZATIONAL',
|
||||
|
||||
|
||||
PRIMARY KEY (`connection_group_id`),
|
||||
UNIQUE KEY `connection_group_name` (`connection_group_name`),
|
||||
@@ -39,7 +42,6 @@ CREATE TABLE `guacamole_connection_group_permission` (
|
||||
`user_id` int(11) NOT NULL,
|
||||
`connection_group_id` int(11) NOT NULL,
|
||||
`permission` enum('READ',
|
||||
'EXECUTE',
|
||||
'UPDATE',
|
||||
'DELETE',
|
||||
'ADMINISTER') NOT NULL,
|
||||
|
@@ -66,24 +66,18 @@ public class MySQLConnectionGroup extends AbstractConnectionGroup {
|
||||
/**
|
||||
* A Directory of connections that have this connection group as a parent.
|
||||
*/
|
||||
private Directory<String, Connection> connectionDirectory;
|
||||
private Directory<String, Connection> connectionDirectory = null;
|
||||
|
||||
/**
|
||||
* A Directory of connection groups that have this connection group as a parent.
|
||||
*/
|
||||
private Directory<String, ConnectionGroup> connectionGroupDirectory;
|
||||
private Directory<String, ConnectionGroup> connectionGroupDirectory = null;
|
||||
|
||||
/**
|
||||
* Service managing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Service for managing connection groups.
|
||||
*/
|
||||
//@Inject
|
||||
//private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Create a default, empty connection group.
|
||||
@@ -112,35 +106,38 @@ public class MySQLConnectionGroup extends AbstractConnectionGroup {
|
||||
*
|
||||
* @param connectionGroupID The ID of the associated database record, if any.
|
||||
* @param identifier The unique identifier associated with this connection group.
|
||||
* @param config The GuacamoleConfiguration associated with this connection.
|
||||
* @param history All ConnectionRecords associated with this connection.
|
||||
* @param userID The IID of the user who queried this connection.
|
||||
*/
|
||||
public void init(Integer connectionGroupID, String identifier,
|
||||
Directory<String, Connection> connectionDirectory,
|
||||
Directory<String, ConnectionGroup> connectionGroupDirectory,
|
||||
int userID) {
|
||||
|
||||
public void init(Integer connectionGroupID, String identifier, int userID) {
|
||||
this.connectionGroupID = connectionGroupID;
|
||||
setIdentifier(identifier);
|
||||
this.connectionDirectory = connectionDirectory;
|
||||
this.connectionGroupDirectory = connectionGroupDirectory;
|
||||
this.userID = userID;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
|
||||
return connectionGroupService.connect(this, info, userID);
|
||||
}
|
||||
|
||||
|
||||
private void loadConnectionDirectory() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<String, Connection> getConnectionDirectory() throws GuacamoleException {
|
||||
if(connectionDirectory == null)
|
||||
loadConnectionDirectory();
|
||||
return connectionDirectory;
|
||||
}
|
||||
|
||||
private void loadConnectionGroupDirectory() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<String, ConnectionGroup> getConnectionGroupDirectory() throws GuacamoleException {
|
||||
if(connectionGroupDirectory == null)
|
||||
loadConnectionGroupDirectory();
|
||||
return connectionGroupDirectory;
|
||||
}
|
||||
|
||||
|
@@ -37,11 +37,24 @@ package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroup;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
@@ -76,10 +89,82 @@ public class ConnectionGroupService {
|
||||
@Inject
|
||||
private Provider<MySQLConnectionGroup> mysqlConnectionGroupProvider;
|
||||
|
||||
public GuacamoleSocket connect(MySQLConnectionGroup aThis,
|
||||
public GuacamoleSocket connect(MySQLConnectionGroup group,
|
||||
GuacamoleClientInformation info, int userID) {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
//public Collection<MySQLConnection> getConnectionGroupConnections()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a map of all connection group names for the given IDs.
|
||||
*
|
||||
* @param ids The IDs of the connection groups to retrieve the names of.
|
||||
* @return A map containing the names of all connection groups and their
|
||||
* corresponding IDs.
|
||||
*/
|
||||
public Map<Integer, String> retrieveNames(Collection<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs.
|
||||
Map<Integer, String> names = new HashMap<Integer, String>();
|
||||
|
||||
// Get all connection groups having the given IDs
|
||||
ConnectionGroupExample example = new ConnectionGroupExample();
|
||||
example.createCriteria().andConnection_group_idIn(Lists.newArrayList(ids));
|
||||
List<ConnectionGroup> connectionGroups = connectionGroupDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (ConnectionGroup connectionGroup : connectionGroups)
|
||||
names.put(connectionGroup.getConnection_group_id(),
|
||||
connectionGroup.getConnection_group_name());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of all the connection groups defined in the system.
|
||||
*
|
||||
* @return A Set of names of all the connection groups defined in the system.
|
||||
*/
|
||||
public Set<String> getAllConnectionGroupNames() {
|
||||
|
||||
// Set of all present connection group names
|
||||
Set<String> names = new HashSet<String>();
|
||||
|
||||
// Query all connection group names
|
||||
List<ConnectionGroup> connectionGroups =
|
||||
connectionGroupDAO.selectByExample(new ConnectionGroupExample());
|
||||
for (ConnectionGroup connectionGroup : connectionGroups)
|
||||
names.add(connectionGroup.getConnection_group_name());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection group IDs of all the connection groups defined in the system.
|
||||
*
|
||||
* @return A list of connection group IDs of all the connection groups defined in the system.
|
||||
*/
|
||||
public List<Integer> getAllConnectionGroupIDs() {
|
||||
|
||||
// Set of all present connection group IDs
|
||||
List<Integer> connectionGroupIDs = new ArrayList<Integer>();
|
||||
|
||||
// Query all connection IDs
|
||||
List<ConnectionGroup> connections =
|
||||
connectionGroupDAO.selectByExample(new ConnectionGroupExample());
|
||||
for (ConnectionGroup connection : connections)
|
||||
connectionGroupIDs.add(connection.getConnection_group_id());
|
||||
|
||||
return connectionGroupIDs;
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -43,15 +43,19 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleSecurityException;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.permission.ConnectionGroupPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
||||
@@ -75,6 +79,12 @@ public class PermissionCheckService {
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for accessing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to users.
|
||||
*/
|
||||
@@ -86,6 +96,12 @@ public class PermissionCheckService {
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to the system as a whole.
|
||||
@@ -131,6 +147,26 @@ public class PermissionCheckService {
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the given connection group.
|
||||
* If permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param affectedConnectionGroupID The connection group that would be affected by the
|
||||
* operation if permission is granted.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @throws GuacamoleSecurityException If the specified permission is not
|
||||
* granted.
|
||||
*/
|
||||
public void verifyConnectionGroupAccess(int userID, int affectedConnectionGroupID, String permissionType) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkConnectionGroupAccess(userID, affectedConnectionGroupID, permissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the system. If
|
||||
* permission is denied, a GuacamoleSecurityException is thrown.
|
||||
@@ -195,6 +231,29 @@ public class PermissionCheckService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the affected
|
||||
* connection group.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param affectedConnectionGroupID The connection group that would be affected by the
|
||||
* operation if permission is granted.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @return true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
public boolean checkConnectionGroupAccess(int userID, Integer affectedConnectionGroupID, String permissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andConnection_group_idEqualTo(affectedConnectionGroupID).andPermissionEqualTo(permissionType);
|
||||
return connectionGroupPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the system.
|
||||
*
|
||||
@@ -293,6 +352,38 @@ public class PermissionCheckService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connection groups a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @return A list of all connection group IDs this user has the specified access
|
||||
* to.
|
||||
*/
|
||||
public List<Integer> retrieveConnectionGroupIDs(int userID,
|
||||
String permissionType) {
|
||||
|
||||
// A system administrator has access to all connections.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return connectionGroupService.getAllConnectionGroupIDs();
|
||||
|
||||
// Query all connection permissions for the given user and permission type
|
||||
ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);
|
||||
example.setDistinct(true);
|
||||
List<ConnectionGroupPermissionKey> connectionGroupPermissions =
|
||||
connectionGroupPermissionDAO.selectByExample(example);
|
||||
|
||||
// Convert result into list of IDs
|
||||
List<Integer> connectionGroupIDs = new ArrayList<Integer>(connectionGroupPermissions.size());
|
||||
for(ConnectionGroupPermissionKey permission : connectionGroupPermissions)
|
||||
connectionGroupIDs.add(permission.getConnection_group_id());
|
||||
|
||||
return connectionGroupIDs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all existing usernames that the given user has permission to
|
||||
* perform the given operation upon.
|
||||
@@ -432,6 +523,52 @@ public class PermissionCheckService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all connection group permissions granted to the user having the
|
||||
* given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all connection group permissions granted to the user having
|
||||
* the given ID.
|
||||
*/
|
||||
public Set<ConnectionGroupPermission> retrieveConnectionGroupPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<ConnectionGroupPermission> permissions = new HashSet<ConnectionGroupPermission>();
|
||||
|
||||
// Query all connection permissions
|
||||
ConnectionGroupPermissionExample connectionGroupPermissionExample = new ConnectionGroupPermissionExample();
|
||||
connectionGroupPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<ConnectionGroupPermissionKey> connectionGroupPermissions =
|
||||
connectionGroupPermissionDAO.selectByExample(connectionGroupPermissionExample);
|
||||
|
||||
// Get list of affected connection IDs
|
||||
List<Integer> connectionGroupIDs = new ArrayList<Integer>();
|
||||
for(ConnectionGroupPermissionKey connectionGroupPermission : connectionGroupPermissions)
|
||||
connectionGroupIDs.add(connectionGroupPermission.getConnection_group_id());
|
||||
|
||||
// Get corresponding names
|
||||
Map<Integer, String> affectedConnectionGroups =
|
||||
connectionGroupService.retrieveNames(connectionGroupIDs);
|
||||
|
||||
// Add connection permissions
|
||||
for(ConnectionGroupPermissionKey connectionGroupPermission : connectionGroupPermissions) {
|
||||
|
||||
// Construct permission from data
|
||||
ConnectionGroupPermission permission = new ConnectionGroupPermission(
|
||||
ConnectionGroupPermission.Type.valueOf(connectionGroupPermission.getPermission()),
|
||||
affectedConnectionGroups.get(connectionGroupPermission.getConnection_group_id())
|
||||
);
|
||||
|
||||
// Add to set
|
||||
permissions.add(permission);
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all system permissions granted to the user having the
|
||||
* given ID.
|
||||
@@ -487,6 +624,9 @@ public class PermissionCheckService {
|
||||
|
||||
// Add connection permissions
|
||||
allPermissions.addAll(retrieveConnectionPermissions(userID));
|
||||
|
||||
// add connection group permissions
|
||||
allPermissions.addAll(retrieveConnectionGroupPermissions(userID));
|
||||
|
||||
// Add system permissions
|
||||
allPermissions.addAll(retrieveSystemPermissions(userID));
|
||||
|
@@ -65,6 +65,14 @@
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_group_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionGroupPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_system_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
|
@@ -0,0 +1,121 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.permission;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-ext.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Jumper.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): James Muehlner
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
/**
|
||||
* A permission which controls operations that directly affect a specific
|
||||
* ConnectionGroup. Note that this permission only refers to the
|
||||
* ConnectionGroup by its identifier. The actual ConnectionGroup
|
||||
* is not stored within.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ConnectionGroupPermission
|
||||
implements ObjectPermission<String> {
|
||||
|
||||
/**
|
||||
* The identifier of the GuacamoleConfiguration associated with the
|
||||
* operation affected by this permission.
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
/**
|
||||
* The type of operation affected by this permission.
|
||||
*/
|
||||
private ObjectPermission.Type type;
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionGroupPermission having the given type
|
||||
* and identifier. The identifier must be the unique identifier assigned
|
||||
* to the ConnectionGroup by the AuthenticationProvider in use.
|
||||
*
|
||||
* @param type The type of operation affected by this permission.
|
||||
* @param identifier The identifier of the ConnectionGroup associated
|
||||
* with the operation affected by this permission.
|
||||
*/
|
||||
public ConnectionGroupPermission(ObjectPermission.Type type, String identifier) {
|
||||
|
||||
this.identifier = identifier;
|
||||
this.type = type;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermission.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
if (identifier != null) hash = 47 * hash + identifier.hashCode();
|
||||
if (type != null) hash = 47 * hash + type.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
// Not equal if null or wrong type
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
|
||||
final ConnectionGroupPermission other =
|
||||
(ConnectionGroupPermission) obj;
|
||||
|
||||
// Not equal if different type
|
||||
if (this.type != other.type)
|
||||
return false;
|
||||
|
||||
// If null identifier, equality depends on whether other identifier
|
||||
// is null
|
||||
if (identifier == null)
|
||||
return other.identifier == null;
|
||||
|
||||
// Otherwise, equality depends entirely on identifier
|
||||
return identifier.equals(other.identifier);
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user