/* Subject.java -- a single entity in the system.
   Copyright (C) 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.DomainCombiner;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

public final class Subject implements Serializable
{
  // Fields.
  // -------------------------------------------------------------------------

  private static final long serialVersionUID = -8308522755600156056L;

  /**
   * @serial The set of principals. The type of this field is SecureSet, a
   *  private inner class.
   */
  private final Set principals;

  /**
   * @serial The read-only flag.
   */
  private boolean readOnly;

  private final transient SecureSet pubCred;
  private final transient SecureSet privCred;

  // Constructors.
  // -------------------------------------------------------------------------

  public Subject()
  {
    principals = new SecureSet (this, SecureSet.PRINCIPALS);
    pubCred = new SecureSet (this, SecureSet.PUBLIC_CREDENTIALS);
    privCred = new SecureSet (this, SecureSet.PRIVATE_CREDENTIALS);
    readOnly = false;
  }

  public Subject (final boolean readOnly, final Set principals,
                  final Set pubCred, final Set privCred)
  {
    if (principals == null || pubCred == null || privCred == null)
      {
        throw new NullPointerException();
      }
    this.principals = new SecureSet (this, SecureSet.PRINCIPALS, principals);
    this.pubCred = new SecureSet (this, SecureSet.PUBLIC_CREDENTIALS, pubCred);
    this.privCred = new SecureSet (this, SecureSet.PRIVATE_CREDENTIALS, privCred);
    this.readOnly = readOnly;
  }

  // Class methods.
  // -------------------------------------------------------------------------

  /**
   * <p>Returns the subject associated with the given {@link
   * AccessControlContext}.</p>
   *
   * <p>All this method does is retrieve the Subject object from the supplied
   * context's {@link DomainCombiner}, if any, and if it is an instance of
   * a {@link SubjectDomainCombiner}.
   *
   * @param context The context to retrieve the subject from.
   * @return The subject assoctiated with the context, or <code>null</code>
   *  if there is none.
   * @throws NullPointerException If <i>subject</i> is null.
   * @throws SecurityException If the caller does not have permission to get
   *  the subject (<code>"getSubject"</code> target of {@link AuthPermission}.
   */
  public static Subject getSubject (final AccessControlContext context)
  {
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        sm.checkPermission (new AuthPermission ("getSubject"));
      }
    DomainCombiner dc = context.getDomainCombiner();
    if (!(dc instanceof SubjectDomainCombiner))
      {
        return null;
      }
    return ((SubjectDomainCombiner) dc).getSubject();
  }

  /**
   * <p>Run a method as another subject. This method will obtain the current
   * {@link AccessControlContext} for this thread, then creates another with
   * a {@link SubjectDomainCombiner} with the given subject. The supplied
   * action will then be run with the modified context.</p>
   *
   * @param subject The subject to run as.
   * @param action The action to run.
   * @return The value returned by the privileged action.
   * @throws SecurityException If the caller is not allowed to run under a
   *  different identity (<code>"doAs"</code> target of {@link AuthPermission}.
   */
  public static Object doAs (final Subject subject, final PrivilegedAction action)
  {
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        sm.checkPermission (new AuthPermission ("doAs"));
      }
    AccessControlContext context =
      new AccessControlContext (AccessController.getContext(),
                                new SubjectDomainCombiner (subject));
    return AccessController.doPrivileged (action, context);
  }

  /**
   * <p>Run a method as another subject. This method will obtain the current
   * {@link AccessControlContext} for this thread, then creates another with
   * a {@link SubjectDomainCombiner} with the given subject. The supplied
   * action will then be run with the modified context.</p>
   *
   * @param subject The subject to run as.
   * @param action The action to run.
   * @return The value returned by the privileged action.
   * @throws SecurityException If the caller is not allowed to run under a
   *  different identity (<code>"doAs"</code> target of {@link AuthPermission}.
   * @throws PrivilegedActionException If the action throws an exception.
   */
  public static Object doAs (final Subject subject,
                             final PrivilegedExceptionAction action)
    throws PrivilegedActionException
  {
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        sm.checkPermission (new AuthPermission ("doAs"));
      }
    AccessControlContext context =
      new AccessControlContext (AccessController.getContext(),
                                new SubjectDomainCombiner(subject));
    return AccessController.doPrivileged (action, context);
  }

  /**
   * <p>Run a method as another subject. This method will create a new
   * {@link AccessControlContext} derived from the given one, with a
   * {@link SubjectDomainCombiner} with the given subject. The supplied
   * action will then be run with the modified context.</p>
   *
   * @param subject The subject to run as.
   * @param action The action to run.
   * @param acc The context to use.
   * @return The value returned by the privileged action.
   * @throws SecurityException If the caller is not allowed to run under a
   *  different identity (<code>"doAsPrivileged"</code> target of {@link
   *  AuthPermission}.
   */
  public static Object doAsPrivileged (final Subject subject,
                                       final PrivilegedAction action,
                                       final AccessControlContext acc)
  {
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        sm.checkPermission (new AuthPermission ("doAsPrivileged"));
      }
    AccessControlContext context =
      new AccessControlContext (acc, new SubjectDomainCombiner (subject));
    return AccessController.doPrivileged (action, context);
  }

  /**
   * <p>Run a method as another subject. This method will create a new
   * {@link AccessControlContext} derived from the given one, with a
   * {@link SubjectDomainCombiner} with the given subject. The supplied
   * action will then be run with the modified context.</p>
   *
   * @param subject The subject to run as.
   * @param action The action to run.
   * @param acc The context to use.
   * @return The value returned by the privileged action.
   * @throws SecurityException If the caller is not allowed to run under a
   *  different identity (<code>"doAsPrivileged"</code> target of
   *  {@link AuthPermission}.
   * @throws PrivilegedActionException If the action throws an exception.
   */
  public static Object doAsPrivileged (final Subject subject,
                                       final PrivilegedExceptionAction action,
				       AccessControlContext acc)
    throws PrivilegedActionException
  {
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        sm.checkPermission (new AuthPermission ("doAsPrivileged"));
      }
    if (acc == null)
      acc = new AccessControlContext (new java.security.ProtectionDomain[0]);
    AccessControlContext context =
      new AccessControlContext (acc, new SubjectDomainCombiner (subject));
    return AccessController.doPrivileged (action, context);
  }

  // Instance methods.
  // -------------------------------------------------------------------------

  public boolean equals (Object o)
  {
    if (!(o instanceof Subject))
      {
        return false;
      }
    Subject that = (Subject) o;
    return principals.containsAll (that.getPrincipals()) &&
      pubCred.containsAll (that.getPublicCredentials()) &&
      privCred.containsAll (that.getPrivateCredentials());
  }

  public Set getPrincipals()
  {
    return principals;
  }

  public Set getPrincipals(Class clazz)
  {
    HashSet result = new HashSet (principals.size());
    for (Iterator it = principals.iterator(); it.hasNext(); )
      {
        Object o = it.next();
        if (o != null && clazz.isAssignableFrom (o.getClass()))
          {
            result.add(o);
          }
      }
    return Collections.unmodifiableSet (result);
  }

  public Set getPrivateCredentials()
  {
    return privCred;
  }

  public Set getPrivateCredentials (Class clazz)
  {
    HashSet result = new HashSet (privCred.size());
    for (Iterator it = privCred.iterator(); it.hasNext(); )
      {
        Object o = it.next();
        if (o != null && clazz.isAssignableFrom (o.getClass()))
          {
            result.add(o);
          }
      }
    return Collections.unmodifiableSet (result);
  }

  public Set getPublicCredentials()
  {
    return pubCred;
  }

  public Set getPublicCredentials (Class clazz)
  {
    HashSet result = new HashSet (pubCred.size());
    for (Iterator it = pubCred.iterator(); it.hasNext(); )
      {
        Object o = it.next();
        if (o != null && clazz.isAssignableFrom (o.getClass()))
          {
            result.add(o);
          }
      }
    return Collections.unmodifiableSet (result);
  }

  public int hashCode()
  {
    return principals.hashCode() + privCred.hashCode() + pubCred.hashCode();
  }

  /**
   * <p>Returns whether or not this subject is read-only.</p>
   *
   * @return True is this subject is read-only.
   */
  public boolean isReadOnly()
  {
    return readOnly;
  }

  /**
   * <p>Marks this subject as read-only.</p>
   *
   * @throws SecurityException If the caller does not have permission to
   *  set this subject as read-only (<code>"setReadOnly"</code> target of
   *  {@link AuthPermission}.
   */
  public void setReadOnly()
  {
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      {
        sm.checkPermission (new AuthPermission ("setReadOnly"));
      }
    readOnly = true;
  }

  public String toString()
  {
    return Subject.class.getName() + " [ principals=" + principals +
      ", private credentials=" + privCred + ", public credentials=" +
      pubCred + ", read-only=" + readOnly + " ]";
  }

// Inner class.
  // -------------------------------------------------------------------------

  /**
   * An undocumented inner class that is used for sets in the parent class.
   */
  private static class SecureSet extends AbstractSet implements Serializable
  {
    // Fields.
    // -----------------------------------------------------------------------

    private static final long serialVersionUID = 7911754171111800359L;

    static final int PRINCIPALS = 0;
    static final int PUBLIC_CREDENTIALS = 1;
    static final int PRIVATE_CREDENTIALS = 2;

    private final Subject subject;
    private final LinkedList elements;
    private final transient int type;

    // Constructors.
    // -----------------------------------------------------------------------

    SecureSet (final Subject subject, final int type, final Collection inElements)
    {
      this (subject, type);
      for (Iterator it = inElements.iterator(); it.hasNext(); )
        {
          Object o = it.next();
          if (type == PRINCIPALS && !(o instanceof Principal))
            {
              throw new IllegalArgumentException(o+" is not a Principal");
            }
          if (!this.elements.contains (o))
            {
              this.elements.add (o);
            }
        }
    }

    SecureSet (final Subject subject, final int type)
    {
      this.subject = subject;
      this.type = type;
      this.elements = new LinkedList();
    }

    // Instance methods.
    // -----------------------------------------------------------------------

    public synchronized int size()
    {
      return elements.size();
    }

    public Iterator iterator()
    {
      return elements.iterator();
    }

    public synchronized boolean add(Object element)
    {
      if (subject.isReadOnly())
        {
          throw new IllegalStateException ("subject is read-only");
        }
      final SecurityManager sm = System.getSecurityManager();
      switch (type)
        {
        case PRINCIPALS:
          if (sm != null)
            {
              sm.checkPermission (new AuthPermission ("modifyPrincipals"));
            }
          if (!(element instanceof Principal))
            {
              throw new IllegalArgumentException ("element is not a Principal");
            }
          break;

        case PUBLIC_CREDENTIALS:
          if (sm != null)
            {
              sm.checkPermission (new AuthPermission ("modifyPublicCredentials"));
            }
          break;

        case PRIVATE_CREDENTIALS:
          if (sm != null)
            {
              sm.checkPermission (new AuthPermission ("modifyPrivateCredentials"));
            }
          break;

        default:
          throw new Error ("this statement should be unreachable");
        }

      if (elements.contains (element))
        {
          return false;
        }

      return elements.add (element);
    }

    public synchronized boolean remove (final Object element)
    {
      if (subject.isReadOnly())
        {
          throw new IllegalStateException ("subject is read-only");
        }
      final SecurityManager sm = System.getSecurityManager();
      switch (type)
        {
        case PRINCIPALS:
          if (sm != null)
            {
              sm.checkPermission (new AuthPermission ("modifyPrincipals"));
            }
          if (!(element instanceof Principal))
            {
              throw new IllegalArgumentException ("element is not a Principal");
            }
          break;

        case PUBLIC_CREDENTIALS:
          if (sm != null)
            {
              sm.checkPermission (new AuthPermission ("modifyPublicCredentials"));
            }
          break;

        case PRIVATE_CREDENTIALS:
          if (sm != null)
            {
              sm.checkPermission (new AuthPermission ("modifyPrivateCredentials"));
            }
          break;

        default:
          throw new Error("this statement should be unreachable");
        }

      return elements.remove(element);
    }

    public synchronized boolean contains (final Object element)
    {
      return elements.contains (element);
    }

    public boolean removeAll (final Collection c)
    {
      if (subject.isReadOnly())
        {
          throw new IllegalStateException ("subject is read-only");
        }
      return super.removeAll (c);
    }

    public boolean retainAll (final Collection c)
    {
      if (subject.isReadOnly())
        {
          throw new IllegalStateException ("subject is read-only");
        }
      return super.retainAll (c);
    }

    public void clear()
    {
      if (subject.isReadOnly())
        {
          throw new IllegalStateException ("subject is read-only");
        }
      elements.clear();
    }

    private synchronized void writeObject (ObjectOutputStream out)
      throws IOException
    {
      throw new UnsupportedOperationException ("FIXME: determine serialization");
    }

    private void readObject (ObjectInputStream in)
      throws ClassNotFoundException, IOException
    {
      throw new UnsupportedOperationException ("FIXME: determine serialization");
    }
  }
}
