/*  Copyright (c) 2000 by Oracle Corporation. All Rights Reserved. */
package oracle.portal.provider.v2;

import java.util.Calendar;

import javax.naming.NamingException;

import oracle.webdb.utils.BaseUser;
import oracle.webdb.utils.SimpleStringBuffer;

import oracle.security.jazn.realm.Realm;

/**
 * Represents the Portal user.  Additionally provides the methods for
 * establishing and reaquiring the user's session. <p> Some Providers have a
 * distinct notion users. Providers are able to configure the Portal (using a
 * login server) to map between the Portal user and the application (Provider)
 * user.  The ProviderUser interface provides access to both the Portal user
 * information and this mapped information.<p> The portal runs in a default
 * public mode.  This occurs when a user accesses the portal without logging
 * in.  This is represented by a special ProviderUser whose portal user name is
 * defined by the String ProviderUser.PUBLIC.  The convenience method
 * isPublicUser() is provided to simplify this check.
 *
 */
public abstract class ProviderUser extends BaseUser 
{

    /**
     * Constant (string) representing the public user.  That is the "user" when
     * a request is made and the person hasn't logged in.
     */
    public static final String PUBLIC = "portal_public";

    /**
     * Constant (string) representing the public user.  That is the "user" when
     * a request is made and the person hasn't logged in.
     */
    public static final String PORTAL_PUBLIC = "portal_public";

    /**
     * Constant (string) representing the public user.  That is the "user" when
     * a request is made and the person hasn't logged in.
     */
    public static final String PUBLIC_USERNAME = "public";

    /**
     * Name used for default portal user's realm, implied when no specific
     * realm information is sent by portal.
     */
    public static final String DEFAULT_SUBSCRIBER_NAME = "_DEFAULT";

    /**
     * Authentication level has not yet been determined.
     */
    public static final int AUTH_LEVEL_NOT_DETERMINED = -3;

    /**
     * JPDK is running against a version of portal that does not support
     * authentication level
     */
    public static final int AUTH_LEVEL_NOT_SUPPORTED = -1;

    /**
     * User is not logged on and does not have a persistent cookie
     */
    public static final int NOT_AUTHENTICATED = 0;

    /**
     * User is not logged on. Weakly authenticated as a PUBLIC portal user
     * using persistent cookie.
     */
    public static final int PUBLIC_WEAK_AUTH = 2;

    /**
     * User is not logged on.  Weakly authenticated as a portal user (any user
     * other than PUBLIC) using persistent cookie.
     */
    public static final int USER_WEAK_AUTH = 5;

    /**
     * User has logged into the portal, using the user id PUBLIC, and been
     * authenticated by the login server within the current session.
     */
    public static final int PUBLIC_STRONG_AUTH = 7;

    /**
     * User has logged into the portal, using a user id other than PUBLIC, and
     * been authenticated by the login server within the current session.
     */
    public static final int USER_STRONG_AUTH = 10;

    /**
     * Gets the name of the portal user represented by this object.
     *
     * @return the portal user name.
     */
    public abstract String getName();

    /**
     * Gets the external application username that is mapped to this portal
     * user.
     *
     * @return the mapped application user.  <b>null</b> if there is no mapped
     * user.
     */
    public abstract String getMappedName();

    /**
     * Gets subscription information related to this user/request Note, the
     * subscription information is specific to the ProviderInstance the current
     * request was received for.
     *
     * @return ProviderSubscription object representing the subscription info
     * or <b>null</b> if there is no subscription info.
     */
    public abstract ProviderSubscription getProviderSubscription();

    /**
     * Gets the subscription key from the ProviderSubscription. Convenience
     * method for getProviderSubscription().getSubscriptionKey().
     *
     * @return the subscription key.
     */
    public String getProviderSubscriptionKey() 
    {
        return getProviderSubscription().getSubscriptionKey();
    }

    /**
     * Get the portal user's realm. This method returns the generic Realm,
     * defined by {@link oracle.security.jazn.realm.Realm}, for the user.
     *
     * @return the portal user's realm.
     */
    public abstract Realm getRealm();

    /**
     * Get the portal user's realm. This method returns the Provider framework
     * specific {@link PortalRealm} implementation.
     */
    public abstract PortalRealm getPortalRealm();
    
    /**
     * Gets the qualified username, ie username appended with company name
     * separated by "@@".
     *
     * @return the qualified username.
     */
    public String getQualifiedName() 
    {
        SimpleStringBuffer qualName = new SimpleStringBuffer(getName());
        qualName.append("@@");
        qualName.append(getPortalRealm().getName());
        return qualName.toString();
    }

    /**
     * Gets the time when this user logged into the Portal.
     *
     * @return the login time.
     */
    public abstract Calendar getLoginTime();

    /**
     * Gets the user's location.  Value is allowed to be <code>null</code>,
     * which means the information is not available.
     *
     * @return a {@link UserLocation} object representing the user's location.
     */
    public abstract UserLocation getLocation();

    /**
     * Gets the Portal session ID for this user.  Portlet developers can use
     * this ID to map to their in memory "session" state vs. using a cookie
     * based mechanism.  The benefit is performance.  If the provider doesn't
     * use cookies the portal can communicate more efficiently with it.
     *
     * @return the Portal session ID for this user.
     */
    public abstract String getPortalSessionId();

    /**
     * Gets the authentication level for the user.
     *
     * @return the authentication level.
     */
    public abstract int getAuthenticationLevel();

    /**
     * Indicates if the user has logged onto the portal in the current session
     * (true). A user who is weakly authentication has not logged on to the
     * portal in the current session so this method will return false.
     *
     * @return <code>true</code> if the user has logged onto the portal,
     * <code>false</code> otherwise.
     */
    public boolean isLoggedOn()
    {
        return (getAuthenticationLevel() > 5 ? true : false);
    }

    /**
     * Indicates if the current user is at least weakly authenticated.
     *
     * @return <code>true</code> if the current user is at least weakly
     * authenticated, <code>false</code> otherwise.
     */
    public boolean isWeaklyAuthenticated()
    {
        return (getAuthenticationLevel() > 0 ? true : false);
    }

    /**
     * Indicates if this request is from a public user, i.e. the user has not
     * logged in and is not weakly authenticated based on a prior login.
     *
     * @return <code>true</code> if the user is accessing the portal in public
     * mode, <code>false</code> otherwise.
     */
    public boolean isPublicUser() 
    {
        return (getAuthenticationLevel() == NOT_AUTHENTICATED);
    }

    /**
     * Used to create and/or reacquire the user session.  If running as a
     * Servlet and sessions are maintained via cookies then the sessions must
     * only be created in Provider.initSession().<p>
     *
     * Note: this method can throw an llegalStateException.  This occurs if the
     * user object has become stale. I.e. no longer contains the state that it
     * needs to acquire/create the session.<p>
     *
     * As all Provider/Portlet APIs give you access to the User object per
     * request you should not (need to) retain the user object via reference in
     * cross-request object (like the session itself).  This only leads to
     * possibilities of memory leaks.
     *
     * @param create if true then a session is created for the user if it
     * doesn't currently exist.
     * @return the session object for this user. <b>null</b> if create is false
     * and the session doesn't already exist.
     */
    public abstract ProviderSession getSession(boolean create) 
        throws IllegalStateException;

    /**
     * Used to create and/or reacquire the user session.  Always creates a
     * session if it doesn't currently exist. The same as calling
     * getSession(true).<p>
     *
     * If running as a Servlet and sessions are maintained via cookies then the
     * sessions must only be created in Provider.initSession().<p>
     *
     * Note: this method can throw an llegalStateException.  This occurs if the
     * user object has become stale. I.e. no longer contains the state that it
     * needs to acquire/create the session.<p>
     *
     * As all Provider/Portlet APIs give you access to the User object per
     * request you should not (need to) retain the user object via reference in
     * cross-request object (like the session itself).  This only leads to
     * possibilities of memory leaks.
     *
     * @return the session object for this user.
     */
    public abstract ProviderSession getSession() throws IllegalStateException;

    /**
     * Get the portal user's distinguished name. 
     * 
     * This method returns the 
     * users distinguished name as stored in OID.
     *
     * @return the portal user's distinguished name.
     */
    public abstract String getUserDN();

    /**
     * Get the portal user's Subscription distinguished name. 
     *
     * This method returns the user's subscriber distinguished 
     * name as stored in OID.
     *
     * @return the portal user's subscriber distinguished name.
     */
    public abstract String getSubscriberDN();

    /**
     * Get the portal user's GUID. 
     *
     * This method returns the user's GUID as stored in OID.
     *
     * @return the portal user's GUID.
     */
    public abstract String getUserGUID();

    /**
     * Get the portal user's subscriber GUID. 
     *
     * This method returns the user's Subscriber GUID as stored in OID.
     *
     * @return the portal user's subscriber GUID.
     */
    public abstract String getSubscriberGUID();

    
    /**
     * Get the portal user's subscriber name. 
     *
     * This method returns the user's Subscriber name as stored in OID.
     *
     * @return the portal user's subscriber GUID.
     */
    public abstract String getSubscriberName();

    /**
     * Get the portal user's first name. 
     *
     * This method returns the user's first name as stored in OID.
     *
     * @return the portal user's first name.
     */
    public abstract String getFirstName();

    /**
     * Get the portal user's last name. 
     *
     * This method returns the user's last name as stored in OID.
     *
     * @return the portal user's last name.
     */
    public abstract String getLastName();

    /**
     * Get the portal user's email address. 
     *
     * This method returns the user's email address as stored in OID.
     *
     * @return the portal user's email address.
     */
    public abstract String getEmail();

    /**
     * Get a named property value of the user as stored in OID.
     *
     * Any property associated with the user can be queried that
     * is stored in the OID user repository. Use the Oracle Directory
     * Manager tool to find out all the properties available.
     * Some of the commonly used property names are defined in OidManager class
     *
     * @param name of a user property 
     * @return the portal user's named property.
     */
    public abstract String getPropertyValue(String propertyName);

    /**
     * check if this user is a member of a group.
     *
     * The users, groups and group membership are stored in OID
     *
     * @param the name of the group
     * @return the whether or not this user is a member of the named group
     */
    public abstract boolean isUserInGroup(String groupName);

    /**
     * Determine if the OidManager is configured. 
     *
     * This is needed because 
     * the methods  return null if there is no Oid Manager or there is no data
     * this method enables the caller to determine the reason why null was
     * returned
     *
     * @return whether the oid manager is configured.
     */
    public abstract boolean isLDAPEnabled();

}

