TorqueTurbineModelManagerImpl.java
package org.apache.fulcrum.security.torque.turbine;
/*
* 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.
*/
import java.sql.Connection;
import org.apache.fulcrum.security.entity.Group;
import org.apache.fulcrum.security.entity.Permission;
import org.apache.fulcrum.security.entity.Role;
import org.apache.fulcrum.security.entity.User;
import org.apache.fulcrum.security.model.turbine.AbstractTurbineModelManager;
import org.apache.fulcrum.security.model.turbine.TurbineModelManager;
import org.apache.fulcrum.security.model.turbine.entity.TurbineGroup;
import org.apache.fulcrum.security.model.turbine.entity.TurbinePermission;
import org.apache.fulcrum.security.model.turbine.entity.TurbineRole;
import org.apache.fulcrum.security.model.turbine.entity.TurbineUser;
import org.apache.fulcrum.security.model.turbine.entity.TurbineUserGroupRole;
import org.apache.fulcrum.security.torque.LazyLoadable;
import org.apache.fulcrum.security.torque.om.TurbineRolePermissionPeer;
import org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity;
import org.apache.fulcrum.security.torque.security.turbine.TorqueAbstractTurbineTurbineSecurityEntity;
import org.apache.fulcrum.security.util.DataBackendException;
import org.apache.fulcrum.security.util.UnknownEntityException;
import org.apache.torque.TorqueException;
import org.apache.torque.criteria.Criteria;
import org.apache.torque.util.Transaction;
/**
* This implementation persists to a database via Torque.
*
* @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
* @version $Id:$
*/
public class TorqueTurbineModelManagerImpl extends AbstractTurbineModelManager implements TurbineModelManager
{
/** Serial version */
private static final long serialVersionUID = -306753988209612899L;
/**
* Grants a Role a Permission
*
* @param role the Role.
* @param permission the Permission.
* @throws DataBackendException if there was an error accessing the data backend.
* @throws UnknownEntityException if role or permission is not present.
*/
@Override
public synchronized void grant(Role role, Permission permission)
throws DataBackendException, UnknownEntityException
{
boolean roleExists = getRoleManager().checkExists(role);
boolean permissionExists = getPermissionManager().checkExists(permission);
if (roleExists && permissionExists)
{
if (role instanceof TurbineRole ) {
((TurbineRole)role).addPermission(permission);
}
if (permission instanceof TurbinePermission) {
((TurbinePermission)permission).addRole(role);
}
Connection con = null;
try
{
con = Transaction.begin();
((TorqueAbstractSecurityEntity)role).update(con);
((TorqueAbstractSecurityEntity)permission).update(con);// this updates all permission
Transaction.commit(con);
con = null;
}
catch (TorqueException e)
{
throw new DataBackendException("grant('" + role.getName() + "', '" + permission.getName() + "') failed", e);
}
finally
{
if (con != null)
{
Transaction.safeRollback(con);
}
}
return;
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
if (!permissionExists)
{
throw new UnknownEntityException("Unknown permission '" + permission.getName() + "'");
}
}
/**
* Revokes a Permission from a Role.
*
* @param role the Role.
* @param permission the Permission.
* @throws DataBackendException if there was an error accessing the data backend.
* @throws UnknownEntityException if role or permission is not present.
*/
@Override
public synchronized void revoke(Role role, Permission permission)
throws DataBackendException, UnknownEntityException
{
boolean roleExists = getRoleManager().checkExists(role);
boolean permissionExists = getPermissionManager().checkExists(permission);
if (roleExists && permissionExists)
{
if (role instanceof TurbineRole ) {
((TurbineRole)role).removePermission(permission);
}
if (permission instanceof TurbinePermission) {
((TurbinePermission)permission).removeRole(role);
}
try
{
Criteria criteria = new Criteria();
criteria.where(TurbineRolePermissionPeer.ROLE_ID, role.getId());
criteria.where(TurbineRolePermissionPeer.PERMISSION_ID, (Integer)permission.getId());
TurbineRolePermissionPeer.doDelete(criteria);
}
catch (TorqueException e)
{
throw new DataBackendException("revoke('" + role.getName() + "', '" + permission.getName() + "') failed", e);
}
return;
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
if (!permissionExists)
{
throw new UnknownEntityException("Unknown permission '" + permission.getName() + "'");
}
}
@Override
public synchronized void grant(User user, Group group, Role role) throws DataBackendException, UnknownEntityException
{
handlePrivileges(Privilege.GRANT, user, group, role );
}
@Override
public synchronized void revoke(User user, Group group, Role role)
throws DataBackendException, UnknownEntityException
{
if (checkExists(user, group, role))
handlePrivileges( Privilege.REVOKE, user, group, role );
}
@Override
public void replace( User user, Role oldRole, Role newRole )
throws DataBackendException, UnknownEntityException
{
Group group = ((TurbineModelManager)this).getGlobalGroup();
if (checkExists(user, oldRole, newRole, group) ) {
handlePrivileges( Privilege.REPLACE_ROLE, user, group, oldRole, newRole );
}
}
private void addUserGroupRole( User user, Role role, Group group )
throws DataBackendException
{
TurbineUserGroupRole new_user_group_role = new TurbineUserGroupRole();
new_user_group_role.setUser(user);
new_user_group_role.setGroup(group);
new_user_group_role.setRole(role);
((TurbineUser) user).addUserGroupRole(new_user_group_role);
if (group instanceof TurbineGroup ) {
if (getGroupManager() instanceof LazyLoadable) {
((TorqueAbstractTurbineTurbineSecurityEntity) group).addUserGroupRole(new_user_group_role,
((LazyLoadable)getGroupManager()).getLazyLoading());
} else {
((TurbineGroup) group).addUserGroupRole(new_user_group_role);
}
}
if (role instanceof TurbineRole ) {
if (getRoleManager() instanceof LazyLoadable) {
((TorqueAbstractTurbineTurbineSecurityEntity) role).addUserGroupRole(new_user_group_role,
((LazyLoadable)getRoleManager()).getLazyLoading());
} else {
((TurbineRole) role).addUserGroupRole(new_user_group_role);
}
}
}
private void removeUserGroupRole( User user, Role role, Group group )
throws DataBackendException, UnknownEntityException
{
boolean ugrFound = false;
for (TurbineUserGroupRole user_group_role : ((TurbineUser) user).getUserGroupRoleSet())
{
if (user_group_role.getUser().equals(user)
&& user_group_role.getGroup().equals(group)
&& user_group_role.getRole().equals(role))
{
ugrFound = true;
((TurbineUser)user).removeUserGroupRole(user_group_role);
if (group instanceof TurbineGroup ) {
if (getGroupManager() instanceof LazyLoadable) {
((TorqueAbstractTurbineTurbineSecurityEntity) group).removeUserGroupRole(user_group_role,
((LazyLoadable)getGroupManager()).getLazyLoading());
} else {
((TurbineGroup) group).removeUserGroupRole(user_group_role);
}
}
if (role instanceof TurbineRole ) {
if (getRoleManager() instanceof LazyLoadable) {
((TorqueAbstractTurbineTurbineSecurityEntity) role).removeUserGroupRole(user_group_role,
((LazyLoadable)getGroupManager()).getLazyLoading());
} else {
((TurbineRole) role).removeUserGroupRole(user_group_role);
}
}
break;
}
}
if (!ugrFound)
{
throw new UnknownEntityException("Could not find User/Group/Role for Role "+ role.getName());
}
}
private boolean checkExists( User user, Group group, Role role ) throws UnknownEntityException, DataBackendException
{
boolean roleExists = getRoleManager().checkExists(role);
boolean userExists = getUserManager().checkExists(user);
boolean groupExists = getGroupManager().checkExists(group);
if (roleExists && groupExists && userExists)
{
return true;
}
if (!roleExists)
{
throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
}
if (!groupExists)
{
throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
}
if (!userExists)
{
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
return false;
}
private boolean checkExists( User user, Role oldRole, Role newRole, Group globalGroup ) throws UnknownEntityException, DataBackendException
{
boolean userExists = getUserManager().checkExists(user);
boolean oldRoleExists = getRoleManager().checkExists(oldRole);
boolean newRoleExists = getRoleManager().checkExists(newRole);
if (userExists && oldRoleExists && newRoleExists && globalGroup != null)
{
return true;
}
if (!oldRoleExists)
{
throw new UnknownEntityException("Unknown role '" + oldRole.getName() + "'");
}
if (!newRoleExists)
{
throw new UnknownEntityException("Unknown role '" + newRole.getName() + "'");
}
if (!userExists)
{
throw new UnknownEntityException("Unknown user '" + user.getName() + "'");
}
return false;
}
private void handlePrivileges( Privilege privilege, User user, Group group, Role role, Role newRole )
throws DataBackendException, UnknownEntityException
{
String logChars = privilege.toString()+ "('"
+ user.getName() + "', '"
+ group.getName() + "', '"
+ role.getName() + "')";
switch (privilege) {
case GRANT:
addUserGroupRole( user, role, group );break;
case REVOKE:
removeUserGroupRole( user, role, group );break;
case REPLACE_ROLE:
addUserGroupRole( user, newRole, group );
removeUserGroupRole( user, role, group );
// the user's user-group-role set is updated, i.e. the old one is removed and the new one added -
// no need to do an additional delete in the database
logChars = Privilege.REPLACE_ROLE.toString()+"('"
+ user.getName() + "', '"
+ role.getName() + "', '"
+ newRole.getName() + "')";
break;
}
syncPrivilegeWithDatabase( user, logChars );
}
private void handlePrivileges( Privilege privilege, User user, Group group, Role role )
throws DataBackendException, UnknownEntityException
{
handlePrivileges( privilege, user, group, role, null );
}
private void syncPrivilegeWithDatabase( User user, String logChars)
throws DataBackendException
{
Connection con = null;
try
{
con = Transaction.begin();
// save only the new user group may be the better contract, but this would
// require/add a dependency to initTurbineUserGroupRoles()
//((TorqueAbstractSecurityEntity)user).save( con );
// update only user
((TorqueAbstractSecurityEntity)user).update(con);
//((TorqueAbstractSecurityEntity)group).update(con);
//((TorqueAbstractSecurityEntity)role).update(con);
Transaction.commit(con);
con = null;
}
catch (TorqueException e)
{
throw new DataBackendException(logChars +" failed", e);
}
catch ( Exception e )
{
throw new DataBackendException(logChars +" failed", e);
}
finally
{
if (con != null)
{
Transaction.safeRollback(con);
}
}
}
}