/*
 * Copyright 2000-2004 The Apache Software Foundation.
 * 
 * Licensed 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.
 */
package org.apache.jetspeed.portlets.security.users;

import java.io.IOException;
import java.io.NotSerializableException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.prefs.Preferences;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.security.auth.Subject;

import org.apache.jetspeed.portlets.security.SecurityResources;
import org.apache.jetspeed.portlets.security.users.JetspeedUserBean;
import org.apache.jetspeed.portlets.security.users.JetspeedUserBean.StringAttribute;
import org.apache.jetspeed.profiler.Profiler;
import org.apache.jetspeed.profiler.rules.PrincipalRule;
import org.apache.jetspeed.security.Group;
import org.apache.jetspeed.security.GroupManager;
import org.apache.jetspeed.security.InvalidNewPasswordException;
import org.apache.jetspeed.security.InvalidPasswordException;
import org.apache.jetspeed.security.PasswordAlreadyUsedException;
import org.apache.jetspeed.security.PasswordCredential;
import org.apache.jetspeed.security.Role;
import org.apache.jetspeed.security.RoleManager;
import org.apache.jetspeed.security.User;
import org.apache.jetspeed.security.UserManager;
import org.apache.jetspeed.security.SecurityException;
import org.apache.jetspeed.security.UserPrincipal;
import org.apache.portals.bridges.beans.TabBean;
import org.apache.portals.bridges.common.GenericServletPortlet;
import org.apache.portals.messaging.PortletMessaging;

/**
 * This portlet is a tabbed editor user interface for editing user attributes
 * and security definitions.
 *
 * @author <a href="mailto:jford@apache.com">Jeremy Ford</a>
 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
 * @version $Id: UserDetailsPortlet.java,v 1.4 2005/03/27 23:33:17 ate Exp $
 */
public class UserDetailsPortlet extends GenericServletPortlet
{
    private final String VIEW_USER = "user"; 
    private final String VIEW_ROLES = "roles";
    private final String VIEW_GROUPS = "groups";
    private final String VIEW_RULES = "rules";
    private final String VIEW_CREDENTIAL = "credential"; 
    private final String VIEW_ALL_RULES = "prules";
    private final String VIEW_SELECTED_RULE = "selectedRule";
    
    private final String USER_ACTION_PREFIX = "security_user.";
    private final String ACTION_UPDATE_ATTRIBUTE = "update_user_attribute";
    private final String ACTION_REMOVE_ATTRIBUTE = "remove_user_attribute";
    private final String ACTION_ADD_ATTRIBUTE = "add_user_attribute";
    private final String ACTION_REMOVE_ROLE = "remove_user_role";
    private final String ACTION_ADD_ROLE = "add_user_role";
    private final String ACTION_REMOVE_GROUP = "remove_user_group";
    private final String ACTION_ADD_GROUP = "add_user_group";
    private final String ACTION_REMOVE_RULE = "remove_user_rule";
    private final String ACTION_ADD_RULE = "add_rule";
    private final String ACTION_UPDATE_CREDENTIAL = "update_user_credential";
    
    private final String TAB_ATTRIBUTES = "user_attributes";
    private final String TAB_ROLE = "user_role";
    private final String TAB_GROUP = "user_group";
    private final String TAB_PROFILE = "user_profile";
    private final String TAB_CREDENTIAL = "user_credential";
    
    /** the id of the roles control */
    private static final String ROLES_CONTROL = "jetspeedRoles";

    /** the id of the groups control */
    private static final String GROUPS_CONTROL = "jetspeedGroups";

    /** The Error Messages KEY */
    public static final String ERROR_MESSAGES = "errorMessages";
    
    private UserManager  userManager;
    private RoleManager  roleManager;
    private GroupManager groupManager;
    private Profiler     profiler;

    private LinkedHashMap userTabMap = new LinkedHashMap();
    private LinkedHashMap anonymousUserTabMap = new LinkedHashMap();
    
    public void init(PortletConfig config)
    throws PortletException 
    {
        super.init(config);
        userManager = (UserManager)getPortletContext().getAttribute(SecurityResources.CPS_USER_MANAGER_COMPONENT);
        if (null == userManager)
        {
            throw new PortletException("Failed to find the User Manager on portlet initialization");
        }
        roleManager = (RoleManager)getPortletContext().getAttribute(SecurityResources.CPS_ROLE_MANAGER_COMPONENT);
        if (null == roleManager)
        {
            throw new PortletException("Failed to find the Role Manager on portlet initialization");
        }
        groupManager = (GroupManager)getPortletContext().getAttribute(SecurityResources.CPS_GROUP_MANAGER_COMPONENT);
        if (null == groupManager)
        {
            throw new PortletException("Failed to find the Group Manager on portlet initialization");
        }
        profiler = (Profiler)getPortletContext().getAttribute(SecurityResources.CPS_PROFILER_COMPONENT);
        if (null == profiler)
        {
            throw new PortletException("Failed to find the Profiler on portlet initialization");
        }
        
        TabBean tb1 = new TabBean(TAB_ATTRIBUTES);
        TabBean tb2 = new TabBean(TAB_ROLE);
        TabBean tb3 = new TabBean(TAB_GROUP);
        TabBean tb4 = new TabBean(TAB_PROFILE);
        TabBean tb5 = new TabBean(TAB_CREDENTIAL);
        
        userTabMap.put(tb1.getId(), tb1);
        userTabMap.put(tb5.getId(), tb5);
        userTabMap.put(tb2.getId(), tb2);
        userTabMap.put(tb3.getId(), tb3); 
        userTabMap.put(tb4.getId(), tb4);
        
        anonymousUserTabMap.put(tb1.getId(), tb1);
        anonymousUserTabMap.put(tb2.getId(), tb2);
        anonymousUserTabMap.put(tb3.getId(), tb3);
        anonymousUserTabMap.put(tb4.getId(), tb4);
    }
    
    public void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException
    {
        response.setContentType("text/html");
        
        String userName = (String)
            request.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                         PortletSession.APPLICATION_SCOPE);

        User user = null;
        if (userName != null)
        {
            // TODO: don't lookup with every view call
            user = lookupUser(userName);
        }
        
        if (user != null)
        {       
            LinkedHashMap tabMap = null;
            if ( userManager.getAnonymousUser().equals(userName) )
            {
                tabMap = anonymousUserTabMap;
            }
            else
            {
                tabMap = userTabMap;
            }
            
            // Tabs
            request.setAttribute("tabs", tabMap.values());        
            TabBean selectedTab = 
                (TabBean) request.getPortletSession().getAttribute(SecurityResources.REQUEST_SELECT_TAB);

            if(selectedTab != null && !tabMap.containsKey(selectedTab.getId()))
            {
                selectedTab = null;
            }
            
            if(selectedTab == null)
            {
                selectedTab = (TabBean) tabMap.values().iterator().next();
            }
            JetspeedUserBean bean = new JetspeedUserBean(user);
            request.setAttribute(VIEW_USER, bean);
            if (selectedTab.getId().equals(TAB_ROLE))
            {                
                Collection userRoles = getRoles(userName);
                request.setAttribute(VIEW_ROLES, userRoles );
                
                // check for refresh on roles list
                String refreshRoles = (String)PortletMessaging.consume(request, SecurityResources.USER_BROWSER, "roles");
                List roles = null;
                if (refreshRoles == null)
                {        
                    roles = (List) request.getPortletSession().getAttribute(ROLES_CONTROL);
                }
                
                // build the roles control and provide it to the view
                try
                {
                    if (roles == null)
                    {
                        roles = new LinkedList();
                        Iterator fullRoles = roleManager.getRoles("");
                        while (fullRoles.hasNext())
                        {
                            Role role = (Role)fullRoles.next();
                            roles.add(role.getPrincipal().getName());
                        }
                        request.getPortletSession().setAttribute(ROLES_CONTROL, roles);
                    }
                }
                catch (SecurityException se)
                {
                    throw new PortletException(se);
                }
                ArrayList selectableRoles = new ArrayList(roles);
                Iterator rolesIter = userRoles.iterator();
                while ( rolesIter.hasNext() )
                {
                    Role role = (Role)rolesIter.next();
                    int index = selectableRoles.indexOf(role.getPrincipal().getName());
                    if (index != -1)
                    {
                        selectableRoles.remove(index);
                    }
                }
                request.setAttribute(ROLES_CONTROL, selectableRoles);
                
            }
            else if (selectedTab.getId().equals(TAB_GROUP))
            {
                Collection userGroups = getGroups(userName);
                request.setAttribute(VIEW_GROUPS, userGroups);
                
                // check for refresh on groups list
                String refreshGroups = (String)PortletMessaging.consume(request, SecurityResources.USER_BROWSER, "groups");
                List groups = null;
                if (refreshGroups == null)
                {        
                    groups = (List) request.getPortletSession().getAttribute(GROUPS_CONTROL);
                }
                
                // build the groups control and provide it to the view
                try
                {
                    if (groups == null)
                    {
                        groups = new LinkedList();
                        Iterator fullGroups = groupManager.getGroups("");
                        while (fullGroups.hasNext())
                        {
                            Group group = (Group)fullGroups.next();
                            groups.add(group.getPrincipal().getName());
                        }
                        request.getPortletSession().setAttribute(GROUPS_CONTROL, groups);
                    }
                }
                catch (SecurityException se)
                {
                    throw new PortletException(se);
                }        
                ArrayList selectableGroups = new ArrayList(groups);
                Iterator groupsIter = userGroups.iterator();
                while ( groupsIter.hasNext() )
                {
                    Group group = (Group)groupsIter.next();
                    int index = selectableGroups.indexOf(group.getPrincipal().getName());
                    if (index != -1)
                    {
                        selectableGroups.remove(index);
                    }
                }
                request.setAttribute(GROUPS_CONTROL, selectableGroups);
                
            }
            else if (selectedTab.getId().equals(TAB_PROFILE))
            {
                request.setAttribute(VIEW_RULES, getRules(user));
                request.setAttribute(VIEW_ALL_RULES, getProfilerRules());
            }
            else if (selectedTab.getId().equals(TAB_CREDENTIAL))
            {
                request.setAttribute(VIEW_CREDENTIAL, getCredential(userName));
            }
           
            request.setAttribute(SecurityResources.REQUEST_SELECT_TAB, selectedTab);
        }

        // check for ErrorMessages
        ArrayList errorMessages = (ArrayList)PortletMessaging.consume(request, ERROR_MESSAGES);
        if (errorMessages != null )
        {
            request.setAttribute(ERROR_MESSAGES,errorMessages);
        }
        
        super.doView(request, response);
    }

    public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) 
        throws PortletException, IOException
    {                        
        String selectedTab = actionRequest.getParameter(SecurityResources.REQUEST_SELECT_TAB);
        if (selectedTab != null)
        {
            TabBean tab = (TabBean) userTabMap.get(selectedTab);
            if (tab != null)
            {
                actionRequest.getPortletSession().setAttribute(
                        SecurityResources.REQUEST_SELECT_TAB, tab);
            }            
        }             
        String action = actionRequest.getParameter(SecurityResources.PORTLET_ACTION);
        if (action != null && action.equals("remove.user"))
        {
            removeUser(actionRequest, actionResponse);
        }
        else if (action != null && isUserPortletAction(action))
        {
            action = getAction(USER_ACTION_PREFIX, action);                
            if (action.endsWith(ACTION_UPDATE_ATTRIBUTE))
            {
                updateUserAttribute(actionRequest, actionResponse);
            }
            else if (action.endsWith(ACTION_REMOVE_ATTRIBUTE))
            {
                removeUserAttributes(actionRequest, actionResponse);
            }
            else if (action.endsWith(ACTION_ADD_ATTRIBUTE))
            {
                addUserAttribute(actionRequest, actionResponse);
            }
            else if (action.endsWith(ACTION_REMOVE_ROLE))
            {
                removeUserRoles(actionRequest, actionResponse);
            }
            else if (action.endsWith(ACTION_ADD_ROLE))
            {
                addUserRole(actionRequest, actionResponse);
            }
            else if (action.endsWith(ACTION_REMOVE_GROUP))
            {
                removeUserGroups(actionRequest, actionResponse);
            }
            else if (action.endsWith(ACTION_ADD_GROUP))
            {
                addUserGroup(actionRequest, actionResponse);
            }
            else if (action.endsWith(this.ACTION_ADD_RULE))
            {
                addUserProfile(actionRequest, actionResponse);
            }
            else if (action.endsWith(this.ACTION_REMOVE_RULE))
            {
                removeUserProfile(actionRequest, actionResponse);
            }
            else if (action.endsWith(this.ACTION_UPDATE_CREDENTIAL))
            {
                updateUserCredential(actionRequest, actionResponse);
            }
        }
    }
    
    private void publishErrorMessage(PortletRequest request, String message)
    {
        try
        {
            ArrayList errors = (ArrayList)PortletMessaging.receive(request,ERROR_MESSAGES);
            if ( errors == null )
            {
                errors = new ArrayList();
            }
            errors.add(message);
            PortletMessaging.publish(request, ERROR_MESSAGES, errors);
        }
        catch (NotSerializableException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }                
    }
    
    public void removeUser(ActionRequest actionRequest, ActionResponse actionResponse) 
    throws PortletException
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                             PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            try
            {
                userManager.removeUser(userName);
                PortletMessaging.publish(actionRequest, "users", "refresh", "all");
            }
            catch (Exception e)
            {
                publishErrorMessage(actionRequest,e.getMessage());
            }
        }
    }
    
    public Principal createPrincipal(Subject subject, Class classe)
    {
        Principal principal = null;
        Iterator principals = subject.getPrincipals().iterator();
        while (principals.hasNext())
        {
            Principal p = (Principal) principals.next();
            if (classe.isInstance(p))
            {
                principal = p;
                break;
            }
        }
        return principal;
    }    

    private void updateUserCredential(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        ResourceBundle bundle = ResourceBundle.getBundle("org.apache.jetspeed.portlets.security.resources.UsersResources",actionRequest.getLocale());

        String userName = (String)
        actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                             PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            try
            {
                String password = actionRequest.getParameter("user_cred_value");
                boolean updated = false;
                if ( password != null && password.trim().length() > 0 )
                {
                    userManager.setPassword(userName, null, password);
                    updated = true;
                }
                PasswordCredential credential = getCredential(userName);
                if ( credential != null )
                {
                    String updateRequiredStr = actionRequest.getParameter("user_cred_updreq");
                    if (updateRequiredStr != null)
                    {
                        boolean updateRequired = Boolean.valueOf(updateRequiredStr).booleanValue();
                        if (updateRequired != credential.isUpdateRequired())
                        {
                            userManager.setPasswordUpdateRequired(userName,updateRequired);
                            updated = true;
                        }
                    }
                    String enabledStr = actionRequest.getParameter("user_cred_enabled");
                    if (enabledStr != null)
                    {
                        boolean enabled = Boolean.valueOf(enabledStr).booleanValue();
                        if (enabled != credential.isEnabled())
                        {
                            userManager.setPasswordEnabled(userName,enabled);
                            updated = true;
                        }
                    }
                }
            }
            catch ( InvalidPasswordException ipe )
            {
                publishErrorMessage(actionRequest,bundle.getString("chgpwd.error.invalidPassword"));
            }
            catch ( InvalidNewPasswordException inpe )
            {
                publishErrorMessage(actionRequest,bundle.getString("chgpwd.error.invalidNewPassword"));
            }
            catch ( PasswordAlreadyUsedException paue )
            {
                publishErrorMessage(actionRequest,bundle.getString("chgpwd.error.passwordAlreadyUsed"));
            }
            catch (SecurityException e)
            {
                publishErrorMessage(actionRequest,e.getMessage());
            }
        }
    }
    
    private void updateUserAttribute(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                 PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            String[] userAttrNames = actionRequest.getParameterValues("user_attr_id");
            if(userAttrNames != null)
            {                
                for (int i=0; i<userAttrNames.length; i++)
                {
                    String userAttrName = userAttrNames[i];
                    String value = actionRequest.getParameter(userAttrName + ":value");
                    user.getUserAttributes().put(userAttrName, value);
                }                
            }        
        }
    }
    
    private void addUserAttribute(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        
        User user = lookupUser(userName);
        if (user != null)
        {
            String userAttrName = actionRequest.getParameter("user_attr_name");
            String userAttrValue = actionRequest.getParameter("user_attr_value");
            if (userAttrName != null && userAttrName.trim().length() > 0)
            {
                Preferences attributes = user.getUserAttributes();
                attributes.put(userAttrName, userAttrValue);
            }
        }
    }

    private void removeUserAttributes(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        List deletes = new LinkedList();
        
        User user = lookupUser(userName);
        if (user != null)
        {
            String[] userAttrNames = actionRequest.getParameterValues("user_attr_id");

            if(userAttrNames != null)
            {
                JetspeedUserBean bean = new JetspeedUserBean(user);
                Preferences attributes = user.getUserAttributes();
                Iterator userAttrIter = bean.getAttributes().iterator();
                while (userAttrIter.hasNext())
                {
                    StringAttribute userAttr = (StringAttribute) userAttrIter.next();
                    for(int ix = 0; ix < userAttrNames.length; ix++)
                    {
                        String userAttrName = userAttrNames[ix];
                        if(userAttr.getName().equals(userAttrName))
                        {
                            deletes.add(userAttrName);
                            break;
                        }
                    }
                }
                Iterator it = deletes.iterator();            
                while (it.hasNext())
                {
                    String attribute = (String)it.next();
                    attributes.remove(attribute);
                }
                
            }            
        }
    }
    
    private void removeUserRoles(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            String[] roleNames = actionRequest.getParameterValues("user_role_id");

            if(roleNames != null)
            {
                for (int ix = 0; ix < roleNames.length; ix++)
                {
                    try
                    {
                        if (roleManager.roleExists(roleNames[ix]))
                        {
                            roleManager.removeRoleFromUser(userName, roleNames[ix]);
                        }
                    }
                    catch (SecurityException e)
                    {
                        publishErrorMessage(actionRequest,e.getMessage());
                        // TODO: logging
                        System.err.println("failed to remove user from role: " + userName + ", "  + roleNames[ix] + e);                       
                    }                
                }
            }            
        }
    }    
    
    private void addUserRole(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        
        User user = lookupUser(userName);
        if (user != null)
        {
            String roleName = actionRequest.getParameter("role_name");
            if (roleName != null && roleName.trim().length() > 0)
            {
                try
                {
                    roleManager.addRoleToUser(userName, roleName);
                }
                catch (SecurityException e)
                {
                    publishErrorMessage(actionRequest,e.getMessage());
                    // TODO: logging
                    System.err.println("failed to add user to role: " + userName + ", "  + roleName + e);                       
                }
            }
        }
    }
    
    private void removeUserGroups(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            String[] groupNames = actionRequest.getParameterValues("user_group_id");

            if(groupNames != null)
            {
                for (int ix = 0; ix < groupNames.length; ix++)
                {
                    try
                    {
                        if (groupManager.groupExists(groupNames[ix]))
                        {
                            groupManager.removeUserFromGroup(userName, groupNames[ix]);
                        }
                    }
                    catch (SecurityException e)
                    {
                        publishErrorMessage(actionRequest,e.getMessage());
                        // TODO: logging
                        System.err.println("failed to remove user from group: " + userName + ", "  + groupNames[ix] + e);                       
                    }                
                }
            }            
        }
    }    
    
    private void addUserGroup(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        
        User user = lookupUser(userName);
        if (user != null)
        {
            String groupName = actionRequest.getParameter("group_name");
            if (groupName != null && groupName.trim().length() > 0)
            {
                try
                {
                    groupManager.addUserToGroup(userName, groupName);
                }
                catch (SecurityException e)
                {
                    publishErrorMessage(actionRequest,e.getMessage());
                    // TODO: logging
                    System.err.println("failed to add user to group: " + userName + ", "  + groupName + e);                       
                }
            }
        }
    }
        
    private String getAction(String prefix, String action)
    {
        return action.substring(prefix.length());
    }

    private boolean isUserPortletAction(String action)
    {
        return action.startsWith(USER_ACTION_PREFIX);
    }
    
    private Collection getRoles(String userName)
    {
        try
        {
            return roleManager.getRolesForUser(userName); 
        }
        catch (SecurityException e)
        {
            // TODO: logging
            System.err.println("roles not found: " + userName + ", " + e);       
        }
        return new LinkedList();
    }
    
    private Collection getGroups(String userName)
    {
        try
        {
            return groupManager.getGroupsForUser(userName); 
        }
        catch (SecurityException e)
        {
            // TODO: logging
            System.err.println("groups not found: " + userName + ", " + e);       
        }
        return new LinkedList();
    }
    
    private PasswordCredential getCredential(String userName)
    {
        PasswordCredential credential = null;
        Set credentials = lookupUser(userName).getSubject().getPrivateCredentials();
        Iterator iter = credentials.iterator();
        while (iter.hasNext())
        {
            Object o = iter.next();
            if (o instanceof PasswordCredential)
            {
                credential = (PasswordCredential)o;
                break;
            }
        }
        return credential;
    }
    
    private User lookupUser(String userName)
    {
        User user = null;
        try
        {
            user = userManager.getUser(userName);
        }
        catch (Exception e)
        {
            // TODO: logging
            System.err.println("user not found: " + userName + ", " + e);
        }    
        return user;
    }
    
    private Collection getProfilerRules()
    {        
        return profiler.getRules();
    }
    
    private Collection getRules(User user)
    {
        Principal userPrincipal = createPrincipal(user.getSubject(), UserPrincipal.class);
        return profiler.getRulesForPrincipal(userPrincipal);
    }

    private void addUserProfile(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            String locatorName = actionRequest.getParameter("locator_name");
            if (locatorName != null && locatorName.trim().length() > 0)
            {
                try
                {
                    Principal userPrincipal = createPrincipal(user.getSubject(), UserPrincipal.class);                          
                    String ruleName = actionRequest.getParameter("select_rule");
                    profiler.setRuleForPrincipal(userPrincipal, 
                            profiler.getRule(ruleName),
                            locatorName);                                                         
                }
                catch (Exception e)
                {
                    publishErrorMessage(actionRequest,e.getMessage());
                    // TODO: logging
                    System.err.println("failed to set rule for principal: " + userName + ", "  + locatorName + e);                       
                }
            }
            
        }
    }
    
    private void removeUserProfile(ActionRequest actionRequest, ActionResponse actionResponse)
    {
        String userName = (String)
            actionRequest.getPortletSession().getAttribute(SecurityResources.PAM_CURRENT_USER, 
                                     PortletSession.APPLICATION_SCOPE);
        User user = lookupUser(userName);
        if (user != null)
        {
            String[] locatorNames = actionRequest.getParameterValues("user_profile_id");

            if(locatorNames != null)
            {
                Principal userPrincipal = createPrincipal(user.getSubject(), UserPrincipal.class);                                              
                Collection rules = profiler.getRulesForPrincipal(userPrincipal);
                for (int ix = 0; ix < locatorNames.length; ix++)
                {
                    try
                    {
                        Iterator it = rules.iterator();
                        while (it.hasNext())
                        {
                            PrincipalRule rule = (PrincipalRule)it.next();
                            if (rule.getLocatorName().equals(locatorNames[ix]))
                            {
                                profiler.deletePrincipalRule(rule);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        publishErrorMessage(actionRequest,e.getMessage());
                        // TODO: logging
                        System.err.println("failed to remove rule for principal: " + userName + ", "  + locatorNames[ix] + e);                       
                    }                
                }
            }                                    
        }
    }        
}
