/* ===============================================================================
*
* 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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.naming.NamingException;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
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.Bug;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.util.CmsPropertyHandler;
import org.infoglue.cms.util.dom.DOMBuilder;
import org.infoglue.deliver.util.CacheController;
import org.infoglue.deliver.util.NullObject;
import org.infoglue.deliver.util.webservices.WebServiceHelper;
/**
* @author Mattias Bogeblad
*
* This authentication module authenticates an user against a webservice.
*/
public class WebServiceAuthorizationModule extends BasicAuthorizationModule implements AuthorizationModule, Serializable
{
private final static Logger logger = Logger.getLogger(WebServiceAuthorizationModule.class.getName());
private final static DOMBuilder domHelper = new DOMBuilder();
protected Properties extraProperties = null;
/**
* This method gets the webservice utility.
*/
public WebServiceHelper getWebServiceHelper() throws SystemException
{
WebServiceHelper wsh = new WebServiceHelper();
String serviceUrl = extraProperties.getProperty("ws.serviceUrl");
if(logger.isDebugEnabled())
logger.info("serviceUrl:" + serviceUrl);
if(serviceUrl == null || serviceUrl.equals(""))
throw new SystemException("The parameter ws.serviceUrl was not found in extra parameters. The url must be defined.");
wsh.setServiceUrl(serviceUrl);
return wsh;
}
/**
* Gets is the implementing class can update as well as read
*/
public boolean getSupportUpdate()
{
return false;
}
/**
* Gets is the implementing class can delete as well as read
*/
public boolean getSupportDelete()
{
return false;
}
/**
* Gets is the implementing class can create as well as read
*/
public boolean getSupportCreate()
{
return false;
}
/**
* Gets an authorized InfoGluePrincipal
*/
public InfoGluePrincipal getAuthorizedInfoGluePrincipal(String userName) throws Exception
{
String userCacheTimeout = this.extraProperties.getProperty("userCacheTimeout", "1800");
String authorizerIndex = this.extraProperties.getProperty("authorizerIndex");
if(authorizerIndex == null)
authorizerIndex = "";
String key = "user_" + userName + authorizerIndex;
InfoGluePrincipal infogluePrincipal = null;
Object infogluePrincipalObject = CacheController.getCachedObjectFromAdvancedCache("WebServiceAuthorizationCache", key, new Integer(userCacheTimeout).intValue());
if(infogluePrincipalObject != null)
{
if(infogluePrincipalObject instanceof NullObject)
{
return null;
}
else
{
infogluePrincipal = (InfoGluePrincipal)infogluePrincipalObject;
logger.warn("Returning cached user:" + userName + ":" + infogluePrincipal);
if(logger.isDebugEnabled())
logger.info("Returning cached user:" + userName + ":" + infogluePrincipal);
return infogluePrincipal;
}
}
String administratorUserName = CmsPropertyHandler.getAdministratorUserName();
String administratorEmail = CmsPropertyHandler.getAdministratorEmail();
//String administratorUserName = CmsPropertyHandler.getProperty("administratorUserName");
//String administratorEmail = CmsPropertyHandler.getProperty("administratorEmail");
final boolean isAdministrator = userName.equalsIgnoreCase(administratorUserName) ? true : false;
if(isAdministrator)
{
infogluePrincipal = new InfoGluePrincipal(userName, "System", "Administrator", administratorEmail, new ArrayList(), new ArrayList(), isAdministrator, this);
}
else
{
try
{
String xml = getWebServiceHelper().getString("getAuthorizedInfoGluePrincipal", userName);
if(logger.isDebugEnabled())
logger.info("xml:" + xml);
if(xml != null && !xml.equals(""))
{
Document document = domHelper.getDocument(xml);
Element errorIdElement = (Element)document.selectSingleNode("/error/id");
if(errorIdElement != null)
{
Element errorMessageElement = (Element)document.selectSingleNode("/error/message");
throw new Exception("Error reported by webservice: " + errorMessageElement.getText() + "(" + errorIdElement.getText() + ") - for user '" + userName + "'\n\n" + xml);
}
Element firstNameElement = (Element)document.selectSingleNode("/user/firstName");
Element lastNameElement = (Element)document.selectSingleNode("/user/lastName");
Element emailElement = (Element)document.selectSingleNode("/user/email");
String firstName = firstNameElement.getText();
String lastName = lastNameElement.getText();
String email = emailElement.getText();
Map metaMap = new HashMap();
Element metaElement = (Element)document.selectSingleNode("/user/meta");
List metaChildNodes = metaElement.elements();
Iterator metaChildNodesIterator = metaChildNodes.iterator();
while(metaChildNodesIterator.hasNext())
{
Element valueElement = (Element)metaChildNodesIterator.next();
String name = valueElement.getName();
String value = valueElement.getText();
metaMap.put(name, value);
}
List roles = new ArrayList();
List groups = new ArrayList();
List rolesElementList = document.selectNodes("/user/roles/role");
Iterator rolesElementListIterator = rolesElementList.iterator();
while(rolesElementListIterator.hasNext())
{
Element roleElement = (Element)rolesElementListIterator.next();
Element nameElement = (Element)roleElement.selectSingleNode("name");
Element displayNameElement = (Element)roleElement.selectSingleNode("displayName");
Element descriptionElement = (Element)roleElement.selectSingleNode("description");
String name = nameElement.getText();
String displayName = name;
if(displayNameElement != null && !displayNameElement.getText().equals(""))
displayName = displayNameElement.getText();
String description = "No description";
if(descriptionElement != null && !descriptionElement.getText().equals(""))
description = descriptionElement.getText();
if(logger.isDebugEnabled())
logger.info("name:" + name);
InfoGlueRole infoglueRole = new InfoGlueRole(name, displayName, description, this);
roles.add(infoglueRole);
}
List groupsElementList = document.selectNodes("/user/groups/group");
Iterator groupsElementListIterator = groupsElementList.iterator();
while(groupsElementListIterator.hasNext())
{
Element groupElement = (Element)groupsElementListIterator.next();
Element nameElement = (Element)groupElement.selectSingleNode("name");
Element displayNameElement = (Element)groupElement.selectSingleNode("displayName");
Element descriptionElement = (Element)groupElement.selectSingleNode("description");
String name = nameElement.getText();
String displayName = name;
if(displayNameElement != null && !displayNameElement.getText().equals(""))
displayName = displayNameElement.getText();
String description = "No description";
if(descriptionElement != null && !descriptionElement.getText().equals(""))
description = descriptionElement.getText();
if(logger.isDebugEnabled())
logger.info("name:" + name);
InfoGlueGroup infoglueGroup = new InfoGlueGroup(name, displayName, description, this);
groups.add(infoglueGroup);
}
infogluePrincipal = new InfoGluePrincipal(userName, firstName, lastName, email, roles, groups, metaMap, isAdministrator, this);
if(infogluePrincipal != null)
CacheController.cacheObjectInAdvancedCache("JNDIAuthorizationCache", key, infogluePrincipal, null, false);
}
}
catch(Exception e)
{
logger.warn("Error:" + e.getMessage(), e);
//e.printStackTrace();
CacheController.cacheObjectInAdvancedCache("JNDIAuthorizationCache", key, new NullObject(), null, false);
}
}
return infogluePrincipal;
}
/**
* Gets an authorized InfoGlueRole.
*/
public InfoGlueRole getAuthorizedInfoGlueRole(String roleName) throws Exception
{
InfoGlueRole infoglueRole = null;
List roles = getRoles();
Iterator rolesIterator = roles.iterator();
while(rolesIterator.hasNext())
{
InfoGlueRole infoglueRoleCandidate = (InfoGlueRole)rolesIterator.next();
if(infoglueRoleCandidate.getName().equals(roleName))
{
infoglueRole = infoglueRoleCandidate;
break;
}
}
return infoglueRole;
}
/**
* Gets an authorized InfoGlueGroup.
*/
public InfoGlueGroup getAuthorizedInfoGlueGroup(String groupName) throws Exception
{
InfoGlueGroup infoglueGroup = null;
List groups = getGroups();
Iterator groupsIterator = groups.iterator();
while(groupsIterator.hasNext())
{
InfoGlueGroup infoglueGroupCandidate = (InfoGlueGroup)groupsIterator.next();
if(infoglueGroupCandidate.getName().equals(groupName))
{
infoglueGroup = infoglueGroupCandidate;
break;
}
}
return infoglueGroup;
}
/**
* This method gets a users roles
*/
public List authorizeUser(String userName) throws Exception
{
return getRoles(userName);
}
/**
* Return a List of roles associated with the given User. Any
* roles present in the user's directory entry are supplemented by
* a directory search. If no roles are associated with this user,
* a zero-length List is returned.
*
* @param context The directory context we are searching
* @param user The User to be checked
*
* @exception NamingException if a directory server error occurs
*/
protected List getRoles(String userName) throws Exception
{
List roles = new ArrayList();
InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(userName);
if(principal != null && principal.getRoles() != null)
roles = principal.getRoles();
return roles;
}
/**
* Return a List of roles associated with the given User. Any
* roles present in the user's directory entry are supplemented by
* a directory search. If no roles are associated with this user,
* a zero-length List is returned.
*
* @param context The directory context we are searching
* @param user The User to be checked
*
* @exception NamingException if a directory server error occurs
*/
protected List getGroups(String userName) throws Exception
{
List groups = new ArrayList();
InfoGluePrincipal principal = getAuthorizedInfoGluePrincipal(userName);
if(principal != null && principal.getRoles() != null)
groups = principal.getGroups();
return groups;
}
/**
* This method gets a list of roles
*/
public List getRoles() throws Exception
{
logger.info("getRoles start....");
String roleCacheTimeout = this.extraProperties.getProperty("roleCacheTimeout", "1800");
String authorizerIndex = this.extraProperties.getProperty("authorizerIndex");
if(authorizerIndex == null)
authorizerIndex = "";
String key = "allRoles" + authorizerIndex;
List roles = (List)CacheController.getCachedObjectFromAdvancedCache("JNDIAuthorizationCache", key, new Integer(roleCacheTimeout).intValue());
if(roles != null)
return roles;
roles = new ArrayList();
String xml = getWebServiceHelper().getString("getRoles");
if(logger.isDebugEnabled())
logger.info("Roles xml:" + xml);
if(xml != null && !xml.equals(""))
{
Document document = domHelper.getDocument(xml);
List roleNodes = document.selectNodes("/roles/role");
Iterator rolesIterator = roleNodes.iterator();
while(rolesIterator.hasNext())
{
Element roleElement = (Element)rolesIterator.next();
Element nameElement = (Element)roleElement.selectSingleNode("name");
Element displayNameElement = (Element)roleElement.selectSingleNode("displayName");
Element descriptionElement = (Element)roleElement.selectSingleNode("description");
String name = nameElement.getText();
String displayName = name;
if(displayNameElement != null && !displayNameElement.getText().equals(""))
displayName = displayNameElement.getText();
String description = "No description";
if(descriptionElement != null && !descriptionElement.getText().equals(""))
description = descriptionElement.getText();
InfoGlueRole infoglueRole = new InfoGlueRole(name, displayName, description, this);
roles.add(infoglueRole);
}
}
if(roles != null)
CacheController.cacheObjectInAdvancedCache("JNDIAuthorizationCache", key, roles, null, false);
return roles;
}
/**
* This method gets a list of users
*/
public List getUsers() throws Exception
{
logger.info("*******************");
logger.info("* getUsers start *");
logger.info("*******************");
String userCacheTimeout = this.extraProperties.getProperty("userCacheTimeout", "1800");
String authorizerIndex = this.extraProperties.getProperty("authorizerIndex");
if(authorizerIndex == null)
authorizerIndex = "";
String key = "allUsers" + authorizerIndex;
List users = (List)CacheController.getCachedObjectFromAdvancedCache("JNDIAuthorizationCache", key, new Integer(userCacheTimeout).intValue());
if(users != null)
return users;
users = new ArrayList();
String xml = getWebServiceHelper().getString("getUsers");
if(xml != null && !xml.equals(""))
{
try
{
Document document = domHelper.getDocument(xml);
List usersNodes = document.selectNodes("/users");
List userNodes = document.selectNodes("/users/user");
Iterator usersIterator = userNodes.iterator();
while(usersIterator.hasNext())
{
Element userElement = (Element)usersIterator.next();
Element userNameElement = (Element)userElement.selectSingleNode("userName");
if(userNameElement == null)
userNameElement = (Element)userElement.selectSingleNode("username");
Element firstNameElement = (Element)userElement.selectSingleNode("firstName");
Element lastNameElement = (Element)userElement.selectSingleNode("lastName");
Element emailElement = (Element)userElement.selectSingleNode("email");
String userName = userNameElement.getText();
if(logger.isDebugEnabled())
logger.info("userName:" + userName);
String firstName = firstNameElement.getText();
String lastName = lastNameElement.getText();
String email = emailElement.getText();
/*
Map metaMap = new HashMap();
Element metaElement = (Element)document.selectSingleNode("/user/meta");
List metaChildNodes = metaElement.elements();
Iterator metaChildNodesIterator = metaChildNodes.iterator();
while(metaChildNodesIterator.hasNext())
{
Element valueElement = (Element)metaChildNodesIterator.next();
String name = valueElement.getName();
String value = valueElement.getText();
metaMap.put(name, value);
}
*/
List roles = new ArrayList();
List groups = new ArrayList();
List rolesElementList = userElement.selectNodes("roles/role");
Iterator rolesElementListIterator = rolesElementList.iterator();
while(rolesElementListIterator.hasNext())
{
Element roleElement = (Element)rolesElementListIterator.next();
Element nameElement = (Element)roleElement.selectSingleNode("name");
Element displayNameElement = (Element)roleElement.selectSingleNode("displayName");
Element descriptionElement = (Element)roleElement.selectSingleNode("description");
String name = nameElement.getText();
String displayName = name;
if(displayNameElement != null && !displayNameElement.getText().equals(""))
displayName = displayNameElement.getText();
String description = "No description";
if(descriptionElement != null && !descriptionElement.getText().equals(""))
description = descriptionElement.getText();
InfoGlueRole infoglueRole = new InfoGlueRole(name, displayName, description, this);
roles.add(infoglueRole);
List groupsElementList = roleElement.selectNodes("groups/group");
Iterator groupsElementListIterator = groupsElementList.iterator();
while(groupsElementListIterator.hasNext())
{
Element groupElement = (Element)groupsElementListIterator.next();
Element groupNameElement = (Element)groupElement.selectSingleNode("name");
Element groupDisplayNameElement = (Element)groupElement.selectSingleNode("displayName");
Element groupDescriptionElement = (Element)groupElement.selectSingleNode("description");
String groupName = nameElement.getText();
String groupDisplayName = groupName;
if(groupDisplayNameElement != null && !groupDisplayNameElement.getText().equals(""))
groupDisplayName = groupDisplayNameElement.getText();
String groupDescription = "No description";
if(groupDescriptionElement != null && !groupDescriptionElement.getText().equals(""))
groupDescription = groupDescriptionElement.getText();
InfoGlueGroup infoglueGroup = new InfoGlueGroup(groupName, groupDisplayName, groupDescription, this);
groups.add(infoglueGroup);
}
}
List groupsElementList = userElement.selectNodes("groups/group");
Iterator groupsElementListIterator = groupsElementList.iterator();
while(groupsElementListIterator.hasNext())
{
Element groupElement = (Element)groupsElementListIterator.next();
Element nameElement = (Element)groupElement.selectSingleNode("name");
Element displayNameElement = (Element)groupElement.selectSingleNode("displayName");
Element descriptionElement = (Element)groupElement.selectSingleNode("description");
String name = nameElement.getText();
String displayName = name;
if(displayNameElement != null && !displayNameElement.getText().equals(""))
displayName = displayNameElement.getText();
String description = "No description";
if(descriptionElement != null && !descriptionElement.getText().equals(""))
description = descriptionElement.getText();
InfoGlueGroup infoglueGroup = new InfoGlueGroup(name, displayName, description, this);
groups.add(infoglueGroup);
}
InfoGluePrincipal infogluePrincipal = new InfoGluePrincipal(userName, firstName, lastName, email, roles, groups, false, this);
users.add(infogluePrincipal);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
logger.info("getUsers end...");
if(users != null)
CacheController.cacheObjectInAdvancedCache("JNDIAuthorizationCache", key, users, null, false);
return users;
}
public List getFilteredUsers(String firstName, String lastName, String userName, String email, String[] roleIds) throws SystemException, Bug
{
List users = new ArrayList();
//TODO
return users;
}
public List getFilteredUsers(Integer offset, Integer limit, String sortProperty, String direction, String searchString, boolean populateRolesAndGroups) throws Exception
{
return getUsers();
}
/* (non-Javadoc)
* @see org.infoglue.cms.security.AuthorizationModule#getRoleUsers(java.lang.String)
*/
public List getUsers(String roleName) throws Exception
{
return getRoleUsers(roleName);
}
public List getRoleUsers(String roleName) throws Exception
{
List users = new ArrayList();
List allUsers = this.getUsers();
Iterator allUsersIterator = allUsers.iterator();
while(allUsersIterator.hasNext())
{
InfoGluePrincipal userCandidate = (InfoGluePrincipal)allUsersIterator.next();
if(userCandidate.getRoles().contains(getAuthorizedInfoGlueRole(roleName)))
{
users.add(userCandidate);
}
}
return users;
}
public Properties getExtraProperties()
{
return this.extraProperties;
}
public void setExtraProperties(Properties properties)
{
this.extraProperties = properties;
}
public void setTransactionObject(Object transactionObject)
{
}
public Object getTransactionObject()
{
return null;
}
/**
* This method returns a list of all groups available to InfoGlue.
*/
public List getGroups() throws Exception
{
logger.info("getGroups start....");
String groupCacheTimeout = this.extraProperties.getProperty("groupCacheTimeout", "1800");
String authorizerIndex = this.extraProperties.getProperty("authorizerIndex");
if(authorizerIndex == null)
authorizerIndex = "";
String key = "allGroups" + authorizerIndex;
List groups = (List)CacheController.getCachedObjectFromAdvancedCache("JNDIAuthorizationCache", key, new Integer(groupCacheTimeout).intValue());
if(groups != null)
return groups;
groups = new ArrayList();
String xml = getWebServiceHelper().getString("getGroups");
if(logger.isDebugEnabled())
logger.info("Groups xml:" + xml);
Document document = domHelper.getDocument(xml);
List groupNodes = document.selectNodes("/groups/group");
Iterator groupsIterator = groupNodes.iterator();
while(groupsIterator.hasNext())
{
Element groupElement = (Element)groupsIterator.next();
Element nameElement = (Element)groupElement.selectSingleNode("name");
Element displayNameElement = (Element)groupElement.selectSingleNode("displayName");
Element descriptionElement = (Element)groupElement.selectSingleNode("description");
String name = nameElement.getText();
String displayName = name;
if(displayNameElement != null && !displayNameElement.getText().equals(""))
displayName = displayNameElement.getText();
String description = "No description";
if(descriptionElement != null && !descriptionElement.getText().equals(""))
description = descriptionElement.getText();
InfoGlueGroup infoglueGroup = new InfoGlueGroup(name, displayName, description, this);
groups.add(infoglueGroup);
}
if(groups != null)
CacheController.cacheObjectInAdvancedCache("JNDIAuthorizationCache", key, groups, null, false);
return groups;
}
/**
* Gets a list of users which is memebers of the given group
*/
public List getGroupUsers(String groupName) throws Exception
{
List users = new ArrayList();
List allUsers = this.getUsers();
Iterator allUsersIterator = allUsers.iterator();
while(allUsersIterator.hasNext())
{
InfoGluePrincipal userCandidate = (InfoGluePrincipal)allUsersIterator.next();
if(userCandidate.getGroups().contains(getAuthorizedInfoGlueGroup(groupName)))
{
users.add(userCandidate);
}
}
return users;
}
public void createInfoGluePrincipal(SystemUserVO systemUserVO) throws Exception
{
throw new SystemException("The WebService Authorization module does not support creation of users yet...");
}
public void updateInfoGluePrincipalPassword(String userName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support updates of users yet...");
}
public void updateInfoGlueAnonymousPrincipalPassword() throws Exception
{
throw new SystemException("The WebService Authorization module does not support updates of user password yet....");
}
public void updateInfoGluePrincipalPassword(String userName, String oldPassword, String newPassword) throws Exception
{
throw new SystemException("The WebService Authorization module does not support updates of user password yet...");
}
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
{
throw new SystemException("The WebService Authorization module does not support deletion of users yet...");
}
public void createInfoGlueRole(RoleVO roleVO) throws Exception
{
throw new SystemException("The WebService Authorization module does not support creation of users yet...");
}
public void updateInfoGlueRole(RoleVO roleVO, String[] userNames) throws Exception
{
}
public void deleteInfoGlueRole(String roleName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support deletion of roles yet...");
}
public void updateInfoGluePrincipal(SystemUserVO systemUserVO, String[] roleNames, String[] groupNames) throws Exception
{
}
public void updateInfoGluePrincipal(SystemUserVO systemUserVO, String oldPassword, String[] roleNames, String[] groupNames) throws Exception
{
}
public void createInfoGlueGroup(GroupVO groupVO) throws Exception
{
throw new SystemException("The WebService Authorization module does not support creation of groups yet...");
}
public void updateInfoGlueGroup(GroupVO roleVO, String[] userNames) throws Exception
{
}
public void deleteInfoGlueGroup(String groupName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support deletion of groups yet...");
}
public void addUserToGroup(String groupName, String userName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support adding of users to groups yet...");
}
public void addUserToRole(String roleName, String userName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support adding of users to roles yet...");
}
public void removeUserFromGroup(String groupName, String userName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support removing users from groups yet...");
}
public void removeUserFromRole(String roleName, String userName) throws Exception
{
throw new SystemException("The WebService Authorization module does not support removing users from roles yet...");
}
/**
* 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);
}
@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();
}
}