/* **************************************************************************

  $Archive: /njcl/src/com/novell/service/security/BinderyIdentity.java $
  $Revision: 12 $
  $Modtime: 3/05/99 7:10p $

  Copyright (c) 1997-1998 Novell, Inc.  All Rights Reserved.

  THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL PROPRIETARY
  AND TRADE SECRET INFORMATION OF NOVELL, INC. ACCESS  TO  THIS  WORK IS
  RESTRICTED TO (I) NOVELL, INC.  EMPLOYEES WHO HAVE A NEED TO  KNOW HOW
  TO  PERFORM  TASKS WITHIN  THE SCOPE  OF  THEIR   ASSIGNMENTS AND (II)
  ENTITIES OTHER  THAN  NOVELL, INC.  WHO  HAVE ENTERED INTO APPROPRIATE
  LICENSE   AGREEMENTS.  NO  PART  OF  THIS WORK MAY BE USED, PRACTICED,
  PERFORMED COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
  CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED,  RECAST, TRANSFORMED
  OR ADAPTED  WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC.  ANY USE
  OR EXPLOITATION  OF  THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE
  PERPETRATOR  TO CRIMINAL AND CIVIL LIABILITY.

****************************************************************************/

package com.novell.service.security;

import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

import com.novell.java.security.Identity;
import com.novell.java.security.IdentityScope;
import com.novell.java.security.KeyManagementException;
import com.novell.java.security.PublicKey;
import com.novell.java.util.Debug;
import com.novell.service.session.SessionManager;

/**
 * Represents an authenticatable entity in a bindery system (a user,
 * an administrator, and so forth). Every BinderyIdentity is associated
 * with a server identity scope, which  is then associated with the
 * bindery administrative domain scope. The server domain scope is a
 * child of the administrative domain scope, and a user identity is
 * a child of the server domain scope.
 *
 * <p>For example, to construct a user named Karah on a bindery
 * server called Jaeger:
 * <code>
 * <pre>
 * IdentityScope administrativeDomain  = new BinderyIdentityScope();
 * IdentityScope server                = new BinderyIdentityScope("Jaeger",administrativeDomain);
 * Identity      user                  = new BinderyIdentity("Karah",server);
 * </pre>
 * </code>
 *
 * @see BinderyIdentityScope
 * @see NdsIdentity
 */
public class BinderyIdentity
   extends XplatIdentity
   implements PasswordIdentityFactory
{
	/**
    * The connection handle for this identity.
    */
   private int connection = 0;

   /**
	 * Construct an identity with the specified user name and no scope.
	 *
	 * @param name                The user name of the identity.
	 */
	public BinderyIdentity (
         String name)
   {
      super (name);
   } // BinderyIdentity ()

   /**
	 * Construct an identity with the specified user name and scope (server
    * name).
	 *
	 * @param name                The user name of the identity.
	 * @param server              The server name of the identity.
	 * @exception KeyManagementException When an error occurs.
	 */
   public BinderyIdentity (
         String name,
         String server)
      throws KeyManagementException
   {
      super (name, new BinderyIdentityScope (server));
   } // BinderyIdentity ()

   /**
	 * Construct an identity with the specified user name and server name as an
    * IdentityScope.
	 *
	 * @param name                The name of the identity.
	 * @param scope               The IdentityScope of the server.
	 * @exception KeyManagementException When an error occurs.
	 */
   public BinderyIdentity (
         String name,
         IdentityScope scope)
      throws KeyManagementException
   {
      super (name, scope);
   } // BinderyIdentity ()

   /**
	 * Constructs an identity from another specified identity.
	 *
	 * @param identity            The identity to copy.
	 * @exception KeyManagementException When an error occurs.
	 */
	public BinderyIdentity (Identity identity)
		throws KeyManagementException
	{
		super (identity);
      if (identity instanceof BinderyIdentity)
         setConnectionHandle (((BinderyIdentity) identity).getConnectionHandle ());
	} // BinderyIdentity ()

   // XplatIdentity methods ==================================================
   /**
	 * Get the administrative domain string.
	 *
	 * @return                    The administrative domain identifier,
    *                            "[BINDERY]".
	 */
   public String getAdministrativeDomain ()
   {
      return (BinderyIdentityScope.ADMINISTRATIVE_DOMAIN_NAME);
   } // getAdministrativeDomain ()

   /**
	 * Parses the identity to create a user name string.
	 *
	 * @return The String name of the user.
	 */
   public String getUsername()
	{
		return (getUsername (this));
	}  // getUsername ()

   /**
	 * Returns the user domain string.
	 *
	 * @return A String containing the user domain.
	 */
	public String getUserDomain()
	{
		return (getUserDomain (this));
	} // getUserDomain ()

   // Bindery specific identity methods ======================================
   /**@internal
	 * Set the connection handle for the identity.
	 *
	 * @param connection          Connection handle for the identity.
	 */
	public void setConnectionHandle (int connection)
	{
		this.connection = connection;
	} // setConnectionHandle ()

   /**@internal
	 * Get the connection handle for the identity.
	 *
	 * @return                    Connection handle for the identity.
	 */
	public int getConnectionHandle ()
	{
		return connection;
	} // getConnectionHandle ()

   // PasswordIdentityFactory methods ========================================
   /**
    * Instantiate a password identity class.
    *
    * @return                    The appropriate PasswordIdentity.
    */
   public PasswordIdentity getPasswordIdentityInstance ()
   {
      try
      {
         return (new BinderyPasswordIdentity (this));
      } catch (KeyManagementException e)
      {
         return (null);
      }
   } // getPasswordIdentityInstance ()

   // Helper methods =========================================================
   /**
	 * Parses the identity to create a user name string.
	 *
	 * @param identity            The identity whose name is to be parsed.
	 * @return                    The user name string.
	 */
   static String getUsername (
         Identity identity)
   {
	   IdentityScope scope = identity.getScope();
	   if(scope == null)
         return "";

      IdentityScope nextScope = scope.getScope();
      if(nextScope == null)
      {
	      String name = scope.getName();
	      if(name.equalsIgnoreCase(BinderyIdentityScope.ADMINISTRATIVE_DOMAIN_NAME))
	         return "";
	      else
	         return identity.getName();
      }

      IdentityScope nextNextScope = nextScope.getScope();
      if(nextNextScope == null)
      {
	      String name = nextScope.getName();
         if (0 == scope.getName().length() ||
             name.equalsIgnoreCase(BinderyIdentityScope.ADMINISTRATIVE_DOMAIN_NAME))
	         return identity.getName();
	      else
	         return identity.getName()+"."+scope.getName();
      }

      return identity.getName()+"."+getUsername(scope);
   } // getUsername ()

   /**
	 * Parses an identity to create a user domain string.
	 *
	 * @param identity            The identity whose domain is to be parsed.
	 * @return                    The user domain String.
	 */
   static String getUserDomain (
         Identity identity)
   {
	   IdentityScope scope = identity.getScope ();
	   if (scope == null)
	   {
	      String name = identity.getName ();
	      if (name.equalsIgnoreCase (BinderyIdentityScope.ADMINISTRATIVE_DOMAIN_NAME))
	         return "";
	      else
	         return name;
	   }

      IdentityScope nextScope = scope.getScope ();
      if (nextScope == null)
      {
	      String name = scope.getName ();
	      if (name.equalsIgnoreCase (BinderyIdentityScope.ADMINISTRATIVE_DOMAIN_NAME))
	         return identity.getName ();
	      else
	         return name;
      }
      // else recurse
      return getUserDomain (scope);
   } // getUserDomain ()

} // class BinderyIdentity
