/*
 * Copyright 2001, 2002 Sun Microsystems, Inc. All Rights Reserved.
 *
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 */

package samples.security.jdbcrealm;

import java.util.Properties;
import java.util.Vector;
import java.util.HashMap;

import com.sun.enterprise.security.acl.RoleMapper;
import com.sun.enterprise.security.auth.realm.BadRealmException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;

import com.iplanet.ias.security.RealmConfig;
import com.iplanet.ias.security.auth.realm.IASRealm;


/**
 * JDBCRealm for supporting RDBMS authentication.
 *
 * <P>This login module provides a sample implementation of a custom realm.
 * You may use this sample as a template for creating alternate custom
 * authentication realm implementations to suit your applications needs.
 *
 * <P>In order to plug in a realm into the server you need to
 * implement both a login module (see JDBCLoginModule for an example)
 * which performs the authentication and a realm (as shown by this
 * class) which is used to manage other realm operations.
 *
 * <P>A custom realm should implement the following methods:
 *
 * <ul>
 *  <li>init(props)
 *  <li>getAuthType()
 *  <li>getGroupNames(username)
 * </ul>
 *
 * <P>IASRealm and other classes and fields referenced in the sample
 * code should be treated as opaque undocumented interfaces.
 *
 */
final public class JDBCRealm extends IASRealm
{
    public static final String AUTH_TYPE = "JDBCRealm";

    Properties _realmProperties = null;
    Vector     _groups = new Vector();

    HashMap _groupCache = new HashMap();
    Vector  _emptyVector;

    public JDBCRealm() {
    }

    
    /**
     * Initialize a realm. This method will be invoked once during server
     * startup.
     *
     * @param props Initialization parameters configured for this realm
     *     in server.xml
     * @exception BadRealmException If the configuration parameters
     *     identify a corrupt realm.
     * @exception NoSuchRealmException If the configuration parameters
     *     specify a realm which doesn't exist.
     *
     */
    protected void init(Properties props)
        throws BadRealmException, NoSuchRealmException
    {
        _realmProperties = props;
        String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM);
        this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx);
        _emptyVector = new Vector();
    }


    /**
     * Returns a short description of the kind of authentication which is
     * supported by this realm.
     *
     * @return Description of the kind of authentication that is directly
     *     supported by this realm.
     */    
    public String getAuthType()
    {
        return AUTH_TYPE;
    }

    
    /**
     * Returns the names of all the groups that this user belongs to.
     * This method is called during authorization when role mapping
     * to groups is processed. An implementation of this method can
     * cache the results for a given user or determine the membership
     * dynamically on every request, as desired.
     *
     * @param username Name of the user in this realm whose group listing
     *     is needed.
     * @return Enumeration of group names (strings).
     * @exception InvalidOperationException thrown if the realm does not
     *     support this operation - e.g. Certificate realm does not support
     *     this operation.
     */
    public java.util.Enumeration getGroupNames (String username)
        throws InvalidOperationException, NoSuchUserException
    {
        Vector v = (Vector)_groupCache.get(username);
        if (v == null) {
            return _emptyVector.elements();
        } else {
            return v.elements();
        }
    }

    
    /**
     * Returns the property string for this realm defined in server.xml
     */    
    public String getRealmProperty(String name) {
       return _realmProperties.getProperty(name);
    }


    /**
     * Set group membership info for a user.
     */
    public void setGroupNames(String username, String[] groups)
    {
        Vector v = new Vector(groups.length + 1);
        for (int i=0; i<groups.length; i++) {
            v.add(groups[i]);
        }
        _groupCache.put(username, v);
    }



}
