/* LoginContext.java
   Copyright (C) 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.security.auth.login;

import gnu.java.security.action.GetSecurityPropertyAction;

import java.security.AccessController;

import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.spi.LoginModule;

public class LoginContext
{

  private static final String OTHER = "other";

  private final String name;
  private final CallbackHandler cbHandler;
  private final Subject subject;
  private final AppConfigurationEntry[] entries;
  private final LoginModule[] modules;
  private final Map sharedState;

  public LoginContext (final String name) throws LoginException
  {
    this (name, new Subject(), defaultHandler());
  }

  public LoginContext (final String name, final CallbackHandler cbHandler)
    throws LoginException
  {
    this (name, new Subject(), cbHandler);
  }

  public LoginContext (final String name, final Subject subject)
    throws LoginException
  {
    this (name, subject, defaultHandler());
  }

  public LoginContext (final String name, final Subject subject,
                       final CallbackHandler cbHandler)
    throws LoginException
  {
    Configuration config = Configuration.getConfig();
    AppConfigurationEntry[] entries = config.getAppConfigurationEntry (name);
    if (entries == null)
      entries = config.getAppConfigurationEntry (OTHER);
    if (entries == null)
      throw new LoginException ("no configured modules for application "
                                + name);
    this.entries = entries;
    modules = new LoginModule[entries.length];
    sharedState = new HashMap();
    for (int i = 0; i < entries.length; i++)
      modules[i] = lookupModule (entries[i], subject, sharedState);
    this.name = name;
    this.subject = subject;
    this.cbHandler = cbHandler;
  }

  /**
   * Returns the authenticated subject, or the parameter passed to one
   * of the constructors. <code>null</code> is returned if the previous
   * login attempt failed and there was no subject provided.
   *
   * @return The subject, or null.
   */
  public Subject getSubject()
  {
    return subject;
  }

  /**
   * Logs a subject in, using all login modules configured for this
   * application. This method will call the {@link LoginModule#login()}
   * method of each module configured for this application, stopping
   * if a REQUISITE module fails or if a SUFFICIENT module succeeds. If
   * the overall login attempt fails, a {@link LoginException} will be
   * thrown.
   *
   * @throws LoginException If logging in fails.
   */
  public void login() throws LoginException
  {
    boolean failure = false;
    for (int i = 0; i < modules.length; i++)
      {
        try
          {
            boolean result = modules[i].login();
            if (!result)
              {
                if (entries[i].getControlFlag() ==
                    AppConfigurationEntry.LoginModuleControlFlag.REQUISITE)
                  throw new LoginException ("REQUISITE module " + entries[i].getLoginModuleName()
                                            + " failed");
                else if (entries[i].getControlFlag() ==
                         AppConfigurationEntry.LoginModuleControlFlag.REQUIRED)
                  failure = true;
              }
            else
              {
                if (entries[i].getControlFlag() ==
                    AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT)
                  break;
              }
          }
        catch (LoginException le)
          {
            if (entries[i].getControlFlag() !=
                AppConfigurationEntry.LoginModuleControlFlag.REQUISITE)
              continue;
            for (int j = 0; j < modules.length; j++)
              modules[i].abort();
            throw le;
          }
      }
    if (failure)
      throw new LoginException ("not all REQUIRED modules succeeded");

    for (int i = 0; i < modules.length; i++)
      modules[i].commit();
  }

  /**
   * Logs a subject out, cleaning up any state that may be in memory.
   *
   * @throws LoginException If logging out fails.
   */
  public void logout() throws LoginException
  {
    for (int i = 0; i < modules.length; i++)
      modules[i].logout();
  }

  // Own methods.

  /**
   * Fetch the default callback handler, based on the
   * auth.login.defaultCallbackHandler property, or null if it is not
   * set.
   */
  private static CallbackHandler defaultHandler()
  {
    GetSecurityPropertyAction act =
      new GetSecurityPropertyAction ("auth.login.defaultCallbackHandler");
    String classname = (String) AccessController.doPrivileged (act);
    if (classname != null)
      {
        try
          {
            return (CallbackHandler) Class.forName (classname).newInstance();
          }
        catch (ClassNotFoundException cnfe)
          {
            return null;
          }
        catch (ClassCastException cce)
          {
            return null;
          }
        catch (IllegalAccessException iae)
          {
            return null;
          }
        catch (InstantiationException ie)
          {
            return null;
          }
      }
    return null;
  }

  private LoginModule lookupModule (AppConfigurationEntry entry,
                                    Subject subject, Map sharedState)
    throws LoginException
  {
    LoginModule module = null;
    Exception cause = null;
    try
      {
        module = (LoginModule) Class.forName (entry.getLoginModuleName()).newInstance();
      }
    catch (ClassNotFoundException cnfe)
      {
        cause = cnfe;
      }
    catch (ClassCastException cce)
      {
        cause = cce;
      }
    catch (IllegalAccessException iae)
      {
        cause = iae;
      }
    catch (InstantiationException ie)
      {
        cause = ie;
      }

    if (cause != null)
      {
        LoginException le = new LoginException ("could not load module "
                                                + entry.getLoginModuleName());
        le.initCause (cause);
        throw le;
      }

    module.initialize (subject, cbHandler, sharedState, entry.getOptions());
    return module;
  }
}
