/* =============================================================================== * * Part of the InfoGlue Content Management Platform (www.infoglue.org) * * =============================================================================== * * Copyright (C) * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2, as published by the * Free Software Foundation. See the file LICENSE.html for more information. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple * Place, Suite 330 / Boston, MA 02111-1307 / USA. * * =============================================================================== */ package org.infoglue.cms.security; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.apache.log4j.Logger; import org.exolab.castor.jdo.Database; import org.infoglue.cms.entities.management.GroupVO; import org.infoglue.cms.entities.management.RoleVO; import org.infoglue.cms.entities.management.SystemUserVO; import org.infoglue.cms.exception.SystemException; import org.infoglue.cms.util.CmsPropertyHandler; import org.infoglue.cms.util.sorters.ReflectionComparator; /** * @author Mattias Bogeblad * * This authorization module is a generic multi-source authorization module. With this you can * define any number of underlying authorization modules which is combined by this module. The order of lookup * is the same as the order the underlying modules are defined in. * * To use this you state org.infoglue.cms.security.GenericCombinedAuthorizationModule as AuthorizationModule * and then you add the underlying modules in Extra security parameters as index based properties like this: * * 0.authorizerClassName=org.infoglue.cms.security.JNDIBasicAuthorizationModule * 1.authorizerClassName=org.infoglue.cms.security.InfoGlueBasicAuthorizationModule * 2.authorizerClassName=com.mycompany.cms.security.MyCustomAuthorizationModule * * Then all modules in turn are asked the queries and if not found the next module is asked. * If you for example want to have several JNDI-sources you are free to define the same module several times and * you can differentiate what properties it should use by setting the index in front of the properties. * For example if you have 2 JNDI sources and they differ in among other things * roleBase=cn=groups,dc=infoglue,dc=org you add the index in front of two lines of this: * * 0.roleBase=cn=groups,dc=infoglue,dc=org * 1.roleBase=cn=internal,cn=groups,dc=companyx,dc=com * * That way the module with index 0 will get all properties without an index and all properties with index 0 will * override the properties without index for just that module. That way you can also have some parameters in common * between two of the same modules. */ public class GenericCombinedAuthorizationModule extends BasicAuthorizationModule implements AuthorizationModule, Serializable { private final static Logger logger = Logger.getLogger(GenericCombinedAuthorizationModule.class.getName()); protected Properties extraProperties = null; private Database transactionObject = null; private List authorizationModules = new ArrayList(); private AuthorizationModule getAuthorizationModule(String authorizationModuleClassName, int index) throws SystemException { AuthorizationModule authorizationModule = null; try { Properties localProperties = new Properties(); Iterator propertiesIterator = this.extraProperties.keySet().iterator(); while(propertiesIterator.hasNext()) { String property = (String)propertiesIterator.next(); String value = this.extraProperties.getProperty(property); if(property.startsWith("" + index + ".")) property = property.substring(2); localProperties.setProperty(property, value); } localProperties.setProperty("authorizerIndex", "" + index); if(logger.isInfoEnabled()) logger.info("InfoGlueAuthenticationFilter.authorizerClass:" + authorizationModuleClassName); authorizationModule = (AuthorizationModule)Class.forName(authorizationModuleClassName).newInstance(); if(logger.isInfoEnabled()) logger.info("authorizationModule:" + authorizationModule); authorizationModule.setExtraProperties(localProperties); authorizationModule.setTransactionObject(this.getTransactionObject()); } catch(Exception e) { logger.error("There was an error initializing the authorizerClass:" + e.getMessage(), e); throw new SystemException("There was an error initializing the authorizerClass:" + e.getMessage(), e); } return authorizationModule; } /** * Gets an authorized InfoGluePrincipal. If the user has logged in with the root-account * we immediately return - otherwise we populate it. */ public InfoGluePrincipal getAuthorizedInfoGluePrincipal(String userName) throws Exception { InfoGluePrincipal infogluePrincipal = null; int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("") && infogluePrincipal == null) { if(logger.isInfoEnabled()) logger.info("getAuthorizedInfoGluePrincipal in " + authorizerClassName); try { infogluePrincipal = getAuthorizationModule(authorizerClassName, i).getAuthorizedInfoGluePrincipal(userName); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } return infogluePrincipal; } /** * Gets an authorized InfoGlueRole. */ public InfoGlueRole getAuthorizedInfoGlueRole(String roleName) throws Exception { InfoGlueRole role = null; int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("") && role == null) { try { role = getAuthorizationModule(authorizerClassName, i).getAuthorizedInfoGlueRole(roleName); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } return role; } /** * Gets an authorized InfoGlueGroup. */ public InfoGlueGroup getAuthorizedInfoGlueGroup(String groupName) throws Exception { InfoGlueGroup group = null; int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("") && group == null) { try { group = getAuthorizationModule(authorizerClassName, i).getAuthorizedInfoGlueGroup(groupName); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } return group; } /** * This method gets a users roles */ /* public List authorizeUser(String userName) throws Exception { List roles = new ArrayList(); int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { try { roles.addAll(getAuthorizationModule(authorizerClassName, i).authorizeUser(userName)); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } return roles; } */ /** * This method gets a list of roles */ public List getRoles() throws Exception { List roles = new ArrayList(); int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { try { List systemRoles = getAuthorizationModule(authorizerClassName, i).getRoles(); if(logger.isInfoEnabled()) logger.info("\nFound:" + systemRoles.size() + " roles in " + i); roles.addAll(systemRoles); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } Collections.sort(roles, new ReflectionComparator("displayName")); return roles; } /** * This method gets a list of groups */ public List getGroups() throws Exception { List groups = new ArrayList(); int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { if(logger.isInfoEnabled()) logger.info("Looking for user in " + authorizerClassName); try { groups.addAll(getAuthorizationModule(authorizerClassName, i).getGroups()); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } Collections.sort(groups, new ReflectionComparator("displayName")); return groups; } /** * This method gets a list of users */ public List getUsers() throws Exception { List users = new ArrayList(); int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { if(logger.isInfoEnabled()) logger.info("Looking for users in " + authorizerClassName); try { users.addAll(getAuthorizationModule(authorizerClassName, i).getUsers()); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } Collections.sort(users, new ReflectionComparator("displayName")); return users; } public List getFilteredUsers(Integer offset, Integer limit, String sortProperty, String direction, String searchString, boolean populateRolesAndGroups) throws Exception { List users = new ArrayList(); int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { if(logger.isInfoEnabled()) logger.info("Looking for users in " + authorizerClassName); try { users.addAll(getAuthorizationModule(authorizerClassName, i).getFilteredUsers(offset, limit, sortProperty, direction, searchString, populateRolesAndGroups)); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } Collections.sort(users, new ReflectionComparator("displayName")); return users; } /* public List getFilteredUsers(String firstName, String lastName, String userName, String email, String[] roleIds) throws Exception { throw new Exception("Unsupported operation"); //return null; } */ public List getUsers(String roleName) throws Exception { return getRoleUsers(roleName); } public List getRoleUsers(String roleName) throws Exception { List users = new ArrayList(); InfoGlueRole role = getAuthorizedInfoGlueRole(roleName); users.addAll(role.getAutorizationModule().getRoleUsers(roleName)); return users; } public List getGroupUsers(String groupName) throws Exception { List users = new ArrayList(); InfoGlueGroup group = getAuthorizedInfoGlueGroup(groupName); users.addAll(group.getAutorizationModule().getGroupUsers(groupName)); return users; } public void createInfoGluePrincipal(SystemUserVO systemUserVO) throws Exception { int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { if(logger.isInfoEnabled()) logger.info("Creating user in " + authorizerClassName); try { getAuthorizationModule(authorizerClassName, i).createInfoGluePrincipal(systemUserVO); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } } public void updateInfoGluePrincipal(SystemUserVO systemUserVO, String[] roleNames, String[] groupNames) throws Exception { InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(systemUserVO.getUserName()); principal.getAutorizationModule().updateInfoGluePrincipal(systemUserVO, roleNames, groupNames); } public void updateInfoGluePrincipal(SystemUserVO systemUserVO, String oldPassword, String[] roleNames, String[] groupNames) throws Exception { InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(systemUserVO.getUserName()); principal.getAutorizationModule().updateInfoGluePrincipal(systemUserVO, oldPassword, roleNames, groupNames); } /** * This method is used to send out a newpassword to an existing users. */ public void updateInfoGluePrincipalPassword(String userName) throws Exception { InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(userName); principal.getAutorizationModule().updateInfoGluePrincipalPassword(userName); } /** * This method is used to send out a newpassword to an existing users. */ public void updateInfoGlueAnonymousPrincipalPassword() throws Exception { InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(CmsPropertyHandler.getAnonymousUser()); principal.getAutorizationModule().updateInfoGlueAnonymousPrincipalPassword(); } /** * This method is used to let a user update his password by giving his/her old one first. */ public void updateInfoGluePrincipalPassword(String userName, String oldPassword, String newPassword) throws Exception { InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(userName); principal.getAutorizationModule().updateInfoGluePrincipalPassword(userName, oldPassword, newPassword); } public void changeInfoGluePrincipalUserName(String userName, String newUserName) throws Exception { throw new SystemException("This AuthorizationModule does not support changing user name of a principal"); } public void deleteInfoGluePrincipal(String userName) throws Exception { InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(userName); principal.getAutorizationModule().deleteInfoGluePrincipal(userName); } public void createInfoGlueRole(RoleVO roleVO) throws Exception { int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { if(logger.isInfoEnabled()) logger.info("Creating role in " + authorizerClassName); try { getAuthorizationModule(authorizerClassName, i).createInfoGlueRole(roleVO); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } } public void deleteInfoGlueRole(String roleName) throws Exception { InfoGlueRole role = getAuthorizedInfoGlueRole(roleName); role.getAutorizationModule().deleteInfoGlueRole(roleName); } public void updateInfoGlueRole(RoleVO roleVO, String[] userNames) throws Exception { InfoGlueRole role = getAuthorizedInfoGlueRole(roleVO.getRoleName()); role.getAutorizationModule().updateInfoGlueRole(roleVO, userNames); } public void createInfoGlueGroup(GroupVO groupVO) throws Exception { int i=0; String authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); while(authorizerClassName != null && !authorizerClassName.equals("")) { if(logger.isInfoEnabled()) logger.info("Creating Group in " + authorizerClassName); try { getAuthorizationModule(authorizerClassName, i).createInfoGlueGroup(groupVO); } catch(Exception e) { e.printStackTrace(); } i++; authorizerClassName = this.extraProperties.getProperty("" + i + ".authorizerClassName"); } } public void deleteInfoGlueGroup(String groupName) throws Exception { InfoGlueGroup group = getAuthorizedInfoGlueGroup(groupName); group.getAutorizationModule().deleteInfoGlueGroup(groupName); } public void updateInfoGlueGroup(GroupVO groupVO, String[] userNames) throws Exception { InfoGlueGroup group = getAuthorizedInfoGlueGroup(groupVO.getGroupName()); group.getAutorizationModule().updateInfoGlueGroup(groupVO, userNames); } public void addUserToGroup(String groupName, String userName) throws Exception { InfoGlueGroup group = getAuthorizedInfoGlueGroup(groupName); group.getAutorizationModule().addUserToGroup(groupName, userName); } public void addUserToRole(String roleName, String userName) throws Exception { InfoGlueRole role = getAuthorizedInfoGlueRole(roleName); role.getAutorizationModule().addUserToRole(roleName, userName); } /** * This method is used to remove user from a role. */ public void removeUserFromRole(String roleName, String userName) throws Exception { InfoGlueRole role = getAuthorizedInfoGlueRole(roleName); role.getAutorizationModule().removeUserFromRole(roleName, userName); } /** * This method is used to remove user from a group. */ public void removeUserFromGroup(String groupName, String userName) throws Exception { InfoGlueGroup group = getAuthorizedInfoGlueGroup(groupName); group.getAutorizationModule().removeUserFromGroup(groupName, userName); } /** * This method is used find out if a user exists. Much quicker than getAuthorizedPrincipal */ public boolean userExists(String userName) throws Exception { return (getAuthorizedInfoGluePrincipal(userName) == null ? false : true); } /** * This method is used find out if a role exists. Much quicker than getRole */ public boolean roleExists(String roleName) throws Exception { return (getAuthorizedInfoGlueRole(roleName) == null ? false : true); } /** * This method is used find out if a group exists. Much quicker than getGroup */ public boolean groupExists(String groupName) throws Exception { return (getAuthorizedInfoGlueGroup(groupName) == null ? false : true); } public boolean getSupportUpdate() { return true; } public boolean getSupportDelete() { return true; } public boolean getSupportCreate() { return true; } public List getFilteredUsers(String firstName, String lastName, String userName, String email, String[] roleIds) throws Exception { return null; } public Properties getExtraProperties() { return this.extraProperties; } public void setExtraProperties(Properties properties) { this.extraProperties = properties; } public void setTransactionObject(Object transactionObject) { this.transactionObject = (Database)transactionObject; } public Object getTransactionObject() { return this.transactionObject; } @Override public Integer getRoleCount(String searchString) throws Exception { return getRoles().size(); } @Override public Integer getGroupCount(String searchString) throws Exception { return getGroups().size(); } @Override public Integer getUserCount(String searchString) throws Exception { return getUsers().size(); } }