head	1.13;
access;
symbols;
locks; strict;
comment	@# @;


1.13
date	2001.07.27.19.18.00;	author leonardr;	state dead;
branches;
next	1.12;

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

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

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

1.9
date	2001.07.26.18.06.37;	author leonardr;	state Exp;
branches;
next	1.8;

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

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

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

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

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

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

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

1.1
date	2001.06.14.15.32.17;	author leonardr;	state Exp;
branches;
next	;


desc
@@


1.13
log
@Factored out user code into a separate XML-RPC handler.
@
text
@/* ================================================================
 * Copyright (c) 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" or
 * "Helm" names nor may "Tigris" or "Helm" 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 org.apache.turbine.util.Log;

import org.tigris.helm.om.*;
import org.tigris.helm.tool.HelmProperties;

/**
 * Used to handle permission calls made via XML-RPC.
 *
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@author <a href="mailto:lucas@@collab.net">Josh Lucas</a>
 */
public class PermissionHandler
{
    /**
     * Whether or not to log debugging information;
     */
    public static final boolean DEBUG = false;

    /**
     * Empty constructor.
     */
    public PermissionHandler()
    {
    }

    /**
     * Takes a Vector of k strings representing actions, and returns
     * another vector containing only those actions which the user
     * posesses.  
     */
    public Vector getPermissionSet(String auth, int userID, int projectID, 
                                   Vector actionsToCheck)
        throws Exception
    {
        Vector permissionSet = null;
        validateAuth(auth);
        User user = UserPeer.getInstance(String.valueOf(userID));
        Project project = ProjectPeer.getInstance(String.valueOf(projectID));
        
        AccessControlList acl = user.getACL();
        permissionSet = new Vector(0);
        for (Iterator i = actionsToCheck.iterator(); i.hasNext();)
        {
            String action = (String)i.next();
            if (acl.hasPermission(action, project))
            {
                permissionSet.addElement(action);
            }
        }
        return permissionSet;
    }

    /**
     * Returns all the resources in which the given user has the given
     * action in the given project.
     */
    public Vector getResourcesForAction(String auth, String domainName, 
                                        String projectName, String userName,
                                        String action)
        throws Exception
    {
        validateAuth(auth);
        Domain domain = ProjectPeer.getDomain(domainName);
        Project project = ProjectPeer.getInstanceByName(domain, projectName);
        User user = UserPeer.getInstanceByLoginName(domain, userName);
        List resources = user.getACL()
            .getResourcesForActionInProject(action, project, false);
        Vector rv = new Vector(resources.size());
        for (Iterator i = resources.iterator(); i.hasNext();)
        {
            rv.add(((Resource)i.next()).getPattern());
        }
        return rv;
    }

    /**
     * Returns a user specified by ID.
     */
    public Hashtable getUserInfo(String auth, int userID)
        throws Exception
    {
        Hashtable user = null;
        validateAuth(auth);
        User u = UserPeer.getInstance(String.valueOf(userID));
        user = userToHash(u);
        return user;
    }

    /**
     * Returns a user specified by domain and login name.
     */
    public Hashtable getUserInfo(String auth, String domainName, 
                                 String loginName)
        throws Exception
    {
        Hashtable user = null;
        validateAuth(auth);
        Domain domain = ProjectPeer.getDomain(domainName);
        User u = UserPeer.getInstanceByLoginName(domain, loginName);
        user = userToHash(u);
        return user;
    }

    /**
     * Returns all the users who have the given action in the given
     * project.
     */
    public Vector getUsersWithAction(String auth, int projectID, String action)
        throws Exception
    {
        Vector users = null;
        validateAuth(auth);
        Project project = ProjectPeer.getInstance(String.valueOf(projectID));
        
        List userObjs = project.getUsersWithAction(action);
        users = new Vector(userObjs.size());
        for (Iterator i = userObjs.iterator(); i.hasNext();)
        {
            User u = (User)i.next();
            users.add(userToHash(u));
        }
        return users;
    }

    /**
     * Returns true iff the given user/password combination is valid.
     */
    public boolean isValidLogin(String auth, String domainName, 
                                String userName, String password)
        throws Exception
    {
        validateAuth(auth);
        Domain domain = ProjectPeer.getDomain(domainName);
        return UserPeer.isValidLogin(domain, userName, password);
    }

    //Helper methods

    /**
     * Does minimal validation for using the XML-RPC service: throws
     * an exception if given other than the magic string.
     */
    private void validateAuth(String auth)
        throws Exception
    {
        String dbPassword =
            (String) HelmProperties.getProperty("databasePassword");     
        if (!dbPassword.equals(auth))
        {
            throw new Exception
                ("Invalid authorization to use XML-RPC service.");
        }
    }

    /**
     * Hacky method which extracts information about a user and puts it
     * in a hash.
     */
    private Hashtable userToHash(User u)
    {
        Hashtable t = new Hashtable();
        t.put("id", u.getID());
        t.put("loginName", u.getLoginName());
        t.put("realName", u.getRealName());
        t.put("email", u.getEmail());
        return t;
    }
}
@


1.12
log
@Return patterns instead of Resource objects (duh).
@
text
@@


1.11
log
@Additions to permission server API for CVS-style checks.
@
text
@d122 1
a122 1
            rv.add(i.next());
@


1.10
log
@Take IDs as integers.
@
text
@d78 50
a155 27
     * Takes a Vector of k strings representing actions, and returns
     * another vector containing only those actions which the user
     * posesses.  
     */
    public Vector getPermissionSet(String auth, int userID, int projectID, 
                                   Vector actionsToCheck)
        throws Exception
    {
        Vector permissionSet = null;
        validateAuth(auth);
        User user = UserPeer.getInstance(String.valueOf(userID));
        Project project = ProjectPeer.getInstance(String.valueOf(projectID));
        
        AccessControlList acl = user.getACL();
        permissionSet = new Vector(0);
        for (Iterator i = actionsToCheck.iterator(); i.hasNext();)
        {
            String action = (String)i.next();
            if (acl.hasPermission(action, project))
            {
                permissionSet.addElement(action);
            }
        }
        return permissionSet;
    }

    /**
a165 2
        //TODO: verify that the user can see this information,
        //though there's no real rules for that as yet.
d175 14
@


1.9
log
@Experiment in allowing methods to throw exceptions rather than
returning nulls.
@
text
@d80 1
a80 1
    public Hashtable getUserInfo(String auth, String userID)
d85 1
a85 1
        User u = UserPeer.getInstance(userID);
d110 2
a111 2
    public Vector getPermissionSet(String auth, String userID, 
                                   String projectID, Vector actionsToCheck)
d116 2
a117 2
        User user = UserPeer.getInstance(userID);
        Project project = ProjectPeer.getInstance(projectID);
d136 1
a136 2
    public Vector getUsersWithAction(String auth, String projectID,
                                     String action)
d141 1
a141 1
        Project project = ProjectPeer.getInstance(projectID);
@


1.8
log
@Removed evil semicolon.
@
text
@d81 1
d84 3
a86 10
        try
        {
            validateAuth(auth);
            User u = UserPeer.getInstance(userID);
            user = userToHash(u);
        }
        catch (Exception e)
        {
            Log.error("",e);
        }
d95 1
d98 4
a101 12
        try
        {
            validateAuth(auth);
            Domain domain = ProjectPeer.getDomain(domainName);
            User u = UserPeer.getInstanceByLoginName(domain, loginName);
            user = userToHash(u);
        }
        catch (Exception e)
        {
            Log.error("", e);
            user = null;
        }
d112 1
d115 7
a121 1
        try
d123 2
a124 7
            validateAuth(auth);
            User user = UserPeer.getInstance(userID);
            Project project = ProjectPeer.getInstance(projectID);

            AccessControlList acl = user.getACL();
            permissionSet = new Vector(0);
            for (Iterator i = actionsToCheck.iterator(); i.hasNext();)
d126 1
a126 5
                String action = (String)i.next();
                if (acl.hasPermission(action, project))
                {
                    permissionSet.addElement(action);
                }
a128 5
        catch (Exception e)
        {
            Log.error("", e);
            permissionSet = null;
        }
d138 1
d141 8
a148 16
        try
        {
            validateAuth(auth);
            Project project = ProjectPeer.getInstance(projectID);

            //TODO: verify that the user can see this information,
            //though there's no real rules for that as yet.
            List userObjs = project.getUsersWithAction(action);
            users = new Vector(userObjs.size());
            for (Iterator i = userObjs.iterator(); i.hasNext();)
            {
                User u = (User)i.next();
                users.add(userToHash(u));
            }
        }
        catch (Exception e)
d150 2
a151 2
            Log.error("", e);
            users = null;
@


1.7
log
@Also, it should compile.
@
text
@d192 1
a192 1
        if (!dbPassword.equals(auth));
@


1.6
log
@No need for that to be public.
@
text
@d54 1
d93 1
a93 1
        return u;
d106 2
a107 1
            User u = UserPeer.getInstanceByName(domainName, loginName);
d140 1
a140 1
                    permSet.addElement(action);
d147 1
a147 1
            permSet = null;
d149 1
a149 1
        return permSet;
@


1.5
log
@Overhaul of API.
@
text
@d185 1
a185 1
    public void validateAuth(String auth)
@


1.4
log
@Changed getPermissionSet to give the sort of answer that will make Kevin happy.
@
text
@d77 20
a96 2
     * Returns all the users who have the given action in the given
     * project.
d98 2
a99 2
    public Hashtable getUserInfo(String username, String key, 
                                 String domainName)
d104 2
a105 2
            Object[] objs = validate(username, key, null, domainName);
            User u = (User)objs[2];
d111 1
d121 2
a122 3
    public Vector getPermissionSet(String username, String key, 
                                   String projectName, String domainName, 
                                   Vector permissions)
d124 1
a124 1
        Vector permSet = new Vector(0);
d127 3
a129 4
            Object[] objs = validate(username, key, projectName, domainName);
            Domain domain = (Domain)objs[0];
            Project project = (Project)objs[1];
            User user = (User)objs[2];
d132 2
a133 1
            for (Iterator i = permissions.iterator(); i.hasNext();)
d135 2
a136 2
                String permission = (String)i.next();
                if (acl.hasPermission(permission, project))
d138 1
a138 1
                    permSet.addElement(permission);
d145 1
a145 1
            permSet = new Vector(0);
d154 1
a154 2
    public Vector getUsersWithAction(String username, String key, 
                                     String projectName, String domainName, 
d160 5
a164 5
            Object[] objs = validate(username, key, projectName, domainName);
            Domain domain = (Domain)objs[0];
            Project project = (Project)objs[1];
            
            //Maybe verify that this user can see this information.
d176 1
d182 2
a183 1
     * Convenience method to validate the user and get objects.
d185 1
a185 2
    private Object[] validate(String username, String key, String projectName,
                              String domainName)
d188 3
a190 4
        Object[] objs = new Object[3];
        Domain domain = ProjectPeer.getDomain(domainName);
        objs[0] = domain;
        if (projectName != null)
d192 2
a193 1
            objs[1] = ProjectPeer.getInstanceByName(domain, projectName);
a194 2
        objs[2] = UserPeer.assertValidLogin(domain, username, key);
        return objs;
@


1.3
log
@Turned on XML-RPC service with permission handler, accepting connections from anyone in the cluster.
@
text
@d98 3
a100 2
     * Takes a Vector of k actions and returns a Vector of k Booleans
     * representing which permissions the given user has.
d106 1
a106 1
        Vector permSet = new Vector(permissions.size());
d115 1
a115 2
            int permsize = permissions.size();
            for (int i = 0; i < permsize; i++)
d117 1
a117 2
                String permission = (String)permissions.get(i);
                Boolean j = Boolean.FALSE;
d120 1
a120 1
                    j = Boolean.TRUE;
a121 1
                permSet.add(i,j);
d127 1
@


1.2
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
@d98 2
a99 3
     * Takes a list of k actions and returns a k-bit bitmap in which
     * the nth most significant bit is 1 iff the user has the nth
     * action in the provided list.
d101 3
a103 3
    public long getPermissionSet(String username, String key, 
                                 String projectName, String domainName, 
                                 Vector permissions)
d105 1
a105 1
        long permSet = 0;
d118 1
d121 1
a121 1
                    permSet |= Math.pow(2, i);
d123 1
a128 1
            permSet = -1;
@


1.1
log
@Preliminary wrapper for permission calls made via XML-RPC.
@
text
@d172 1
a172 1
        Domain domain = DomainPeer.getInstanceByName(domainName);
@

