/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.aimluck.eip.services.security; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Vector; import javax.servlet.ServletConfig; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.jetspeed.om.security.Permission; import org.apache.jetspeed.om.security.Role; import org.apache.jetspeed.services.JetspeedSecurity; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.rundata.JetspeedRunData; import org.apache.jetspeed.services.rundata.JetspeedRunDataService; import org.apache.jetspeed.services.security.JetspeedSecurityCache; import org.apache.jetspeed.services.security.JetspeedSecurityException; import org.apache.jetspeed.services.security.JetspeedSecurityService; import org.apache.jetspeed.services.security.PermissionException; import org.apache.jetspeed.services.security.PermissionManagement; import org.apache.turbine.services.InitializationException; import org.apache.turbine.services.TurbineBaseService; import org.apache.turbine.services.TurbineServices; import org.apache.turbine.services.resources.ResourceService; import org.apache.turbine.services.rundata.RunDataService; import com.aimluck.eip.cayenne.om.security.TurbinePermission; import com.aimluck.eip.cayenne.om.security.TurbineRolePermission; import com.aimluck.eip.orm.Database; /** * パーミッションを管理するクラスです。 <br /> * */ public class ALPermissionManagement extends TurbineBaseService implements PermissionManagement { private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(ALPermissionManagement.class.getName()); private JetspeedRunDataService runDataService = null; private final static String CASCADE_DELETE = "programmatic.cascade.delete"; private final static boolean DEFAULT_CASCADE_DELETE = true; private final static String CONFIG_SYSTEM_PERMISSIONS = "system.permissions"; private boolean cascadeDelete; private final static String CACHING_ENABLE = "caching.enable"; private boolean cachingEnable = true; private Vector<?> systemPermissions = null; /** * */ public Iterator<?> getPermissions(String rolename) throws JetspeedSecurityException { Role role = null; try { if (cachingEnable) { Iterator<?> iterator = JetspeedSecurityCache.getPermissions(rolename); if (iterator != null) { return iterator; } } role = JetspeedSecurity.getRole(rolename); } catch (JetspeedSecurityException e) { logger.error("Failed to Retrieve Role: ", e); throw new PermissionException("Failed to Retrieve Role: ", e); } List<TurbineRolePermission> rels; HashMap<String, Permission> perms; try { Expression exp = ExpressionFactory.matchDbExp( TurbineRolePermission.ROLE_ID_PK_COLUMN, Integer.valueOf(role.getId())); rels = Database.query(TurbineRolePermission.class, exp).fetchList(); if (rels.size() > 0) { perms = new HashMap<String, Permission>(rels.size()); } else { perms = new HashMap<String, Permission>(); } for (int ix = 0; ix < rels.size(); ix++) { TurbineRolePermission rel = rels.get(ix); Permission perm = rel.getTurbinePermission(); perms.put(perm.getName(), perm); } } catch (Exception e) { logger.error("Failed to retrieve permissions ", e); throw new PermissionException("Failed to retrieve permissions ", e); } return perms.values().iterator(); } /** * */ public Iterator<TurbinePermission> getPermissions() throws JetspeedSecurityException { List<TurbinePermission> permissions; try { permissions = Database.query(TurbinePermission.class).fetchList(); } catch (Exception e) { logger.error("Failed to retrieve permissions ", e); throw new PermissionException("Failed to retrieve permissions ", e); } return permissions.iterator(); } /** * */ public void addPermission(Permission permission) throws JetspeedSecurityException { if (permissionExists(permission.getName())) { throw new PermissionException("The permission '" + permission.getName() + "' already exists"); } try { // 新規オブジェクトモデル TurbinePermission tpermission = Database.create(TurbinePermission.class); tpermission.setName(permission.getName()); tpermission.setOBJECTDATA(null); Database.commit(); } catch (Exception e) { Database.rollback(); String message = "Failed to create permission '" + permission.getName() + "'"; logger.error(message, e); throw new PermissionException(message, e); } } /** * */ public void savePermission(Permission permission) throws JetspeedSecurityException { if (!permissionExists(permission.getName())) { throw new PermissionException("The permission '" + permission.getName() + "' doesn't exists"); } try { if (permission instanceof TurbinePermission) { Database.commit(); } else { throw new PermissionException( "TurbinePermissionManagment: Permission is not a Turbine permission, cannot update"); } } catch (Exception e) { Database.rollback(); String message = "Failed to create permission '" + permission.getName() + "'"; logger.error(message, e); throw new PermissionException(message, e); } } /** * */ public void removePermission(String permissionName) throws JetspeedSecurityException { try { if (systemPermissions.contains(permissionName)) { throw new PermissionException("[" + permissionName + "] is a system permission and cannot be removed"); } Permission permission = this.getPermission(permissionName); if (cascadeDelete) { Expression exp = ExpressionFactory.matchDbExp( TurbineRolePermission.PERMISSION_ID_PK_COLUMN, Integer.valueOf(permission.getId())); Database.query(TurbineRolePermission.class, exp).deleteAll(); } Database.delete((TurbineRolePermission) permission); Database.commit(); if (cachingEnable) { JetspeedSecurityCache.removeAllPermissions(permissionName); } } catch (Exception e) { String message = "Failed to remove permission '" + permissionName + "'"; logger.error(message, e); throw new PermissionException(message, e); } finally { } } /** * */ public void grantPermission(String roleName, String permissionName) throws JetspeedSecurityException { try { Role role = JetspeedSecurity.getRole(roleName); Permission permission = this.getPermission(permissionName); // 新規オブジェクトモデル TurbineRolePermission role_permission = Database.create(TurbineRolePermission.class); role_permission.setRoleId(Integer.parseInt(role.getId())); role_permission.setPermissionId(Integer.parseInt(permission.getId())); Database.commit(); } catch (Exception e) { String message = "Grant permission '" + permissionName + "' to role '" + roleName + "' failed: "; logger.error(message, e); throw new PermissionException(message, e); } } /** * */ public void revokePermission(String roleName, String permissionName) throws JetspeedSecurityException { try { Role role = JetspeedSecurity.getRole(roleName); Permission permission = this.getPermission(permissionName); Expression exp1 = ExpressionFactory.matchDbExp( TurbineRolePermission.ROLE_ID_PK_COLUMN, Integer.valueOf(role.getId())); Expression exp2 = ExpressionFactory.matchDbExp( TurbineRolePermission.PERMISSION_ID_PK_COLUMN, Integer.valueOf(permission.getId())); Database .query(TurbineRolePermission.class, exp1) .andQualifier(exp2) .deleteAll(); if (cachingEnable) { JetspeedSecurityCache.removePermission(roleName, permissionName); } } catch (Exception e) { Database.rollback(); String message = "Revoke permission '" + permissionName + "' to role '" + roleName + "' failed: "; logger.error(message, e); throw new PermissionException(message, e); } } /** * */ public boolean hasPermission(String roleName, String permissionName) throws JetspeedSecurityException { List<TurbineRolePermission> permissions; try { if (cachingEnable) { return JetspeedSecurityCache.hasPermission(roleName, permissionName); } Role role = JetspeedSecurity.getRole(roleName); Permission permission = this.getPermission(permissionName); Expression exp1 = ExpressionFactory.matchDbExp( TurbineRolePermission.ROLE_ID_PK_COLUMN, Integer.valueOf(role.getId())); Expression exp2 = ExpressionFactory.matchDbExp( TurbineRolePermission.PERMISSION_ID_PK_COLUMN, Integer.valueOf(permission.getId())); permissions = Database .query(TurbineRolePermission.class, exp1) .andQualifier(exp2) .fetchList(); } catch (Exception e) { String message = "Failed to check permission '" + permissionName + "'"; logger.error(message, e); throw new PermissionException(message, e); } return (permissions.size() > 0); } /** * */ public Permission getPermission(String permissionName) throws JetspeedSecurityException { List<TurbinePermission> permissions; try { permissions = Database.query(TurbinePermission.class).fetchList(); } catch (Exception e) { String message = "Failed to retrieve permission '" + permissionName + "'"; logger.error(message, e); throw new PermissionException(message, e); } if (permissions.size() > 1) { throw new PermissionException( "Multiple Permissions with same permissionname '" + permissionName + "'"); } if (permissions.size() == 1) { TurbinePermission permission = permissions.get(0); return permission; } throw new PermissionException("Unknown permission '" + permissionName + "'"); } protected JetspeedRunData getRunData() { JetspeedRunData rundata = null; if (this.runDataService != null) { rundata = this.runDataService.getCurrentRunData(); } return rundata; } /** * * @param permissionName * @return * @throws PermissionException */ protected boolean permissionExists(String permissionName) throws PermissionException { List<TurbinePermission> permissions; try { Expression exp = ExpressionFactory.matchExp( TurbinePermission.PERMISSION_NAME_PROPERTY, permissionName); permissions = Database.query(TurbinePermission.class, exp).fetchList(); } catch (Exception e) { logger.error("Failed to check account's presence", e); throw new PermissionException("Failed to check account's presence", e); } if (permissions.size() < 1) { return false; } return true; } /** * */ @Override public synchronized void init(ServletConfig conf) throws InitializationException { if (getInit()) { return; } super.init(conf); ResourceService serviceConf = ((TurbineServices) TurbineServices.getInstance()) .getResources(JetspeedSecurityService.SERVICE_NAME); this.runDataService = (JetspeedRunDataService) TurbineServices.getInstance().getService( RunDataService.SERVICE_NAME); cascadeDelete = serviceConf.getBoolean(CASCADE_DELETE, DEFAULT_CASCADE_DELETE); cachingEnable = serviceConf.getBoolean(CACHING_ENABLE, cachingEnable); systemPermissions = serviceConf.getVector(CONFIG_SYSTEM_PERMISSIONS, new Vector<Object>()); setInit(true); } }