head	1.36;
access;
symbols
	TIGRIS_NOV_12_2000:1.35
	OLDHELM:1.35.0.2
	TIGRIS_NOV_11_2000:1.35
	TIGRIS_SEP_13_2000:1.6.0.2
	TIGRIS_BASELINE:1.20;
locks; strict;
comment	@# @;


1.36
date	2000.11.12.23.08.42;	author dlr;	state dead;
branches;
next	1.35;

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

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

1.33
date	2000.10.17.21.59.41;	author dlr;	state Exp;
branches;
next	1.32;

1.32
date	2000.10.07.18.58.20;	author dlr;	state Exp;
branches;
next	1.31;

1.31
date	2000.10.03.18.25.46;	author dlr;	state Exp;
branches;
next	1.30;

1.30
date	2000.10.03.07.16.41;	author dlr;	state Exp;
branches;
next	1.29;

1.29
date	2000.10.03.06.22.01;	author dlr;	state Exp;
branches;
next	1.28;

1.28
date	2000.10.03.04.49.21;	author dlr;	state Exp;
branches;
next	1.27;

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

1.26
date	2000.10.03.02.22.13;	author dlr;	state Exp;
branches;
next	1.25;

1.25
date	2000.10.03.00.30.43;	author leonardr;	state Exp;
branches;
next	1.24;

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

1.23
date	2000.10.02.22.39.29;	author leonardr;	state Exp;
branches;
next	1.22;

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

1.21
date	2000.09.29.19.55.46;	author dlr;	state Exp;
branches;
next	1.20;

1.20
date	2000.09.25.23.09.04;	author ed;	state Exp;
branches;
next	1.19;

1.19
date	2000.09.25.07.08.32;	author dlr;	state Exp;
branches;
next	1.18;

1.18
date	2000.09.25.06.39.46;	author dlr;	state Exp;
branches;
next	1.17;

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

1.16
date	2000.09.25.06.35.06;	author dlr;	state Exp;
branches;
next	1.15;

1.15
date	2000.09.25.06.33.52;	author dlr;	state Exp;
branches;
next	1.14;

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

1.13
date	2000.09.25.06.11.41;	author dlr;	state Exp;
branches;
next	1.12;

1.12
date	2000.09.25.05.58.01;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2000.09.25.05.51.47;	author dlr;	state Exp;
branches;
next	1.10;

1.10
date	2000.09.25.02.59.33;	author dlr;	state Exp;
branches;
next	1.9;

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

1.8
date	2000.09.25.01.50.27;	author dlr;	state Exp;
branches;
next	1.7;

1.7
date	2000.09.25.00.41.23;	author dlr;	state Exp;
branches;
next	1.6;

1.6
date	2000.09.20.03.13.16;	author brian;	state Exp;
branches;
next	1.5;

1.5
date	2000.06.22.22.57.01;	author dlr;	state Exp;
branches;
next	1.4;

1.4
date	2000.05.26.00.20.05;	author jrobbins;	state Exp;
branches;
next	1.3;

1.3
date	2000.04.18.00.10.34;	author jrobbins;	state Exp;
branches;
next	1.2;

1.2
date	2000.02.03.04.21.32;	author jrobbins;	state Exp;
branches;
next	1.1;

1.1
date	2000.01.30.01.59.38;	author jrobbins;	state Exp;
branches;
next	;


desc
@@


1.36
log
@Does not exist in newhelm.
@
text
@/* ================================================================
 * Copyright (c) 2000 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 Collab.Net (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 Collab.Net.
 * 
 * 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 COLLAB.NET 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 Collab.Net.
 */


package org.tigris.helm.database;

import java.util.*;
import com.sun.java.util.collections.*;
import java.sql.*;
import gnu.regexp.RE;

import org.webmacro.util.*;
import org.webmacro.servlet.*;

import com.workingdogs.village.*;

import org.joist.util.*;
import org.joist.database.*;

import org.tigris.helm.tool.TigrisUpdate;
import org.tigris.helm.tool.UpdateException;

/**
 * Specializes the Joist UserManger to also update the Tigris permissions 
 * tables.
 *
 * TODO: Indicate the relationship between <code>User.userID</code> and 
 * <code>domain_{privs,users}.username</code>.
 *
 * @@author <a href="mailto:jrobbins@@collab.net">Jason Robbins</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@version $Id: TUserManager.java,v 1.35 2000/10/23 21:42:14 dlr Exp $
 */
public class TUserManager extends org.joist.database.UserManager
{
    static private Log log = new Log("TusrMgr", "Tigris User manager");
    static private boolean debug = true;

    /**
     * Indicates that a given user does not exist.
     */
    public static class NoSuchUserException extends Exception
    {
        public NoSuchUserException(String message)
        {
            super(message);
        }    
    } /* end class NoSuchUserException */

    /**
     * Indicates that a given user already exists.
     */
    public static class AlreadyExists extends Exception
    {
        /**
         * The <code>username</code> of the user that already exists.
         */
        private String username;
    
        /**
         * Create a new instance.
         *
         * @@param username the username that already exists
         */
        public AlreadyExists(String username)
        {
            super("User " + username + " already exists");
            this.username = username;
        }
    
        /**
         * Return the <code>username</code> of the user that already exists.
         */
        public String getUserName()
        {
            return username;
        }
    } /* end class AlreadyExists */

    /**
     * A user entry from the Tigris database
     */
    public static class Entry
    {
        /**
         * The user's application name.
         */
        private String username;

        /**
         * The user's real name.
         */
        private String realname;

        /**
         * Create a new user entry with the given username and real name
         */
        public Entry(String username, String realname)
        {
            this.username = username;
            this.realname = realname;
        }

        /**
         * Returns the user's application name.
         */
        public String getUserName()
        {
            return username;
        }

        /**
         * Returns the user's real name.
         */
        public String getRealName()
        {
            return realname;
        }
    }
  
    /**
     * Create an instance with an associated <code>DataManager</code>.
     *
     * @@param dataMgr The associated <code>DataManager</code>.
     */
    public TUserManager(DataManager dataMgr)
    {
        super(dataMgr);
    }

    /**
     * Adds a new user registration to the database.
     *
     * @@param  connection  the JDBC database connection
     * @@param  context  the WebContext
     * @@return the system-assigned userID for the newly added user.
     */
    public Integer addUser (Connection connection, WebContext context,
                            String username, String password,
                            String email, String realName)
        throws SQLException, DataSetException, JoistDatabaseException, 
               UpdateException
    {
        Integer userID = super.addUser(connection, context, username, 
                                       password);
        // Add user to domain_privs table.  All privileges default to off.
        PreparedStatement stmt = connection.prepareStatement
            ("INSERT INTO domain_privs (username) VALUES (?)");
        stmt.setString(1, username);
        stmt.executeUpdate();
        stmt.close();

        // Add user to domain_users table. At this point the user should be 
        // all set up and ready to go.
        stmt = connection.prepareStatement
            ("INSERT INTO domain_users (username, password, email, " + 
             "real_name) VALUES (?, PASSWORD(?), ?, ?)");
        stmt.setString(1, username);
        stmt.setString(2, password);
        stmt.setString(3, email);
        stmt.setString(4, realName);
        stmt.executeUpdate();
        stmt.close();

        // TODO: Call specific scripts rather than general update.
        TigrisUpdate.update(connection);

        return userID;
    }

    /**
     * Given a <code>userID</code>, return the associated <code>loginID</code>.
     */
    public String getLoginID (Connection connection, String userID)
        throws NoSuchUserException, SQLException
    {
        return getUserFieldValue(connection, "loginID", "userID", userID);
    }

    /**
     * Given a <code>loginID</code>, return the associated <code>userID</code>.
     */
    public String getUserID (Connection connection, String loginID)
        throws NoSuchUserException, SQLException
    {
        return getUserFieldValue(connection, "userID", "loginID", loginID);
    }
    
    /**
     * Returns the associated field value for a given key/value pair.
     *
     * @@param desiredField The database field whose value is desired.
     * @@param keyField     The database field to use as a key.
     * @@param keyValue     The database key value.
     * @@return             The value of the <code>desiredField</code> field.
     * @@exception NoSuchUserException The user can't be found.
     * @@exception SQLException        Database access error.
     */
    protected final String getUserFieldValue (Connection connection, 
                                              String desiredField, 
                                              String keyField, String keyValue)
        throws NoSuchUserException, SQLException
    {
        String desiredValue = null;

        // Fetch the desired value.
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT ").append(desiredField).append(" FROM User WHERE ");
        sql.append(keyField).append('=').append(escapeAndQuoteSQL(keyValue));
        Statement stmt = connection.createStatement();
        ResultSet r = stmt.executeQuery(sql.toString());
        if (r.next())
        {
            desiredValue = r.getString(1);
        }
        else
        {
            throw new NoSuchUserException(keyField + '=' + keyValue);
        }
        stmt.close();

        return desiredValue;
    }

    /**
     *  Deletes an existing user record from the database
     *  Do this as a "soft delete".  Copy the record to a
     *  DeletedUser table before deleting from the User table.
     */
    public void deleteUser (Connection connection, String loginID)
        throws SQLException
    {
        try
        {
            String userID = getUserID(connection, loginID);

            // Delete user from all tables
            super.deleteUser(connection, userID);
            Statement stmt = connection.createStatement();
            String whereQuery = " WHERE username = '" + loginID + '\'';
            stmt.executeUpdate("DELETE FROM domain_users" + whereQuery);
            stmt.executeUpdate("DELETE FROM domain_privs" + whereQuery);
            stmt.executeUpdate("DELETE FROM project_privs" + whereQuery);
            stmt.executeUpdate("DELETE FROM module_privs" + whereQuery);
            stmt.close();

            // Update the database
            // TODO: replace general back end with specific scripts
            TigrisUpdate.update(connection);
        }
        catch (Exception e)
        {
            log.exception(e);
        }
    }

    /**
     * Gets the users for the specified project.
     *
     * @@param connection  The JDBC connection to use.
     * @@param projectName The name of the project for which users are desired.
     * @@return            The project's users.
     */
    public static List getUsersForProject(Connection connection, 
                                          String projectName)
        throws SQLException
    {
        return getUsers(connection, projectName, null);
    }

    /**
     * Gets the users for the specified module.
     *
     * @@param connection  The JDBC connection to use.
     * @@param projectName The name of the project for which users are desired.
     * @@param moduleName  The name of the module for which users are desired 
     *                    (or null if users for all modules should be 
     *                    retrieved).
     * @@return            The project's module's users.
     */
    public static final List getUsersForModule(Connection connection, 
                                               String projectName, 
                                               String moduleName)
        throws SQLException
    {
        return getUsers(connection, projectName, moduleName);
    }

    /**
     * Gets <i>all</i> users with both their real and application names.
     *
     * @@param connection The JDBC connection to use.
     * @@return           All users.
     */
    public static final List getUsers(Connection connection)
        throws SQLException
    {
        return getUsers(connection, null, null);
    }
    
    /**
     * Gets the specified users.
     *
     * @@param connection  The JDBC connection to use.
     * @@param projectName The name of the project for which users are desired 
     *                    (or null if users for all projects should be 
     *                    retreived).
     * @@param moduleName  The name of the module for which users are desired 
     *                    (or null if users for all modules should be 
     *                    retrieved).
     * @@return            The desired users.
     */
    protected static List getUsers(Connection connection, String projectName, 
                                   String moduleName)
        throws SQLException
    {
        ArrayList users = new ArrayList();
    
        // Build the SQL query.
        // TODO: Add a new project homepage column.
        StringBuffer sql = new StringBuffer
            ("SELECT domain_users.username, domain_users.real_name " + 
             "FROM domain_users");
        if (projectName != null || moduleName != null);
        {
            // Add _privs tables to query.
            if (projectName != null)
            {
                sql.append(", project_privs");
            }
            if (moduleName != null)
            {
                sql.append(", module_privs");
            }

            // Add clause indicator.
            if (projectName != null || moduleName != null)
            {
                sql.append(" WHERE ");
            }

            // Add joins and criteria.
            if (projectName != null)
            {
                sql.append("domain_users.username=project_privs.username");
                sql.append(" AND project_privs.project=");
                sql.append(escapeAndQuoteSQL(projectName));
            }
            if (moduleName != null)
            {
                if (projectName != null);
                {
                    sql.append(" AND ");
                }
                sql.append("domain_users.username=module_privs.username");
                sql.append(" AND module_privs.project=");
                sql.append(escapeAndQuoteSQL(moduleName));
            }
        }
        sql.append(" ORDER BY domain_users.username");

        // Get the desired users.
        Statement stmt = connection.createStatement();
        ResultSet result = stmt.executeQuery(sql.toString());
        while (result.next())
        {
            users.add(new Entry(result.getString(1), result.getString(2)));
        }
        stmt.close();

        return users;
    }
    
    /**
     * TODO: doc
     */
    public boolean isModuleOwner(Connection connection, String loginID,
                                 String project, String module) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        Statement s = connection.createStatement();
        String q = "SELECT extent FROM PermissionExtent"+
            " WHERE userID='" + userID + "'"+
            " AND permissionID=211"; //TODO: hardcoded
        ResultSet r = s.executeQuery(q);
        while (r.next()) {
            String extent = r.getString(1);
            try {
                RE pat = new RE(extent);
                if (pat.isMatch(project + "/" + module)) return true;
            }
            catch (gnu.regexp.REException e) {
                log.exception(e);
            }
        }

        String roleID = getUserRoleID(connection, loginID);
        // TODO: Don't hard-code database keys!
        return ("4".equals(roleID) || 
                "7".equals(roleID) || 
                "10".equals(roleID));
    }
    
    /**
     * TODO: doc
     */
    public void setModuleOwner(Connection connection, String loginID,
                               String project, String module, boolean isOwner) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        boolean wasOwner = isModuleOwner(connection, loginID, project, module);
        if (isOwner && wasOwner) return;
        if (!isOwner && !wasOwner) return;

        // TODO: Don't hard-code database keys!
        int permissionIDs[] = {211, 212, 220, 221, 222};
        Statement s = connection.createStatement();
        for (int i = 0; i < permissionIDs.length; i++) {
            if (isOwner) {
                s.executeUpdate("INSERT INTO PermissionExtent"+
                                " (userID, permissionID, extent) VALUES"+
                                " (" + userID +", " + permissionIDs[i] +
                                ", '" + project + "/" + module +"')");
            }
            else {
                s.executeUpdate("DELETE FROM PermissionExtent" +
                                " WHERE userID="+ userID + 
                                " AND permissionID="+ permissionIDs[i] +
                                " AND extent='" +
                                project + "/" + module + "'");
            }
        }
    }

    /**
     * TODO: doc
     */
    public boolean isProjectOwner(Connection connection, String loginID,
                                  String project) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        Statement s = connection.createStatement();
        String q = "SELECT extent FROM PermissionExtent"+
            " WHERE userID='" + userID + "'"+
            " AND permissionID=154";
        ResultSet r = s.executeQuery(q);
        while (r.next()) {
            String extent = r.getString(1);
            try {
                RE pat = new RE(extent);
                if (pat.isMatch(project)) return true;
            }
            catch (gnu.regexp.REException e) {
                log.exception(e);
            }
        }
        String roleID = getUserRoleID(connection, loginID);
        if ("4".equals(roleID) || "7".equals(roleID) || "10".equals(roleID)) return true;
        return false;
    }
    
    /**
     * TODO: doc
     */
    public void setProjectOwner(Connection connection, String loginID,
                                String project, boolean isOwner) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        boolean wasOwner = isProjectOwner(connection, loginID, project);
        if (isOwner && wasOwner) return;
        if (!isOwner && !wasOwner) return;

        // TODO: dont hard-code this!
        int permissionIDs[] = {53, 154, 225, 226, 227, 211, 212, 220, 221, 222};
        Statement s = connection.createStatement();
        for (int i = 0; i < permissionIDs.length; i++) {
            if (isOwner) {
                s.executeUpdate("INSERT INTO PermissionExtent"+
                                " (userID, permissionID, extent) VALUES"+
                                " (" + userID +", " + permissionIDs[i] +
                                ", '" + project + ".*')");
            }
            else {
                s.executeUpdate("DELETE FROM PermissionExtent" +
                                " WHERE userID="+ userID + 
                                " AND permissionID="+ permissionIDs[i] +
                                " AND extent='" + project + ".*'");
            }
        }
    }
    
    /**
     * TODO: doc
     */
    public void setUserRole(Connection connection,
                            String loginID, String roleName)
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        String roleID = getRoleID(connection, roleName);

        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT roleID "+
                           "FROM UserRole " +
                           "WHERE userID=" + userID);
        if (r.next()) {
            s.executeUpdate("UPDATE UserRole "+
                            "SET roleID=" + roleID + ' ' +
                            "WHERE userID=" + userID);
        }
        else {
            s.executeUpdate("INSERT INTO UserRole (userID, roleID) " +
                            "VALUES (" + userID + ", " + roleID + ')');
        }    
    }

    /**
     * TODO: doc
     */
    public String getUserRole(Connection connection, String loginID)
        throws SQLException, NoSuchUserException
    {
        String roleID = getUserRoleID(connection, loginID);
        String roleName = getRoleName(connection, roleID);
        return roleName;
    }
    
    
    /**
     * TODO: doc
     */
    public String getUserRoleID(Connection connection, String loginID)
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        Statement s = connection.createStatement();
        ResultSet r = s.executeQuery("SELECT roleID "+
                                     "FROM UserRole " +
                                     "WHERE userID='" + userID + "'");

        // If the user has no roles, default to "Active Developer".
        return (r.next() ? r.getString(1) : "2");
    }

    /**
     * Returns the role name associated with the specified database key.
     */
    public String getRoleName(Connection connection, String roleID)
        throws SQLException
    {
        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT name FROM Role WHERE roleID=" + roleID);
        return (r.next() ? r.getString(1) : "Active Developer");
    }
    
    /**
     * Returns the database key associated with the specified role name.
     */
    public String getRoleID(Connection connection, String roleName)
        throws SQLException
    {
        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT roleID FROM Role WHERE name=" + 
                           escapeAndQuoteSQL(roleName));

        // If no role associated, default to "Active Developer".
        return (r.next() ? r.getString(1) : "2");
    }
} /* end class TUserManager */
@


1.35
log
@Added a tad of docomm.  ;P
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.34 2000/10/23 21:37:00 dlr Exp $
@


1.34
log
@Applying bug fix from Robert Watt <watt@@collab.net> to handle correct
SQL generation.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.33 2000/10/17 21:59:41 dlr Exp $
d594 1
a594 1
     * TODO: dococmm
d606 1
a606 1
     * TODO: doc
d612 5
a616 2
        ResultSet r = s.executeQuery("SELECT roleID FROM Role " + 
                                     "WHERE name=" + escapeAndQuoteSQL(roleName));
@


1.33
log
@Shouldn't use a PreparedStatement when building the entire query
dynamically.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.32 2000/10/07 18:58:20 dlr Exp $
d589 2
a590 1
        return (r.next() ? r.getString(1) : "Active Developer");
d594 1
a594 1
     * TODO: doc
@


1.32
log
@Corrected conflict between the MM MySQL driver's
PreparedStatement.setString(String) method and Joist's EscapedString
and QuotedString utilities.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.31 2000/10/03 18:25:46 dlr Exp $
d250 5
a254 6
        PreparedStatement stmt = 
            connection.prepareStatement("SELECT ? FROM User WHERE ?=?");
        stmt.setString(1, desiredField);
        stmt.setString(2, keyField);
        stmt.setString(3, QuotedString.from(keyValue));
        ResultSet r = stmt.executeQuery();
@


1.31
log
@renamed method
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.30 2000/10/03 07:16:41 dlr Exp $
a188 2
        username = sanitizeSQL(username);

d202 3
a204 3
        stmt.setString(2, QuotedString.from(password));
        stmt.setString(3, QuotedString.from(email));
        stmt.setString(4, sanitizeSQL(realName));
d391 1
a391 1
                sql.append(sanitizeSQL(projectName));
d401 1
a401 1
                sql.append(sanitizeSQL(moduleName));
d613 1
a613 1
                                     "WHERE name=" + sanitizeSQL(roleName));
@


1.30
log
@Correcting SQL generation.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.29 2000/10/03 06:22:01 dlr Exp $
d222 1
a222 1
        return getFieldValue(connection, "loginID", "userID", userID);
d231 1
a231 1
        return getFieldValue(connection, "userID", "loginID", loginID);
d244 3
a246 3
    protected final String getFieldValue (Connection connection, 
                                          String desiredField, 
                                          String keyField, String keyValue)
@


1.29
log
@Yay, let's hear it for maintainence of deprecating code!
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.28 2000/10/03 04:49:21 dlr Exp $
d388 1
a388 1
            // Add joins.
a391 13
                if (moduleName != null);
                {
                    sql.append(" AND ");
                }
            }
            if (moduleName != null)
            {
                sql.append("domain_users.username=module_privs.username");
            }

            // Add criteria.
            if (projectName != null)
            {
d397 5
@


1.28
log
@It seems that PreparedStatement dynamic insertion points--i.e. ? characters--cannot be in quotes.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.27 2000/10/03 02:53:14 dlr Exp $
d256 1
a256 1
        stmt.setString(3, keyValue);
@


1.27
log
@slim fast
@
text
@d60 1
a61 1
import org.joist.util.*;
d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.26 2000/10/03 02:22:13 dlr Exp $
d202 1
a202 1
             "real_name) VALUES (?, PASSWORD('?'), '?', ?)");
d204 2
a205 2
        stmt.setString(2, password);
        stmt.setString(3, email);
@


1.26
log
@Add Entry objects to the List.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.25 2000/10/03 00:30:43 leonardr Exp $
d564 1
a564 1
                           "WHERE userID='" + userID + "' ");
d567 2
a568 2
                            "SET roleID='" + roleID + "' " +
                            "WHERE userID='" + userID + "' ");
d571 2
a572 4
            s.executeUpdate("INSERT INTO UserRole "+
                            "(userID, roleID) "+
                            " VALUES "+
                            "('" + userID + "', '" + roleID +"')");
a594 1
    
d599 2
a600 3
        if (!r.next()) return "Active Developer";
        String roleID = r.getString(1);
        return roleID;
d611 2
a612 5
            s.executeQuery("SELECT name "+
                           "FROM Role " +
                           "WHERE roleID='" + roleID + "'");
        if (r.next()) return r.getString(1);
        return "Active Developer";
d622 3
a624 6
        ResultSet r = 
            s.executeQuery("SELECT roleID "+
                           "FROM Role " +
                           "WHERE name='" + roleName + "'");
        if (r.next()) return r.getString(1);
        return "2";
@


1.25
log
@Close the first instance of PreparedStatement that we created.  -dlr
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.24 2000/10/03 00:22:59 leonardr Exp $
d421 1
a421 1
            users.add(result.getString(1));
@


1.24
log
@Corrected domain_users field name.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.23 2000/10/02 22:39:29 leonardr Exp $
d196 1
@


1.23
log
@Changed bitwise OR to logical OR.  -dlr
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.22 2000/10/02 22:35:11 leonardr Exp $
d367 1
a367 1
            ("SELECT domain_users.username, domain_users.realname " + 
@


1.22
log
@Fixed bug in getUsers() which would cause improper SQL when listing all users (eg. not by project or module)
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.21 2000/09/29 19:55:46 dlr Exp $
d382 1
a382 1
            if (projectName != null | moduleName != null)
@


1.21
log
@Collab.Net --> CollabNet in copyright.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.20 2000/09/25 23:09:04 ed Exp $
d382 4
a385 1
            sql.append(" WHERE ");
@


1.20
log
@kill CRs (no changes other than whitespace)
@
text
@d2 1
a2 1
 * Copyright (c) 2000 Collab.Net.  All rights reserved.
d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.19 2000/09/25 07:08:32 dlr Exp $
@


1.19
log
@Corrected bogus SQL introduced by previous refactoring.  Please review
this one instead, thanks!
@
text
@d1 632
a632 632
/* ================================================================
 * Copyright (c) 2000 Collab.Net.  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 Collab.Net (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 Collab.Net.
 * 
 * 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 COLLAB.NET 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 Collab.Net.
 */


package org.tigris.helm.database;

import java.util.*;
import com.sun.java.util.collections.*;
import java.sql.*;
import gnu.regexp.RE;

import org.webmacro.util.*;
import org.webmacro.servlet.*;

import com.workingdogs.village.*;

import org.joist.database.*;
import org.joist.util.*;

import org.tigris.helm.tool.TigrisUpdate;
import org.tigris.helm.tool.UpdateException;

/**
 * Specializes the Joist UserManger to also update the Tigris permissions 
 * tables.
 *
 * TODO: Indicate the relationship between <code>User.userID</code> and 
 * <code>domain_{privs,users}.username</code>.
 *
 * @@author <a href="mailto:jrobbins@@collab.net">Jason Robbins</a>
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@version $Id: TUserManager.java,v 1.18 2000/09/25 06:39:46 dlr Exp $
 */
public class TUserManager extends org.joist.database.UserManager
{
    static private Log log = new Log("TusrMgr", "Tigris User manager");
    static private boolean debug = true;

    /**
     * Indicates that a given user does not exist.
     */
    public static class NoSuchUserException extends Exception
    {
        public NoSuchUserException(String message)
        {
            super(message);
        }    
    } /* end class NoSuchUserException */

    /**
     * Indicates that a given user already exists.
     */
    public static class AlreadyExists extends Exception
    {
        /**
         * The <code>username</code> of the user that already exists.
         */
        private String username;
    
        /**
         * Create a new instance.
         *
         * @@param username the username that already exists
         */
        public AlreadyExists(String username)
        {
            super("User " + username + " already exists");
            this.username = username;
        }
    
        /**
         * Return the <code>username</code> of the user that already exists.
         */
        public String getUserName()
        {
            return username;
        }
    } /* end class AlreadyExists */

    /**
     * A user entry from the Tigris database
     */
    public static class Entry
    {
        /**
         * The user's application name.
         */
        private String username;

        /**
         * The user's real name.
         */
        private String realname;

        /**
         * Create a new user entry with the given username and real name
         */
        public Entry(String username, String realname)
        {
            this.username = username;
            this.realname = realname;
        }

        /**
         * Returns the user's application name.
         */
        public String getUserName()
        {
            return username;
        }

        /**
         * Returns the user's real name.
         */
        public String getRealName()
        {
            return realname;
        }
    }
  
    /**
     * Create an instance with an associated <code>DataManager</code>.
     *
     * @@param dataMgr The associated <code>DataManager</code>.
     */
    public TUserManager(DataManager dataMgr)
    {
        super(dataMgr);
    }

    /**
     * Adds a new user registration to the database.
     *
     * @@param  connection  the JDBC database connection
     * @@param  context  the WebContext
     * @@return the system-assigned userID for the newly added user.
     */
    public Integer addUser (Connection connection, WebContext context,
                            String username, String password,
                            String email, String realName)
        throws SQLException, DataSetException, JoistDatabaseException, 
               UpdateException
    {
        Integer userID = super.addUser(connection, context, username, 
                                       password);
        username = sanitizeSQL(username);

        // Add user to domain_privs table.  All privileges default to off.
        PreparedStatement stmt = connection.prepareStatement
            ("INSERT INTO domain_privs (username) VALUES (?)");
        stmt.setString(1, username);
        stmt.executeUpdate();

        // Add user to domain_users table. At this point the user should be 
        // all set up and ready to go.
        stmt = connection.prepareStatement
            ("INSERT INTO domain_users (username, password, email, " + 
             "real_name) VALUES (?, PASSWORD('?'), '?', ?)");
        stmt.setString(1, username);
        stmt.setString(2, password);
        stmt.setString(3, email);
        stmt.setString(4, sanitizeSQL(realName));
        stmt.executeUpdate();
        stmt.close();

        // TODO: Call specific scripts rather than general update.
        TigrisUpdate.update(connection);

        return userID;
    }

    /**
     * Given a <code>userID</code>, return the associated <code>loginID</code>.
     */
    public String getLoginID (Connection connection, String userID)
        throws NoSuchUserException, SQLException
    {
        return getFieldValue(connection, "loginID", "userID", userID);
    }

    /**
     * Given a <code>loginID</code>, return the associated <code>userID</code>.
     */
    public String getUserID (Connection connection, String loginID)
        throws NoSuchUserException, SQLException
    {
        return getFieldValue(connection, "userID", "loginID", loginID);
    }
    
    /**
     * Returns the associated field value for a given key/value pair.
     *
     * @@param desiredField The database field whose value is desired.
     * @@param keyField     The database field to use as a key.
     * @@param keyValue     The database key value.
     * @@return             The value of the <code>desiredField</code> field.
     * @@exception NoSuchUserException The user can't be found.
     * @@exception SQLException        Database access error.
     */
    protected final String getFieldValue (Connection connection, 
                                          String desiredField, 
                                          String keyField, String keyValue)
        throws NoSuchUserException, SQLException
    {
        String desiredValue = null;

        // Fetch the desired value.
        PreparedStatement stmt = 
            connection.prepareStatement("SELECT ? FROM User WHERE ?=?");
        stmt.setString(1, desiredField);
        stmt.setString(2, keyField);
        stmt.setString(3, keyValue);
        ResultSet r = stmt.executeQuery();
        if (r.next())
        {
            desiredValue = r.getString(1);
        }
        else
        {
            throw new NoSuchUserException(keyField + '=' + keyValue);
        }
        stmt.close();

        return desiredValue;
    }

    /**
     *  Deletes an existing user record from the database
     *  Do this as a "soft delete".  Copy the record to a
     *  DeletedUser table before deleting from the User table.
     */
    public void deleteUser (Connection connection, String loginID)
        throws SQLException
    {
        try
        {
            String userID = getUserID(connection, loginID);

            // Delete user from all tables
            super.deleteUser(connection, userID);
            Statement stmt = connection.createStatement();
            String whereQuery = " WHERE username = '" + loginID + '\'';
            stmt.executeUpdate("DELETE FROM domain_users" + whereQuery);
            stmt.executeUpdate("DELETE FROM domain_privs" + whereQuery);
            stmt.executeUpdate("DELETE FROM project_privs" + whereQuery);
            stmt.executeUpdate("DELETE FROM module_privs" + whereQuery);
            stmt.close();

            // Update the database
            // TODO: replace general back end with specific scripts
            TigrisUpdate.update(connection);
        }
        catch (Exception e)
        {
            log.exception(e);
        }
    }

    /**
     * Gets the users for the specified project.
     *
     * @@param connection  The JDBC connection to use.
     * @@param projectName The name of the project for which users are desired.
     * @@return            The project's users.
     */
    public static List getUsersForProject(Connection connection, 
                                          String projectName)
        throws SQLException
    {
        return getUsers(connection, projectName, null);
    }

    /**
     * Gets the users for the specified module.
     *
     * @@param connection  The JDBC connection to use.
     * @@param projectName The name of the project for which users are desired.
     * @@param moduleName  The name of the module for which users are desired 
     *                    (or null if users for all modules should be 
     *                    retrieved).
     * @@return            The project's module's users.
     */
    public static final List getUsersForModule(Connection connection, 
                                               String projectName, 
                                               String moduleName)
        throws SQLException
    {
        return getUsers(connection, projectName, moduleName);
    }

    /**
     * Gets <i>all</i> users with both their real and application names.
     *
     * @@param connection The JDBC connection to use.
     * @@return           All users.
     */
    public static final List getUsers(Connection connection)
        throws SQLException
    {
        return getUsers(connection, null, null);
    }
    
    /**
     * Gets the specified users.
     *
     * @@param connection  The JDBC connection to use.
     * @@param projectName The name of the project for which users are desired 
     *                    (or null if users for all projects should be 
     *                    retreived).
     * @@param moduleName  The name of the module for which users are desired 
     *                    (or null if users for all modules should be 
     *                    retrieved).
     * @@return            The desired users.
     */
    protected static List getUsers(Connection connection, String projectName, 
                                   String moduleName)
        throws SQLException
    {
        ArrayList users = new ArrayList();
    
        // Build the SQL query.
        // TODO: Add a new project homepage column.
        StringBuffer sql = new StringBuffer
            ("SELECT domain_users.username, domain_users.realname " + 
             "FROM domain_users");
        if (projectName != null || moduleName != null);
        {
            // Add _privs tables to query.
            if (projectName != null)
            {
                sql.append(", project_privs");
            }
            if (moduleName != null)
            {
                sql.append(", module_privs");
            }

            // Add clause indicator.
            sql.append(" WHERE ");

            // Add joins.
            if (projectName != null)
            {
                sql.append("domain_users.username=project_privs.username");
                if (moduleName != null);
                {
                    sql.append(" AND ");
                }
            }
            if (moduleName != null)
            {
                sql.append("domain_users.username=module_privs.username");
            }

            // Add criteria.
            if (projectName != null)
            {
                sql.append(" AND project_privs.project=");
                sql.append(sanitizeSQL(projectName));
            }
            if (moduleName != null)
            {
                sql.append(" AND module_privs.project=");
                sql.append(sanitizeSQL(moduleName));
            }
        }
        sql.append(" ORDER BY domain_users.username");

        // Get the desired users.
        Statement stmt = connection.createStatement();
        ResultSet result = stmt.executeQuery(sql.toString());
        while (result.next())
        {
            users.add(result.getString(1));
        }
        stmt.close();

        return users;
    }
    
    /**
     * TODO: doc
     */
    public boolean isModuleOwner(Connection connection, String loginID,
                                 String project, String module) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        Statement s = connection.createStatement();
        String q = "SELECT extent FROM PermissionExtent"+
            " WHERE userID='" + userID + "'"+
            " AND permissionID=211"; //TODO: hardcoded
        ResultSet r = s.executeQuery(q);
        while (r.next()) {
            String extent = r.getString(1);
            try {
                RE pat = new RE(extent);
                if (pat.isMatch(project + "/" + module)) return true;
            }
            catch (gnu.regexp.REException e) {
                log.exception(e);
            }
        }

        String roleID = getUserRoleID(connection, loginID);
        // TODO: Don't hard-code database keys!
        return ("4".equals(roleID) || 
                "7".equals(roleID) || 
                "10".equals(roleID));
    }
    
    /**
     * TODO: doc
     */
    public void setModuleOwner(Connection connection, String loginID,
                               String project, String module, boolean isOwner) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        boolean wasOwner = isModuleOwner(connection, loginID, project, module);
        if (isOwner && wasOwner) return;
        if (!isOwner && !wasOwner) return;

        // TODO: Don't hard-code database keys!
        int permissionIDs[] = {211, 212, 220, 221, 222};
        Statement s = connection.createStatement();
        for (int i = 0; i < permissionIDs.length; i++) {
            if (isOwner) {
                s.executeUpdate("INSERT INTO PermissionExtent"+
                                " (userID, permissionID, extent) VALUES"+
                                " (" + userID +", " + permissionIDs[i] +
                                ", '" + project + "/" + module +"')");
            }
            else {
                s.executeUpdate("DELETE FROM PermissionExtent" +
                                " WHERE userID="+ userID + 
                                " AND permissionID="+ permissionIDs[i] +
                                " AND extent='" +
                                project + "/" + module + "'");
            }
        }
    }

    /**
     * TODO: doc
     */
    public boolean isProjectOwner(Connection connection, String loginID,
                                  String project) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        Statement s = connection.createStatement();
        String q = "SELECT extent FROM PermissionExtent"+
            " WHERE userID='" + userID + "'"+
            " AND permissionID=154";
        ResultSet r = s.executeQuery(q);
        while (r.next()) {
            String extent = r.getString(1);
            try {
                RE pat = new RE(extent);
                if (pat.isMatch(project)) return true;
            }
            catch (gnu.regexp.REException e) {
                log.exception(e);
            }
        }
        String roleID = getUserRoleID(connection, loginID);
        if ("4".equals(roleID) || "7".equals(roleID) || "10".equals(roleID)) return true;
        return false;
    }
    
    /**
     * TODO: doc
     */
    public void setProjectOwner(Connection connection, String loginID,
                                String project, boolean isOwner) 
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        boolean wasOwner = isProjectOwner(connection, loginID, project);
        if (isOwner && wasOwner) return;
        if (!isOwner && !wasOwner) return;

        // TODO: dont hard-code this!
        int permissionIDs[] = {53, 154, 225, 226, 227, 211, 212, 220, 221, 222};
        Statement s = connection.createStatement();
        for (int i = 0; i < permissionIDs.length; i++) {
            if (isOwner) {
                s.executeUpdate("INSERT INTO PermissionExtent"+
                                " (userID, permissionID, extent) VALUES"+
                                " (" + userID +", " + permissionIDs[i] +
                                ", '" + project + ".*')");
            }
            else {
                s.executeUpdate("DELETE FROM PermissionExtent" +
                                " WHERE userID="+ userID + 
                                " AND permissionID="+ permissionIDs[i] +
                                " AND extent='" + project + ".*'");
            }
        }
    }
    
    /**
     * TODO: doc
     */
    public void setUserRole(Connection connection,
                            String loginID, String roleName)
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
        String roleID = getRoleID(connection, roleName);

        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT roleID "+
                           "FROM UserRole " +
                           "WHERE userID='" + userID + "' ");
        if (r.next()) {
            s.executeUpdate("UPDATE UserRole "+
                            "SET roleID='" + roleID + "' " +
                            "WHERE userID='" + userID + "' ");
        }
        else {
            s.executeUpdate("INSERT INTO UserRole "+
                            "(userID, roleID) "+
                            " VALUES "+
                            "('" + userID + "', '" + roleID +"')");
        }    
    }

    /**
     * TODO: doc
     */
    public String getUserRole(Connection connection, String loginID)
        throws SQLException, NoSuchUserException
    {
        String roleID = getUserRoleID(connection, loginID);
        String roleName = getRoleName(connection, roleID);
        return roleName;
    }
    
    
    /**
     * TODO: doc
     */
    public String getUserRoleID(Connection connection, String loginID)
        throws SQLException, NoSuchUserException
    {
        String userID = getUserID(connection, loginID);
    
        Statement s = connection.createStatement();
        ResultSet r = s.executeQuery("SELECT roleID "+
                                     "FROM UserRole " +
                                     "WHERE userID='" + userID + "'");
        if (!r.next()) return "Active Developer";
        String roleID = r.getString(1);
        return roleID;
    }

    /**
     * TODO: doc
     */
    public String getRoleName(Connection connection, String roleID)
        throws SQLException
    {
        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT name "+
                           "FROM Role " +
                           "WHERE roleID='" + roleID + "'");
        if (r.next()) return r.getString(1);
        return "Active Developer";
    }
    
    /**
     * TODO: doc
     */
    public String getRoleID(Connection connection, String roleName)
        throws SQLException
    {
        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT roleID "+
                           "FROM Role " +
                           "WHERE name='" + roleName + "'");
        if (r.next()) return r.getString(1);
        return "2";
    }
} /* end class TUserManager */
@


1.18
log
@Boolean tests now on sale!
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.17 2000/09/25 06:37:22 dlr Exp $
d367 2
a368 2
            ("SELECT module_privs.username, module_privs.realname " + 
             "FROM module_privs");
d371 11
d384 1
d387 1
a387 2
                sql.append("project=").append(sanitizeSQL(projectName));

d395 13
a407 1
                sql.append("module=").append(sanitizeSQL(moduleName));
d410 1
a410 1
        sql.append(" ORDER BY module_privs.username");
@


1.17
log
@Methods are now retrieving both the application and real names.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.16 2000/09/25 06:35:06 dlr Exp $
d376 5
a380 4
            }
            if (projectName != null && moduleName != null);
            {
                sql.append(" AND ");
@


1.16
log
@oops--extra closing paren!
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.15 2000/09/25 06:33:52 dlr Exp $
d307 1
a307 1
     * @@return            The project's application users.
d324 1
a324 1
     * @@return            The project's module's application users.
d336 3
@


1.15
log
@MAJOR getUsersXXX() methods refactoring--please review.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.14 2000/09/25 06:12:38 dlr Exp $
d356 1
a356 1
                                   String moduleName))
@


1.14
log
@Corrected method header comment.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.13 2000/09/25 06:11:41 dlr Exp $
d307 1
a307 1
     * @@return            The project's users.
d313 1
a313 1
        return getUsersForModule(connection, projectName, null);
d322 32
a353 3
     *                    (or null if user names should be retrieved for all 
     *                    modules).
     * @@return            The project's users.
d355 2
a356 2
    public static List getUsersForModule(Connection connection, 
                                         String projectName, String moduleName)
d361 1
a361 1
        // Get the desired users.
d364 18
a381 5
            ("SELECT module_privs.username FROM module_privs WHERE project=");
        sql.append(sanitizeSQL(projectName));
        if (moduleName != null)
        {
            sql.append(" AND module=").append(sanitizeSQL(moduleName));
d384 2
a393 19
        return users;
    }

    /**
     * TODO: doc
     */
    public static List getUsers(Connection connection)
        throws SQLException
    {
        ArrayList users = new ArrayList();
    
        Statement s = connection.createStatement();
        ResultSet r = 
            s.executeQuery("SELECT domain_users.username, domain_users.real_name "+
                           "FROM domain_users " +
                           "ORDER BY domain_users.username");
        while (r.next()) {
            users.add(new Entry(r.getString(1), r.getString(2)));
        }
@


1.13
log
@The refactoring continues...getUsersForProject() now wrappers
getUsersForModule().  Ahhh yeah baby.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.12 2000/09/25 05:58:01 dlr Exp $
d322 2
a323 2
     *                    (or null if user should be retrieved for all 
     *                    projects).
@


1.12
log
@Corrected typos, kept in step with TableManager interface change.
@
text
@d75 1
a75 1
 * @@version $Id: TUserManager.java,v 1.11 2000/09/25 05:51:47 dlr Exp $
a303 2
     * HELP: The old JavaDoc on this method indicated that it retrieved 
     * <b>all</b> users, but the implemention did not match this comment.
d305 3
a307 3
     * @@param connection The JDBC connection to use.
     * @@param pojectName The name of the project for which users are desired.
     * @@return           The project's users.
d313 1
a313 16
        ArrayList users = new ArrayList();
    
        // Get the desired users.
        // TODO: Add a new project homepage column.
        PreparedStatement stmt = connection.prepareStatement
            ("SELECT project_privs.username FROM project_privs " + 
             "WHERE project=? ORDER BY project_privs.username");
        stmt.setString(1, sanitizeSQL(projectName));
        ResultSet r = stmt.executeQuery();
        while (r.next())
        {
            users.add(r.getString(1));
        }
        stmt.close();

        return users;
d317 8
a324 1
     * TODO: doc
d328 2
a329 1
        throws SQLException {
d332 15
a346 10
        Statement s = connection.createStatement();
        // TODO--2.0: project homepage column
        ResultSet r = 
            s.executeQuery("SELECT module_privs.username "+
                           "FROM module_privs " +
                           "WHERE project='" + projectName + "' " +
                           "AND module='" + moduleName + "' " +
                           "ORDER BY module_privs.username");
        while (r.next()) {
            users.add(r.getString(1));
d348 2
@


1.11
log
@More code cleanup, JavaDoc, and JavaDoc stubs.
@
text
@d75 1
a75 1
 * @@version $Id: $
d189 1
a189 1
        username = sqlSanitize(username);
d205 1
a205 1
        stmt.setString(4, sqlSanitize(realName));
d298 1
a298 1
            log.execption(e);
d322 1
a322 1
        stmt.setString(1, sqlSanitize(projectName));
@


1.10
log
@Corrected cut'n'paste errors.
@
text
@d72 4
d82 7
a88 2
    public static class NoSuchUserException extends Exception {
        public NoSuchUserException(String message) {
d93 8
a100 1
    public static class AlreadyExists extends Exception {
d104 1
a104 1
         * Create a new "user already exists" exception
d108 2
a109 1
        public AlreadyExists(String username) {
d115 1
a115 1
         * Return the username that already exists
d117 2
a118 1
        public String getUserName() {
d126 11
a136 2
    public static class Entry {
        private String username, realname;
d141 2
a142 1
        public Entry(String username, String realname) {
d147 5
a151 1
        public String getUserName() {
d155 5
a159 1
        public String getRealName() {
d166 2
d278 2
a279 1
        try {
d281 2
a282 1
      
d284 1
a284 3
            Statement s = connection.createStatement();
      
            // Delete user from all tables
d286 6
a291 5
            s.executeUpdate("DELETE FROM domain_users" + whereQuery);
            s.executeUpdate("DELETE FROM domain_privs" + whereQuery);
            s.executeUpdate("DELETE FROM project_privs" + whereQuery);
            s.executeUpdate("DELETE FROM module_privs" + whereQuery);
      
d296 3
a298 5
        catch (UpdateException e) {
            //TODO: how can I handle this exception?
        }
        catch (NoSuchUserException e) {
            //TODO: how can I handle this exception?
d302 9
a310 2
    /** Actually gets ALL users */
    
d313 2
a314 1
        throws SQLException {
d317 9
a325 8
        Statement s = connection.createStatement();
        // TODO--2.0: project homepage column
        ResultSet r = 
            s.executeQuery("SELECT project_privs.username "+
                           "FROM project_privs " +
                           "WHERE project='" + projectName + "' " +
                           "ORDER BY project_privs.username");
        while (r.next()) {
d328 2
d333 3
d355 3
d374 3
d405 3
d437 3
d465 3
d496 3
d524 3
d536 3
d553 3
d568 3
a581 1

@


1.9
log
@Refactored getUserID() and getLoginID() methods to use a common--and
new--method, getFieldValue().  This is a generic method that
constructs the appropriate SQL dynamically.  It should probably be
enhanced and pushed up the OO-heirarchy into the TableManager class.
@
text
@d183 1
a183 1
        return getFieldValue(connection, "loginID", "userID", loginID);
d225 1
a225 1
            throw new NoSuchUserException("userID=" + userID);
@


1.8
log
@Removed tabs, then let Emacs re-indent appropriately.
@
text
@d69 3
d129 1
a129 1
     *  Create an instance with a data manager.
a135 1

d137 1
a137 1
     *  Adds a new user registration to the database
d169 1
d178 1
a178 1
     * Given the sXc userID, return the loginID (also used in tigris).
d181 1
a181 1
        throws SQLException, NoSuchUserException
d183 1
a183 10
        // TODO: what is the relationship between userID and username
        Statement s = connection.createStatement();
    
        // Delete user from all tables
        String query = "SELECT loginID FROM User WHERE userID = '" + userID +
            "'";
        ResultSet r = s.executeQuery(query);

        if (r.next()) return r.getString(1);
        else throw new NoSuchUserException("userID=" + userID);
a184 1
  
d186 3
d190 1
a190 1
        throws SQLException, NoSuchUserException
d192 2
a193 2
        // TODO: what is the relationship between userID and username
        Statement s = connection.createStatement();
d195 33
a227 4
        // Delete user from all tables
        String query = "SELECT userID FROM User WHERE loginID = '" + loginID +
            "'";
        ResultSet r = s.executeQuery(query);
d229 1
a229 2
        if (r.next()) return r.getString(1);
        else throw new NoSuchUserException("loginID=" + loginID);
d231 1
a231 2
  
    
@


1.7
log
@Corrected buggy quoting problems and replaced previous implementation
with a much cleaner and higher performance one.
@
text
@d72 2
a73 2
  static private Log log = new Log("TusrMgr", "Tigris User manager");
  static private boolean debug = true;
d75 26
a100 5
  public static class NoSuchUserException extends Exception {
    public NoSuchUserException(String message) {
	    super(message);
    }    
  } /* end class NoSuchUserException */
a101 3
  public static class AlreadyExists extends Exception {
    private String username;
    
d103 1
a103 3
     * Create a new "user already exists" exception
     *
     * @@param username the username that already exists
d105 18
a122 3
    public AlreadyExists(String username) {
	    super("User " + username + " already exists");
	    this.username = username;
d124 1
a124 1
    
d126 1
a126 1
     * Return the username that already exists
d128 3
a130 2
    public String getUserName() {
	    return username;
d132 1
a132 1
  } /* end class AlreadyExists */
d135 5
a139 1
     * A user entry from the Tigris database
a140 36
    public static class Entry {
	private String username, realname;

	/**
	 * Create a new user entry with the given username and real name
	 */
	public Entry(String username, String realname) {
	    this.username = username;
	    this.realname = realname;
	}

	public String getUserName() {
	    return username;
	}

	public String getRealName() {
	    return realname;
	}
    }
  
  /**
   *  Create an instance with a data manager.
   */
	public TUserManager(DataManager dataMgr)
  {
    super(dataMgr);
  }


  /**
   *  Adds a new user registration to the database
   *
   * @@param  connection  the JDBC database connection
   * @@param  context  the WebContext
   * @@return the system-assigned userID for the newly added user.
   */
d142 3
a144 3
			    String username, String password,
			    String email, String realName)
	throws SQLException, DataSetException, JoistDatabaseException, 
d174 17
a190 17
  /**
   * Given the sXc userID, return the loginID (also used in tigris).
   */
  public String getLoginID (Connection connection, String userID)
    throws SQLException, NoSuchUserException
  {
    // TODO: what is the relationship between userID and username
    Statement s = connection.createStatement();
	
    // Delete user from all tables
    String query = "SELECT loginID FROM User WHERE userID = '" + userID +
      "'";
    ResultSet r = s.executeQuery(query);

    if (r.next()) return r.getString(1);
    else throw new NoSuchUserException("userID=" + userID);
  }
d193 14
a206 14
  public String getUserID (Connection connection, String loginID)
    throws SQLException, NoSuchUserException
  {
    // TODO: what is the relationship between userID and username
    Statement s = connection.createStatement();
	
    // Delete user from all tables
    String query = "SELECT userID FROM User WHERE loginID = '" + loginID +
      "'";
    ResultSet r = s.executeQuery(query);

    if (r.next()) return r.getString(1);
    else throw new NoSuchUserException("loginID=" + loginID);
  }
d209 10
a218 10
  /**
   *  Deletes an existing user record from the database
   *  Do this as a "soft delete".  Copy the record to a
   *  DeletedUser table before deleting from the User table.
   */
	public void deleteUser (Connection connection, String loginID)
    throws SQLException
  {
    try {
      String userID = getUserID(connection, loginID);
d220 2
a221 2
      super.deleteUser(connection, userID);
      Statement s = connection.createStatement();
d223 6
a228 6
      // Delete user from all tables
      String whereQuery = " WHERE username = '" + loginID + '\'';
      s.executeUpdate("DELETE FROM domain_users" + whereQuery);
      s.executeUpdate("DELETE FROM domain_privs" + whereQuery);
      s.executeUpdate("DELETE FROM project_privs" + whereQuery);
      s.executeUpdate("DELETE FROM module_privs" + whereQuery);
d230 10
a239 3
      // Update the database
      // TODO: replace general back end with specific scripts
      TigrisUpdate.update(connection);
a240 7
    catch (UpdateException e) {
      //TODO: how can I handle this exception?
    }
    catch (NoSuchUserException e) {
      //TODO: how can I handle this exception?
    }
  }
d244 51
a294 51
  public static List getUsersForProject(Connection connection, 
				       String projectName)
    throws SQLException {
    ArrayList users = new ArrayList();
    
    Statement s = connection.createStatement();
    // TODO--2.0: project homepage column
    ResultSet r = 
	s.executeQuery("SELECT project_privs.username "+
		       "FROM project_privs " +
		       "WHERE project='" + projectName + "' " +
		       "ORDER BY project_privs.username");
    while (r.next()) {
	    users.add(r.getString(1));
    }
    return users;
  }

  public static List getUsersForModule(Connection connection, 
				       String projectName, String moduleName)
    throws SQLException {
    ArrayList users = new ArrayList();
    
    Statement s = connection.createStatement();
    // TODO--2.0: project homepage column
    ResultSet r = 
	s.executeQuery("SELECT module_privs.username "+
		       "FROM module_privs " +
		       "WHERE project='" + projectName + "' " +
		       "AND module='" + moduleName + "' " +
		       "ORDER BY module_privs.username");
    while (r.next()) {
	    users.add(r.getString(1));
    }
    return users;
  }

  public static List getUsers(Connection connection)
    throws SQLException
    {
	ArrayList users = new ArrayList();
	
	Statement s = connection.createStatement();
	ResultSet r = 
	    s.executeQuery("SELECT domain_users.username, domain_users.real_name "+
			   "FROM domain_users " +
			   "ORDER BY domain_users.username");
	while (r.next()) {
	    users.add(new Entry(r.getString(1), r.getString(2)));
	}
	return users;
d298 2
a299 2
				 String project, String module) 
	throws SQLException, NoSuchUserException
d301 22
a322 19
	String userID = getUserID(connection, loginID);
	Statement s = connection.createStatement();
	String q = "SELECT extent FROM PermissionExtent"+
	    " WHERE userID='" + userID + "'"+
	    " AND permissionID=211"; //TODO: hardcoded
	ResultSet r = s.executeQuery(q);
	while (r.next()) {
	    String extent = r.getString(1);
	    try {
		RE pat = new RE(extent);
		if (pat.isMatch(project + "/" + module)) return true;
	    }
	    catch (gnu.regexp.REException e) {
		log.exception(e);
	    }
	}
	String roleID = getUserRoleID(connection, loginID);
	if ("4".equals(roleID) || "7".equals(roleID) || "10".equals(roleID)) return true;
	return false;
d326 2
a327 2
			       String project, String module, boolean isOwner) 
	throws SQLException, NoSuchUserException
d329 23
a351 23
	String userID = getUserID(connection, loginID);
	boolean wasOwner = isModuleOwner(connection, loginID, project, module);
	if (isOwner && wasOwner) return;
	if (!isOwner && !wasOwner) return;

	// TODO: dont hard-code this!
	int permissionIDs[] = {211, 212, 220, 221, 222};
	Statement s = connection.createStatement();
	for (int i = 0; i < permissionIDs.length; i++) {
	    if (isOwner) {
		s.executeUpdate("INSERT INTO PermissionExtent"+
				" (userID, permissionID, extent) VALUES"+
				" (" + userID +", " + permissionIDs[i] +
				", '" + project + "/" + module +"')");
	    }
	    else {
		s.executeUpdate("DELETE FROM PermissionExtent" +
				" WHERE userID="+ userID + 
				" AND permissionID="+ permissionIDs[i] +
				" AND extent='" +
				project + "/" + module + "'");
	    }
	}
d355 2
a356 2
				 String project) 
	throws SQLException, NoSuchUserException
d358 19
a376 19
	String userID = getUserID(connection, loginID);
	Statement s = connection.createStatement();
	String q = "SELECT extent FROM PermissionExtent"+
	    " WHERE userID='" + userID + "'"+
	    " AND permissionID=154";
	ResultSet r = s.executeQuery(q);
	while (r.next()) {
	    String extent = r.getString(1);
	    try {
		RE pat = new RE(extent);
		if (pat.isMatch(project)) return true;
	    }
	    catch (gnu.regexp.REException e) {
		log.exception(e);
	    }
	}
	String roleID = getUserRoleID(connection, loginID);
	if ("4".equals(roleID) || "7".equals(roleID) || "10".equals(roleID)) return true;
	return false;
d380 2
a381 2
			       String project, boolean isOwner) 
	throws SQLException, NoSuchUserException
d383 22
a404 22
	String userID = getUserID(connection, loginID);
	boolean wasOwner = isProjectOwner(connection, loginID, project);
	if (isOwner && wasOwner) return;
	if (!isOwner && !wasOwner) return;

	// TODO: dont hard-code this!
	int permissionIDs[] = {53, 154, 225, 226, 227, 211, 212, 220, 221, 222};
	Statement s = connection.createStatement();
	for (int i = 0; i < permissionIDs.length; i++) {
	    if (isOwner) {
		s.executeUpdate("INSERT INTO PermissionExtent"+
				" (userID, permissionID, extent) VALUES"+
				" (" + userID +", " + permissionIDs[i] +
				", '" + project + ".*')");
	    }
	    else {
		s.executeUpdate("DELETE FROM PermissionExtent" +
				" WHERE userID="+ userID + 
				" AND permissionID="+ permissionIDs[i] +
				" AND extent='" + project + ".*'");
	    }
	}
d408 2
a409 2
				   String loginID, String roleName)
	throws SQLException, NoSuchUserException
d411 2
a412 2
	String userID = getUserID(connection, loginID);
	String roleID = getRoleID(connection, roleName);
d414 16
a429 16
	Statement s = connection.createStatement();
	ResultSet r = 
	    s.executeQuery("SELECT roleID "+
			   "FROM UserRole " +
			   "WHERE userID='" + userID + "' ");
	if (r.next()) {
	    s.executeUpdate("UPDATE UserRole "+
			    "SET roleID='" + roleID + "' " +
			    "WHERE userID='" + userID + "' ");
	}
	else {
	    s.executeUpdate("INSERT INTO UserRole "+
			    "(userID, roleID) "+
			    " VALUES "+
			    "('" + userID + "', '" + roleID +"')");
	}	
d433 1
a433 1
	throws SQLException, NoSuchUserException
d435 3
a437 3
       String roleID = getUserRoleID(connection, loginID);
       String roleName = getRoleName(connection, roleID);
       return roleName;
d440 1
a440 1
	
d442 1
a442 1
	throws SQLException, NoSuchUserException
d444 9
a452 9
	String userID = getUserID(connection, loginID);
	
	Statement s = connection.createStatement();
	ResultSet r = s.executeQuery("SELECT roleID "+
				     "FROM UserRole " +
				     "WHERE userID='" + userID + "'");
	if (!r.next()) return "Active Developer";
	String roleID = r.getString(1);
	return roleID;
d456 1
a456 1
	throws SQLException
d458 7
a464 7
	Statement s = connection.createStatement();
	ResultSet r = 
	    s.executeQuery("SELECT name "+
			   "FROM Role " +
			   "WHERE roleID='" + roleID + "'");
	if (r.next()) return r.getString(1);
	return "Active Developer";
d468 1
a468 1
	throws SQLException
d470 7
a476 7
	Statement s = connection.createStatement();
	ResultSet r = 
	    s.executeQuery("SELECT roleID "+
			   "FROM Role " +
			   "WHERE name='" + roleName + "'");
	if (r.next()) return r.getString(1);
	return "2";
@


1.6
log
@
Obtained from:
Submitted by:
Reviewed by:

Moved from org.helm to org.tigris.helm
Moved from org/helm to org/tigris/helm

perl -pi.bak -e, how I love thee

note: this update was done POST-CVS-REPOSITORY surgury.  In order to
get this right, you may need to remove the directories

$CVSROOT/helm/java/org/helm
$CVSROOT/helm/data/htdoc/look/www/org/helm
$CVSROOT/helm/templates/org/helm

before doing the "CVS update" call, since those directories don't
exist anymore and CVS will try to create lockfiles for you in them,
giving you an error.
@
text
@d144 2
a145 1
	throws SQLException, DataSetException, JoistDatabaseException, UpdateException
d147 20
a166 1
    Integer userID = super.addUser(connection, context, username, password);
d168 2
a169 1
    Statement s = connection.createStatement();
d171 2
a172 28
    //TODO: do I need two connections to two databases?
    
    // Add user to domain_privs table. All privileges default to off
    s.executeUpdate("INSERT INTO domain_privs (username) VALUES ('"
                    + username + "')");

    // Add user to domain_users table. At this point the user should
    // be all set up and ready to go
    s.executeUpdate("INSERT INTO domain_users (username, password, "
                    + "email, real_name) VALUES ('" + username
                    + "', PASSWORD('" + password + "'), '" + email
                    + "', '" + realName + "')");

    //TODO: call specific scripts rather than general update
    TigrisUpdate.update(connection);
    
    return userID;
  }


  /**
   *  Updates an existing user record in the database
   */
	public void updateUser (Connection connection, String userID, WebContext context)
    throws SQLException, DataSetException, JoistDatabaseException
  {
    super.updateUser(connection, userID, context);
  }
@


1.5
log
@Removed an unneeded import statement, corrected a comment, and nuked
some whitespace.
@
text
@d48 1
a48 1
package org.helm.database;
d63 2
a64 2
import org.helm.tool.TigrisUpdate;
import org.helm.tool.UpdateException;
@


1.4
log
@fixes related to sponsor admin bugs
@
text
@a52 1
import javax.servlet.http.*;
a65 2


d67 3
a69 3
  * Specializes the sXc user manger to also update tigris permissions tables.
  */

@


1.3
log
@switched from collections2.jar to collections.jar
@
text
@d325 2
d379 2
d440 9
d450 1
a450 1

d457 1
a457 2
	String roleName = getRoleName(connection, roleID);
	return roleName;	    
@


1.2
log
@Added tigris.org license
PR:
Obtained from:
Submitted by:
Reviewed by:
@
text
@d51 1
@


1.1
log
@initial checking
@
text
@d1 46
a46 1
// Copyright (c) 2000 Collab.Net, Inc. All Rights Reserved.
@

