head	1.72;
access;
symbols
	TIGRIS_1_1_0RC2:1.41.2.1.4.3
	TIGRIS_1_1_0RC1:1.41.2.1.4.3
	TIGRIS_1_1:1.41.2.1.4.3.0.2
	TIGRIS_1_0_8:1.41.2.1.4.2
	TIGRIS_1_0_8RC3:1.41.2.1.4.2
	TIGRIS_1_0_8RC2:1.41.2.1.4.2
	TIGRIS_1_0_8RC1:1.41.2.1.4.2
	TIGRIS_1_0_7:1.41.2.1.4.2
	TIGRIS_1_0_7RC3:1.41.2.1.4.2
	TIGRIS_1_0_7RC2:1.41.2.1.4.2
	TIGRIS_1_0_7RC1:1.41.2.1.4.2
	TIGRIS_1_0_6:1.41.2.1.4.2
	TIGRIS_1_0_6RC5:1.41.2.1.4.2
	TIGRIS_1_0_6RC4:1.41.2.1.4.2
	TIGRIS_1_0_6RC3:1.41.2.1.4.2
	TIGRIS_1_0_6RC2:1.41.2.1.4.2
	TIGRIS_1_0_6RC1:1.41.2.1.4.2
	TIGRIS_1_0_5:1.41.2.1.4.2
	TIGRIS_1_0_5RC6:1.41.2.1.4.2
	TIGRIS_1_0_5RC5:1.41.2.1.4.2
	TIGRIS_1_0_5RC4:1.41.2.1.4.2
	TIGRIS_1_0_5RC3:1.41.2.1.4.2
	TIGRIS_1_0_5RC2:1.41.2.1.4.2
	TIGRIS_1_0_5RC1:1.41.2.1.4.2
	TIGRIS_1_0_4:1.41.2.1.4.2
	TIGRIS_1_0_3:1.41.2.1.4.2
	TIGRIS_1_0_2:1.41.2.1
	TIGRIS_1_0_1:1.41.2.1
	TIGRIS_1_0:1.41.2.1.0.4
	TIGRIS_1_0_0:1.41.2.1
	TIGRIS_1_0_0_RC1:1.41.0.2
	dlr:1.1.1
	TIGRIS_0_9_2_4:1.21
	TIGRIS_0_9_2_3:1.21
	HELM_PEER_PORT_BRANCH:1.1.1.2
	TURBINE_PEER:1.26
	TIGRIS_0_9_2_1:1.26
	TIGRIS_0_9_2:1.21.0.2
	TIGRIS_0_9_0:1.13.0.2
	TIGRIS_0_8_4:1.8.0.2
	NEWHELM:1.1.1.1
	TIGRIS_NOV_12_2000:1.1.1;
locks; strict;
comment	@# @;


1.72
date	2001.08.11.09.08.08;	author dlr;	state Exp;
branches;
next	1.71;

1.71
date	2001.08.10.20.10.59;	author leonardr;	state Exp;
branches;
next	1.70;

1.70
date	2001.07.30.21.25.13;	author leonardr;	state Exp;
branches;
next	1.69;

1.69
date	2001.07.19.18.42.22;	author dlr;	state Exp;
branches;
next	1.68;

1.68
date	2001.07.02.21.41.46;	author leonardr;	state Exp;
branches;
next	1.67;

1.67
date	2001.06.18.22.12.21;	author leonardr;	state Exp;
branches;
next	1.66;

1.66
date	2001.06.01.21.28.32;	author leonardr;	state Exp;
branches;
next	1.65;

1.65
date	2001.05.30.14.46.47;	author leonardr;	state Exp;
branches;
next	1.64;

1.64
date	2001.05.30.01.11.12;	author leonardr;	state Exp;
branches;
next	1.63;

1.63
date	2001.05.25.23.04.01;	author leonardr;	state Exp;
branches;
next	1.62;

1.62
date	2001.05.23.01.50.20;	author dlr;	state Exp;
branches;
next	1.61;

1.61
date	2001.05.23.00.35.00;	author leonardr;	state Exp;
branches;
next	1.60;

1.60
date	2001.05.22.00.14.19;	author leonardr;	state Exp;
branches;
next	1.59;

1.59
date	2001.05.11.19.38.55;	author leonardr;	state Exp;
branches;
next	1.58;

1.58
date	2001.04.25.22.37.51;	author dlr;	state Exp;
branches;
next	1.57;

1.57
date	2001.04.25.21.58.29;	author dlr;	state Exp;
branches;
next	1.56;

1.56
date	2001.04.25.21.47.39;	author dlr;	state Exp;
branches;
next	1.55;

1.55
date	2001.04.25.21.45.26;	author dlr;	state Exp;
branches;
next	1.54;

1.54
date	2001.04.20.21.40.28;	author leonardr;	state Exp;
branches;
next	1.53;

1.53
date	2001.04.20.16.13.01;	author leonardr;	state Exp;
branches;
next	1.52;

1.52
date	2001.04.18.22.39.19;	author dlr;	state Exp;
branches;
next	1.51;

1.51
date	2001.04.12.18.49.01;	author leonardr;	state Exp;
branches;
next	1.50;

1.50
date	2001.04.11.21.09.58;	author dlr;	state Exp;
branches;
next	1.49;

1.49
date	2001.04.11.21.01.21;	author dlr;	state Exp;
branches;
next	1.48;

1.48
date	2001.04.11.16.28.50;	author leonardr;	state Exp;
branches;
next	1.47;

1.47
date	2001.04.05.18.28.54;	author leonardr;	state Exp;
branches;
next	1.46;

1.46
date	2001.04.05.18.27.15;	author leonardr;	state Exp;
branches;
next	1.45;

1.45
date	2001.04.05.17.32.54;	author leonardr;	state Exp;
branches;
next	1.44;

1.44
date	2001.04.04.02.51.35;	author leonardr;	state Exp;
branches;
next	1.43;

1.43
date	2001.04.04.01.20.47;	author leonardr;	state Exp;
branches;
next	1.42;

1.42
date	2001.04.04.00.49.17;	author leonardr;	state Exp;
branches;
next	1.41;

1.41
date	2001.03.24.00.14.15;	author leonardr;	state Exp;
branches
	1.41.2.1;
next	1.40;

1.40
date	2001.03.21.23.26.58;	author dlr;	state Exp;
branches;
next	1.39;

1.39
date	2001.03.20.02.09.13;	author leonardr;	state Exp;
branches;
next	1.38;

1.38
date	2001.03.19.19.14.15;	author leonardr;	state Exp;
branches;
next	1.37;

1.37
date	2001.03.19.18.20.33;	author leonardr;	state Exp;
branches;
next	1.36;

1.36
date	2001.03.15.23.50.07;	author dlr;	state Exp;
branches;
next	1.35;

1.35
date	2001.03.14.22.48.44;	author dlr;	state Exp;
branches;
next	1.34;

1.34
date	2001.03.12.21.40.44;	author dlr;	state Exp;
branches;
next	1.33;

1.33
date	2001.03.09.01.24.23;	author leonardr;	state Exp;
branches;
next	1.32;

1.32
date	2001.03.07.02.38.37;	author leonardr;	state Exp;
branches;
next	1.31;

1.31
date	2001.03.07.02.23.07;	author leonardr;	state Exp;
branches;
next	1.30;

1.30
date	2001.03.07.01.53.27;	author lucas;	state Exp;
branches;
next	1.29;

1.29
date	2001.02.23.21.19.19;	author leonardr;	state Exp;
branches;
next	1.28;

1.28
date	2001.02.22.18.08.29;	author leonardr;	state Exp;
branches;
next	1.27;

1.27
date	2001.02.21.01.08.25;	author dlr;	state Exp;
branches;
next	1.26;

1.26
date	2001.01.26.18.29.08;	author edk;	state Exp;
branches
	1.26.2.1;
next	1.25;

1.25
date	2001.01.26.05.24.07;	author edk;	state dead;
branches;
next	1.24;

1.24
date	2001.01.24.21.41.50;	author leonardr;	state Exp;
branches;
next	1.23;

1.23
date	2001.01.24.20.42.49;	author dlr;	state Exp;
branches;
next	1.22;

1.22
date	2001.01.23.20.38.00;	author leonardr;	state Exp;
branches;
next	1.21;

1.21
date	2001.01.15.19.14.23;	author leonardr;	state Exp;
branches;
next	1.20;

1.20
date	2001.01.15.18.28.52;	author leonardr;	state Exp;
branches;
next	1.19;

1.19
date	2001.01.11.17.20.19;	author leonardr;	state Exp;
branches;
next	1.18;

1.18
date	2001.01.05.21.42.39;	author leonardr;	state Exp;
branches;
next	1.17;

1.17
date	2001.01.05.01.10.56;	author dlr;	state Exp;
branches;
next	1.16;

1.16
date	2000.12.28.01.44.45;	author leonardr;	state Exp;
branches;
next	1.15;

1.15
date	2000.12.27.23.12.35;	author leonardr;	state Exp;
branches;
next	1.14;

1.14
date	2000.12.23.00.48.19;	author dlr;	state Exp;
branches;
next	1.13;

1.13
date	2000.12.14.03.04.17;	author edk;	state Exp;
branches;
next	1.12;

1.12
date	2000.12.13.02.57.37;	author leonardr;	state Exp;
branches;
next	1.11;

1.11
date	2000.12.07.02.21.33;	author leonardr;	state Exp;
branches;
next	1.10;

1.10
date	2000.12.06.23.02.10;	author leonardr;	state Exp;
branches;
next	1.9;

1.9
date	2000.12.05.00.26.41;	author dlr;	state Exp;
branches;
next	1.8;

1.8
date	2000.11.29.01.16.33;	author leonardr;	state Exp;
branches;
next	1.7;

1.7
date	2000.11.17.02.43.31;	author leonardr;	state Exp;
branches;
next	1.6;

1.6
date	2000.11.15.00.34.56;	author leonardr;	state Exp;
branches;
next	1.5;

1.5
date	2000.11.14.22.57.48;	author leonardr;	state Exp;
branches;
next	1.4;

1.4
date	2000.11.14.00.43.42;	author leonardr;	state Exp;
branches;
next	1.3;

1.3
date	2000.11.14.00.08.36;	author leonardr;	state Exp;
branches;
next	1.2;

1.2
date	2000.11.13.22.39.52;	author leonardr;	state Exp;
branches;
next	1.1;

1.1
date	2000.11.12.21.16.37;	author dlr;	state Exp;
branches
	1.1.1.1;
next	;

1.1.1.1
date	2000.11.12.21.16.37;	author dlr;	state Exp;
branches;
next	1.1.1.2;

1.1.1.2
date	2001.02.21.00.35.10;	author dlr;	state Exp;
branches;
next	;

1.26.2.1
date	2001.01.28.01.02.19;	author dlr;	state dead;
branches;
next	1.26.2.2;

1.26.2.2
date	2001.01.28.01.18.28;	author dlr;	state Exp;
branches;
next	1.26.2.3;

1.26.2.3
date	2001.01.29.20.50.03;	author leonardr;	state Exp;
branches;
next	1.26.2.4;

1.26.2.4
date	2001.01.29.21.10.43;	author dlr;	state Exp;
branches;
next	1.26.2.5;

1.26.2.5
date	2001.01.30.01.21.06;	author leonardr;	state Exp;
branches;
next	1.26.2.6;

1.26.2.6
date	2001.01.30.21.38.43;	author leonardr;	state Exp;
branches;
next	1.26.2.7;

1.26.2.7
date	2001.01.30.23.56.38;	author leonardr;	state Exp;
branches;
next	1.26.2.8;

1.26.2.8
date	2001.01.31.01.18.27;	author leonardr;	state Exp;
branches;
next	1.26.2.9;

1.26.2.9
date	2001.01.31.01.48.23;	author leonardr;	state Exp;
branches;
next	1.26.2.10;

1.26.2.10
date	2001.01.31.02.40.42;	author leonardr;	state Exp;
branches;
next	1.26.2.11;

1.26.2.11
date	2001.02.01.02.57.47;	author leonardr;	state Exp;
branches;
next	1.26.2.12;

1.26.2.12
date	2001.02.01.18.03.00;	author leonardr;	state Exp;
branches;
next	1.26.2.13;

1.26.2.13
date	2001.02.01.20.40.24;	author leonardr;	state Exp;
branches;
next	1.26.2.14;

1.26.2.14
date	2001.02.01.21.25.07;	author dlr;	state Exp;
branches;
next	1.26.2.15;

1.26.2.15
date	2001.02.07.19.49.33;	author leonardr;	state Exp;
branches;
next	1.26.2.16;

1.26.2.16
date	2001.02.08.16.07.44;	author leonardr;	state Exp;
branches;
next	1.26.2.17;

1.26.2.17
date	2001.02.09.18.03.16;	author leonardr;	state Exp;
branches;
next	1.26.2.18;

1.26.2.18
date	2001.02.12.16.19.02;	author leonardr;	state Exp;
branches;
next	1.26.2.19;

1.26.2.19
date	2001.02.12.17.09.40;	author leonardr;	state Exp;
branches;
next	1.26.2.20;

1.26.2.20
date	2001.02.14.01.38.53;	author leonardr;	state Exp;
branches;
next	1.26.2.21;

1.26.2.21
date	2001.02.15.20.50.43;	author leonardr;	state Exp;
branches;
next	1.26.2.22;

1.26.2.22
date	2001.02.16.03.01.34;	author dlr;	state Exp;
branches;
next	;

1.41.2.1
date	2001.04.05.17.43.49;	author dlr;	state Exp;
branches
	1.41.2.1.4.1;
next	;

1.41.2.1.4.1
date	2001.04.26.00.32.02;	author leonardr;	state Exp;
branches;
next	1.41.2.1.4.2;

1.41.2.1.4.2
date	2001.04.26.00.45.35;	author leonardr;	state Exp;
branches;
next	1.41.2.1.4.3;

1.41.2.1.4.3
date	2001.07.17.18.59.23;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.72
log
@Upgrading to Turbine 3.0-dev, Fulcrum 1.0, and Torque 1.0.
@
text
@/* ================================================================
 * Copyright (c) 2000-2001 CollabNet.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet (http://www.collab.net/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */

package org.tigris.helm.security;

import java.util.*;

import gnu.regexp.RE;
import gnu.regexp.REException;

import org.apache.commons.util.BufferCache;

import org.apache.torque.util.Criteria;

import org.tigris.helm.DoesNotExist;
import org.tigris.helm.om.*;
import org.tigris.helm.security.ACLException;
import org.tigris.helm.tool.HelmProperties;
import org.tigris.helm.tool.cache.SimpleRegisterableCache;
import org.tigris.helm.tool.cache.TableTrackingBufferCache;
import org.apache.turbine.util.Log;

/**
 * Provides permission checking.  A permission is defined as an action plus a 
 * resource.
 * <p>
 * ACLs are checked in two places: 
 * <ul>
 * <li>business logic to determine if an action is permitted</li>
 * <li>presentation layer to decide what do display</li>
 * </ul>
 *
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 * @@version $Id: AccessControlList.java,v 1.71 2001/08/10 20:10:59 leonardr Exp $
 */
public class AccessControlList
{
    /**
     * Whether to log debugging information.
     */
    private static final boolean DEBUG = false;

    /**
     * Whether to log timing information.
     */
    private static final boolean TIMING_DEBUG = false;

    /**
     * How many permission checks to cache.
     */
    private static final int RECENT_CHECKS_TO_HOLD = 128;

    /**
     * ACLs for users.
     */
    private static ACLCache userACLs;

    /**
     * BufferCache containing the results of recently done permission
     * checks.  
     */
    private BufferCache recentChecks;

    /**
     * The user whose ACL this is.
     */
    private User user;

    /**
     * The user-specific portion of the ACL: a Map keyed by 
     * Project to Lists of Roles.
     */
    private Map originalRolesByProject;

    /**
     * Another Map like rolesByProject, but containing roles the user
     * has in projects due to their presence in project groups and as
     * subprojects of other projects. 
     */
    private Map derivedRolesByProject;

    /**
     * Indicates that a role is original (granted directly to a project)
     */
    private static final boolean ORIGINAL = true;

    /**
     * Indicates that a role is derived (granted to a project which
     * contains another project)
     */
    private static final boolean DERIVED = false; 
    
    /**
     * A mapping of projects to booleans; the presence of a project
     * in this Map means that the roles this user has in the
     * project have been distributed (as derived roles) across the
     * subprojects.
     */
    private Set expandedProjects;

    static
    {
        try
        {
            userACLs = new ACLCache();
        }
        catch (Exception e)
        {
            throw new RuntimeException(e.getMessage());
        }

    }

    /**
     * Gets the ACL for the root user.
     */
    public final static AccessControlList getSuperUserACL()
        throws Exception
    {
        return getACL(UserPeer.getSuperUser());
    }
              
    /**
     * Gets the (possibly cached) ACL for the given user. 
     */
    public synchronized static AccessControlList getACL(User user)
        throws Exception
    {
        AccessControlList acl;
        Map cache = userACLs.getCache();
        if (cache.containsKey(user)) 
        {
            acl = (AccessControlList)cache.get(user);
        }
        else 
        {
            acl = rebuildACL(user);
        }
        return acl;
    }

    /**
     * Rebuilds the ACL for the given userID, 
     */
    public static AccessControlList rebuildACL(User user)
        throws Exception
    {
        AccessControlList acl = null;
        Map cache = userACLs.getCache();
        synchronized(cache)
        {
            acl = new AccessControlList(user);
            cache.put(user, acl);
        }
        return acl;
    }
    
    /**
     * Instantiates a new ACL for the specified user.
     *
     * @@param user  The user whose ACL is desired.
     *
     * @@exception Exception     Generic database error.
     */
    protected AccessControlList (User user)
        throws Exception
    {
        recentChecks = new BufferCache(RECENT_CHECKS_TO_HOLD);
        this.user = user;
        this.originalRolesByProject = new HashMap();
        this.derivedRolesByProject = new HashMap();
        constructOriginalRolesByProject();
        expandedProjects = new HashSet();
        dump();                
    }

    /**
     * Get the ID of the user whose ACL this is.
     *
     * return A user ID.
     */
    public String getUserID()
    {
        return user.getID();
    }

    /**
     * Get the User whose ACL this is.
     *
     * return A User object.
     */
    public User getUser()
    {
        return user;
    }

    ///////////////////////////////////////////////////////////////////////
    // Roles.
    ///////////////////////////////////////////////////////////////////////

    /**
     * Throws an exception if user's ACL doesn't have the specified role.
     *
     * @@param roleID The role to check for.
     *
     * @@exception ACLException If user doesn't have the role.
     */
    public void assertRole (Role role)
        throws ACLException, Exception
    {
        if (!hasRole(role))
        {
            throw new ACLException(this, role.getName(), "Host", null);
        }
    }

    /**
     * Checks whether the user's ACL has the role in the host/cluster.
     *
     * @@param roleID The role to check for.
     * @@return       Whether access is allowed.
     */
    public boolean hasRole (Role role)
        throws Exception
    {
        return hasRole(role, ProjectPeer.getHost());
    }

    /**
     * Checks whether the user's ACL has the role in the specified project.
     *
     * @@param role   The role to check for.
     * @@param project   The project to check for the role in.
     * @@return True iff this user has the given role in the given
     *         project. 
     */
    public boolean hasRole(Role role, Project project)
        throws Exception
    {
        boolean flag = false;

        List rolesForProject = getOriginalRolesForProject(project);
        if (rolesForProject != null && rolesForProject.contains(role))
        {
            flag = true;
        }
        
        return flag;
    }

    ///////////////////////////////////////////////////////////////////////
    // Host permissions.
    ///////////////////////////////////////////////////////////////////////

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on the host.
     *
     * @@param action   The action to check for.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission(String action)
        throws ACLException, Exception
    {
        if (!hasPermission(action))
        {
            throw new ACLException(this, action, "Host", null);
        }
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on the host.
     *
     * @@param action   The action to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermission (String action)
        throws Exception
    {
        return hasPermission(action, ProjectPeer.getHost());
    }

    ///////////////////////////////////////////////////////////////////////
    // Project permissions.
    ///////////////////////////////////////////////////////////////////////

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param project    The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission (String action, Project project)
        throws ACLException
    {
        assertPermission(action, null, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param project    The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission (String action, String resource, 
                                  Project project)
        throws ACLException
    {
        boolean ok = false;
        try 
        {
            if (hasPermission(action, resource, project))
            {
                ok = true;
            } 
        } 
        catch (Exception ignore) 
        {
            //Will be turned into an ACLException.
        }
        if (!ok)
        {
            throw new ACLException(this, action, 
                                   "Project " + project.getName(), resource);
        }

    }
    
    ///////////////////////////////////////////////////////////////////////
    // The general checker which all other checkers eventually call.
    ///////////////////////////////////////////////////////////////////////
    /**
     * Checks whether the user's ACL has action to perform an action on a 
     * given project.
     *
     * @@param action    The action to check for.
     * @@param project   The project to which the action applies.
     * @@return          Whether access is allowed.
     */
    public boolean hasPermission (String action, Project project)
        throws Exception
    {        
        return hasPermission(action, null, project);
    }

    /**
     * Checks whether the user's ACL has action to perform an action on a 
     * resource in a given project. If the action is affected by
     * project disablement and the project is disabled, they don't
     * have permission.
     *
     * @@param action    The action to check for.
     * @@param resource  The resource to which the action applies.
     * @@param project   The project to which the action applies.
     * @@return          Whether access is allowed.
     */
    public boolean hasPermission (String action, String resource, 
                                  Project project)
        throws Exception
    {        
        boolean usedCache = true;

        long seconds = 0;
        if (TIMING_DEBUG)
        {
            seconds = System.currentTimeMillis();
        }

        List key = new ArrayList(3);
        key.add(action);
        key.add(resource);
        key.add(project.getProjectId());
        Boolean result = (Boolean) recentChecks.get(key);

        // Recent permission check results may be cached.
        if (result == null)
        {
            synchronized (recentChecks)
            {
                result = (Boolean) recentChecks.get(key);
                if (result == null)
                {
                    result = Boolean.FALSE;
                    usedCache = false;
                    
                    // Perform permission check.
                    List resourcesForAction = 
                        getResourcesForActionInProject(action, project, false);
                    Resource scope;
                    Iterator i = resourcesForAction.iterator();
                    while (i.hasNext())
                    {
                        scope = (Resource) i.next();
                        if (resourceMatchesScope(resource, scope.getPattern()))
                        {
                            result = Boolean.TRUE;
                            break;
                        }
                    }           
                    recentChecks.put(key, result);
                    if (DEBUG)
                    {
                        Log.debug("User " + user.getLoginName() 
                                  + (result.booleanValue() ? " has":" lacks")
                                  + " permission " + action + '/' + resource
                                  + " in project " + project.getName());
                    }
                }
            }
        }

        if (TIMING_DEBUG)
        {
            long seconds2 = System.currentTimeMillis();
            Log.debug((usedCache ? "Using" : "Not using") +
                      " cache, permission check took " +
                      String.valueOf(seconds2-seconds) + " milliseconds.");
        }

        return result.booleanValue();
    }

    
    /**
     * Returns all the resources in which this user has the named action
     * in the given project.
     */
    public List getResourcesForActionInProject
        (String actionName, Project project, boolean includeRole)
        throws DoesNotExist, Exception
    {
        Action actionObj = ActionPeer.getInstanceByName(actionName);
        return getResourcesForActionInProject(actionObj, project, includeRole);
    }

    /**
     * Returns all the resources in which this user has the named action
     * in the given project.
     */
    public List getResourcesForActionInProject
        (Action action, Project project, Boolean includeRole)
        throws DoesNotExist, Exception
    {
        return getResourcesForActionInProject(action, project, 
                                              includeRole.booleanValue());
    }

    /**
     * Returns all the resources in which this user has the named action
     * in the given project.
     */
    public List getResourcesForActionInProject
        (Action action, Project project, boolean includeRole)
        throws DoesNotExist, Exception
    {
        Set resourcesForAction = new HashSet();
        if (project.isLocked() && action.isAffectedByProjectLock())
        {
            //Checks of lock-affected actions on locked projects never
            //go through.
            if (DEBUG)
            {
                Log.debug("Project " + project.getName() 
                          + " is locked, not getting resources for " 
                          + action + " for user " + user.getLoginName());
            }
        }
        else
        {
            //Iterate through their roles in this project to get a list of
            //resources for which they have the given action.
            List rolesForProject = getAllRolesForProject(project);
            if (rolesForProject != null)
            {
                Iterator i = rolesForProject.iterator();
                while (i.hasNext())
                {
                    Role role = (Role)i.next();
                    if (DEBUG) 
                    {
                        Log.debug("Does role " + role.getName() 
                                  + " have action " + action.getName()
                                  + " in project " + project.getName() +'?');
                    }
                    List resourcesForActionRole =
                        role.getResourcesForAction(action);
                    
                    if (!includeRole) 
                    {
                        resourcesForAction.addAll(resourcesForActionRole);
                    }
                    else 
                    {
                        for (Iterator k = resourcesForActionRole.iterator();
                             k.hasNext();)
                        {
                            Resource resource = (Resource)k.next();
                            resourcesForAction.add(resource.getPattern() 
                                                   + '(' + role.getName() 
                                                   + ')');
                        }
                    }
                }
            }
        }
        return Arrays.asList(resourcesForAction.toArray());
    }
                   
    /**
     * Checks whether a resources matches the user's scope.
     *
     * @@param resource The resource to check access to.
     * @@param scope    The scope of the user's action.
     * @@return         Whether the resource and scope match.
     */
    private boolean resourceMatchesScope (String resource, String scope)
    {
        if (DEBUG) Log.debug("Does '" + resource + "' match '" + scope + "'?");
        boolean isMatch = (resource == null || resource.equals(""));

        // If the match is not immediately evident, compare resource to scope.
        if (!isMatch)
        {
	    // FUTURE: consider an optimization for scopes of the form:
	    // "prefix.*suffix".  Where prefix do not contain any regex
	    // characters. 
            try
            {
                RE pat = new RE(scope);
                isMatch = pat.isMatch(resource);
            }
            catch (REException assumeNoMatch)
            {
                isMatch = false;
            }
        }
        if (DEBUG)
        {
            if (isMatch) Log.debug("Resource matches.");
            else Log.debug("Resource does not match.");
        }
        return isMatch;
    }

    /**
     * Returns true iff this ACL would lose the given action without
     * the given role. Used for the root non-permission-reduction
     * safety net.  
     */
    public boolean wouldLosePermissionWithout(Action action, Role role)
        throws Exception
    {
        List toCheck = new ArrayList();
        if (Action.HOST_TYPE.equals(action.getType()))
        {
            toCheck.add(ProjectPeer.getHost());
        }
        else
        {
            List domains = ProjectPeer.getHost().getDomains();
            for (Iterator i = domains.iterator(); i.hasNext();)
            {
                Project p = (Project)i.next();
                if (p.isDomain() && !p.isHost())
                {
                    toCheck.add(p);
                }
            }
        }

        boolean wouldLose = true;
        for (Iterator i = toCheck.iterator(); i.hasNext();)
        {
            wouldLose = true;
            Project p = (Project)i.next();
            List roles = getAllRolesForProject(p);
            if (roles.contains(role))
            {
                List toRemove = new ArrayList(1);
                toRemove.add(role);
                roles.removeAll(toRemove);
                for (Iterator j = roles.iterator(); j.hasNext();)
                {
                    Role r = (Role)j.next();
                    List resources = r.getResourcesForAction(action);
                    
                    for (Iterator k = resources.iterator(); k.hasNext();)
                    {
                        Resource res = (Resource)k.next();
                        if (resourceMatchesScope(res.getPattern(), ".*"))
                        {
                            wouldLose = false;
                            break;
                        }
                    }
                    if (!wouldLose)
                    {
                        //We found a role with the action; no need to
                        //check the next role.
                        break;
                    }
                }
            }
            else
            {
                //They didn't have this role in the first place, so
                //they can't lose the action without the role.
                wouldLose = false;
            }
            if (wouldLose)
            {
                //We've already established disaster; no need to check
                //the next project.
                break;
            }
        }       
        return wouldLose;
    }

    //
    // Handles expansion of roles.
    //

    /**
     * Returns the user's original roles in a project.
     *
     * @@param projectID  The project to obtain roles for.
     */
    private List getOriginalRolesForProject(Project project)
    {
        return (List)originalRolesByProject.get(project);
    }

    /**
     * Returns the conjunction of the user's original and derived roles
     * in a project.
     *
     * @@param projectID  The project to obtain roles for
     */
    private List getAllRolesForProject(Project project)
        throws Exception
    {        
        // Give us the derived roles we have in this project via
        // parent projects and project groups.        
        expandRolesForProject(project);

        List original = (List)originalRolesByProject.get(project);
        List derived = (List)derivedRolesByProject.get(project);
        List all = new Vector();
        if (original != null)
        {
            all.addAll(original);
        } 
        if (derived != null)
        {
            all.addAll(derived);
        }
        dump();
        return all;
    }

    /**
     * Gives all original roles in parent projects to this project as
     * derived roles.  
     */
    private void expandRolesForProject(Project project)
        throws Exception
    {  
        if (!expandedProjects.contains(project))
        {        
            List publicParents = project.getPermissionedParents(true);
            List privateParents = project.getPermissionedParents(false);

            for (Iterator i = publicParents.iterator(); i.hasNext();)
            {
                Project parent = (Project)i.next();
                List rolesForParent = getOriginalRolesInProject(parent);
                for (Iterator j = rolesForParent.iterator(); j.hasNext();)
                {
                    addRoleToRolesByProject((Role)j.next(), project, DERIVED);
                }
            }

            for (Iterator i = privateParents.iterator(); i.hasNext();)
            {
                Project parent = (Project)i.next();
                List rolesForParent = getOriginalRolesInProject(parent);
                for (Iterator j = rolesForParent.iterator(); j.hasNext();)
                {
                    Role derivedRole = (Role)j.next();                    
                    if (derivedRole.canRecurseIntoPrivateProjects())
                    {
                        addRoleToRolesByProject(derivedRole, project, DERIVED);
                    }
                }
            }
            expandedProjects.add(project);
        }
    }  

    /**
     * Constructs the list of roles the user has in projects.
     */
    private void constructOriginalRolesByProject()
        throws Exception
    {
        if (DEBUG) 
        {
            Log.debug("Constructing roles by project for " +
                      user.getRealName());
        }
        originalRolesByProject = new HashMap();
        
        List effectiveUserIDs = user.effectiveUserIDs();
        if (DEBUG) Log.debug("Effective user IDs: " + effectiveUserIDs);

        Criteria c = new Criteria()
            .addIn(UserRoleProjectPeer.USER_ID, effectiveUserIDs.toArray())
            .add(UserRoleProjectPeer.APPROVED_BY, 
                 UserPeer.getNobodyUser().getUserId(), Criteria.NOT_EQUAL);
        List urps = UserRoleProjectPeer.doSelect(c);

        Role role = null;
        Project project = null;
        List rolesForProject = null;
        for (Iterator i = urps.iterator(); i.hasNext();)
        {
            UserRoleProject entry = (UserRoleProject)i.next();
            role = RolePeer.retrieveByPK(entry.getRoleId());
            project = ProjectPeer.retrieveByPK(entry.getProjectId());
            if (DEBUG) Log.debug("Found role " + role.getName() + " in project " + project.getName());
            addRoleToRolesByProject(role, project, ORIGINAL);
        }
    }
    
    /**
     * Adds a role in a project to the appropriate RolesByProject
     * hash.
     * <p>
     * TODO: Make this take a bunch of roles for better
     * efficiency.
     *
     * @@param roleID    The role to add.
     * @@param projectID  The project in which the user has the role.
     */
    private void addRoleToRolesByProject(Role role, Project project,
                                         boolean original)
    {       
        Map hash = (original ? originalRolesByProject : derivedRolesByProject);
        List rolesForProject = (List)hash.get(project);   
        if (rolesForProject == null)
        {
            rolesForProject = new Vector();
        }
      
        if (!rolesForProject.contains(role))
        {
            rolesForProject.add(role);
        }        
        hash.put(project, rolesForProject);
    }

    //
    // Some methods used by PermissionDump.
    //

    /**
     * Forces a role expansion of all projects, so that the user's ACL
     * contains an explicit mention of every role they have in every
     * project.
     */
    public void expandRolesForAllProjects()
        throws Exception
    {
        List groups = ProjectPeer.doSelect(new Criteria());
        for (Iterator i = groups.iterator(); i.hasNext(); )
        {
            Project p = (Project)i.next();
            expandRolesForProject(p);
        }
    }

    /**
     * Returns a list of all projects in which this user has any role.
     */
    public List getProjectsWithAnyRole()
        throws Exception
    {
        return getProjectsWithAnyRole(null);
    }

    /**
     * Returns a list of all projects which match the given criteria
     * and in which this user has any role.  
     */
    public List getProjectsWithAnyRole(String filter)
        throws Exception
    {
        List p = new ArrayList();
        List orig = getProjectsWithOriginalRole();
        if (orig != null) p.addAll(orig);
        List derived = getProjectsWithDerivedRole();
        if (derived != null)
        {
            for (Iterator i = derived.iterator(); i.hasNext(); )
            {
                Project project = (Project)i.next();
                if (!p.contains(project))
                {
                    p.add(project);
                }
            }
        }

        List matchingFilter = null;
        if (filter == null)
        {
            matchingFilter = p;
        }
        else
        {
            matchingFilter = new ArrayList(p.size());
            for (Iterator i = p.iterator(); i.hasNext();)
            {
                Project pr = (Project)i.next();
                if (pr.getName().toUpperCase()
                    .lastIndexOf(filter.toUpperCase()) != -1)
                {
                    matchingFilter.add(pr);
                }
            }
        }
        return matchingFilter;
    }

    /**
     * Returns all the projects in which this user (or some group to
     * which the user belongs) has been assigned an explicit role.
     */
    public List getProjectsWithOriginalRole()
    {
        return getProjectsWithRoleFromMap(originalRolesByProject);
    }

    /**
     * Returns all the projects in which this user (or some group to
     * which the user belongs) effectively has a role by virtue of
     * having that role in a superproject or a project group which
     * contains the project.
     */
    public List getProjectsWithDerivedRole()
        throws Exception
    {
        expandRolesForAllProjects();
        return getProjectsWithRoleFromMap(derivedRolesByProject);
    }
    
    private List getProjectsWithRoleFromMap(Map t)
    {
        return new ArrayList(t.keySet());
    }

    /**
     * Returns the original roles a user has in the given project.
     */
    public List getOriginalRolesInProject(Project project)
    {
        return getRolesInProjectFromMap(project, originalRolesByProject);
    }

    /**
     * Returns the roles a user has in given project due to having the
     * same role in a superproject or a project group which contains the
     * project.
     */
    public List getDerivedRolesInProject(Project project)
    {
        return getRolesInProjectFromMap(project, derivedRolesByProject);
    }

    private List getRolesInProjectFromMap(Project project, Map t)
    {
        List l = null;
        for (Iterator i = t.keySet().iterator(); i.hasNext();)
        {
            Project p = (Project)i.next();
            if (p.equals(project))
            {
                l = (List)t.get(p);
                break;
            }
        }
        if (l == null) l = new ArrayList(0);
        return l;
    }

    /**
     * Dumps the ACL to the log.
     */
    public void dump()
    {
        if (!DEBUG) return;
        StringBuffer s = new StringBuffer();
        s.append("\noriginalRolesByProject for "+ user.getLoginName() + ":\n");
        
        for (Iterator i = originalRolesByProject.keySet().iterator(); 
             i.hasNext();)
        {
            Project project = (Project)i.next();
            List rolesForProject = 
                (List)originalRolesByProject.get(project);
            s.append(" Roles for project " + project.getName() + ": ");
            for (Iterator j = rolesForProject.iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                s.append(r.getName() + " ");
            }                        
            s.append("\n");
        }    

        s.append("\nderivedRolesByProject (so far) for "+ user.getLoginName() 
                 + ":\n");
        
        for (Iterator i = derivedRolesByProject.keySet().iterator(); 
             i.hasNext(); )
        {
            Project project = (Project)i.next();
            List rolesForProject = 
                (List)derivedRolesByProject.get(project);
            s.append(" Roles for project " + project.getName() + ": ");
            for (Iterator j = rolesForProject.iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                s.append(r.getName() + " ");
            }                        
            s.append("\n");
        }    

        Log.debug(s.toString());        
    }


    static class ACLCache extends SimpleRegisterableCache
    {
        /**
         * The HelmObject subclasses changes to which should trigger
         * an ACL cache invalidation.  
         */
        private static Class[] interestingDescriptors =
        {
            Action.class, 
            Project.class,
            ProjectProjectgroup.class,
            Resource.class,
            Role.class,
            RoleActionResource.class,
            User.class,
            UserRoleProject.class,
            UserUsergroup.class,
        };

        /**
         * The minimum size of the ACL cache.
         */
        private static final int MINIMUM_CACHE_SIZE = 100;

        /**
         * Passthrough constructor.
         */
        public ACLCache()
            throws Exception
        {
            super("ACL cache", interestingDescriptors, 
                  new TableTrackingBufferCache
                      (UserPeer.TABLE_NAME, 
                       Attribute.FRACTIONAL_USER_CACHE_SIZE, 
                       MINIMUM_CACHE_SIZE));
        }
    }   

    //Deprecated methods.

    /**
     * Checks whether the user's ACL has the role in the specified domain.
     *
     * @@deprecated Use hasRole(role, domain) instead.
     */
    public boolean hasRoleInDomain(Role role, Domain domain)
        throws Exception
    {
        return hasRole(role, domain);
    }

    /**
     * Checks whether the user's ACL has the role in the host.
     *
     * @@deprecated Use hasRole(role) instead;
     *
     * @@param roleID   The role to check for.
     * @@return         Whether the user has the role.
     */
    public boolean hasRoleInHost (Role role)
        throws Exception
    {
        return hasRole(role);
    }

    /**
     * Checks whether the user's ACL has the role in the specified project.
     *
     * @@deprecated Use hasRole(role, project) instead.
     * @@param role   The role to check for.
     * @@param project   The project to check for the role in.
     * @@return True iff this user has the given role in the given
     *         project. 
     */
    public boolean hasRoleInProject (Role role, Project project)
        throws Exception
    {
        return hasRole(role, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on the host.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action   The action to check for.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForHost(String action)
        throws ACLException, Exception
    {
        assertPermission(action);
    }
    
    /**
     * Checks whether the user's ACL has permission to perform an action
     * on the host.
     *
     * @@deprecated     Use hasPermission instead.
     * @@param action   The action to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForHost (String action)
        throws Exception
    {
        return hasPermission(action);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking in the domain. Use
     *             assertPermission instead.
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermissionForDomain (String action, Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, null, domain);
    }
    
    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             assertPermission instead.
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param domain     The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermissionForDomain (String action, String resource, 
                                           Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, resource, domain);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             hasPermission instead.
     * @@param action   The action to check for.
     * @@param domain   The domain to check permission in.
     * @@return Whether access is allowed.  
     */
    public boolean hasPermissionForDomain (String action, Domain domain)
        throws Exception
    {
        return hasPermission(action, domain);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a project.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action   The action to check for.
     * @@param project The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForProject (String action, Project project)
        throws ACLException
    {
        assertPermission(action, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action     The action to check for.
     * @@param resourceID The resource to check.
     * @@param project  The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForProject (String action, String resource, 
                                            Project project)
        throws ACLException
    {
        assertPermission(action, resource, project);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action on a 
     * project.  
     *
     * @@deprecated Use hasPermission instead.
     * @@param action   The action to check for.
     * @@param project The project to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForProject (String action, Project project)
        throws Exception
    {
        return hasPermission(action, project);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action on a 
     * project.  
     *
     * @@deprecated Use hasPermission instead.
     * @@param action   The action to check for.
     * @@param project  The project to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForProject (String action, String resource,
                                            Project project)
        throws Exception
    {
        return hasPermission(action, resource, project);
    }
}
@


1.71
log
@Added JavaDoc for public methods which lacked it.
@
text
@d54 1
a54 4
import org.apache.turbine.util.BufferCache;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.TurbineException;
import org.apache.turbine.util.db.Criteria;
d56 1
a56 1
import org.tigris.helm.tool.HelmProperties;
d59 3
d64 1
a64 2
import org.tigris.helm.om.*;
import org.tigris.helm.security.ACLException;
d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.70 2001/07/30 21:25:13 leonardr Exp $
@


1.70
log
@Permission check changes: don't return duplicate resources, and make all permission checks of any kind fail if the project is locked and the action is affected by the lock.
@
text
@d79 1
a79 1
 * @@version $Id: AccessControlList.java,v 1.69 2001/07/19 18:42:22 dlr Exp $
d819 5
d888 4
d897 6
d915 3
d923 5
@


1.69
log
@Updated in light of the port of Joist JoistProperties class to Helm (as class HelmProperties).
@
text
@d79 1
a79 1
 * @@version $Id: AccessControlList.java,v 1.68 2001/07/02 21:41:46 leonardr Exp $
a412 41
        boolean ok = false;
        boolean check = true;
        if (project.isLocked())
        {
            Action actionObj = ActionPeer.getInstanceByName(action);
            if (actionObj.isAffectedByProjectLock())
            {
                check = false;
                if (DEBUG)
                {
                    Log.debug("Project " + project.getName() 
                              + " is locked, not checking permission " 
                              + action + '/' + resource + " for user " 
                              + user.getLoginName());
                }
            }
        }

        if (check)
        {
            ok = hasPermissionIgnoreLock(action, resource, project);
        }

        return ok;
    }

    /**
     * Checks whether the user's ACL has action to perform an action on a 
     * resource in a given project. Returns true even if the action
     * is one affected by disabling projects, and the project is
     * disabled.
     *
     * @@param action    The action to check for.
     * @@param resource  The resource to which the action applies.
     * @@param project   The project to which the action applies.
     * @@return          Whether access is allowed.
     */
    public boolean hasPermissionIgnoreLock (String action, String resource, 
                                            Project project)
        throws Exception
    {        
d437 1
a437 1

d475 12
d488 4
d496 1
a496 1
        return getResourcesForActionInProject(action.getName(), project,
d499 5
a503 1
    
d505 1
a505 1
        (String actionName, Project project, boolean includeRole)
d508 2
a509 6
        Action action = ActionPeer.getInstanceByName(actionName);
        //Iterate through their roles in this project to get a list of
        //resources for which they have the given action.
        List resourcesForAction = new ArrayList();
        List rolesForProject = getAllRolesForProject(project);
        if (rolesForProject != null)
d511 3
a513 2
            Iterator i = rolesForProject.iterator();
            while (i.hasNext())
d515 14
a528 2
                Role role = (Role)i.next();
                if (DEBUG) 
d530 15
a544 15
                    Log.debug("Does role " + role.getName() + " have action " 
                              + actionName + " in project " +
                              project.getName() +'?');
                }
                List resourcesForActionRole =
                    role.getResourcesForAction(action);

                if (!includeRole) 
                {
                    resourcesForAction.addAll(resourcesForActionRole);
                }
                else 
                {
                    for (Iterator k = resourcesForActionRole.iterator();
                         k.hasNext();)
d546 8
a553 3
                        Resource resource = (Resource)k.next();
                        resourcesForAction.add(resource.getPattern() 
                                               + '(' + role.getName() + ')');
d558 1
a558 1
        return resourcesForAction;
@


1.68
log
@Prohibit actions which would cause root to lose a host or domain permission.
@
text
@d59 1
a59 1
import org.joist.util.JoistProperties;
d79 1
a79 1
 * @@version $Id: AccessControlList.java,v 1.67 2001/06/18 22:12:21 leonardr Exp $
@


1.67
log
@Huge patch of the day: Got rid of redundant HELM_DOMAIN table. The project representation of the domain and the host is now the canonical one. Host and Domain now subclass ProjectGroup. The canonical representation of a project's membership in a domain group is now the corresponding mapping in HELM_PROJECT_PROJECTGROUP. Schema changes: No more HELM_DOMAIN table (obviously); no more DOMAIN_ID in HELM_PROJECT; HELM_USER and HELM_VC_VIEW now have foreign keys in HELM_PROJECT instead of HELM_DOMAIN.
@
text
@a56 1
import org.apache.turbine.util.TurbineException;
d59 2
d79 1
a79 1
 * @@version $Id: AccessControlList.java,v 1.66 2001/06/01 21:28:32 leonardr Exp $
d604 75
d1015 1
a1015 1
    }
@


1.66
log
@Made PermissionDump less of a burden on browsers.
@
text
@a49 1
import java.rmi.RemoteException;
d62 1
d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.65 2001/05/30 14:46:47 leonardr Exp $
d151 1
a151 1
        catch (RemoteException e)
d270 1
a270 1
        return hasRoleInDomain(role, DomainPeer.getHostDomain());
d274 1
a274 19
     * Checks whether the user's ACL has the role in the host.
     *
     * @@param roleID   The role to check for.
     * @@return         Whether the user has the role.
     */
    public boolean hasRoleInHost (Role role)
        throws Exception
    {
        return hasRole(role);
    }

    public boolean hasRole(Role role, Domain domain)
        throws Exception
    {
        return hasRoleInDomain(role, domain);
    }

    /**
     * Checks whether the user's ACL has the role in the specified domain.
d276 4
a279 3
     * @@param roleID   The role to check for.
     * @@param domain   The domain to check for the role in.
     * @@return         Whether access is allowed.
a280 6
    public boolean hasRoleInDomain (Role role, Domain domain)
        throws Exception
    {
        return hasRoleInProject(role, domain.getSpecialProject());
    }

a283 12
        return hasRoleInProject(role, project);
    }

    /**
     * Checks whether the user's ACL has the role in the specified project.
     *
     * @@param roleID    The role to check for.
     * @@param projectID The domain to check for the role in.
     * @@return          Whether access is allowed.
     */
    public boolean hasRoleInProject (Role role, Project project)
    {
a302 29
     * @@deprecated Use assertPermission instead.
     * @@param action   The action to check for.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForHost(String action)
        throws ACLException, Exception
    {
        assertPermission(action);
    }

    
    /**
     * Checks whether the user's ACL has permission to perform an action
     * on the host.
     *
     * @@deprecated     Use hasPermission instead.
     * @@param action   The action to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForHost (String action)
        throws Exception
    {
        return hasPermission(action);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on the host.
     *
d325 1
a325 130
        return hasPermission(action, ProjectPeer.getHostProject());
    }

    ///////////////////////////////////////////////////////////////////////
    // Domain permissions.
    ///////////////////////////////////////////////////////////////////////

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking in the domain. Use
     *             assertPermission instead.
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermissionForDomain (String action, Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, null, domain);
    }
    
    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             assertPermission instead.
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param domain     The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermissionForDomain (String action, String resource, 
                                           Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, resource, domain);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             hasPermission instead.
     * @@param action   The action to check for.
     * @@param domain   The domain to check permission in.
     * @@return Whether access is allowed.  
     */
    public boolean hasPermissionForDomain (String action, Domain domain)
        throws Exception
    {
        return hasPermission(action, domain);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check permission in.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermission(String action, Domain domain)
        throws Exception
    {
        return hasPermission(action, null, domain);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermission (String action, Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, null, domain);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermission (String action, String resource, 
                                  Domain domain)
        throws ACLException, Exception
    {
        if (!hasPermission(action, resource, domain))
        {
            throw new ACLException(this, action, "Domain " + domain.getName(),
                                   resource);
        }
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a resource in a domain.
     *
     * @@param action   The action to check for.
     * @@param resource The resrouce to check.
     * @@param domain   The domain to check permission in.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermission (String action, String resource, 
                                  Domain domain)
        throws Exception
    {
        boolean ok = false;
            
        Project hostProject = ProjectPeer.getHostProject();
        Project domainProject = ProjectPeer.getDomainProject(domain);
        if (hasPermission(action, resource, domainProject)
            || hasPermission(action, resource, hostProject))
        {
            ok = true;
        }
        return ok;
a333 63
     * an action on a project.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action   The action to check for.
     * @@param project The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForProject (String action, Project project)
        throws ACLException
    {
        assertPermission(action, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action     The action to check for.
     * @@param resourceID The resource to check.
     * @@param project  The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForProject (String action, String resource, 
                                            Project project)
        throws ACLException
    {
        assertPermission(action, resource, project);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action on a 
     * project.  
     *
     * @@deprecated Use hasPermission instead.
     * @@param action   The action to check for.
     * @@param project The project to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForProject (String action, Project project)
        throws Exception
    {
        return hasPermission(action, project);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action on a 
     * project.  
     *
     * @@deprecated Use hasPermission instead.
     * @@param action   The action to check for.
     * @@param project  The project to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForProject (String action, String resource,
                                            Project project)
        throws Exception
    {
        return hasPermission(action, resource, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
a492 1

d496 1
a496 1
                                  + (result.booleanValue() ? "has":"lacks")
d923 5
d931 1
a931 1
            throws RemoteException
d933 5
a937 1
            super("ACL cache", interestingDescriptors, new BufferCache(100));
d939 186
@


1.65
log
@ACL should no longer be interested in this nonexistance class.
@
text
@d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.64 2001/05/30 01:11:12 leonardr Exp $
d1004 1
a1004 1
    // Some methods used by the script runner.
d1018 3
d1024 10
d1049 7
a1055 1
        for (Iterator i = p.iterator(); i.hasNext();)
d1057 10
a1066 1
            Project x = (Project)i.next();
d1068 1
a1068 1
        return p;
@


1.64
log
@Got rid of denormalized project-project group mapping table in favor of per-JVM caching solution.
@
text
@d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.63 2001/05/25 23:04:01 leonardr Exp $
a1142 1
            DenormalizedProjectProjectgroup.class,
@


1.63
log
@Rebuilding of denormalized table should generate cluster events, and the ACL cache should be interested in such events.
@
text
@d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.62 2001/05/23 01:50:20 dlr Exp $
d911 4
a914 2
            List parentMappings = project.getDenormalizedMappingsForParents();
            for (Iterator i = parentMappings.iterator(); i.hasNext();)
d916 7
a922 4
                DenormalizedProjectProjectgroup mapping = 
                    (DenormalizedProjectProjectgroup)i.next();
                Project parent = ProjectPeer.getInstance
                    (mapping.getParentID());
d924 3
d930 2
a931 3
                    Role derivedRole = (Role)j.next();
                    if (mapping.publicPath() || 
                        derivedRole.canRecurseIntoPrivateProjects())
@


1.62
log
@Ported Helm from WebMacro to Velocity.
@
text
@d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.61 2001/05/23 00:35:00 leonardr Exp $
d1136 1
@


1.61
log
@Cleanup of caching and cache invalidation.
@
text
@d57 2
d78 1
a78 1
 * @@version $Id: AccessControlList.java,v 1.60 2001/05/22 00:14:19 leonardr Exp $
@


1.60
log
@Bug fixes for clustering.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.59 2001/05/11 19:38:55 leonardr Exp $
d1129 1
a1129 1
        private static String[] interestingDescriptors =
d1131 9
a1139 9
            Action.class.getName(), 
            Project.class.getName(),
            ProjectProjectgroup.class.getName(),
            Resource.class.getName(),
            Role.class.getName(),
            RoleActionResource.class.getName(),
            User.class.getName(),
            UserRoleProject.class.getName(),
            UserUsergroup.class.getName(),
d1148 1
a1148 1
            super(interestingDescriptors, new BufferCache(100));
@


1.59
log
@A Heartbreaking Patch of Staggering Genius: adds capacity (but no interface) for deeply nested projects, categories, and project groups. As a side effect, gets rid of the hacky special 'all public projects in domain' group. There are probably bugs in this, and some of those bugs are probably security holes, so watch out.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.58 2001/04/25 22:37:51 dlr Exp $
a1124 1

d1129 1
a1129 1
        private static String[] affectingClasses =
d1148 1
a1148 28
            super(AccessControlList.class, new BufferCache(100));
        }

        /**
         * This cache is invalidated whenever a RoleActionResource or
         * a Role is changed.
         */
        protected final boolean affectedByInvalidation
            (Object invalidationDescriptor)
        {
            boolean affects = false;
            if (invalidationDescriptor == null)
            {
                affects = true;
            }
            else if (invalidationDescriptor instanceof String)
            {
                String objectClassName = (String)invalidationDescriptor;
                for (int i = 0; i < affectingClasses.length; i++)
                {
                    if (objectClassName.equals(affectingClasses[i]))
                    {
                        affects = true;
                        break;
                    }
                }
            }
            return affects;
@


1.58
log
@Refactored hasPermissionIgnoreLock():

* Removed need for primitive local boolean.

* Streamlined code.

* Corrected bug introduced by last commit where the permission check
result wasn't set correctly when a second cache check came up with a
value.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.57 2001/04/25 21:58:29 dlr Exp $
d118 3
a120 2
     * Another Map like rolesByProject, but containing roles the
     * user has via having a role in a project group.
d130 2
a131 2
     * Indicates that a role is derived (granted to a project group which
     * contains a project)
d134 1
a134 1

d136 4
a139 4
     * A mapping of project groups to booleans; the presence of a
     * project group in this Map means that the roles this user has in
     * the project group have been distributed (as derived roles)
     * across the projects in the project group.  
d141 1
a141 1
    private Map haveExpandedProject;
d215 1
a215 1
        haveExpandedProject = new HashMap();
a301 13
    /**
     * Checks whether the user's ACL has the role in the group of public projects in the specified domain.
     *
     * @@param roleID   The role to check for.
     * @@param domain   The domain to check for the role in.
     * @@return         Whether access is allowed.
     */
    public boolean hasRoleInPublicDomainProjects (Role role, Domain domain)
        throws Exception
    {
        return hasRoleInProject(role, domain.getSpecialPublicProject());
    }

d511 2
a512 15
        if (!hostProject.equals(domainProject))
        {
            Project publicDomainProject = ProjectPeer.getPublicDomainProject(domain);
            if (hasPermission(action, resource, domainProject)
                || hasPermission(action, resource, publicDomainProject))
            {
                ok = true;
            }
        }
        else if (DEBUG)
        {
            Log.debug("This is the host domain; there's no public project.");
        }

        if (ok == false && hasPermission(action, resource, hostProject))
d882 1
a882 5
        // project groups.  

        // TODO: Use HaveExpandedProject to only do this when
        // neccessary.
        
d900 4
d906 5
a910 7
    {                
        List groups = project.getGroups();
        for (Iterator i = groups.iterator(); i.hasNext();)
        {
            ProjectGroup group = (ProjectGroup)i.next();
            List rolesForGroup = getOriginalRolesInProject(group);
            for (Iterator j = rolesForGroup.iterator(); j.hasNext();)
d912 15
a926 2
                Role derivedRole = (Role)j.next();
                addRoleToRolesByProject(derivedRole, project, DERIVED);
d928 1
@


1.57
log
@Sync on recentChecks to avoid a race condition when performing the
same check twice for the same user.  Having no synchronization should
be fine, but sync'ing results in less computation (and therefore less
load).
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.56 2001/04/25 21:47:39 dlr Exp $
a731 1
        boolean ok = false;
a739 1
        // First, check the cache.
d744 4
a747 6
        Boolean cachedValue = (Boolean) recentChecks.get(key);
        if (cachedValue != null)
        {
            ok = cachedValue.booleanValue();
        }
        else
d751 2
a752 2
                cachedValue = (Boolean) recentChecks.get(key);
                if (cachedValue == null)
d754 4
d767 1
a767 1
                            ok = true;
d771 1
a771 2
                    usedCache = false;
                    recentChecks.put(key, new Boolean(ok));
d776 3
a778 3
                                  + (ok ? "has":"lacks") + " permission "
                                  + action + '/' + resource + " in project "
                                  + project.getName());
d783 1
d791 2
a792 1
        return ok;
@


1.56
log
@Corrected debugging trace message.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.55 2001/04/25 21:45:26 dlr Exp $
d753 1
a753 4
            List resourcesForAction = 
                getResourcesForActionInProject(action, project, false);
            Resource scope;
            for (Iterator i = resourcesForAction.iterator(); i.hasNext();)
d755 2
a756 2
                scope = (Resource)i.next();
                if (resourceMatchesScope(resource, scope.getPattern()))
d758 23
a780 2
                    ok = true;
                    break;
a781 10
            }           
            usedCache = false;
            recentChecks.put(key, new Boolean(ok));

            if (DEBUG)
            {
                Log.debug("User " + user.getLoginName() 
                          + (ok ? "has":"lacks") + " permission " + action 
                          + '/' + resource + " in project "
                          + project.getName());
d787 3
a789 1
            Log.debug((usedCache?"Using":"Not using") + " cache, permission check took " + String.valueOf(seconds2-seconds) + " milliseconds.");
@


1.55
log
@JavaDoc tweak.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.54 2001/04/20 21:40:28 leonardr Exp $
d741 1
a741 1
        //First, check the cache.
d746 1
a746 1
        Boolean cachedValue = (Boolean)recentChecks.get(key);
d772 2
a773 1
                          + '/' + resource + " in project" + project.getName());
@


1.54
log
@The ACL cache cares about a whole lot of classes.
@
text
@d67 1
a67 1
 *
d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.53 2001/04/20 16:13:01 leonardr Exp $
@


1.53
log
@Invalidate the ACL when a change occurs to an object that might require ACL rebuilding.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.52 2001/04/18 22:39:19 dlr Exp $
d1135 2
d1140 2
@


1.52
log
@SequencedHashtable, BufferCache, and BaseUnicastRemoteService have been moved into Turbine.  Changed references accordingly.
@
text
@d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.51 2001/04/12 18:49:01 leonardr Exp $
d98 1
a98 1
    private static SimpleRegisterableCache userACLs;
d146 1
a146 2
            userACLs = new SimpleRegisterableCache(AccessControlList.class, 
                                                   new BufferCache(100));
a214 1
        dumpStatic();
d1123 2
a1124 4
    /**
     * Dumps the static ACL information to the log.
     */
    public static void dumpStatic()
d1126 49
a1174 4
        if (!DEBUG) return;
        //         Log.debug(RoleActionResourcePeer.dumpStatic());
        //         Log.debug(UserUsergroupPeer.dumpStatic());
        //         Log.debug(ProjectProjectgroupPeer.dumpStatic());
a1175 1

@


1.51
log
@Caching fixes and additions.
@
text
@d55 2
a57 1
import org.apache.turbine.util.Log;
a59 1
import org.tigris.helm.tool.BufferCache;
d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.50 2001/04/11 21:09:58 dlr Exp $
@


1.50
log
@Debug cleanup.
@
text
@d50 1
d60 1
d76 1
a76 1
 * @@version $Id: AccessControlList.java,v 1.49 2001/04/11 21:01:21 dlr Exp $
d98 1
a98 1
    private static Map userACLs = new BufferCache(100);
d142 14
d172 2
a173 1
        if (userACLs.containsKey(user)) 
d175 1
a175 1
            acl = (AccessControlList)userACLs.get(user);
d191 2
a192 1
        synchronized(userACLs)
d195 1
a195 1
            userACLs.put(user, acl);
@


1.49
log
@Too much information.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.48 2001/04/11 16:28:50 leonardr Exp $
d924 4
a927 1
            Log.debug("Constructing roles by project for " + user.getRealName());
@


1.48
log
@Gated debug statement.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.47 2001/04/05 18:28:54 leonardr Exp $
d81 1
a81 1
    private static final boolean DEBUG = true;
@


1.47
log
@Removed unneccessary debug information.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.46 2001/04/05 18:27:15 leonardr Exp $
d81 1
a81 1
    private static final boolean DEBUG = false;
d516 1
a516 1
        else
@


1.46
log
@Gated timing information behind TIMING_DEBUG variable.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.45 2001/04/05 17:32:54 leonardr Exp $
a503 4
        if (action.equals("Project - Approve"))
        {
            Log.debug("Checkign project approve in domain " + domain.getName());
        }
a512 5
                if (action.equals("Project - Approve"))
                {
                    Log.debug("I've got approve. " + domain.getName());
                }

@


1.45
log
@Don't put roles into a user's ACL unless they're approved by someone other than Nobody.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.44 2001/04/04 02:51:35 leonardr Exp $
d84 5
d726 1
d728 5
a732 1
        long seconds = System.currentTimeMillis();
d758 1
d768 5
a772 2
        long seconds2 = System.currentTimeMillis();
        Log.debug("Permission check took " + String.valueOf(seconds2-seconds) + " milliseconds.");
@


1.44
log
@Tests demonstrate that lists are faster than sets. They're also
(academically) safer because they allow for the action to be the same
string as the resource.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.43 2001/04/04 01:20:47 leonardr Exp $
d722 2
a748 1
            Log.debug(action+"/"+resource+"/"+project.getName() + " is not cached.");
d757 2
d926 3
a928 1
            .addIn(UserRoleProjectPeer.USER_ID, effectiveUserIDs.toArray());
@


1.43
log
@Why didn't I think of this before? Instead of (or in addition to)
caching all the information used by the access control checking
algorithm, just cache the outcome of the algorithm. Anything that
causes the cache to be out of date will also cause the ACL to be
invalidated, and the ACL will be rebuilt when next requested, with an
empty cache.

Woohoo!
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.42 2001/04/04 00:49:17 leonardr Exp $
d499 5
d512 5
d520 4
d723 5
a727 5
        Set set = new HashSet(3);
        set.add(action);
        set.add(resource);
        set.add(project);
        Boolean cachedValue = (Boolean)recentChecks.get(set);
d746 2
a747 1
            recentChecks.put(set, new Boolean(ok));
@


1.42
log
@These lock/unlock statements should no longer be neccessary.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.41 2001/03/24 00:14:15 leonardr Exp $
d84 5
d94 6
d187 1
d707 28
a734 7
        List resourcesForAction = 
            getResourcesForActionInProject(action, project, false);
        Resource scope;
        for (Iterator i = resourcesForAction.iterator(); i.hasNext();)
        {
            scope = (Resource)i.next();
            if (resourceMatchesScope(resource, scope.getPattern()))
d736 3
a738 2
                ok = true;
                break;
a739 7
        }

        if (DEBUG)
        {
            Log.debug("User " + user.getLoginName() 
                      + (ok ? "has":"lacks") + " permission " + action 
                      + '/' + resource + " in project" + project.getName());
@


1.41
log
@These methods need to be public because ACLDump uses them.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.40 2001/03/21 23:26:58 dlr Exp $
a81 19

    /**
     * SQL statement used to lock the tables used to build an ACL.
     */
    private static final String LOCK_TABLES = "lock tables " + 
        "HELM_USER read, " +
        "HELM_ROLE read," +
        "HELM_USER_USERGROUP read, "+
        "HELM_PROJECT read, " +
        "HELM_PROJECT_PROJECTGROUP read, " +
        "HELM_USER_ROLE_PROJECT read, " +
        "HELM_ACTION read, " + 
        "HELM_RESOURCE read, " + 
        "HELM_ROLE_ACTION_RESOURCE read";

    /**
     * SQL statement used to unlock the tables used to build an ACL.
     */
    private static final String UNLOCK_TABLES = "unlock tables";
@


1.41.2.1
log
@Merged in leonardr security bug fix to HEAD, minus extraneous trace:

Don't put roles into a user's ACL unless they're approved by someone
other than Nobody.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.41 2001/03/24 00:14:15 leonardr Exp $
d900 1
a900 3
            .addIn(UserRoleProjectPeer.USER_ID, effectiveUserIDs.toArray())
            .add(UserRoleProjectPeer.APPROVED_BY, 
                 UserPeer.getNobodyUser().getUserId(), Criteria.NOT_EQUAL);
@


1.41.2.1.4.1
log
@Backported beautiful caching.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.41.2.1 2001/04/05 17:43:49 dlr Exp $
d84 1
a84 1
     * How many permission checks to cache.
d86 10
a95 1
    private static final int RECENT_CHECKS_TO_HOLD = 128;
d98 1
a98 1
     * ACLs for users.
d100 1
a100 1
    private static Map userACLs = new BufferCache(100);
d103 1
a103 2
     * BufferCache containing the results of recently done permission
     * checks.  
d105 1
a105 1
    private BufferCache recentChecks;
a194 1
        recentChecks = new BufferCache(RECENT_CHECKS_TO_HOLD);
d714 4
a717 8

        //First, check the cache.
        Set set = new HashSet(3);
        set.add(action);
        set.add(resource);
        set.add(project);
        Boolean cachedValue = (Boolean)recentChecks.get(set);
        if (cachedValue == null)
d719 2
a720 1
            synchronized(recentChecks)
d722 2
a723 20
                cachedValue = (Boolean)recentChecks.get(set);
                if (cachedValue == null)
                {
                    Boolean result = Boolean.FALSE;
                    List resourcesForAction = 
                        getResourcesForActionInProject(action, project, false);
                    Resource scope;
                    for (Iterator i = resourcesForAction.iterator(); 
                         i.hasNext();)
                    {
                        scope = (Resource)i.next();
                        if (resourceMatchesScope(resource, scope.getPattern()))
                        {
                            result = Boolean.TRUE;
                            break;
                        }
                    }           
                    recentChecks.put(set, result);
                    cachedValue = result;
                }
d730 2
a731 3
                      + (cachedValue.booleanValue() ? "has":"lacks") 
                      + " permission " + action + '/' + resource 
                      + " in project" + project.getName());
d733 1
a733 1
        return cachedValue.booleanValue();
@


1.41.2.1.4.2
log
@Beautiful Caching II: Now with extra beauty!
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.41.2.1.4.1 2001/04/26 00:32:02 leonardr Exp $
a83 5
     * Whether to log timing information.
     */
    private static final boolean TIMING_DEBUG = false;

    /**
d690 1
a690 1
    
d692 1
a692 1
     * Checks whether the user's ACL has action to perform an action on a
d702 1
a702 1
    public boolean hasPermissionIgnoreLock (String action, String resource,
d705 2
a706 8
    {                
        boolean usedCache = true;
        
        long seconds = 0;
        if (TIMING_DEBUG)
        {
            seconds = System.currentTimeMillis();
        }
d708 7
a714 8
        List key = new ArrayList(3);
        key.add(action);
        key.add(resource);
        key.add(project.getProjectId());
        Boolean result = (Boolean) recentChecks.get(key);

        // Recent permission check results may be cached.
        if (result == null)
d716 1
a716 1
            synchronized (recentChecks)
d718 2
a719 2
                result = (Boolean) recentChecks.get(key);
                if (result == null)
d721 1
a721 4
                    result = Boolean.FALSE;
                    usedCache = false;

                    // Perform permission check.
d725 2
a726 2
                    Iterator i = resourcesForAction.iterator();
                    while (i.hasNext())
d728 1
a728 1
                        scope = (Resource) i.next();
d735 2
a736 9
                    recentChecks.put(key, result);

                    if (DEBUG)
                    {
                        Log.debug("User " + user.getLoginName() 
                                  + (result.booleanValue() ? "has":"lacks")
                                  + " permission " + action + '/' + resource
                                  + " in project " + project.getName());
                    }
d741 1
a741 1
        if (TIMING_DEBUG)
d743 4
a746 4
            long seconds2 = System.currentTimeMillis();
            Log.debug((usedCache ? "Using" : "Not using") +
                      " cache, permission check took " +
                      String.valueOf(seconds2-seconds) + " milliseconds.");
d748 2
a750 2
        return result.booleanValue();
    }
@


1.41.2.1.4.3
log
@Don't give people roles in projects through categories.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.41.2.1.4.2 2001/04/26 00:45:35 leonardr Exp $
d914 2
a915 1
            if (!(group.isCategory() && !project.isCategory()))
d917 2
a918 6
                List rolesForGroup = getOriginalRolesInProject(group);
                for (Iterator j = rolesForGroup.iterator(); j.hasNext();)
                {
                    Role derivedRole = (Role)j.next();
                    addRoleToRolesByProject(derivedRole, project, DERIVED);
                }
@


1.40
log
@Moved class variable down between constants and instance variable--a
more logical position in the file.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.39 2001/03/20 02:09:13 leonardr Exp $
d983 1
a983 1
    protected List getProjectsWithOriginalRole()
d988 1
a988 1
    protected List getProjectsWithDerivedRole()
d1000 1
a1000 1
    protected List getOriginalRolesInProject(Project project)
d1005 1
a1005 1
    protected List getDerivedRolesInProject(Project project)
@


1.39
log
@I've gotten performance numbers from this test; taking the code out for now.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.38 2001/03/19 19:14:15 leonardr Exp $
a83 5
     * ACLs for users.
     */
    private static Map userACLs = new BufferCache(100);

    /**
d101 5
@


1.38
log
@Only base users have ACLs.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.37 2001/03/19 18:20:33 leonardr Exp $
a1079 79
    }

    ///////////////////////////////////////////////////////////////////////
    //Methods for dumping ACLs to the lookup cache.  Building the
    //lookup cache is horribly inefficient, taking about 3 minutes for
    //a site the size of tigris.org; my goal is to see if the time
    //saved by using the cache is worth having a cache at all. If it
    //is, I'll build the cache in a quicker way.
    ///////////////////////////////////////////////////////////////////////

    public static List getAllACLs()
        throws Exception
    {
        List users = UserPeer.doSelect(new Criteria().add(UserPeer.TYPE, User.REGULAR_TYPE));
        List acls = new ArrayList(users.size());
        for (Iterator i = users.iterator(); i.hasNext();)
        {
            User u = (User)i.next();
            acls.add(u.getACL());
        }
        return acls;
    }

    public static void dumpAllToCache()
        throws Exception
    {
        Log.debug("Started dumping to cache at " + new Date());
        for (Iterator i = getAllACLs().iterator(); i.hasNext();)
        {
            AccessControlList acl = (AccessControlList)i.next();
            acl.dumpToCache();
        }
        Log.debug("Done dumping to cache at " + new Date());
    }

    public void dumpToCache()
        throws Exception
    {
        //Log.debug("Dumping " + getUser().getLoginName());
        Criteria o = new Criteria()
            .add(UserProjectActionResourcePeer.USER_ID, getUser().getID());
        UserProjectActionResourcePeer.doDelete(o);
        for (Iterator i = getProjectsWithAnyRole().iterator(); i.hasNext();)
        {            
            Project p = (Project)i.next();
            //Log.debug(" Dumping " + p.getName());
            for (Iterator j = getAllRolesForProject(p).iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                //Log.debug("  Dumping " + r.getName());
                List permissions = r.getPermissions();
                for (Iterator k = permissions.iterator(); k.hasNext();)
                {
                    Permission perm = (Permission)k.next();
                    Action a = perm.getAction();
                    Resource res = perm.getResource();
                    if (a.isVersionControl())
                    {
                        Criteria c = new Criteria()
                            .add(UserProjectActionResourcePeer.USER_LOGIN_NAME, 
                                 getUser().getLoginName())
                            .add(UserProjectActionResourcePeer.USER_ID, 
                                 getUser().getID())
                            .add(UserProjectActionResourcePeer.PROJECT_NAME, 
                                 p.getName())
                            .add(UserProjectActionResourcePeer.PROJECT_ID, 
                                 p.getID())
                            .add(UserProjectActionResourcePeer.ACTION_NAME,
                                 a.getName())
                            .add(UserProjectActionResourcePeer.RESOURCE_PATTERN,
                                 res.getPattern());
                        try 
                        {
                            UserProjectActionResourcePeer.doInsert(c);
                        }catch (Exception ignore){}
                    }
                }
            }
        }
@


1.37
log
@First stab at denormalized ACL lookup helper table.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.36 2001/03/15 23:50:07 dlr Exp $
d1093 1
a1093 1
        List users = UserPeer.doSelect(new Criteria(0));
@


1.36
log
@Use a BufferCache to put an upper limit on the size of the class.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.35 2001/03/14 22:48:44 dlr Exp $
d1081 80
@


1.35
log
@* Increased debugging information.
* Moved some Lists from ArrayList to Vector for thread safety.
* Reduced accessibility on methods used only at a package scope.
* Refactored getProjectsWithRoleFromMap() from 6 lines to 1.
@
text
@d58 1
d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.34 2001/03/12 21:40:44 dlr Exp $
a77 1

d86 1
a86 1
    private static Map userACLs = Collections.synchronizedMap(new HashMap());
@


1.34
log
@Append primitive chars, not single character String objects.
@
text
@d73 1
a73 1
 * @@version $Id: AccessControlList.java,v 1.33 2001/03/09 01:24:23 leonardr Exp $
d756 2
a757 1
            for (Iterator i = rolesForProject.iterator(); i.hasNext();)
d763 2
a764 1
                              + action.getName() + '?');
d857 1
a857 1
        List all = new ArrayList();
d933 1
a933 1
            rolesForProject = new ArrayList();
d983 1
a983 1
    public List getProjectsWithOriginalRole()
d988 1
a988 1
    public List getProjectsWithDerivedRole()
d995 1
a995 1
    public List getProjectsWithRoleFromMap(Map t)
d997 1
a997 6
        List l = new ArrayList(t.size());
        for (Iterator i = t.keySet().iterator(); i.hasNext(); )
        {
            l.add((Project)i.next());
        }
        return l;
d1000 1
a1000 1
    public List getOriginalRolesInProject(Project project)
d1005 1
a1005 1
    public List getDerivedRolesInProject(Project project)
@


1.33
log
@More renaming madness as the act of 'project disabling' becomes 'project locking'
@
text
@d73 1
a73 1
 * @@version $Id: AccessControlList.java,v 1.32 2001/03/07 02:38:37 leonardr Exp $
d778 1
a778 1
                                               + "(" + role.getName() + ")");
@


1.32
log
@Corrected compile errors.
@
text
@d73 1
a73 1
 * @@version $Id: AccessControlList.java,v 1.31 2001/03/07 02:23:07 leonardr Exp $
d674 1
a674 1
        if (!project.isEnabled())
d677 1
a677 1
            if (actionObj.isAffectedByProjectDisable())
d683 1
a683 1
                              + " is disabled, not checking permission " 
d692 1
a692 1
            ok = hasPermissionIgnoreDisable(action, resource, project);
d709 2
a710 2
    public boolean hasPermissionIgnoreDisable (String action, String resource, 
                                               Project project)
@


1.31
log
@Put in check to fail certain permission checks when a project is disabled.
@
text
@d73 1
a73 1
 * @@version $Id: AccessControlList.java,v 1.30 2001/03/07 01:53:27 lucas Exp $
d676 2
a677 2
            Action actionObj = ActionPeer.getActionByName();
            if (actionObj.isAffectedByProjectDisable)
d692 1
a692 1
            ok = hasPermissionIgnoreDisable(action, project, resource);
@


1.30
log
@Corrected regex madness for Torque upgrade.  -dlr
@
text
@d73 1
a73 1
 * @@version $Id: AccessControlList.java,v 1.29 2001/02/23 21:19:19 leonardr Exp $
d659 3
a661 1
     * resource in a given project.
d673 41
d726 1
a726 1
        
a732 1

d736 1
d973 4
@


1.29
log
@Here's a revolutionary idea. If they don't have permission, throw an exception! It can't fail!
@
text
@a58 2
import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.base.*;
d73 1
a73 1
 * @@version $Id: AccessControlList.java,v 1.28 2001/02/22 18:08:29 leonardr Exp $
@


1.28
log
@Pedantically changed some formatting.
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.27 2001/02/21 01:08:25 dlr Exp $
d623 2
a624 1
        try {
d629 7
a635 1
        } catch (Exception e) {
d639 1
@


1.27
log
@This is the highest revision from the HELM_PEER_PORT_BRANCH.  The previous import caused too many conflicts to resolve manually
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.22 2001/02/16 03:01:34 dlr Exp $
d718 2
a719 1
                if (!includeRole) {
d722 2
a723 1
                else {
@


1.26
log
@readding all the files as part of the process of returning to the way
things were as of tuesday
@
text
@d2 1
a2 1
 * Copyright (c) 2000 CollabNet.  All rights reserved.
a49 4
import java.sql.*;
import java.io.PrintStream;

import org.webmacro.util.Log;
d54 2
a55 6
import com.workingdogs.village.*;

import org.apache.turbine.services.db.TurbineDB;
import org.apache.turbine.util.db.pool.DBConnection;

import org.joist.database.*;
d58 3
a60 4
import org.tigris.helm.database.*;
import org.tigris.helm.domain.User;
import org.tigris.helm.domain.Role;
import org.tigris.helm.project.Project;
d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.22 2001/01/23 20:38:00 leonardr Exp $
a78 4
    /**
     * Open the log file.
     */
    private static Log log = new Log("acl", "AccessControlList");
d83 1
a83 6
    private static boolean debug = true;

    /**
     * The ACL's data access.
     */
    private DataManager dMgr;
d94 2
a95 2
        "User read, " +
        "Role read," +
d110 1
a110 1
     * The user who this ACL is for.
d112 1
a112 1
    private String userID;
d115 2
a116 2
     * The user-specific portion of the ACL: a Hashtable keyed by 
     * Project to ArrayLists of Roles.
d118 1
a118 1
    private Hashtable originalRolesByProject;
d121 1
a121 1
     * Another Hashtable like rolesByProject but containing roles the
d124 1
a124 1
    private Hashtable derivedRolesByProject;
d127 1
a127 1
     * TODO
d132 2
a133 1
     * TODO
d138 4
a141 1
     * TODO
d146 1
a146 1
     * Static container of the permissions held by roles.
d148 6
a153 17
    private static Hashtable actionsByRole = new Hashtable();
       
    /**
     * Static mapping of users to user groups.
     */
    private static Hashtable userGroups = new Hashtable();

    /**
     * Static mapping of projects to project groups.
     */
    private static Hashtable projectGroups = new Hashtable();
       
    /**
     * A JDBC connection.
     */
    private Connection connection;

d155 1
a155 1
     * Static initializer--build the static hash tables.
d157 2
a158 1
    static
d160 2
a161 2
        DBConnection dbConn = null;
        try
d163 1
a163 47
            // Get a connection from the Turbine ConnectionPool.
            dbConn = TurbineDB.getConnection();
            Connection conn = dbConn.getConnection();
            Statement stmt = null;
            try
            {
                // Grab a light weight database lock.
                stmt = conn.createStatement();
                stmt.executeUpdate(LOCK_TABLES);
            }
            catch (Exception e)
            {
                log.info("Table locking/unlocking error in static " +
                          "initializer: " + e.getMessage());
                throw new RuntimeException(e.getMessage());
            }

            DataManager dMgr = new DataManager();
                                                         
            try
            {
                buildActionsByRole(conn, dMgr);            
                buildUserGroups(conn, dMgr);                
                buildProjectGroups(conn, dMgr);
            
                if (stmt != null)
                {
                    // Unlock the database tables.
                    stmt.executeUpdate(UNLOCK_TABLES);
                    stmt.close();
                }
            }
            catch (DataSetException e)
            {
                log.exception(e);
                throw new RuntimeException(e.getMessage());
            }
            catch (SQLException e)
            {
                log.exception(e);
                throw new RuntimeException(e.getMessage());
            }
            catch (JoistDatabaseException e)
            {
                log.exception(e);
                throw new RuntimeException(e.getMessage());
            }
d165 1
a165 1
        catch (Exception dbEx)
d167 1
a167 18
            log.info("Database error in static initiliazer: " + 
                      dbEx.getMessage());
            throw new RuntimeException(dbEx.getMessage());
        }
        finally
        {
            // Return the connection to the pool.
            if (dbConn != null)
            {
                try
                {
                    TurbineDB.releaseConnection(dbConn);
                }
                catch (Exception e)
                {
                    throw new RuntimeException(e.getMessage());
                }
            }
d169 1
d173 1
a173 1
     * Gets the ACL for the given userID, 
d175 2
a176 4
    public static AccessControlList getACL(Connection connection,
                                           DataManager dMgr,
                                           String userID)
        throws SQLException, DataSetException, JoistDatabaseException
d178 2
a179 2
        AccessControlList acl;
        if (userACLs.containsKey(userID))
d181 2
a182 3
            acl = (AccessControlList) userACLs.get(userID);
        } else {
            acl = rebuildACL(connection, dMgr, userID);
a185 14

    /**
     * Rebuilds the ACL for the given userID, 
     */
    public static AccessControlList rebuildACL(Connection connection,
                                               DataManager dMgr,
                                               String userID)
        throws SQLException, DataSetException, JoistDatabaseException
    {
        AccessControlList acl = new AccessControlList(connection, dMgr,
                                                      userID);
        userACLs.put(userID, acl);
        return acl;
    }
d190 10
a199 17
     * @@param conn    The JDBC database connection to use.
     * @@param dMgr    The <code>DataManager</code> to get 
     *                 <code>TableManager</code>s from.
     * @@param userID  The database key of the user whose ACL is desired.
     *
     * @@exception DataSetException Village error.
     * @@exception SQLException     Generic database error.
     */
    public AccessControlList (Connection connection, DataManager dMgr, 
                              String userID)
        throws DataSetException, SQLException, JoistDatabaseException
    {
        this.connection = connection;
        this.userID = userID;
        this.dMgr = dMgr;
        this.originalRolesByProject = new Hashtable();
        this.derivedRolesByProject = new Hashtable();
d202 2
a203 2
        //dumpStatic();
        //dump();                
a206 35
     * Constructs the list of roles the user has in projects.
     */
    private void constructOriginalRolesByProject()
        throws DataSetException, SQLException, JoistDatabaseException
    {
        UserRoleProjectManager urpMgr = (UserRoleProjectManager)
            dMgr.getManager("org.tigris.helm.database.UserRoleProjectManager");
        
        originalRolesByProject = new Hashtable();

        ArrayList effectiveUserIDs = new ArrayList();
        ArrayList userGroupsForUser = (ArrayList)userGroups.get(userID);
        effectiveUserIDs.add(userID);        
        if (userGroupsForUser != null)
        {
            effectiveUserIDs.addAll(userGroupsForUser);
        }
        
        DataSet roles = urpMgr.getRolesProjectsForUsers
            (connection, effectiveUserIDs);
        Record role = null;
        String roleID = null;
        String projectID = null;
        ArrayList rolesForProject = null;
        for (int i = 0; i < roles.size(); i++)
        {
            role = roles.getRecord(i);
            roleID = role.getValue(UserRoleProjectManager.ROLE_ID).toString();
            projectID = role.getValue(UserRoleProjectManager.PROJECT_ID)
                .toString();
            addRoleToRolesByProject(roleID, projectID, ORIGINAL);
        }
    }
    
    /**
d213 1
a213 1
        return userID;
a221 2
        throws SQLException, DataSetException, JoistDatabaseException, 
               DoesNotExist
d223 1
a223 1
        return User.getInstance(connection, dMgr, userID);
d237 2
a238 2
    public void assertRole (String roleID)
        throws ACLException
d240 1
a240 1
        if (!hasRole(roleID))
d242 1
a242 1
            throw new ACLException(this, roleID, "Host", null);
d252 2
a253 1
    public boolean hasRole (String roleID)
d255 1
a255 1
        return hasRoleInDomain(roleID, null);
d264 2
a265 1
    public boolean hasRoleInHost (String roleID)
d267 7
a273 1
        return hasRole(roleID);
d280 1
a280 1
     * @@param domainID The domain to check for the role in.
d283 2
a284 1
    public boolean hasRoleInDomain (String roleID, String domainID)
d286 1
a286 6
        ProjectManager pMgr = (ProjectManager)
            dMgr.getManager("org.tigris.helm.database.ProjectManager");
        String projectID = (domainID != null ? 
                            pMgr.getDomainProjectID(domainID) : 
                            pMgr.getHostProjectID());
        return hasRoleInProject(roleID, projectID);
d293 1
a293 1
     * @@param domainID The domain to check for the role in.
d296 8
a303 1
    public boolean hasRoleInPublicDomainProjects (String roleID, String domainID)
d305 1
a305 6
        ProjectManager pMgr = (ProjectManager)
            dMgr.getManager("org.tigris.helm.database.ProjectManager");
        String projectID = (domainID != null ? 
                            pMgr.getPublicDomainProjectID(domainID) : 
                            pMgr.getHostProjectID());
        return hasRoleInProject(roleID, projectID);
d315 1
a315 1
    public boolean hasRoleInProject (String roleID, String projectID)
d319 2
a320 2
        ArrayList rolesForProject = getOriginalRolesForProject(projectID);
        if (rolesForProject != null && rolesForProject.contains(roleID))
d336 29
d368 2
a369 2
    public void assertPermissionForHost (String action)
        throws ACLException
d371 1
a371 1
        if (!hasPermissionForHost(action))
d384 2
a385 1
    public boolean hasPermissionForHost (String action)
d387 1
a387 3
        ProjectManager pMgr = (ProjectManager)
            dMgr.getManager("org.tigris.helm.database.ProjectManager");
        return hasPermission(action, pMgr.getHostProjectID());
d398 3
d402 2
a403 2
     * @@param domainID The domain to check.
     * @@exception ACLException If user doesn't have permission.
d405 2
a406 2
    public void assertPermissionForDomain (String action, String domainID)
        throws ACLException
d408 1
a408 1
        assertPermissionForDomain(action, null, domainID);
d410 1
a410 1

d415 3
d420 2
a421 2
     * @@param domainID   The domain to check.
     * @@exception ACLException If user doesn't have permission.
d424 19
a442 2
                                           String domainID)
        throws ACLException
d444 1
a444 5
        if (!hasPermissionForDomain(action, resource, domainID))
        {
            throw new ACLException(this, action, "Domain " + domainID,
                                   resource);
        }
d452 1
a452 1
     * @@param domainID The domain ID to check permission in.
d455 2
a456 1
    public boolean hasPermissionForDomain (String action, String domainID)
d458 34
a491 1
        return hasPermissionForDomain (action, null, domainID);
d500 1
a500 1
     * @@param domainID The domain ID to check permission in.
d503 3
a505 2
    public boolean hasPermissionForDomain (String action, String resource,
                                           String domainID)
d508 7
a514 18
        ProjectManager pMgr = (ProjectManager)
            dMgr.getManager("org.tigris.helm.database.ProjectManager");
        DomainManager domMgr = (DomainManager)
            dMgr.getManager("org.tigris.helm.database.DomainManager");
        String hostProjectID = pMgr.getHostProjectID();
        String hostDomainID = null;
        try {
            hostDomainID = domMgr.getHostDomainID();
        } catch (JoistDatabaseException ignore) {
        } catch (DataSetException ignore) {
        }
        if (!domainID.equals(hostDomainID))
        {
            String domainProjectID = pMgr.getDomainProjectID(domainID);
            String publicDomainProjectID = 
                pMgr.getPublicDomainProjectID(domainID);
            if (hasPermission(action, resource, domainProjectID)
                || hasPermission(action, resource, publicDomainProjectID))
d520 1
a520 1
        if (hasPermission(action, resource, hostProjectID))
a523 1

d535 1
d537 1
a537 1
     * @@param projectID The project to check.
d540 1
a540 1
    public void assertPermissionForProject (String action, String projectID)
d543 1
a543 1
        assertPermissionForProject(action, null, projectID);
d550 1
d553 1
a553 1
     * @@param projectID  The project to check.
d557 1
a557 1
                                            String projectID)
d560 1
a560 5
        if (!hasPermissionForProject(action, resource, projectID))
        {
            throw new ACLException(this, action, "Project " + projectID,
                                   resource);
        }
d567 1
d569 1
a569 1
     * @@param projectID The project to check for.
d572 2
a573 1
    public boolean hasPermissionForProject (String action, String projectID)
d575 1
a575 1
        return hasPermission(action, projectID);
d582 1
d584 1
a584 1
     * @@param projectID The project to check for.
d588 17
a604 1
                                            String projectID)
d606 1
a606 1
        return hasPermission(action, resource, projectID);
d609 25
d642 1
a642 1
     * @@param projectID The project to which the action applies.
d645 2
a646 1
    public boolean hasPermission (String action, String projectID)
d648 1
a648 1
        return hasPermission(action, null, projectID);
d657 1
a657 1
     * @@param projectID The project to which the action applies.
d661 2
a662 1
                                  String projectID)
d664 1
d666 3
a668 2
            getResourcesForActionInProject(action, projectID, false);
        if (resourcesForAction != null)
d670 2
a671 2
            String scope = null;
            for (Iterator j = resourcesForAction.iterator(); j.hasNext();)
d673 2
a674 11
                scope = (String)j.next();
                if (resourceMatchesScope(resource, scope))
                {
                    /*if (debug) 
                      log.info("Role " + roleID + 
                      " has permission " + action + "/" 
                      + resource + " in project" 
                      + projectID);*/
                        
                    return true;
                }
d676 1
a676 1
        }        
d678 16
a693 6
        //No role has the right permissions--fail.
        /*if (debug) log.info("User " + getUserID() 
                            + " lacks permission " + action + "/" 
                            + resource + " in project" + projectID);*/
        
        return false;
d696 3
a698 2
    public List getResourcesForActionInProject(String action, String projectID,
                                               boolean includeRole)
d700 1
d704 1
a704 1
        List rolesForProject = getAllRolesForProject(projectID);        
d709 2
a710 6
                String roleID = (String)i.next();
                /*if (debug) log.info("Does role " + roleID + " have action " 
                  + action + '?');*/
                Hashtable actionsForRole = 
                    (Hashtable)actionsByRole.get(roleID);
                if (actionsForRole != null)
d712 5
a716 20
                    //Get the extents to which the role holds this action.
                    ArrayList resourcesForActionRole = 
                        (ArrayList)actionsForRole.get(action);
                    if (resourcesForActionRole != null)
                    {
                        if (!includeRole)
                        {
                            resourcesForAction.addAll(resourcesForActionRole);
                        } else {
                            for (Iterator j = 
                                     resourcesForActionRole.iterator();
                                 j.hasNext();)
                            {
                                String resource = (String)j.next();
                                try {
                                    Role role = new Role(connection, dMgr, roleID);
                                    resourcesForAction.add(resource + "(" + role.getName() + ")");
                                } catch (Exception e) {
                                    resourcesForAction.add(resource + "(Role " + roleID + ")");
                                }
d718 2
a719 3
                            }
                        }
                    }
d721 3
a723 50
            }
        }
        return resourcesForAction;
    }

    /**
     * Returns the conjunction of the user's original and derived roles
     * in a project.
     *
     * @@param projectID  The project to obtain roles for
     */
    private ArrayList getAllRolesForProject(String projectID)
    {        
        // Give us the derived roles we have in this project via
        // project groups.  

        // TODO: Use HaveExpandedProject to only do this when
        // neccessary.

        expandRolesForProject(projectID);
        
        ArrayList original = (ArrayList)originalRolesByProject.get(projectID);
        ArrayList derived = (ArrayList)derivedRolesByProject.get(projectID);
        ArrayList all = new ArrayList();
        if (original != null)
        {
            all.addAll(original);
        } 
        if (derived != null)
        {
            all.addAll(derived);
        }
        return all;
    }

    private void expandRolesForProject(String projectID)
    {
        ArrayList groupsForProject = 
            (ArrayList)projectGroups.get(projectID);
        if (groupsForProject != null)
        {
            for (Iterator i = groupsForProject.iterator(); i.hasNext();)
            {
                String projectGroupID = (String)i.next();
                ArrayList rolesForGroup = 
                    getOriginalRolesForProject(projectGroupID);
                if (rolesForGroup != null)
                {
                    for (Iterator j = rolesForGroup.iterator(); 
                         j.hasNext();)
d725 3
a727 6
                        String derivedRoleID = (String)j.next();
                        /*log.info("User has role " + derivedRoleID 
                          + " in project " + projectID 
                          + " via project " + projectGroupID);*/
                        addRoleToRolesByProject(derivedRoleID, projectID, 
                                                DERIVED);
a730 33
        }              
    }
    
    /**
     * Returns the user's original roles in a project.
     *
     * @@param projectID  The project to obtain roles for.
     */
    private ArrayList getOriginalRolesForProject(String projectID)
    {
        return (ArrayList)originalRolesByProject.get(projectID);
    }
    
    /**
     * Adds a role in a project to the appropriate RolesByProject
     * hash.
     * <p>
     * TODO: Make this take a bunch of roles for better
     * efficiency.
     *
     * @@param roleID    The role to add.
     * @@param projectID  The project in which the user has the role.
     */
    private void addRoleToRolesByProject(String roleID, String projectID,
                                         boolean original)
    {
        ArrayList rolesForProject = null;
        Hashtable hash = original?originalRolesByProject:derivedRolesByProject;
        if (hash.containsKey(projectID))
        {
            rolesForProject = (ArrayList)hash.get(projectID);
        } else {
            rolesForProject = new ArrayList();
d732 1
a732 6
        
        if (!rolesForProject.contains(roleID))
        {
            rolesForProject.add(roleID);
        }        
        hash.put(projectID, rolesForProject);
d734 1
a734 1

d744 2
a745 3
        //        if (debug) log.info("Does '" + resource + "' match '" + scope + "'?");
        boolean isMatch = (resource == null ||
                           resource.equals(""));
d747 1
a747 1
        // If the match is immediately evident, compare resource to scope.
d763 5
a767 3
        //        if (isMatch) log.info("Resource matches.");
        //        else log.info("Resource does not match.");

d771 4
d776 1
a776 3
     * Given a project ID, fills rolesForProject{projectID} with
     * an ArrayList containing the roles the user has in that 
     * project.
d778 1
a778 3
     * @@param resource The resource to check access to.
     * @@param scope    The scope of the user's action.
     * @@return         Whether the resource and scope match.
d780 1
a780 2
    private ArrayList buildRolesForProject(String projectID)
        throws DataSetException, SQLException, JoistDatabaseException
d782 1
a782 36
        //For each userID representing the user:
        // Get the list of roles that userID has in the given project.
        // Add it to the big list
        //Return the big list

        ArrayList roles = new ArrayList();

        UserUserGroupManager usrGrpMgr = (UserUserGroupManager) 
            dMgr.getManager("org.tigris.helm.database.UserUserGroupManager");

        UserRoleProjectManager urpMgr = (UserRoleProjectManager) 
            dMgr.getManager("org.tigris.helm.database.UserRoleProjectManager");

        DataSet userGroups = usrGrpMgr.getCompositesForBase(connection, userID);
        String groupID;
        boolean done = false;
        for (int i = 0; i < userGroups.size() && done == false; i++)
        {
            if (i < userGroups.size())
            {
                groupID = userGroups.getRecord(i)
                    .getValue(usrGrpMgr.getJoinCompositeField()).toString();
            } else {
                done = true;
                groupID = userID;
            }
            DataSet roleSet = 
                urpMgr.getRolesForUserProject(connection, userID, projectID);
            for (int j = 0; j < roleSet.size(); j++)
            {
                roles.add(roleSet.getRecord(i)
                          .getValue(UserRoleProjectManager.ROLE_ID));
            }
                
        }
        return roles;
a784 1

d786 2
a787 1
     * Clears and populates the static actionsByRole Hashtable.
d789 1
a789 5
     * @@param connection A JDBC connection
     * @@param dMgr a DataManager
     * @@exception DataSetException
     * @@exception SQLExceptio
     * @@exception JoistDatabaseException 
d791 2
a792 3
    public static void buildActionsByRole(Connection conn, 
                                          DataManager dMgr)
        throws DataSetException, SQLException, JoistDatabaseException
d794 2
a795 1
        actionsByRole.clear();
d797 2
a798 2
        ActionManager actMgr = (ActionManager) dMgr
            .getManager("org.tigris.helm.database.ActionManager");
d800 1
a800 2
        ResourceManager resMgr = (ResourceManager)dMgr
            .getManager("org.tigris.helm.database.ResourceManager");        
d802 27
a828 69
        RoleActionResourceManager rarMgr = (RoleActionResourceManager) dMgr.
            getManager("org.tigris.helm.database.RoleActionResourceManager");
        
        RoleManager roleMgr = (RoleManager) dMgr.
            getManager("org.joist.database.RoleManager");        
        
        //Build actionsByRole.
        // Get a list of all the roles
        // For each role:
        //  Get a list of all the permissions for that role
        //  For each permission:
        //   Add the extent of this permission to an ArrayList keyed
        //    to the action ID.
        //  Key the Hashtable to the role ID
        DataSet roleSet = roleMgr.listRoles(conn);
        for (int i = 0; i < roleSet.size(); i++)
        {
            Hashtable actionsForRole = new Hashtable();
            Record roleRecord = roleSet.getRecord(i);
            String roleID = 
                roleRecord.getValue(RoleManager.ROLE_ID).asString();
            
            // Get all Permissions (Actions on Resources) granted
            // by this Role.
            DataSet permissionSet = 
                rarMgr.getActionsResourcesForRole(conn, roleID);
            
            ArrayList resourcesForAction = new ArrayList();
            
            // For each Permission (Action + Resource) granted by this
            // Role, give permissions an entry for the Action,
            // keyed to an ArrayList which contains (at least) the
            // Resources granted to that Action by this Permission.
            for (int j = 0; j < permissionSet.size(); j++)
            {                    
                Record permissionRecord = permissionSet.getRecord(j);
                    
                String actionID = permissionRecord
                    .getValue(RoleActionResourceManager.ACTION_ID)
                    .asString();
                    
                String actionName = actMgr.actionName(actionID);
                
                String resourceID = permissionRecord
                    .getValue(RoleActionResourceManager.RESOURCE_ID)
                    .asString();

                String resourceName = resMgr.getResourceName(conn, 
                                                             resourceID);
            
                // If no other Permission for this role (so far)
                // grants the same Action, create a new ArrayList
                // for the action. Otherwise, get the old ArrayList
                // from the Hashtable.
                if (actionsByRole.containsKey(actionName))
                {   
                    resourcesForAction = (ArrayList)actionsByRole
                        .get(actionName);
                }
                else
                {
                    resourcesForAction = new ArrayList();
                }                 
                
                resourcesForAction.add(resourceName);
                
                // Add to the description of this Role the Resources for
                // which it has this Action.
                actionsForRole.put(actionName, resourcesForAction);
a829 1
            actionsByRole.put(roleID, actionsForRole);
d831 1
a831 2

    }
d834 1
a834 6
     * Clears and populates the static userGroups Hashtable.
     *
     * @@param connection A JDBC connection
     * @@param dMgr a DataManager 
     * @@exception DataSetException
     * @@exception SQLException
d836 6
a841 8
    public static void buildUserGroups(Connection conn, 
                                       DataManager dMgr)
        throws DataSetException, SQLException
    {        
        userGroups.clear();

        UserManager uMgr = (UserManager)dMgr
            .getManager("org.joist.database.UserManager");
d843 2
a844 2
        UserUserGroupManager usrGrpMgr = (UserUserGroupManager) 
            dMgr.getManager("org.tigris.helm.database.UserUserGroupManager");
d846 14
a859 20
        //Build userGroups.
        // Get a list of all the users
        // For each user:
        //   Get a list of all the groups to which that user belongs.
        //   Turn the list into an ArrayList
        //   Key the list to the user ID
        DataSet userSet = uMgr.getUserList(conn);
        for (int i = 0; i < userSet.size(); i++)
        {
            ArrayList groupsForUser = new ArrayList(); 
            String userID = userSet.getRecord(i).getValue(uMgr.USER_ID)
                .toString();
            DataSet groupSet = usrGrpMgr.getCompositesForBase(conn, userID);
            for (int j = 0; j < groupSet.size(); j++)
            {
                String groupID = groupSet.getRecord(j)
                    .getValue(usrGrpMgr.getJoinCompositeField()).toString();
                groupsForUser.add(groupID);
            }
            userGroups.put(userID, groupsForUser);
a860 1
        
d862 1
a862 1

d864 5
a868 1
     * Clears and populates the static projectGroups Hashtable.
d870 11
a880 34
     * @@param connection A JDBC connection
     * @@param dMgr a DataManager 
     * @@exception DataSetException
     * @@exception SQLException
     */
    public static void buildProjectGroups(Connection conn, 
                                          DataManager dMgr)
        throws DataSetException, SQLException
    {        
        projectGroups.clear();

        ProjectManager pMgr = (ProjectManager)dMgr.
            getManager("org.tigris.helm.database.ProjectManager");        
        
        ProjectProjectGroupManager prjGrpMgr =  (ProjectProjectGroupManager)
            dMgr.getManager
            ("org.tigris.helm.database.ProjectProjectGroupManager");

        DataSet projectSet = pMgr.getAllProjects(conn);
        for (int i = 0; i < projectSet.size(); i++)
        {
            ArrayList groupsForProject = new ArrayList(); 
            String projectID = null;
            
            projectID = projectSet.getRecord(i)
                .getValue(ProjectManager.PROJECT_ID).toString();
            DataSet groupSet = prjGrpMgr.getCompositesForBase(conn, projectID);
            for (int j = 0; j < groupSet.size(); j++)
            {
                String groupID = groupSet.getRecord(j)
                    .getValue(prjGrpMgr.getJoinCompositeField()).toString();
                groupsForProject.add(groupID);
            }
            projectGroups.put(projectID, groupsForProject);
d882 6
d890 3
a892 3
    /********************************************************
     *The following are dump functions for debugging.
     ********************************************************/
d895 1
d897 2
a898 1
        for (Enumeration e = projectGroups.keys(); e.hasMoreElements(); )
d900 2
a901 2
            String projectID = (String)e.nextElement();
            expandRolesForProject(projectID);
d906 1
a906 1
        throws SQLException, DataSetException, DoesNotExist
d909 4
a912 4
        List a = getProjectsWithOriginalRole();
        if (a != null) p.addAll(a);
        List b = getProjectsWithDerivedRole();
        if (b != null)
d914 1
a914 1
            for (Iterator i = b.iterator(); i.hasNext();)
a925 1

a926 1
        throws SQLException, DataSetException, DoesNotExist
d928 1
a928 1
        return getProjectsWithRoleFromHash(originalRolesByProject);
d932 1
a932 1
        throws SQLException, DataSetException, DoesNotExist
d935 1
a935 1
        return getProjectsWithRoleFromHash(derivedRolesByProject);
d937 2
a938 3

    public List getProjectsWithRoleFromHash(Hashtable t)
        throws SQLException, DataSetException, DoesNotExist
d940 2
a941 2
        ArrayList projects=new ArrayList();
        if (t != null)
d943 1
a943 6
            for (Enumeration e = t.keys(); e.hasMoreElements(); )
            {
                String projectID = (String)e.nextElement();
                Project project = new Project(connection, dMgr, projectID);
                projects.add(project);
            }
d945 1
a945 1
        return projects;
a948 1
        throws SQLException, DataSetException, DoesNotExist
d950 1
a950 1
        return getRolesInProjectFromHash(project, originalRolesByProject);
a953 1
        throws SQLException, DataSetException, DoesNotExist
d955 1
a955 1
        return getRolesInProjectFromHash(project, derivedRolesByProject);
d958 1
a958 2
    private List getRolesInProjectFromHash(Project project, Hashtable t)
        throws SQLException, DataSetException, DoesNotExist
d960 2
a961 3
        ArrayList roles = new ArrayList();
        ArrayList roleIDs = (ArrayList)t.get(project.getID());
        for (Iterator i = roleIDs.iterator(); i.hasNext();)
d963 6
a968 1
            roles.add(new Role(connection, dMgr, (String)i.next()));
d970 2
a971 1
        return roles;
d979 1
a979 1
        if (!debug) return;
d981 1
a981 1
        s.append("\noriginalRolesByProject for userID "+ userID + ":\n");
d983 2
a984 2
        for (Enumeration e = originalRolesByProject.keys();
             e.hasMoreElements(); )
d986 5
a990 5
            String projectID = (String)e.nextElement();
            ArrayList rolesForProject = 
                (ArrayList)originalRolesByProject.get(projectID);
            s.append(" Roles for project " + projectID + ": ");
            for (Iterator i = rolesForProject.iterator(); i.hasNext();)
d992 2
a993 1
                s.append((String)i.next() + " ");
d998 2
a999 1
        s.append("\nderivedRolesByProject for userID "+ userID + ":\n");
d1001 2
a1002 2
        for (Enumeration e = derivedRolesByProject.keys();
             e.hasMoreElements(); )
d1004 5
a1008 5
            String projectID = (String)e.nextElement();
            ArrayList rolesForProject = 
                (ArrayList)derivedRolesByProject.get(projectID);
            s.append(" Roles for project " + projectID + ": ");
            for (Iterator i = rolesForProject.iterator(); i.hasNext();)
d1010 2
a1011 1
                s.append((String)i.next() + " ");
d1016 1
a1016 1
        log.info(s.toString());        
d1024 4
a1027 55
        if (!debug) return;
        AccessControlList.dumpActionsByRole();
        AccessControlList.dumpUserGroups();
        AccessControlList.dumpProjectGroups();
    }

    /**
     * Logs the mapping of roles to actions and extents.
     */
    private static void dumpActionsByRole()
    {
        if (!debug) return;
        StringBuffer s = new StringBuffer();
        s.append("AccessControlList actionsByRole:\n");
        for (Enumeration f = actionsByRole.keys(); f.hasMoreElements();)
        {
            String roleName = (String)f.nextElement();
            s.append(" " + roleName + ":\n");
            Hashtable actionsForRole = (Hashtable)actionsByRole.get(roleName);
            for (Enumeration g = actionsForRole.keys(); g.hasMoreElements();)
            {
                String actionName = (String)g.nextElement();
                s.append("  " + actionName + ": ");
                ArrayList resourcesForAction = (ArrayList)actionsForRole.get(actionName);
                for (int i = 0; i < resourcesForAction.size(); i++)
                {
                    s.append((String)resourcesForAction.get(i) + ' ');
                }
                s.append("\n");                
            }
            s.append("\n");
        }
        log.info(s);
    }

    /**
     * Logs the mapping of users to user groups.
     */
    private static void dumpUserGroups()
    {
        if (!debug) return;
        StringBuffer s = new StringBuffer();
        s.append("AccessControlList userGroups dump:\n");
        for (Enumeration f = userGroups.keys(); f.hasMoreElements();)
        {
            String userID = (String)f.nextElement();
            s.append(" User " + userID + " belongs to these groups: ");
            ArrayList groupsForUser = (ArrayList)userGroups.get(userID);
            for (int i = 0; i < groupsForUser.size(); i++)
            {
                s.append((String)groupsForUser.get(i) + ' ');
            }
            s.append("\n");
        }
        log.info(s);
a1028 24

    /**
     * Logs the mapping of projects to project groups.
     */
    private static void dumpProjectGroups()
    {
        if (!debug) return;
        StringBuffer s = new StringBuffer();
        s.append("AccessControlList projectGroups dump:\n");
        for (Enumeration f = projectGroups.keys(); f.hasMoreElements();)
        {
            String projectID = (String)f.nextElement();
            s.append(" Project " + projectID + " belongs to these groups: ");
            ArrayList projectsForUser = 
                (ArrayList)projectGroups.get(projectID);
            for (int i = 0; i < projectsForUser.size(); i++)
            {
                s.append((String)projectsForUser.get(i) + ' ');
            }
            s.append("\n");
        }
        log.info(s);
    }

@


1.26.2.1
log
@Porting to the Turbine Peer system.  -dlr and leonardr
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.26 2001/01/26 18:29:08 edk Exp $
@


1.26.2.2
log
@Classes ported to the Turbine Peer system. -dlr and leonardr
@
text
@d49 4
a54 2
import java.util.*;

d58 12
a69 5
import org.tigris.helm.om.User;
//import org.tigris.helm.om.Role;
import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.Project;
import org.tigris.helm.om.Domain;
d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.24 2001/01/24 21:41:50 leonardr Exp $
d96 6
a101 1
    private static final boolean DEBUG = true;
d112 2
a113 2
        "HELM_USER read, " +
        "HELM_ROLE read," +
d133 2
a134 2
     * The user-specific portion of the ACL: a Map keyed by 
     * Project to Lists of Roles.
d136 1
a136 1
    private Map originalRolesByProject;
d139 1
a139 1
     * Another Map like rolesByProject, but containing roles the
d142 1
a142 1
    private Map derivedRolesByProject;
d145 1
a145 1
     * Indicates that a role is original (granted directly to a project)
d150 1
a150 2
     * Indicates that a role is derived (granted to a project group which
     * contains a project)
d158 21
a178 1
              
d182 419
d602 117
a718 86
//     static
//     {
//         DBConnection dbConn = null;
//         try
//         {
//             // Get a connection from the Turbine ConnectionPool.
//             dbConn = TurbineDB.getConnection();
//             Connection conn = dbConn.getConnection();
//             Statement stmt = null;
//             try
//             {
//                 // Grab a light weight database lock.
//                 stmt = conn.createStatement();
//                 stmt.executeUpdate(LOCK_TABLES);
//             }
//             catch (Exception e)
//             {
//                 log.info("Table locking/unlocking error in static " +
//                           "initializer: " + e.getMessage());
//                 throw new RuntimeException(e.getMessage());
//             }

//             try
//             {
//                 if (stmt != null)
//                 {
//                     // Unlock the database tables.
//                     stmt.executeUpdate(UNLOCK_TABLES);
//                     stmt.close();
//                 }
//             }
//             catch (DBException e)
//             {
//                 log.exception(e);
//                 throw new RuntimeException(e.getMessage());
//             }
//         }
//         catch (Exception dbEx)
//         {
//             log.info("Database error in static initiliazer: " + 
//                       dbEx.getMessage());
//             throw new RuntimeException(dbEx.getMessage());
//         }
//         finally
//         {
//             // Return the connection to the pool.
//             if (dbConn != null)
//             {
//                 try
//                 {
//                     TurbineDB.releaseConnection(dbConn);
//                 }
//                 catch (Exception e)
//                 {
//                     throw new RuntimeException(e.getMessage());
//                 }
//             }
//         }
//     }

//     /**
//      * Gets the (possibly cached) ACL for the given userID, 
//      */
//     public static AccessControlList getACL(String userID)
//         throws Exception
//     {
//         AccessControlList acl;
//         if (userACLs.containsKey(userID))
//         {
//             acl = (AccessControlList)userACLs.get(userID);
//         } else {
//             acl = rebuildACL(userID);
//         }
//         return acl;
//     }

//     /**
//      * Rebuilds the ACL for the given userID, 
//      */
//     public static AccessControlList rebuildACL(String userID)
//         throws Exception
//     {
//         AccessControlList acl = new AccessControlList(userID);
//         userACLs.put(userID, acl);
//         return acl;
//     }
d720 63
a782 369
//     /**
//      * Instantiates a new ACL for the specified user.
//      *
//      * @@param userID  The database key of the user whose ACL is desired.
//      *
//      * @@exception Exception     Generic database error.
//      */
//     public AccessControlList (String userID)
//         throws Exception
//     {
//         this.userID = userID;
//         this.originalRolesByProject = new HashMap();
//         this.derivedRolesByProject = new HashMap();
//         constructOriginalRolesByProject();
//         haveExpandedProject = new HashMap();
//         dumpStatic();
//         dump();                
//     }

     /**
      * Get the ID of the user whose ACL this is.
      *
      * return A user ID.
      */
     public String getUserID()
     {
         return userID;
     }

     /**
      * Get the User whose ACL this is.
      *
      * return A User object.
      */
     public User getUser()
         throws Exception
     {
         return UserPeer.getInstance(userID);
     }

//     ///////////////////////////////////////////////////////////////////////
//     // Roles.
//     ///////////////////////////////////////////////////////////////////////

//      /**
//       * Throws an exception if user's ACL doesn't have the specified role.
//       *
//       * @@param roleID The role to check for.
//       *
//       * @@exception ACLException If user doesn't have the role.
//       */
//      public void assertRole (String roleID)
//          throws ACLException
//      {
//          if (!hasRole(roleID))
//          {
//              throw new ACLException(this, roleID, "Host", null);
//          }
//      }

//      /**
//       * Checks whether the user's ACL has the role in the host/cluster.
//       *
//       * @@param roleID The role to check for.
//       * @@return       Whether access is allowed.
//       */
//      public boolean hasRole (String roleID)
//      {
//          return hasRoleInDomain(roleID, null);
//      }

//      /**
//       * Checks whether the user's ACL has the role in the host.
//       *
//       * @@param roleID   The role to check for.
//       * @@return         Whether the user has the role.
//       */
//      public boolean hasRoleInHost (int roleID)
//      {
//          return hasRole(roleID);
//      }

//      /**
//      * Checks whether the user's ACL has the role in the specified domain.
//      *
//       * @@param roleID   The role to check for.
//       * @@param domain   The domain to check for the role in.
//       * @@return         Whether access is allowed.
//       */
//      public boolean hasRoleInDomain (String roleID, Domain domain)
//      {
//          int projectID = (domainID != null ? 
//                              Project.getDomainProject(domainID).getID(): 
//                              Project.hostProject().getID());
//          return hasRoleInProject(roleID, projectID);
//          return true;
//      }

//     /**
//      * Checks whether the user's ACL has the role in the group of public projects in the specified domain.
//      *
//      * @@param roleID   The role to check for.
//      * @@param domain   The domain to check for the role in.
//      * @@return         Whether access is allowed.
//      */
//     public boolean hasRoleInPublicDomainProjects (String roleID, Domain domain)
//     {
//         String projectID = (domainID != null ? 
//                             Project.getPublicDomainProject
//                             (domainID).getID() :
//                             ProjectPeer.getHostProject().getID());
//         return hasRoleInProject(rolID, projectID);
//     }

//     /**
//      * Checks whether the user's ACL has the role in the specified project.
//      *
//      * @@param roleID    The role to check for.
//      * @@param projectID The domain to check for the role in.
//      * @@return          Whether access is allowed.
//      */
//     public boolean hasRoleInProject (String roleID, String projectID)
//     {
//         boolean flag = false;

//         List rolesForProject = getOriginalRolesForProject(projectID);
//         if (rolesForProject != null && rolesForProject.contains(roleID))
//         {
//             flag = true;
//         }
        
//         return flag;
//     }

//     ///////////////////////////////////////////////////////////////////////
//     // Host permissions.
//     ///////////////////////////////////////////////////////////////////////

     /**
      * Throws an exception if user's ACL doesn't have permission to perform
      * an action on the host.
      *
      * @@param action   The action to check for.
      * @@exception ACLException If user doesn't have permission.
      */
     public void assertPermissionForHost (String action)
         throws ACLException, Exception
     {
         if (!hasPermissionForHost(action))
         {
             throw new ACLException(this, action, "Host", null);
         }
     }

     /**
      * Checks whether the user's ACL has permission to perform an action
      * on the host.
      *
      * @@param action   The action to check for.
      * @@return         Whether access is allowed.
      */
     public boolean hasPermissionForHost (String action)
         throws Exception
     {
         return hasPermissionForProject(action, ProjectPeer.getHostProject());
     }

     ///////////////////////////////////////////////////////////////////////
     // Domain permissions.
     ///////////////////////////////////////////////////////////////////////

     /**
      * Throws an exception if user's ACL doesn't have permission to perform
      * an action on a domain.
      *
      * @@param action   The action to check for.
      * @@param domain   The domain to check.
      * @@exception ACLException If user doesn't have permission.
      */
     public void assertPermissionForDomain (String action, Domain domain)
         throws ACLException, Exception
     {
         assertPermissionForDomain(action, null, domain);
     }

     /**
      * Throws an exception if user's ACL doesn't have permission to perform
      * an action on a resource in a domain.
      *
      * @@param action     The action to check for.
      * @@param resource   The resource to check.
      * @@param domain     The domain to check.
      * @@exception ACLException If user doesn't have permission.
      */
     public void assertPermissionForDomain (String action, String resource, 
                                            Domain domain)
         throws ACLException, Exception
     {
         if (!hasPermissionForDomain(action, resource, domain))
         {
             throw new ACLException(this, action, "Domain " + domain.getName(),
                                    resource);
         }
     }

     /**
      * Checks whether the user's ACL has permission to perform an action
      * on a domain.
      *
      * @@param action   The action to check for.
      * @@param domain   The domain to check permission in.
      * @@return         Whether access is allowed.
      */
     public boolean hasPermissionForDomain (String action, Domain domain)
         throws Exception
     {
         return hasPermissionForDomain (action, null, domain);
     }

     /**
      * Checks whether the user's ACL has permission to perform an action
      * on a resource in a domain.
      *
      * @@param action   The action to check for.
      * @@param resource The resrouce to check.
      * @@param domain   The domain to check permission in.
      * @@return         Whether access is allowed.
      */
     public boolean hasPermissionForDomain (String action, String resource,
                                            Domain domain)
         throws Exception
     {
         boolean ok = false;
         Project hostProject = ProjectPeer.getHostProject();
         Project domainProject = ProjectPeer.getDomainProject(domain);
         if (!hostProject.equals(domainProject))
         {
             Project publicDomainProject = ProjectPeer.getPublicDomainProject(domain);
             if (hasPermission(action, resource, domainProject)
                 || hasPermission(action, resource, publicDomainProject))
             {
                 ok = true;
             }
         }

         if (ok == false && hasPermission(action, resource, hostProject))
         {
             ok = true;
         }

         return ok;
     }

     ///////////////////////////////////////////////////////////////////////
     // Project permissions.
     ///////////////////////////////////////////////////////////////////////

     /**
      * Throws an exception if user's ACL doesn't have permission to perform
      * an action on a project.
      *
      * @@param action   The action to check for.
      * @@param project The project to check.
      * @@exception ACLException If user doesn't have permission.
      */
     public void assertPermissionForProject (String action, Project project)
         throws ACLException
     {
         assertPermissionForProject(action, null, project);
     }

     /**
      * Throws an exception if user's ACL doesn't have permission to perform
      * an action on a resource in a project.
      *
      * @@param action     The action to check for.
      * @@param resourceID The resource to check.
      * @@param project  The project to check.
      * @@exception ACLException If user doesn't have permission.
      */
     public void assertPermissionForProject (String action, String resource, 
                                             Project project)
         throws ACLException
     {
         if (!hasPermissionForProject(action, resource, project))
         {
             throw new ACLException(this, action, "Project " + project.getName(),
                                    resource);
         }
     }

     /**
      * Checks whether the user's ACL has permission to perform an action on a 
      * project.  
      *
      * @@param action   The action to check for.
      * @@param project The project to check for.
      * @@return         Whether access is allowed.
      */
     public boolean hasPermissionForProject (String action, Project project)
     {
         return hasPermission(action, project);
     }

     /**
      * Checks whether the user's ACL has permission to perform an action on a 
      * project.  
      *
      * @@param action   The action to check for.
      * @@param project  The project to check for.
      * @@return         Whether access is allowed.
      */
     public boolean hasPermissionForProject (String action, String resource,
                                             Project project)
     {
         return hasPermission(action, resource, project);
     }

     ///////////////////////////////////////////////////////////////////////
     // The general checker which all other checkers eventually call.
     ///////////////////////////////////////////////////////////////////////
     /**
      * Checks whether the user's ACL has action to perform an action on a 
      * given project.
      *
      * @@param action    The action to check for.
      * @@param project   The project to which the action applies.
      * @@return          Whether access is allowed.
      */
     public boolean hasPermission (String action, Project project)
     {        
         return hasPermission(action, null, project);
     }

     /**
      * Checks whether the user's ACL has action to perform an action on a 
      * resource in a given project.
      *
      * @@param action    The action to check for.
      * @@param resource  The resource to which the action applies.
      * @@param project   The project to which the action applies.
      * @@return          Whether access is allowed.
      */
     public boolean hasPermission (String action, String resource, 
                                   Project project)
     {        
         return true;
         //         List resourcesForAction = 
         //             getResourcesForActionInProject(action, project, false);
         //         if (resourcesForAction != null)
         //         {
//             String scope = null;
//             for (Iterator j = resourcesForAction.iterator(); j.hasNext();)
//             {
//                 scope = (String)j.next();
//                 if (resourceMatchesScope(resource, scope))
//                 {
//                     if (DEBUG) log.info("Role " + roleID + " has permission " +
//                                         action + '/' + resource + " in project"
//                                         + project.getName());
//                     return true;
//                 }
//             }
//         }        
        
//         //No role has the right permissions--fail.
//         if (DEBUG) log.info("User " + getUserID() 
//                             + " lacks permission " + action + "/" 
//                             + resource + " in project" + project.getName());
d784 51
a834 2
//         return false;
     }
d836 199
a1034 165
//     public List getResourcesForActionInProject
//         (String action, String projectID, boolean includeRole)
//     {
//         //Iterate through their roles in this project to get a list of
//         //resources for which they have the given action.
//         List resourcesForAction = new ArrayList();
//         List rolesForProject = getAllRolesForProject(projectID);        
//         if (rolesForProject != null)
//         {
//             for (Iterator i = rolesForProject.iterator(); i.hasNext();)
//             {
//                 String roleID = (String)i.next();
//                 if (DEBUG) log.info("Does role " + roleID + " have action " 
//                   + action + '?');
//                 Map actionsForRole = (Map)getPermissionsForRole(roleID);
//                 if (actionsForRole != null)
//                 {
//                     //Get the extents to which the role holds this action.
//                     List resourcesForActionRole = 
//                         (List)actionsForRole.get(action);
//                     if (resourcesForActionRole != null)
//                     {
//                         if (!includeRole)
//                         {
//                             resourcesForAction.addAll(resourcesForActionRole);
//                         } else {
//                             for (Iterator j = 
//                                      resourcesForActionRole.iterator();
//                                  j.hasNext();)
//                             {
//                                 String resource = (String)j.next();
//                                 try {
//                                     Role role = Role.getInstance(roleID);
//                                     resourcesForAction.add(resource + "(" + role.getName() + ")");
//                                 } catch (Exception e) {
//                                     resourcesForAction.add(resource + "(Role " + roleID + ")");
//                                 }

//                             }
//                         }
//                     }
//                 }
//             }
//         }
//         return resourcesForAction;
         //     }
                   
//     /**
//      * Checks whether a resources matches the user's scope.
//      *
//      * @@param resource The resource to check access to.
//      * @@param scope    The scope of the user's action.
//      * @@return         Whether the resource and scope match.
//      */
//     private boolean resourceMatchesScope (String resource, String scope)
//     {
//         if (DEBUG) log.info("Does '" + resource + "' match '" + scope + "'?");
//         boolean isMatch = (resource == null || resource.equals(""));

//         // If the match is not immediately evident, compare resource to scope.
//         if (!isMatch)
//         {
// 	    // FUTURE: consider an optimization for scopes of the form:
// 	    // "prefix.*suffix".  Where prefix do not contain any regex
// 	    // characters. 
//             try
//             {
//                 RE pat = new RE(scope);
//                 isMatch = pat.isMatch(resource);
//             }
//             catch (REException assumeNoMatch)
//             {
//                 isMatch = false;
//             }
//         }
//         if (isMatch) log.info("Resource matches.");
//         else log.info("Resource does not match.");

//         return isMatch;
//     }

//     //
//     // Handles expansion of roles.
//     //

//     /**
//      * Returns the user's original roles in a project.
//      *
//      * @@param projectID  The project to obtain roles for.
//      */
//     private List getOriginalRolesForProject(String projectID)
//     {
//         return (List)originalRolesByProject.get(projectID);
//     }

//     /**
//      * Returns the conjunction of the user's original and derived roles
//      * in a project.
//      *
//      * @@param projectID  The project to obtain roles for
//      */
//     private List getAllRolesForProject(String projectID)
//     {        
//         // Give us the derived roles we have in this project via
//         // project groups.  

//         // TODO: Use HaveExpandedProject to only do this when
//         // neccessary.

//         expandRolesForProject(projectID);
        
//         List original = (List)originalRolesByProject.get(projectID);
//         List derived = (List)derivedRolesByProject.get(projectID);
//         List all = new ArrayList();
//         if (original != null)
//         {
//             all.addAll(original);
//         } 
//         if (derived != null)
//         {
//             all.addAll(derived);
//         }
//         return all;
//     }

//     private void expandRolesForProject(String projectID)
//     {
//         List groupsForProject =
//             ProjectProjectgroupPeer.getGroupsForProject(projectID);
//         for (Iterator i = groupsForProject.iterator(); i.hasNext();)
//         {
//             String projectGroupID = (String)i.next();
//             List rolesForGroup = 
//                 getOriginalRolesForProject(projectGroupID);
//             if (rolesForGroup != null)
//             {
//                 for (Iterator j = rolesForGroup.iterator(); 
//                      j.hasNext();)
//                 {
//                     String derivedRoleID = (String)j.next();
//                     log.info("User has role " + derivedRoleID 
//                              + " in project " + projectID 
//                              + " via project " + projectGroupID);
//                     addRoleToRolesByProject(derivedRoleID, projectID, 
//                                             DERIVED);
//                 }
//             }
//         }
//     }  

//     /**
//      * Constructs the list of roles the user has in projects.
//      */
//     private void constructOriginalRolesByProject()
//         throws Exception
//     {
//         originalRolesByProject = new HashMap();

//         List effectiveUserIDs = new ArrayList();
//         effectiveUserIDs.add(userID);
//         List userGroupsForUser = (ArrayList)userGroups.get(userID);
//         if (userGroupsForUser != null)
//         {
//             effectiveUserIDs.addAll(userGroupsForUser);
//         }
d1036 310
a1345 174
//         List urps = UserRoleProjectPeer.getRolesProjectsForUsers
//             (effectiveUserIDs);
//         Record role = null;
//         String roleID = null;
//         String projectID = null;
//         List rolesForProject = null;
//         for (Iterator i = urps.iterator(); i.hasNext();)
//         {
//             UserRoleProject entry = i.next();
//             roleID = entry.getRoleID();
//             projectID = entry.getProjectID();
//             addRoleToRolesByProject(roleID, projectID, ORIGINAL);
//         }
//     }
    
//     /**
//      * Adds a role in a project to the appropriate RolesByProject
//      * hash.
//      * <p>
//      * TODO: Make this take a bunch of roles for better
//      * efficiency.
//      *
//      * @@param roleID    The role to add.
//      * @@param projectID  The project in which the user has the role.
//      */
//     private void addRoleToRolesByProject(String roleID, String projectID,
//                                          boolean original)
//     {
//         List rolesForProject = null;
//         Map hash = original?originalRolesByProject:derivedRolesByProject;
//         if (hash.containsKey(projectID))
//         {
//             rolesForProject = (List)hash.get(projectID);
//         } else {
//             rolesForProject = new ArrayList();
//         }
        
//         if (!rolesForProject.contains(roleID))
//         {
//             rolesForProject.add(roleID);
//         }        
//         hash.put(projectID, rolesForProject);
//     }

//     //
//     // Some methods used by the script runner.
//     //

//     public void expandRolesForAllProjects()
//     {
//         List groups = ProjectPeer.runSelect(new Criterion());
//         for (Iterator i = groups.keys(); i.iterator(); )
//         {
//             String projectID = (String)i.next();
//             expandRolesForProject(projectID);
//         }
//     }

//     public List getProjectsWithAnyRole()
//     {
//         List p = new ArrayList();
//         List a = getProjectsWithOriginalRole();
//         if (a != null) p.addAll(a);
//         List b = getProjectsWithDerivedRole();
//         if (b != null)
//         {
//             for (Iterator i = b.iterator(); i.hasNext();)
//             {
//                 Project project = (Project)i.next();
//                 if (!p.contains(project))
//                 {
//                     p.add(project);
//                 }
//             }
//         }
//         return p;
//     }

//     public List getProjectsWithOriginalRole()
//     {
//         return getProjectsWithRoleFromMap(originalRolesByProject);
//     }

//     public List getProjectsWithDerivedRole()
//     {
//         expandRolesForAllProjects();
//         return getProjectsWithRoleFromMap(derivedRolesByProject);
//     }

//     public List getProjectsWithRoleFromMap(Map t)
//     {
//         List projects=new ArrayList();
//         if (t != null)
//         {
//             for (Iterator i = t.keySet().iterator(); i.hasNext(); )
//             {
//                 projects.add(Project.getInstance((String)i.next()));
//             }
//         }
//         return projects;
//     }

//     public List getOriginalRolesInProject(Project project)
//     {
//         return getRolesInProjectFromMap(project, originalRolesByProject);
//     }

//     public List getDerivedRolesInProject(Project project)
//     {
//         return getRolesInProjectFromMap(project, derivedRolesByProject);
//     }

//     private List getRolesInProjectFromMap(Project project, Map t)
//     {
//         List roles = new ArrayList();
//         List roleIDs = (List)t.get(project.getID());
//         for (Iterator i = roleIDs.iterator(); i.hasNext();)
//         {
//             roles.add(RolePeer.retrieveById((String)i.next()));
//         }
//         return roles;
//     }

     /**
      * Dumps the ACL to the log.
      */
     public void dump()
     {
         if (!DEBUG) return;
         StringBuffer s = new StringBuffer();
//          s.append("\noriginalRolesByProject for userID "+ userID + ":\n");
        
//          for (Iterator i = originalRolesByProject.keySet().iterator(); i.hasNext();)
//          {
//              String projectID = (String)e.next();
//              List rolesForProject = 
//                  (List)originalRolesByProject.get(projectID);
//              s.append(" Roles for project " + projectID + ": ");
//              for (Iterator j = rolesForProject.iterator(); j.hasNext();)
//              {
//                  s.append((String)j.next() + " ");
//              }                        
//              s.append("\n");
//          }    

//         s.append("\nderivedRolesByProject for userID "+ userID + ":\n");
        
//         for (Iterator i = derivedRolesByProject.keySet.iterator();
//              e.hasNext(); )
//         {
//             String projectID = (String)e.nextElement();
//             List rolesForProject = 
//                 (List)derivedRolesByProject.get(projectID);
//             s.append(" Roles for project " + projectID + ": ");
//             for (Iterator j = rolesForProject.iterator(); j.hasNext();)
//             {
//                 s.append((String)j.next() + " ");
//             }                        
//             s.append("\n");
//         }    

         log.info(s.toString());        
     }

     /**
      * Dumps the static ACL information to the log.
      */
     public static void dumpStatic()
     {
         if (!DEBUG) return;
//         log.info(RoleActionResourcePeer.dumpStatic());
//         log.info(UserUsergroupPeer.dumpStatic());
//         log.info(ProjectProjectgroupPeer.dumpStatic());
     }
@


1.26.2.3
log
@Ported grab-an-acl methods.
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.2 2001/01/28 01:18:28 dlr Exp $
d114 1
a114 1
     * The user whose ACL this is.
d116 1
a116 1
    private User user;
d210 15
a224 24
    /**
     * Gets the (possibly cached) ACL for the given user. 
     */
    public static AccessControlList getACL(User user)
        throws Exception
    {
        AccessControlList acl;
        if (userACLs.containsKey(user))
        {
            acl = (AccessControlList)userACLs.get(user);
        } else {
            acl = rebuildACL(user);
        }
        return acl;
    }

    /**
     * Gets the ACL for the superuser
     */
    public static AccessControlList getSuperuserACL()
        throws Exception
    {
        return getACL(UserPeer.getSuperUser());
    }
d226 10
a235 10
     /**
      * Rebuilds the ACL for the given userID, 
      */
     public static AccessControlList rebuildACL(User user)
         throws Exception
     {
         AccessControlList acl = new AccessControlList(user);
         userACLs.put(user, acl);
         return acl;
     }
d237 18
a254 18
     /**
      * Instantiates a new ACL for the specified user.
      *
      * @@param user  The user whose ACL is desired.
      *
      * @@exception Exception     Generic database error.
      */
     public AccessControlList (User user)
         throws Exception
     {
         this.user = user;
         //this.originalRolesByProject = new HashMap();
         //this.derivedRolesByProject = new HashMap();
         //constructOriginalRolesByProject();
         //haveExpandedProject = new HashMap();
         //dumpStatic();
         //dump();                
     }
d263 1
a263 1
         return user.getID()
d274 1
a274 1
         return user;
@


1.26.2.4
log
@* Simplified connection release in static initializer block.
* Corrected horrifying formatting in getACL() method.
* Renamed getSuperuserACL() to getSuperUserACL(), deprecating old
  version, and making both final to inline.
* Adding some internal synchronization to rebuildACL() method to avoid
  excessive database hits and object creation during race condition.
* Corrected ctor formatting, and made it protected (use getACL()
  instead).
* Added semi-colon to getUserID() implemenation to correct syntax
  error.
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.3 2001/01/29 20:50:03 leonardr Exp $
d142 1
a142 1
     * TODO: Describe WTF this is.
d196 1
a196 1
//             try
d198 8
a205 5
//                 TurbineDB.releaseConnection(dbConn);
//             }
//             catch (Exception e)
//             {
//                 throw new RuntimeException(e.getMessage());
d217 2
a218 1
        if (userACLs.containsKey(user)) {
d220 1
a220 2
        }
        else {
d227 1
a227 1
     * Gets the ACL for the root user.
d229 1
a229 1
    public final static AccessControlList getSuperUserACL()
a234 9
    /**
     * @@deprecated Use getSuperUserACL() instead (capitalization difference).
     */
    public final static AccessControlList getSuperuserACL()
        throws Exception
    {
        return getSuperUserACL();
    }

d240 5
a244 13
    {
        AccessControlList acl = null;
        synchronized (userACLs) {
            if (userACLs.containsKey(user)) {
                acl = (AccessControlList)userACLs.get(user);
            }
            else {
                acl = new AccessControlList(user);
                userACLs.put(user, acl);
            }
        }
        return acl;
    }
d246 18
a263 18
    /**
     * Instantiates a new ACL for the specified user.
     *
     * @@param user  The user whose ACL is desired.
     *
     * @@exception Exception     Generic database error.
     */
    protected AccessControlList (User user)
        throws Exception
    {
        this.user = user;
        //this.originalRolesByProject = new HashMap();
        //this.derivedRolesByProject = new HashMap();
        //constructOriginalRolesByProject();
        //haveExpandedProject = new HashMap();
        //dumpStatic();
        //dump();                
    }
d272 1
a272 1
         return user.getID();
@


1.26.2.5
log
@Ported ProjectGroup, among other stuff.
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.4 2001/01/29 21:10:43 dlr Exp $
d230 9
@


1.26.2.6
log
@Ported the ACL construction functionality.
@
text
@d56 2
a57 3
import org.apache.turbine.util.db.Criteria;

import org.tigris.helm.om.*;
d59 2
d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.5 2001/01/30 01:21:06 leonardr Exp $
d142 1
a142 4
     * A mapping of project groups to booleans; the presence of a
     * project group in this Map means that the roles this user has in
     * the project group have been distributed (as derived roles)
     * across the projects in the project group.  
d147 61
d262 6
a267 6
        this.originalRolesByProject = new HashMap();
        this.derivedRolesByProject = new HashMap();
        constructOriginalRolesByProject();
        haveExpandedProject = new HashMap();
        dumpStatic();
        dump();                
d774 52
a825 7
    /**
     * Constructs the list of roles the user has in projects.
     */
    private void constructOriginalRolesByProject()
        throws Exception
    {
        originalRolesByProject = new HashMap();
d827 6
a832 46
        List effectiveUserIDs = user.effectiveUserIDs();
     
        Criteria c = new Criteria()
            .addIn(UserRoleProjectPeer.USER_ID, effectiveUserIDs.toArray());
        List urps = UserRoleProjectPeer.doSelect(c);

        Role role = null;
        Project project = null;
        List rolesForProject = null;
        for (Iterator i = urps.iterator(); i.hasNext();)
        {
            UserRoleProject entry = (UserRoleProject)i.next();
            role = RolePeer.retrieveByPK(entry.getRoleId());
            project = ProjectPeer.retrieveByPK(entry.getProjectId());
            addRoleToRolesByProject(role, project, ORIGINAL);
        }
    }
    
     /**
      * Adds a role in a project to the appropriate RolesByProject
      * hash.
      * <p>
      * TODO: Make this take a bunch of roles for better
      * efficiency.
      *
      * @@param roleID    The role to add.
      * @@param projectID  The project in which the user has the role.
      */
    private void addRoleToRolesByProject(Role role, Project project,
                                         boolean original)
    {
        List rolesForProject = null;
        Map hash = original?originalRolesByProject:derivedRolesByProject;
        if (hash.containsKey(project))
        {
            rolesForProject = (List)hash.get(project);
        } else {
            rolesForProject = new ArrayList();
        }
      
        if (!rolesForProject.contains(role))
        {
            rolesForProject.add(role);
        }        
        hash.put(project, rolesForProject);
    }
@


1.26.2.7
log
@More ACL porting.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.6 2001/01/30 21:38:43 leonardr Exp $
d232 41
a272 3
    ///////////////////////////////////////////////////////////////////////
    // Roles.
    ///////////////////////////////////////////////////////////////////////
d274 15
a288 15
     /**
      * Throws an exception if user's ACL doesn't have the specified role.
      *
      * @@param roleID The role to check for.
      *
      * @@exception ACLException If user doesn't have the role.
      */
     public void assertRole (Role role)
         throws ACLException, Exception
     {
         if (!hasRole(role))
         {
             throw new ACLException(this, role.getName(), "Host", null);
         }
     }
d290 15
a304 11
     /**
      * Checks whether the user's ACL has the role in the host/cluster.
      *
      * @@param roleID The role to check for.
      * @@return       Whether access is allowed.
      */
     public boolean hasRole (Role role)
         throws Exception
     {
         return hasRoleInDomain(role, DomainPeer.getHostDomain());
     }
d306 10
a315 11
     /**
      * Checks whether the user's ACL has the role in the host.
      *
      * @@param roleID   The role to check for.
      * @@return         Whether the user has the role.
      */
     public boolean hasRoleInHost (Role role)
         throws Exception
     {
         return hasRole(role);
     }
d317 5
a321 42
     /**
     * Checks whether the user's ACL has the role in the specified domain.
     *
      * @@param roleID   The role to check for.
      * @@param domain   The domain to check for the role in.
      * @@return         Whether access is allowed.
      */
     public boolean hasRoleInDomain (Role role, Domain domain)
         throws Exception
     {
         return hasRoleInProject(role, domain.getSpecialProject());
     }

    /**
     * Checks whether the user's ACL has the role in the group of public projects in the specified domain.
     *
     * @@param roleID   The role to check for.
     * @@param domain   The domain to check for the role in.
     * @@return         Whether access is allowed.
     */
    public boolean hasRoleInPublicDomainProjects (Role role, Domain domain)
         throws Exception
    {
        return hasRoleInProject(role, domain.getSpecialPublicProject());
    }

    /**
     * Checks whether the user's ACL has the role in the specified project.
     *
     * @@param roleID    The role to check for.
     * @@param projectID The domain to check for the role in.
     * @@return          Whether access is allowed.
     */
    public boolean hasRoleInProject (Role role, Project project)
    {
        boolean flag = false;

        List rolesForProject = getOriginalRolesForProject(project);
        if (rolesForProject != null && rolesForProject.contains(role))
        {
            flag = true;
        }
d323 2
a324 2
        return flag;
    }
d326 3
a328 3
    ///////////////////////////////////////////////////////////////////////
    // Host permissions.
    ///////////////////////////////////////////////////////////////////////
d646 3
a648 3
    //
    // Handles expansion of roles.
    //
d650 9
a658 9
    /**
     * Returns the user's original roles in a project.
     *
     * @@param projectID  The project to obtain roles for.
     */
    private List getOriginalRolesForProject(Project project)
    {
        return (List)originalRolesByProject.get(project);
    }
d660 10
a669 11
    /**
     * Returns the conjunction of the user's original and derived roles
     * in a project.
     *
     * @@param projectID  The project to obtain roles for
     */
    private List getAllRolesForProject(Project project)
        throws Exception
    {        
        // Give us the derived roles we have in this project via
        // project groups.  
d671 2
a672 2
        // TODO: Use HaveExpandedProject to only do this when
        // neccessary.
d674 1
a674 1
        expandRolesForProject(project);
d676 13
a688 13
        List original = (List)originalRolesByProject.get(project);
        List derived = (List)derivedRolesByProject.get(project);
        List all = new ArrayList();
        if (original != null)
        {
            all.addAll(original);
        } 
        if (derived != null)
        {
            all.addAll(derived);
        }
        return all;
    }
d690 24
a713 18
    private void expandRolesForProject(Project group)
        throws Exception
    {
        List rolesForGroup = getOriginalRolesInProject(group);
        List projects = group.expand();
        for (Iterator i = projects.iterator(); i.hasNext();)
        {
            Project p = (Project)i.next();
            for (Iterator j = rolesForGroup.iterator(); j.hasNext();)
            {
                Role derivedRole = (Role)j.next();
                log.info("User has role " + derivedRole.getName()
                         + " in project " + p.getID()
                         + " via project " + group.getName());
                addRoleToRolesByProject(derivedRole, p, DERIVED);
            }
        }
    }  
d770 13
a782 3
     //
     // Some methods used by the script runner.
     //
d784 19
a802 10
    public void expandRolesForAllProjects()
        throws Exception
    {
        List groups = ProjectPeer.doSelect(new Criteria());
        for (Iterator i = groups.iterator(); i.hasNext(); )
        {
            Project p = (Project)i.next();
            expandRolesForProject(p);
        }
    }
d804 4
a807 20
     public List getProjectsWithAnyRole()
         throws Exception
     {
         List p = new ArrayList();
         List a = getProjectsWithOriginalRole();
         if (a != null) p.addAll(a);
         List b = getProjectsWithDerivedRole();
         if (b != null)
        {
            for (Iterator i = b.iterator(); i.hasNext();)
            {
                Project project = (Project)i.next();
                if (!p.contains(project))
                {
                    p.add(project);
                }
            }
        }
        return p;
    }
d809 5
a813 4
    public List getProjectsWithOriginalRole()
    {
        return getProjectsWithRoleFromMap(originalRolesByProject);
    }
d815 12
a826 16
    public List getProjectsWithDerivedRole()
        throws Exception
    {
        expandRolesForAllProjects();
        return getProjectsWithRoleFromMap(derivedRolesByProject);
    }
    
    public List getProjectsWithRoleFromMap(Map t)
    {
        List l = new ArrayList();
        for (Iterator i = t.keySet().iterator(); i.hasNext();)
        {
            l.add((Project)i.next());
        }
        return l;
    }
d828 4
a831 4
     public List getOriginalRolesInProject(Project project)
     {
         return getRolesInProjectFromMap(project, originalRolesByProject);
     }
d833 4
a836 4
     public List getDerivedRolesInProject(Project project)
     {
         return getRolesInProjectFromMap(project, derivedRolesByProject);
     }
d838 10
a847 4
     private List getRolesInProjectFromMap(Project project, Map t)
     {
         return (List)t.get(project);
     }
@


1.26.2.8
log
@More permissions checking.
@
text
@a57 1
import org.tigris.helm.DoesNotExist;
d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.7 2001/01/30 23:56:38 leonardr Exp $
d561 46
a606 37
    public List getResourcesForActionInProject
        (String actionName, Project project, boolean includeRole)
        throws DoesNotExist, Exception
    {
        Action action = ActionPeer.getInstanceByName(actionName);
        //Iterate through their roles in this project to get a list of
        //resources for which they have the given action.
        List resourcesForAction = new ArrayList();
        List rolesForProject = getAllRolesForProject(project);
        if (rolesForProject != null)
        {
            for (Iterator i = rolesForProject.iterator(); i.hasNext();)
            {
                Role role = (Role)i.next();
                if (DEBUG) 
                {
                    log.info("Does role " + role.getName() + " have action " 
                             + action + '?');
                }
                List resourcesForActionRole = role.getResourcesForAction(action);

                if (!includeRole)
                {
                    resourcesForAction.addAll(resourcesForActionRole);
                } else {
                    for (Iterator k = resourcesForActionRole.iterator();
                         k.hasNext();)
                    {
                        Resource resource = (Resource)k.next();
                        resourcesForAction.add(resource.getPattern() 
                                               + "(" + role.getName() + ")");
                    }
                }
            }
        }
        return resourcesForAction;
    }
d608 30
a637 11
    /**
     * Checks whether a resources matches the user's scope.
     *
     * @@param resource The resource to check access to.
     * @@param scope    The scope of the user's action.
     * @@return         Whether the resource and scope match.
     */
    private boolean resourceMatchesScope (String resource, String scope)
    {
        if (DEBUG) log.info("Does '" + resource + "' match '" + scope + "'?");
        boolean isMatch = (resource == null || resource.equals(""));
d639 2
a640 23
        // If the match is not immediately evident, compare resource to scope.
        if (!isMatch)
        {
	    // FUTURE: consider an optimization for scopes of the form:
	    // "prefix.*suffix".  Where prefix do not contain any regex
	    // characters. 
            try
            {
                RE pat = new RE(scope);
                isMatch = pat.isMatch(resource);
            }
            catch (REException assumeNoMatch)
            {
                isMatch = false;
            }
        }
        if (DEBUG)
        {
            if (isMatch) log.info("Resource matches.");
            else log.info("Resource does not match.");
        }
        return isMatch;
    }
@


1.26.2.9
log
@Ported the remainder of the ACL code.
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.8 2001/01/31 01:18:27 leonardr Exp $
d473 2
a474 7
         boolean ok = false;
         try {
             if (hasPermissionForProject(action, resource, project))
             {
                 ok = true;
             } 
         } catch (Exception e) {
a488 1
         throws Exception
a502 1
         throws Exception
a518 1
         throws Exception
a533 1
         throws Exception
d535 23
a557 13
         boolean ok = false;
         List resourcesForAction = 
             getResourcesForActionInProject(action, project, false);
         Resource scope;
         for (Iterator i = resourcesForAction.iterator(); i.hasNext();)
         {
             scope = (Resource)i.next();
             if (resourceMatchesScope(resource, scope.getPattern()))
             {
                 ok = true;
                 break;
             }
         }
d559 1
a559 8
         if (DEBUG)
         {
             log.info("User " + user.getLoginName() 
                      + (ok ? "has":"lacks") + " permission " + action 
                      + '/' + resource + " in project" + project.getName());
         }

         return ok;
d835 1
a835 1
         s.append("\noriginalRolesByProject for "+ user.getLoginName() + ":\n");
d837 12
a848 14
         for (Iterator i = originalRolesByProject.keySet().iterator(); 
              i.hasNext();)
         {
             Project project = (Project)i.next();
             List rolesForProject = 
                 (List)originalRolesByProject.get(project);
             s.append(" Roles for project " + project.getName() + ": ");
             for (Iterator j = rolesForProject.iterator(); j.hasNext();)
             {
                 Role r = (Role)j.next();
                 s.append(r.getName() + " ");
             }                        
             s.append("\n");
         }    
d850 1
a850 2
         s.append("\nderivedRolesByProject (so far) for "+ user.getLoginName() 
                  + ":\n");
d852 13
a864 14
         for (Iterator i = derivedRolesByProject.keySet().iterator(); 
              i.hasNext(); )
         {
             Project project = (Project)i.next();
             List rolesForProject = 
                 (List)originalRolesByProject.get(project);
             s.append(" Roles for project " + project.getName() + ": ");
             for (Iterator j = rolesForProject.iterator(); j.hasNext();)
             {
                 Role r = (Role)j.next();
                 s.append(r.getName() + " ");
             }                        
             s.append("\n");
        }    
@


1.26.2.10
log
@Misc cleanup for ACL.
@
text
@d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.9 2001/01/31 01:48:23 leonardr Exp $
a147 9

    /**
     * Gets the ACL for the root user.
     */
    public final static AccessControlList getSuperUserACL()
        throws Exception
    {
        return getACL(UserPeer.getSuperUser());
    }
d152 1
a152 1
    public synchronized static AccessControlList getACL(User user)
d156 1
a156 2
        if (userACLs.containsKey(user)) 
        {
d159 1
a159 2
        else 
        {
d166 1
a166 1
     * Rebuilds the ACL for the given userID, 
d168 1
a168 1
    public static AccessControlList rebuildACL(User user)
d171 9
d181 8
a188 4
        synchronized(userACLs)
        {
            acl = new AccessControlList(user);
            userACLs.put(user, acl);
d228 1
@


1.26.2.11
log
@Big patch to make access control work.
@
text
@d49 2
a56 1
import org.apache.turbine.util.Log;
d75 1
a75 1
 * @@version $Id: AccessControlList.java,v 1.26.2.10 2001/01/31 02:40:42 leonardr Exp $
d79 4
d435 1
d557 3
a559 3
             Log.debug("User " + user.getLoginName() 
                       + (ok ? "has":"lacks") + " permission " + action 
                       + '/' + resource + " in project" + project.getName());
d581 2
a582 2
                    Log.debug("Does role " + role.getName() + " have action " 
                             + action.getName() + '?');
d612 1
a612 1
        if (DEBUG) Log.debug("Does '" + resource + "' match '" + scope + "'?");
d633 2
a634 2
            if (isMatch) Log.debug("Resource matches.");
            else Log.debug("Resource does not match.");
d667 2
a669 2
        expandRolesForProject(project);

a680 1
        dump();
d684 1
a684 1
    private void expandRolesForProject(Project project)
d686 4
a689 4
    {                
        List groups = project.getGroups();

        for (Iterator i = groups.iterator(); i.hasNext();)
d691 1
a691 2
            ProjectGroup group = (ProjectGroup)i.next();
            List rolesForGroup = getOriginalRolesInProject(group);
d695 4
a698 4
                Log.debug("User has role " + derivedRole.getName()
                          + " in project " + project.getID()
                          + " via project " + group.getName());
                addRoleToRolesByProject(derivedRole, project, DERIVED);
a708 1
        Log.debug("Constructing roles by project for " + user.getRealName());
a724 1
            Log.debug("Found role " + role.getName() + " in project " + project.getName());
d741 2
a742 1
    {       
d744 1
a744 2
        List rolesForProject = (List)hash.get(project);   
        if (rolesForProject == null)
d746 2
d828 1
a828 11
         List l = null;
         for (Iterator i = t.keySet().iterator(); i.hasNext();)
         {
             Project p = (Project)i.next();
             if (p.equals(project))
             {
                 l = (List)t.get(p);
                 break;
             }
         }
         return l;
d863 1
a863 1
                 (List)derivedRolesByProject.get(project);
d873 1
a873 1
         Log.debug(s.toString());        
d882 3
a884 3
//         Log.debug(RoleActionResourcePeer.dumpStatic());
//         Log.debug(UserUsergroupPeer.dumpStatic());
//         Log.debug(ProjectProjectgroupPeer.dumpStatic());
@


1.26.2.12
log
@Misc. changes to support PermissionDump.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.11 2001/02/01 02:57:47 leonardr Exp $
a557 8

    public List getResourcesForActionInProject
        (Action action, Project project, Boolean includeRole)
        throws DoesNotExist, Exception
    {
        return getResourcesForActionInProject(action.getName(), project,
                                              includeRole.booleanValue());
    }
d683 1
d807 1
a807 2
            Project p = (Project)i.next();
            l.add(p);
a833 1
         if (l == null) l = new ArrayList();
@


1.26.2.13
log
@More fixes for ACL and ACLDump.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.12 2001/02/01 18:03:00 leonardr Exp $
d716 1
a716 2
        Log.info("Effective user IDs: " + effectiveUserIDs);

@


1.26.2.14
log
@Cleanup and optimization.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.13 2001/02/01 20:40:24 leonardr Exp $
d586 1
a586 2
                List resourcesForActionRole =
                    role.getResourcesForAction(action);
d588 2
a589 1
                if (!includeRole) {
d591 1
a591 2
                }
                else {
d748 1
a748 1
        Map hash = (original ? originalRolesByProject : derivedRolesByProject);
d781 6
a786 6
         List orig = getProjectsWithOriginalRole();
         if (orig != null) p.addAll(orig);
         List derived = getProjectsWithDerivedRole();
         if (derived != null)
         {
            for (Iterator i = derived.iterator(); i.hasNext(); )
d812 2
a813 2
        List l = new ArrayList(t.size());
        for (Iterator i = t.keySet().iterator(); i.hasNext(); )
d815 2
a816 1
            l.add((Project)i.next());
d843 1
a843 1
         if (l == null) l = new ArrayList(0);
@


1.26.2.15
log
@Gated debug statements
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.14 2001/02/01 21:25:07 dlr Exp $
d82 1
a82 1
    private static final boolean DEBUG = false;
d699 3
d713 1
a713 2
        if (DEBUG) 
            Log.debug("Constructing roles by project for " + user.getRealName());
d731 1
a731 1
            if (DEBUG) Log.debug("Found role " + role.getName() + " in project " + project.getName());
@


1.26.2.16
log
@Added hasRole(Role, Domain) and hasRole(Role, Project) as hasRoleInDomain(Role, Project) and hasRoleInProject(Role, Project) are redundantly named.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.15 2001/02/07 19:49:33 leonardr Exp $
a268 6
    public boolean hasRole(Role role, Domain domain)
        throws Exception
    {
        return hasRoleInDomain(role, domain);
    }

a292 6
    }

    public boolean hasRole(Role role, Project project)
        throws Exception
    {
        return hasRoleInProject(role, project);
@


1.26.2.17
log
@Added wrapper method.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.16 2001/02/08 16:07:44 leonardr Exp $
a410 6

    public boolean hasPermission(String action, Domain domain)
        throws Exception
    {
        return hasPermissionForDomain(action, domain);
    }
@


1.26.2.18
log
@Deprecated methods with unneccessarily verbose names.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.17 2001/02/09 18:03:16 leonardr Exp $
d205 19
a223 19
    /**
     * Get the ID of the user whose ACL this is.
     *
     * return A user ID.
     */
    public String getUserID()
    {
        return user.getID();
    }

    /**
     * Get the User whose ACL this is.
     *
     * return A User object.
     */
    public User getUser()
    {
        return user;
    }
d229 39
a267 39
    /**
     * Throws an exception if user's ACL doesn't have the specified role.
     *
     * @@param roleID The role to check for.
     *
     * @@exception ACLException If user doesn't have the role.
     */
    public void assertRole (Role role)
        throws ACLException, Exception
    {
        if (!hasRole(role))
        {
            throw new ACLException(this, role.getName(), "Host", null);
        }
    }

    /**
     * Checks whether the user's ACL has the role in the host/cluster.
     *
     * @@param roleID The role to check for.
     * @@return       Whether access is allowed.
     */
    public boolean hasRole (Role role)
        throws Exception
    {
        return hasRoleInDomain(role, DomainPeer.getHostDomain());
    }

    /**
     * Checks whether the user's ACL has the role in the host.
     *
     * @@param roleID   The role to check for.
     * @@return         Whether the user has the role.
     */
    public boolean hasRoleInHost (Role role)
        throws Exception
    {
        return hasRole(role);
    }
d275 1
a275 1
    /**
d278 9
a286 9
     * @@param roleID   The role to check for.
     * @@param domain   The domain to check for the role in.
     * @@return         Whether access is allowed.
     */
    public boolean hasRoleInDomain (Role role, Domain domain)
        throws Exception
    {
        return hasRoleInProject(role, domain.getSpecialProject());
    }
d296 1
a296 1
        throws Exception
d331 80
a410 114
    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on the host.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action   The action to check for.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForHost(String action)
        throws ACLException, Exception
    {
        assertPermission(action);
    }

    
    /**
     * Checks whether the user's ACL has permission to perform an action
     * on the host.
     *
     * @@deprecated     Use hasPermission instead.
     * @@param action   The action to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForHost (String action)
        throws Exception
    {
        return hasPermission(action);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on the host.
     *
     * @@param action   The action to check for.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission(String action)
        throws ACLException, Exception
    {
        if (!hasPermission(action))
        {
            throw new ACLException(this, action, "Host", null);
        }
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on the host.
     *
     * @@param action   The action to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermission (String action)
        throws Exception
    {
        return hasPermission(action, ProjectPeer.getHostProject());
    }

    ///////////////////////////////////////////////////////////////////////
    // Domain permissions.
    ///////////////////////////////////////////////////////////////////////

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking in the domain. Use
     *             assertPermission instead.
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermissionForDomain (String action, Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, null, domain);
    }
    
    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             assertPermission instead.
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param domain     The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermissionForDomain (String action, String resource, 
                                           Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, resource, domain);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a domain.
     *
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             hasPermission instead.
     * @@param action   The action to check for.
     * @@param domain   The domain to check permission in.
     * @@return Whether access is allowed.  
     */
    public boolean hasPermissionForDomain (String action, Domain domain)
        throws Exception
    {
        return hasPermission(action, domain);
    }
a411 8
    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check permission in.
     * @@return         Whether access is allowed.
     */
d418 148
a565 216
    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermission (String action, Domain domain)
        throws ACLException, Exception
    {
        assertPermission(action, null, domain);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermission (String action, String resource, 
                                  Domain domain)
        throws ACLException, Exception
    {
        if (!hasPermission(action, resource, domain))
        {
            throw new ACLException(this, action, "Domain " + domain.getName(),
                                   resource);
        }
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a resource in a domain.
     *
     * @@param action   The action to check for.
     * @@param resource The resrouce to check.
     * @@param domain   The domain to check permission in.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermission (String action, String resource, 
                                  Domain domain)
        throws Exception
    {
        boolean ok = false;
        Project hostProject = ProjectPeer.getHostProject();
        Project domainProject = ProjectPeer.getDomainProject(domain);
        if (!hostProject.equals(domainProject))
        {
            Project publicDomainProject = ProjectPeer.getPublicDomainProject(domain);
            if (hasPermission(action, resource, domainProject)
                || hasPermission(action, resource, publicDomainProject))
            {
                ok = true;
            }
        }

        if (ok == false && hasPermission(action, resource, hostProject))
        {
            ok = true;
        }
        return ok;
    }

    ///////////////////////////////////////////////////////////////////////
    // Project permissions.
    ///////////////////////////////////////////////////////////////////////

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a project.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action   The action to check for.
     * @@param project The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForProject (String action, Project project)
        throws ACLException
    {
        assertPermission(action, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@deprecated Use assertPermission instead.
     * @@param action     The action to check for.
     * @@param resourceID The resource to check.
     * @@param project  The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermissionForProject (String action, String resource, 
                                            Project project)
        throws ACLException
    {
        assertPermission(action, resource, project);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action on a 
     * project.  
     *
     * @@deprecated Use hasPermission instead.
     * @@param action   The action to check for.
     * @@param project The project to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForProject (String action, Project project)
        throws Exception
    {
        return hasPermission(action, project);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action on a 
     * project.  
     *
     * @@deprecated Use hasPermission instead.
     * @@param action   The action to check for.
     * @@param project  The project to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForProject (String action, String resource,
                                            Project project)
        throws Exception
    {
        return hasPermission(action, resource, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param project    The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission (String action, Project project)
        throws ACLException
    {
        assertPermission(action, null, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param project    The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission (String action, String resource, 
                                  Project project)
        throws ACLException
    {
        boolean ok = false;
        try {
            if (hasPermission(action, resource, project))
            {
                ok = true;
            } 
        } catch (Exception e) {
            throw new ACLException(this, action, 
                                   "Project " + project.getName(), resource);
        }
    }
    
    ///////////////////////////////////////////////////////////////////////
    // The general checker which all other checkers eventually call.
    ///////////////////////////////////////////////////////////////////////
    /**
     * Checks whether the user's ACL has action to perform an action on a 
     * given project.
     *
     * @@param action    The action to check for.
     * @@param project   The project to which the action applies.
     * @@return          Whether access is allowed.
     */
    public boolean hasPermission (String action, Project project)
        throws Exception
    {        
        return hasPermission(action, null, project);
    }

    /**
     * Checks whether the user's ACL has action to perform an action on a 
     * resource in a given project.
     *
     * @@param action    The action to check for.
     * @@param resource  The resource to which the action applies.
     * @@param project   The project to which the action applies.
     * @@return          Whether access is allowed.
     */
    public boolean hasPermission (String action, String resource, 
                                  Project project)
        throws Exception
    {        
        boolean ok = false;
        List resourcesForAction = 
            getResourcesForActionInProject(action, project, false);
        Resource scope;
        for (Iterator i = resourcesForAction.iterator(); i.hasNext();)
        {
            scope = (Resource)i.next();
            if (resourceMatchesScope(resource, scope.getPattern()))
            {
                ok = true;
                break;
            }
        }
d567 6
a572 6
        if (DEBUG)
        {
            Log.debug("User " + user.getLoginName() 
                      + (ok ? "has":"lacks") + " permission " + action 
                      + '/' + resource + " in project" + project.getName());
        }
d574 2
a575 2
        return ok;
    }
d602 1
a602 1
                              + action.getName() + '?');
d752 10
a761 10
    /**
     * Adds a role in a project to the appropriate RolesByProject
     * hash.
     * <p>
     * TODO: Make this take a bunch of roles for better
     * efficiency.
     *
     * @@param roleID    The role to add.
     * @@param projectID  The project in which the user has the role.
     */
d779 3
a781 3
    //
    // Some methods used by the script runner.
    //
d794 9
a802 9
    public List getProjectsWithAnyRole()
        throws Exception
    {
        List p = new ArrayList();
        List orig = getProjectsWithOriginalRole();
        if (orig != null) p.addAll(orig);
        List derived = getProjectsWithDerivedRole();
        if (derived != null)
        {
d837 34
a870 34
    public List getOriginalRolesInProject(Project project)
    {
        return getRolesInProjectFromMap(project, originalRolesByProject);
    }

    public List getDerivedRolesInProject(Project project)
    {
        return getRolesInProjectFromMap(project, derivedRolesByProject);
    }

    private List getRolesInProjectFromMap(Project project, Map t)
    {
        List l = null;
        for (Iterator i = t.keySet().iterator(); i.hasNext();)
        {
            Project p = (Project)i.next();
            if (p.equals(project))
            {
                l = (List)t.get(p);
                break;
            }
        }
        if (l == null) l = new ArrayList(0);
        return l;
    }

    /**
     * Dumps the ACL to the log.
     */
    public void dump()
    {
        if (!DEBUG) return;
        StringBuffer s = new StringBuffer();
        s.append("\noriginalRolesByProject for "+ user.getLoginName() + ":\n");
d872 14
a885 14
        for (Iterator i = originalRolesByProject.keySet().iterator(); 
             i.hasNext();)
        {
            Project project = (Project)i.next();
            List rolesForProject = 
                (List)originalRolesByProject.get(project);
            s.append(" Roles for project " + project.getName() + ": ");
            for (Iterator j = rolesForProject.iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                s.append(r.getName() + " ");
            }                        
            s.append("\n");
        }    
d887 2
a888 2
        s.append("\nderivedRolesByProject (so far) for "+ user.getLoginName() 
                 + ":\n");
d890 13
a902 13
        for (Iterator i = derivedRolesByProject.keySet().iterator(); 
             i.hasNext(); )
        {
            Project project = (Project)i.next();
            List rolesForProject = 
                (List)derivedRolesByProject.get(project);
            s.append(" Roles for project " + project.getName() + ": ");
            for (Iterator j = rolesForProject.iterator(); j.hasNext();)
            {
                Role r = (Role)j.next();
                s.append(r.getName() + " ");
            }                        
            s.append("\n");
d905 2
a906 2
        Log.debug(s.toString());        
    }
d908 10
a917 10
    /**
     * Dumps the static ACL information to the log.
     */
    public static void dumpStatic()
    {
        if (!DEBUG) return;
        //         Log.debug(RoleActionResourcePeer.dumpStatic());
        //         Log.debug(UserUsergroupPeer.dumpStatic());
        //         Log.debug(ProjectProjectgroupPeer.dumpStatic());
    }
@


1.26.2.19
log
@Got rid of infinite recursion.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.18 2001/02/12 16:19:02 leonardr Exp $
d457 1
a457 1
        return hasPermission(action, null, domain);
@


1.26.2.20
log
@This needs to be gated so it doesn't show up always.
@
text
@d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.19 2001/02/12 17:09:40 leonardr Exp $
d843 1
a843 1
        if (DEBUG) Log.debug("Effective user IDs: " + effectiveUserIDs);
@


1.26.2.21
log
@Normalized copyright dates.
@
text
@d2 1
a2 1
 * Copyright (c) 2000-2001 CollabNet.  All rights reserved.
d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.20 2001/02/14 01:38:53 leonardr Exp $
@


1.26.2.22
log
@Added new imports necessitated by Torque.
@
text
@a59 1
import org.tigris.helm.om.base.*;
d74 1
a74 1
 * @@version $Id: AccessControlList.java,v 1.26.2.21 2001/02/15 20:50:43 leonardr Exp $
@


1.25
log
@revert this stuff to its state as of 2001/01/24 12:42:00 GMT -- with
the following exceptions, which have some different modifications so
they'll work with changes which have happened in joist:

ProjectNewsEdit.java
SkinManager.java
SkinStyleElementValueManager.java
StyleElementManager.java
StyleManager.java

it compiles.  i dunno if it works, though.
@
text
@d63 1
a63 1
import org.joist.database.DataManager;
d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.24 2001/01/24 21:41:50 leonardr Exp $
d175 5
d219 11
a229 1
            catch (DBException e)
d264 1
a264 1
        throws DBException
d282 1
a282 1
        throws DBException
d303 1
a303 1
        throws DBException
d305 1
d310 1
a310 1
        constructOriginalRolesByProject(connection);
d319 2
a320 2
    private void constructOriginalRolesByProject(Connection connection)
        throws DBException
d350 1
a350 1

d366 3
a368 2
    public User getUser(Connection connection)
        throws DBException, DoesNotExist
d720 2
a721 3
    public List getResourcesForActionInProject
        (Connection connection, String action, String projectID, 
         boolean includeRole)
d909 1
a909 1
    private ArrayList buildRolesForProject(Connection connection, String projectID)
d954 1
a954 1
     * @@param conn A JDBC connection
d962 1
a962 2
        throws DataSetException, SQLException, JoistDatabaseException,
               DBException
d976 1
a976 1
            getManager("org.tigris.helm.database.RoleManager");        
d1044 1
d1062 1
a1062 1
            .getManager("org.tigris.helm.database.UserManager");
d1179 1
a1179 1
    public List getProjectsWithRoleFromHash(Connection connection, Hashtable t)
d1195 1
a1195 1
    public List getOriginalRolesInProject(Connection connection, Project project)
d1201 1
a1201 1
    public List getDerivedRolesInProject(Connection connection, Project project)
d1207 1
a1207 1
    private List getRolesInProjectFromHash(Connection connection, Project project, Hashtable t)
@


1.24
log
@Ported UserManager and RoleManager to Helm. Started moving other TableManagers toward a grab-connection-on-demand model. Massive breakage ensues. dlr and I are working on it.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.23 2001/01/24 20:42:49 dlr Exp $
@


1.23
log
@Making use of DBException.
@
text
@d63 1
a63 1
import org.joist.database.*;
d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.22 2001/01/23 20:38:00 leonardr Exp $
a174 5
     * A JDBC connection.
     */
    private Connection connection;

    /**
d214 1
a214 11
            catch (DataSetException e)
            {
                log.exception(e);
                throw new RuntimeException(e.getMessage());
            }
            catch (SQLException e)
            {
                log.exception(e);
                throw new RuntimeException(e.getMessage());
            }
            catch (JoistDatabaseException e)
d249 1
a249 1
        throws SQLException, DataSetException, JoistDatabaseException
d267 1
a267 1
        throws SQLException, DataSetException, JoistDatabaseException
d288 1
a288 1
        throws DataSetException, SQLException, JoistDatabaseException
a289 1
        this.connection = connection;
d294 1
a294 1
        constructOriginalRolesByProject();
d303 2
a304 2
    private void constructOriginalRolesByProject()
        throws DataSetException, SQLException, JoistDatabaseException
d350 2
a351 3
    public User getUser()
        throws SQLException, DataSetException, JoistDatabaseException, 
               DoesNotExist
d703 3
a705 2
    public List getResourcesForActionInProject(String action, String projectID,
                                               boolean includeRole)
d893 1
a893 1
    private ArrayList buildRolesForProject(String projectID)
d938 1
a938 1
     * @@param connection A JDBC connection
d961 1
a961 1
            getManager("org.joist.database.RoleManager");        
d1046 1
a1046 1
            .getManager("org.joist.database.UserManager");
d1163 1
a1163 1
    public List getProjectsWithRoleFromHash(Hashtable t)
d1179 1
a1179 1
    public List getOriginalRolesInProject(Project project)
d1185 1
a1185 1
    public List getDerivedRolesInProject(Project project)
d1191 1
a1191 1
    private List getRolesInProjectFromHash(Project project, Hashtable t)
@


1.22
log
@Added method to check role membership in the public projects group for a domain.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.21 2001/01/15 19:14:23 leonardr Exp $
d350 1
a350 1
    
d962 2
a963 1
        throws DataSetException, SQLException, JoistDatabaseException
a1044 1

@


1.21
log
@Also, it should be public because other classes will be interested in it.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.20 2001/01/15 18:28:52 leonardr Exp $
d433 18
a450 1
     * Checks whether the user's ACL has the role in the specified domain.
@


1.20
log
@Configurable roles means that actionsByRole is of interest in ACL dumps.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.19 2001/01/11 17:20:19 leonardr Exp $
d1247 1
a1247 1
    private static void dumpStatic()
@


1.19
log
@Inserted check for null.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.18 2001/01/05 21:42:39 leonardr Exp $
d1250 1
a1250 1
        //        AccessControlList.dumpActionsByRole();
@


1.18
log
@Big patch bringing the smart script runner online.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.17 2001/01/05 01:10:56 dlr Exp $
d1166 1
a1166 1
        for (Enumeration e = t.keys(); e.hasMoreElements(); )
d1168 6
a1173 3
            String projectID = (String)e.nextElement();
            Project project = new Project(connection, dMgr, projectID);
            projects.add(project);
@


1.17
log
@Migrated to latest Turbine CVS to avoid connection release bug (fixed long ago in Turbine CVS--we just had a bunk version).
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.16 2000/12/28 01:44:45 leonardr Exp $
d696 1
a696 1
        if (debug) log.info("User " + getUserID() 
d698 1
a698 1
                            + resource + " in project" + projectID);
@


1.16
log
@Get rid of debug info that often floods the log.
@
text
@d60 1
a60 1
import org.apache.turbine.services.db.PoolBrokerService;
d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.15 2000/12/27 23:12:35 leonardr Exp $
d188 1
a188 1
            dbConn = PoolBrokerService.getInstance().getConnection();
d248 1
a248 1
                    PoolBrokerService.getInstance().releaseConnection(dbConn);
@


1.15
log
@Support for users in the host domain.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.14 2000/12/23 00:48:19 dlr Exp $
a782 1
        log.info("Expanding roles for project " + projectID);
@


1.14
log
@Removed unnecessary getCache() implementations in BusinessObject subclasses and migrated to a factory method for User's primary database key ctor.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.13 2000/12/14 03:04:17 edk Exp $
d552 2
a553 2
        String domainProjectID = pMgr.getDomainProjectID(domainID);
        String publicDomainProjectID = pMgr.getPublicDomainProjectID(domainID);
d555 19
a573 3
        if (hasPermission(action, resource, domainProjectID)
            || hasPermission(action, resource, publicDomainProjectID)
            || hasPermission(action, resource, hostProjectID))
d783 1
@


1.13
log
@* adjust for corrections to Role constructor
* correct another Role constructor which listed the DataManager before
  the Connection
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.12 2000/12/13 02:57:37 leonardr Exp $
d370 1
a370 1
        return new User(connection, dMgr, userID);
@


1.12
log
@Corrected bugs in and wrote first usage of audit logging.
@
text
@d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.11 2000/12/07 02:21:33 leonardr Exp $
d720 1
a720 1
                                    Role role = new Role(dMgr, connection, roleID);
d1178 1
a1178 1
            roles.add(new Role(dMgr, connection, (String)i.next()));
@


1.11
log
@New (and extremely bulky) PermissionDump servlet.
@
text
@d67 1
d84 1
a84 1
 * @@version $Id: AccessControlList.java,v 1.10 2000/12/06 23:02:10 leonardr Exp $
d361 11
@


1.10
log
@Added support for servlet access to ACL information.
@
text
@d32 1
a32 1
 * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
d83 1
a83 1
 * @@version $Id: AccessControlList.java,v 1.9 2000/12/05 00:26:41 dlr Exp $
d646 36
a681 4
        //Iterate through their roles in this project--see if some
        //role has the right permission.
        ArrayList rolesForProject;
        rolesForProject = getAllRolesForProject(projectID);        
d687 2
a688 2
                /*                if (debug) log.info("Does role " + roleID + " have action " 
                                  + action + '?');*/
d694 1
a694 1
                    ArrayList resourcesForAction = 
d696 1
a696 1
                    if (resourcesForAction != null)
d698 1
a698 3
                        String scope = null;
                        for (Iterator j = resourcesForAction.iterator();
                             j.hasNext();)
d700 5
a704 2
                            scope = (String)j.next();
                            if (resourceMatchesScope(resource, scope))
d706 8
a713 7
                                if (debug) 
                                /*    log.info("Role " + roleID + 
                                             " has permission " + action + "/" 
                                             + resource + " in project" 
                                             + projectID);*/
                                
                                return true;
d716 2
a717 2
                    }        
                }    
d720 1
a720 7
        
        //No role has the right permissions--fail.
        if (debug) log.info("User " + getUserID() 
                            + " lacks permission " + action + "/" 
                            + resource + " in project" + projectID);

        return false;
d1090 31
d1130 1
a1130 5
        for (Enumeration e = projectGroups.keys(); e.hasMoreElements(); )
        {
            String projectID = (String)e.nextElement();
            expandRolesForProject(projectID);
        }
@


1.9
log
@Could use some better docs.
@
text
@d65 1
d67 2
d83 1
a83 1
 * @@version $Id: AccessControlList.java,v 1.8 2000/11/29 01:16:33 leonardr Exp $
d709 18
d743 2
a744 2
                                 + " in project " + projectID 
                                 + " via project " + projectGroupID);*/
d750 1
a750 14
        }
        
        ArrayList original = (ArrayList)originalRolesByProject.get(projectID);
        ArrayList derived = (ArrayList)derivedRolesByProject.get(projectID);
        ArrayList all = new ArrayList();
        if (original != null)
        {
            all.addAll(original);
        } 
        if (derived != null)
        {
            all.addAll(derived);
        }
        return all;
d752 1
a752 1

d1061 54
@


1.8
log
@All addition of users to user groups should go through the business objects.
@
text
@d17 1
a17 1
 * software developed by CollabNet (http://www.Collab.Net/)."
d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.7 2000/11/17 02:43:31 leonardr Exp $
d140 3
d144 4
d149 4
@


1.7
log
@Don't grant or revoke script-intensive roles unless it results in a change of state for the user.
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.6 2000/11/15 00:34:56 leonardr Exp $
d313 6
a318 2
        effectiveUserIDs.add(userID);
        effectiveUserIDs.addAll((ArrayList)userGroups.get(userID));
@


1.6
log
@Modernized ProjectMembers.
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.5 2000/11/14 22:57:48 leonardr Exp $
d372 11
@


1.5
log
@Split up ProjectMembershipRequest to show requested/approved/other roles.
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.4 2000/11/14 00:43:42 leonardr Exp $
d626 2
a627 2
                /*if (debug) log.info("Does role " + roleID + " have action " 
                  + action + '?');*/
d644 2
a645 2
                                /*if (debug) 
                                    log.info("Role " + roleID + 
d648 2
a649 2
                                             + projectID);
                                */
@


1.4
log
@Bugfix and removal of no-longer-needed debugging
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.3 2000/11/14 00:08:36 leonardr Exp $
a382 2
        boolean flag = false;

d388 13
d402 2
a403 2
        ArrayList rolesForProject = getAllRolesForProject(projectID);
        if (rolesForProject != null)
d405 1
a405 9
            for (Iterator i = rolesForProject.iterator(); i.hasNext(); )
            {
                String rid = (String)i.next();
                if (rid.equals(roleID))
                {
                    flag = true;
                    break;
                }
            }
d407 1
a407 1

@


1.3
log
@Fixed annoying bug that gave you permissions you didn't deserve.
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.2 2000/11/13 22:39:52 leonardr Exp $
d623 2
a624 2
                if (debug) log.info("Does role " + roleID + " have action " 
                  + action + '?');
d641 1
a641 1
                                if (debug) 
d646 1
a646 1
                                
d692 1
a692 1
                        log.info("User has role " + derivedRoleID 
d694 1
a694 1
                                 + " via project " + projectGroupID);
@


1.2
log
@Permission checking bugfixes; one more big one on the way.
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.1.1.1 2000/11/12 21:16:37 dlr Exp $
d132 1
a132 1
    private Hashtable rolesByProject;
d142 1
d293 6
a298 4
        this.rolesByProject = null;
        constructRolesByProject();
        //        dumpStatic();
        //        dump();                
d304 1
a304 1
    private void constructRolesByProject()
d310 1
a310 1
        rolesByProject = new Hashtable();
d328 1
a328 1
            addRoleToRolesByProject(roleID, projectID);
d331 1
a331 1

d391 1
a391 1
        ArrayList rolesForProject = (ArrayList)rolesByProject.get(projectID);
a613 27
        // Give us the roles we have in this project via project groups.
        // TODO: Only do this once.
        ArrayList groupsForProject = (ArrayList)projectGroups.get(projectID);
        if (groupsForProject != null)
        {
            for (Iterator i = groupsForProject.iterator(); i.hasNext();)
            {
                String projectGroupID = (String)i.next();
                ArrayList rolesForGroup = (ArrayList)rolesByProject
                    .get(projectGroupID);
                if (rolesForGroup != null)
                {
                    for (Iterator j = rolesForGroup.iterator(); j.hasNext();)
                    {
                        String derivedRoleID = (String)j.next();
                        log.info("User has role " + derivedRoleID + " in project " + projectID + " via project " + projectGroupID);
                        addRoleToRolesByProject(derivedRoleID, projectID);
                    }
                }
            }
        }

        //        log.info("Dumping static:");
        //        dumpStatic();
        //        log.info("Dumping ACL:");
        //        dump();

d617 1
a617 1
        rolesForProject = (ArrayList)rolesByProject.get(projectID);        
d662 63
d727 1
a727 1
     * Adds a role in a project to the user's RolesByProject
d736 2
a737 1
    private void addRoleToRolesByProject(String roleID, String projectID)
d740 2
a741 1
        if (rolesByProject.containsKey(projectID))
d743 1
a743 1
            rolesForProject = (ArrayList)rolesByProject.get(projectID);
d752 1
a752 1
        rolesByProject.put(projectID, rolesForProject);
d1032 1
a1032 1
        s.append("\nrolesByProject for userID "+ userID + ":\n");
d1034 1
a1034 1
        for (Enumeration e = rolesByProject.keys();
d1039 1
a1039 1
                (ArrayList)rolesByProject.get(projectID);
d1047 17
@


1.1
log
@Initial revision
@
text
@d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.78 2000/11/11 20:54:36 dlr Exp $
d102 1
a102 1
    private static Map userACLs = Collections.synchronizedMap(new HashMap());   
d135 9
d294 2
a295 1
        //dump();        
d626 1
d647 2
a648 2
                /*if (debug) log.info("Does role " + roleID + " have action " 
                  + action + '?');*/
d665 1
a665 1
                                /*                                if (debug) 
d670 1
a670 1
                                */
d681 1
a681 1
                            + " does not have permission " + action + "/" 
@


1.1.1.1
log
@Merging newhelm tree into helm, as per IZ issue #557.  Previous major version of helm is tagged TIGRIS_NOV_11_2000.
@
text
@@


1.1.1.2
log
@Replacing the HEAD with the HELM_PEER_PORT_BRANCH.
@
text
@d2 1
a2 1
 * Copyright (c) 2000-2001 CollabNet.  All rights reserved.
d17 1
a17 1
 * software developed by CollabNet (http://www.collab.net/)."
d32 1
a32 1
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
d50 4
d58 6
a63 2
import org.apache.turbine.util.db.Criteria;
import org.apache.turbine.util.Log;
d65 1
a65 4
import org.tigris.helm.DoesNotExist;
import org.tigris.helm.om.*;
import org.tigris.helm.om.peer.*;
import org.tigris.helm.om.base.*;
d80 1
a80 1
 * @@version $Id: AccessControlList.java,v 1.26.2.22 2001/02/16 03:01:34 dlr Exp $
d84 4
d92 6
a97 1
    private static final boolean DEBUG = false;
d102 1
a102 1
    private static Map userACLs = Collections.synchronizedMap(new HashMap());
d108 2
a109 2
        "HELM_USER read, " +
        "HELM_ROLE read," +
d124 1
a124 1
     * The user whose ACL this is.
d126 1
a126 1
    private User user;
d129 2
a130 2
     * The user-specific portion of the ACL: a Map keyed by 
     * Project to Lists of Roles.
d132 1
a132 1
    private Map originalRolesByProject;
d135 1
a135 2
     * Another Map like rolesByProject, but containing roles the
     * user has via having a role in a project group.
d137 2
a138 2
    private Map derivedRolesByProject;

d140 1
a140 1
     * Indicates that a role is original (granted directly to a project)
d142 1
a142 1
    private static final boolean ORIGINAL = true;
d145 1
a145 2
     * Indicates that a role is derived (granted to a project group which
     * contains a project)
d147 2
a148 2
    private static final boolean DERIVED = false; 

d150 1
a150 4
     * A mapping of project groups to booleans; the presence of a
     * project group in this Map means that the roles this user has in
     * the project group have been distributed (as derived roles)
     * across the projects in the project group.  
d152 1
a152 1
    private Map haveExpandedProject;
d155 1
a155 1
     * Gets the ACL for the root user.
d157 1
a157 2
    public final static AccessControlList getSuperUserACL()
        throws Exception
d159 72
a230 1
        return getACL(UserPeer.getSuperUser());
d232 1
a232 1
              
d234 1
a234 1
     * Gets the (possibly cached) ACL for the given user. 
d236 4
a239 2
    public synchronized static AccessControlList getACL(User user)
        throws Exception
d242 1
a242 5
        if (userACLs.containsKey(user)) 
        {
            acl = (AccessControlList)userACLs.get(user);
        }
        else 
d244 3
a246 1
            acl = rebuildACL(user);
d254 8
a261 9
    public static AccessControlList rebuildACL(User user)
        throws Exception
    {
        AccessControlList acl = null;
        synchronized(userACLs)
        {
            acl = new AccessControlList(user);
            userACLs.put(user, acl);
        }
d268 22
a289 3
     * @@param user  The user whose ACL is desired.
     *
     * @@exception Exception     Generic database error.
d291 2
a292 2
    protected AccessControlList (User user)
        throws Exception
d294 23
a316 7
        this.user = user;
        this.originalRolesByProject = new HashMap();
        this.derivedRolesByProject = new HashMap();
        constructOriginalRolesByProject();
        haveExpandedProject = new HashMap();
        dumpStatic();
        dump();                
d326 1
a326 1
        return user.getID();
a328 9
    /**
     * Get the User whose ACL this is.
     *
     * return A User object.
     */
    public User getUser()
    {
        return user;
    }
d341 2
a342 2
    public void assertRole (Role role)
        throws ACLException, Exception
d344 1
a344 1
        if (!hasRole(role))
d346 1
a346 1
            throw new ACLException(this, role.getName(), "Host", null);
d356 1
a356 20
    public boolean hasRole (Role role)
        throws Exception
    {
        return hasRoleInDomain(role, DomainPeer.getHostDomain());
    }

    /**
     * Checks whether the user's ACL has the role in the host.
     *
     * @@param roleID   The role to check for.
     * @@return         Whether the user has the role.
     */
    public boolean hasRoleInHost (Role role)
        throws Exception
    {
        return hasRole(role);
    }

    public boolean hasRole(Role role, Domain domain)
        throws Exception
d358 1
a358 1
        return hasRoleInDomain(role, domain);
d365 1
a365 1
     * @@param domain   The domain to check for the role in.
d368 1
a368 2
    public boolean hasRoleInDomain (Role role, Domain domain)
        throws Exception
d370 1
a370 15
        return hasRoleInProject(role, domain.getSpecialProject());
    }

    /**
     * Checks whether the user's ACL has the role in the group of public projects in the specified domain.
     *
     * @@param roleID   The role to check for.
     * @@param domain   The domain to check for the role in.
     * @@return         Whether access is allowed.
     */
    public boolean hasRoleInPublicDomainProjects (Role role, Domain domain)
        throws Exception
    {
        return hasRoleInProject(role, domain.getSpecialPublicProject());
    }
d372 5
a376 5
    public boolean hasRole(Role role, Project project)
        throws Exception
    {
        return hasRoleInProject(role, project);
    }
d378 2
a379 13
    /**
     * Checks whether the user's ACL has the role in the specified project.
     *
     * @@param roleID    The role to check for.
     * @@param projectID The domain to check for the role in.
     * @@return          Whether access is allowed.
     */
    public boolean hasRoleInProject (Role role, Project project)
    {
        boolean flag = false;

        List rolesForProject = getOriginalRolesForProject(project);
        if (rolesForProject != null && rolesForProject.contains(role))
d381 9
a389 1
            flag = true;
d391 1
a391 1
        
a402 1
     * @@deprecated Use assertPermission instead.
d406 2
a407 30
    public void assertPermissionForHost(String action)
        throws ACLException, Exception
    {
        assertPermission(action);
    }

    
    /**
     * Checks whether the user's ACL has permission to perform an action
     * on the host.
     *
     * @@deprecated     Use hasPermission instead.
     * @@param action   The action to check for.
     * @@return         Whether access is allowed.
     */
    public boolean hasPermissionForHost (String action)
        throws Exception
    {
        return hasPermission(action);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on the host.
     *
     * @@param action   The action to check for.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission(String action)
        throws ACLException, Exception
d409 1
a409 1
        if (!hasPermission(action))
d422 1
a422 2
    public boolean hasPermission (String action)
        throws Exception
d424 3
a426 1
        return hasPermission(action, ProjectPeer.getHostProject());
a436 3
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking in the domain. Use
     *             assertPermission instead.
d438 2
a439 2
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
d441 2
a442 2
    public void assertPermissionForDomain (String action, Domain domain)
        throws ACLException, Exception
d444 1
a444 1
        assertPermission(action, null, domain);
d446 1
a446 1
    
a450 3
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             assertPermission instead.
d453 2
a454 2
     * @@param domain     The domain to check.
     * @@exception ACLException If user doesn't have permission.  
d457 2
a458 2
                                           Domain domain)
        throws ACLException, Exception
d460 5
a464 1
        assertPermission(action, resource, domain);
a470 3
     * @@deprecated Since it takes a Domain object, it should be
     *             obvious that you're checking the domain. Use
     *             hasPermission instead.
d472 1
a472 15
     * @@param domain   The domain to check permission in.
     * @@return Whether access is allowed.  
     */
    public boolean hasPermissionForDomain (String action, Domain domain)
        throws Exception
    {
        return hasPermission(action, domain);
    }

    /**
     * Checks whether the user's ACL has permission to perform an action
     * on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check permission in.
d475 1
a475 16
    public boolean hasPermission(String action, Domain domain)
        throws Exception
    {
        return hasPermission(action, null, domain);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermission (String action, Domain domain)
        throws ACLException, Exception
d477 1
a477 20
        assertPermission(action, null, domain);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a domain.
     *
     * @@param action   The action to check for.
     * @@param domain   The domain to check.
     * @@exception ACLException If user doesn't have permission.  
     */
    public void assertPermission (String action, String resource, 
                                  Domain domain)
        throws ACLException, Exception
    {
        if (!hasPermission(action, resource, domain))
        {
            throw new ACLException(this, action, "Domain " + domain.getName(),
                                   resource);
        }
d486 1
a486 1
     * @@param domain   The domain to check permission in.
d489 2
a490 3
    public boolean hasPermission (String action, String resource, 
                                  Domain domain)
        throws Exception
d493 8
a500 13
        Project hostProject = ProjectPeer.getHostProject();
        Project domainProject = ProjectPeer.getDomainProject(domain);
        if (!hostProject.equals(domainProject))
        {
            Project publicDomainProject = ProjectPeer.getPublicDomainProject(domain);
            if (hasPermission(action, resource, domainProject)
                || hasPermission(action, resource, publicDomainProject))
            {
                ok = true;
            }
        }

        if (ok == false && hasPermission(action, resource, hostProject))
d504 1
a515 1
     * @@deprecated Use assertPermission instead.
d517 1
a517 1
     * @@param project The project to check.
d520 1
a520 1
    public void assertPermissionForProject (String action, Project project)
d523 1
a523 1
        assertPermission(action, project);
a529 1
     * @@deprecated Use assertPermission instead.
d532 1
a532 1
     * @@param project  The project to check.
d536 1
a536 1
                                            Project project)
d539 5
a543 1
        assertPermission(action, resource, project);
a549 1
     * @@deprecated Use hasPermission instead.
d551 1
a551 1
     * @@param project The project to check for.
d554 1
a554 2
    public boolean hasPermissionForProject (String action, Project project)
        throws Exception
d556 1
a556 1
        return hasPermission(action, project);
a562 1
     * @@deprecated Use hasPermission instead.
d564 1
a564 1
     * @@param project  The project to check for.
d568 1
a568 2
                                            Project project)
        throws Exception
d570 1
a570 1
        return hasPermission(action, resource, project);
a572 40
    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param project    The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission (String action, Project project)
        throws ACLException
    {
        assertPermission(action, null, project);
    }

    /**
     * Throws an exception if user's ACL doesn't have permission to perform
     * an action on a resource in a project.
     *
     * @@param action     The action to check for.
     * @@param resource   The resource to check.
     * @@param project    The project to check.
     * @@exception ACLException If user doesn't have permission.
     */
    public void assertPermission (String action, String resource, 
                                  Project project)
        throws ACLException
    {
        boolean ok = false;
        try {
            if (hasPermission(action, resource, project))
            {
                ok = true;
            } 
        } catch (Exception e) {
            throw new ACLException(this, action, 
                                   "Project " + project.getName(), resource);
        }
    }
    
d581 1
a581 1
     * @@param project   The project to which the action applies.
d584 1
a584 2
    public boolean hasPermission (String action, Project project)
        throws Exception
d586 1
a586 1
        return hasPermission(action, null, project);
d595 1
a595 1
     * @@param project   The project to which the action applies.
d599 1
a599 2
                                  Project project)
        throws Exception
d601 4
a604 5
        boolean ok = false;
        List resourcesForAction = 
            getResourcesForActionInProject(action, project, false);
        Resource scope;
        for (Iterator i = resourcesForAction.iterator(); i.hasNext();)
d606 1
a606 2
            scope = (Resource)i.next();
            if (resourceMatchesScope(resource, scope.getPattern()))
d608 11
a618 2
                ok = true;
                break;
a620 7
        
        if (DEBUG)
        {
            Log.debug("User " + user.getLoginName() 
                      + (ok ? "has":"lacks") + " permission " + action 
                      + '/' + resource + " in project" + project.getName());
        }
d622 9
a630 20
        return ok;
    }

    public List getResourcesForActionInProject
        (Action action, Project project, Boolean includeRole)
        throws DoesNotExist, Exception
    {
        return getResourcesForActionInProject(action.getName(), project,
                                              includeRole.booleanValue());
    }
    
    public List getResourcesForActionInProject
        (String actionName, Project project, boolean includeRole)
        throws DoesNotExist, Exception
    {
        Action action = ActionPeer.getInstanceByName(actionName);
        //Iterate through their roles in this project to get a list of
        //resources for which they have the given action.
        List resourcesForAction = new ArrayList();
        List rolesForProject = getAllRolesForProject(project);
d635 6
a640 2
                Role role = (Role)i.next();
                if (DEBUG) 
d642 4
a645 12
                    Log.debug("Does role " + role.getName() + " have action " 
                              + action.getName() + '?');
                }
                List resourcesForActionRole =
                    role.getResourcesForAction(action);

                if (!includeRole) {
                    resourcesForAction.addAll(resourcesForActionRole);
                }
                else {
                    for (Iterator k = resourcesForActionRole.iterator();
                         k.hasNext();)
d647 18
a664 5
                        Resource resource = (Resource)k.next();
                        resourcesForAction.add(resource.getPattern() 
                                               + "(" + role.getName() + ")");
                    }
                }
d667 7
a673 1
        return resourcesForAction;
d675 28
a702 1
                   
d712 3
a714 2
        if (DEBUG) Log.debug("Does '" + resource + "' match '" + scope + "'?");
        boolean isMatch = (resource == null || resource.equals(""));
d716 1
a716 1
        // If the match is not immediately evident, compare resource to scope.
d732 3
a734 5
        if (DEBUG)
        {
            if (isMatch) Log.debug("Resource matches.");
            else Log.debug("Resource does not match.");
        }
a737 4
    //
    // Handles expansion of roles.
    //

d739 3
a741 1
     * Returns the user's original roles in a project.
d743 3
a745 1
     * @@param projectID  The project to obtain roles for.
d747 2
a748 1
    private List getOriginalRolesForProject(Project project)
d750 4
a753 2
        return (List)originalRolesByProject.get(project);
    }
d755 1
a755 11
    /**
     * Returns the conjunction of the user's original and derived roles
     * in a project.
     *
     * @@param projectID  The project to obtain roles for
     */
    private List getAllRolesForProject(Project project)
        throws Exception
    {        
        // Give us the derived roles we have in this project via
        // project groups.  
d757 2
a758 4
        // TODO: Use HaveExpandedProject to only do this when
        // neccessary.
        
        expandRolesForProject(project);
d760 2
a761 14
        List original = (List)originalRolesByProject.get(project);
        List derived = (List)derivedRolesByProject.get(project);
        List all = new ArrayList();
        if (original != null)
        {
            all.addAll(original);
        } 
        if (derived != null)
        {
            all.addAll(derived);
        }
        dump();
        return all;
    }
d763 4
a766 5
    private void expandRolesForProject(Project project)
        throws Exception
    {                
        List groups = project.getGroups();
        for (Iterator i = groups.iterator(); i.hasNext();)
d768 1
a768 3
            ProjectGroup group = (ProjectGroup)i.next();
            List rolesForGroup = getOriginalRolesInProject(group);
            for (Iterator j = rolesForGroup.iterator(); j.hasNext();)
d770 5
a774 2
                Role derivedRole = (Role)j.next();
                addRoleToRolesByProject(derivedRole, project, DERIVED);
d776 8
d785 3
a787 1
    }  
d790 7
a796 1
     * Constructs the list of roles the user has in projects.
d798 8
a805 6
    private void constructOriginalRolesByProject()
        throws Exception
    {
        if (DEBUG) 
            Log.debug("Constructing roles by project for " + user.getRealName());
        originalRolesByProject = new HashMap();
d807 2
a808 2
        List effectiveUserIDs = user.effectiveUserIDs();
        if (DEBUG) Log.debug("Effective user IDs: " + effectiveUserIDs);
d810 71
a880 14
        Criteria c = new Criteria()
            .addIn(UserRoleProjectPeer.USER_ID, effectiveUserIDs.toArray());
        List urps = UserRoleProjectPeer.doSelect(c);

        Role role = null;
        Project project = null;
        List rolesForProject = null;
        for (Iterator i = urps.iterator(); i.hasNext();)
        {
            UserRoleProject entry = (UserRoleProject)i.next();
            role = RolePeer.retrieveByPK(entry.getRoleId());
            project = ProjectPeer.retrieveByPK(entry.getProjectId());
            if (DEBUG) Log.debug("Found role " + role.getName() + " in project " + project.getName());
            addRoleToRolesByProject(role, project, ORIGINAL);
d882 1
d884 1
a884 1
    
d886 1
a886 5
     * Adds a role in a project to the appropriate RolesByProject
     * hash.
     * <p>
     * TODO: Make this take a bunch of roles for better
     * efficiency.
d888 4
a891 2
     * @@param roleID    The role to add.
     * @@param projectID  The project in which the user has the role.
d893 5
a897 16
    private void addRoleToRolesByProject(Role role, Project project,
                                         boolean original)
    {       
        Map hash = (original ? originalRolesByProject : derivedRolesByProject);
        List rolesForProject = (List)hash.get(project);   
        if (rolesForProject == null)
        {
            rolesForProject = new ArrayList();
        }
      
        if (!rolesForProject.contains(role))
        {
            rolesForProject.add(role);
        }        
        hash.put(project, rolesForProject);
    }
d899 5
a903 3
    //
    // Some methods used by the script runner.
    //
d905 20
a924 8
    public void expandRolesForAllProjects()
        throws Exception
    {
        List groups = ProjectPeer.doSelect(new Criteria());
        for (Iterator i = groups.iterator(); i.hasNext(); )
        {
            Project p = (Project)i.next();
            expandRolesForProject(p);
d926 1
d929 31
a959 10
    public List getProjectsWithAnyRole()
        throws Exception
    {
        List p = new ArrayList();
        List orig = getProjectsWithOriginalRole();
        if (orig != null) p.addAll(orig);
        List derived = getProjectsWithDerivedRole();
        if (derived != null)
        {
            for (Iterator i = derived.iterator(); i.hasNext(); )
d961 3
a963 5
                Project project = (Project)i.next();
                if (!p.contains(project))
                {
                    p.add(project);
                }
d965 1
a966 1
        return p;
d969 3
a971 4
    public List getProjectsWithOriginalRole()
    {
        return getProjectsWithRoleFromMap(originalRolesByProject);
    }
d973 4
a976 2
    public List getProjectsWithDerivedRole()
        throws Exception
d978 6
a983 8
        expandRolesForAllProjects();
        return getProjectsWithRoleFromMap(derivedRolesByProject);
    }
    
    public List getProjectsWithRoleFromMap(Map t)
    {
        List l = new ArrayList(t.size());
        for (Iterator i = t.keySet().iterator(); i.hasNext(); )
d985 11
a995 3
            l.add((Project)i.next());
        }
        return l;
d998 4
a1001 1
    public List getOriginalRolesInProject(Project project)
d1003 4
a1006 1
        return getRolesInProjectFromMap(project, originalRolesByProject);
d1009 4
a1012 1
    public List getDerivedRolesInProject(Project project)
d1014 4
a1017 7
        return getRolesInProjectFromMap(project, derivedRolesByProject);
    }

    private List getRolesInProjectFromMap(Project project, Map t)
    {
        List l = null;
        for (Iterator i = t.keySet().iterator(); i.hasNext();)
d1019 4
a1022 2
            Project p = (Project)i.next();
            if (p.equals(project))
d1024 8
a1031 2
                l = (List)t.get(p);
                break;
d1033 1
d1035 1
a1035 2
        if (l == null) l = new ArrayList(0);
        return l;
d1039 1
a1039 1
     * Dumps the ACL to the log.
d1041 1
a1041 1
    public void dump()
d1043 1
a1043 1
        if (!DEBUG) return;
d1045 2
a1046 4
        s.append("\noriginalRolesByProject for "+ user.getLoginName() + ":\n");
        
        for (Iterator i = originalRolesByProject.keySet().iterator(); 
             i.hasNext();)
d1048 4
a1051 5
            Project project = (Project)i.next();
            List rolesForProject = 
                (List)originalRolesByProject.get(project);
            s.append(" Roles for project " + project.getName() + ": ");
            for (Iterator j = rolesForProject.iterator(); j.hasNext();)
d1053 2
a1054 3
                Role r = (Role)j.next();
                s.append(r.getName() + " ");
            }                        
d1056 3
a1058 1
        }    
d1060 9
a1068 5
        s.append("\nderivedRolesByProject (so far) for "+ user.getLoginName() 
                 + ":\n");
        
        for (Iterator i = derivedRolesByProject.keySet().iterator(); 
             i.hasNext(); )
d1070 5
a1074 5
            Project project = (Project)i.next();
            List rolesForProject = 
                (List)derivedRolesByProject.get(project);
            s.append(" Roles for project " + project.getName() + ": ");
            for (Iterator j = rolesForProject.iterator(); j.hasNext();)
d1076 2
a1077 3
                Role r = (Role)j.next();
                s.append(r.getName() + " ");
            }                        
d1079 2
a1080 3
        }    

        Log.debug(s.toString());        
a1082 10
    /**
     * Dumps the static ACL information to the log.
     */
    public static void dumpStatic()
    {
        if (!DEBUG) return;
        //         Log.debug(RoleActionResourcePeer.dumpStatic());
        //         Log.debug(UserUsergroupPeer.dumpStatic());
        //         Log.debug(ProjectProjectgroupPeer.dumpStatic());
    }
@

