<?php
/**
 * File containing the ezcAuthenticationSession class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @filesource
 * @package Authentication
 * @version //autogen//
 */

/**
 * Support for session authentication and saving of authentication information
 * between requests.
 *
 * Contains the methods:
 * - start - starts the session, calling the PHP function session_start()
 * - load - returns the information stored in the session key ezcAuth_id
 * - save - saves information in the session key ezcAuth_id and also saves
 *          the current timestamp in the session key ezcAuth_timestamp
 * - destroy - deletes the information stored in the session keys ezcAuth_id
 *             and ezcAuth_timestamp
 * - regenerateId - regenerates the PHPSESSID value
 *
 * Example of use (combined with the Htpasswd filter):
 * <code>
 * // no headers should be sent before calling $session->start()
 * $session = new ezcAuthenticationSession();
 * $session->start();
 *
 * // retrieve the POST request information
 * $user = isset( $_POST['user'] ) ? $_POST['user'] : $session->load();
 * $password = isset( $_POST['password'] ) ? $_POST['password'] : null;
 * $credentials = new ezcAuthenticationPasswordCredentials( $user, $password );
 * $authentication = new ezcAuthentication( $credentials );
 * $authentication->session = $session;
 * $authentication->addFilter( new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd' ) );
 * // add other filters if needed
 * if ( !$authentication->run() )
 * {
 *     // authentication did not succeed, so inform the user
 *     $status = $authentication->getStatus();
 *     $err = array(
 *             'ezcAuthenticationHtpasswdFilter' => array(
 *                 ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 *                 ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 *                 ),
 *             'ezcAuthenticationSession' => array(
 *                 ezcAuthenticationSession::STATUS_EMPTY => '',
 *                 ezcAuthenticationSession::STATUS_EXPIRED => 'Session expired'
 *                 )
 *             );
 *     foreach ( $status as $line )
 *     {
 *         list( $key, $value ) = each( $line );
 *         echo $err[$key][$value] . "\n";
 *     }
 * }
 * else
 * {
 *     // authentication succeeded, so allow the user to see his content
 * }
 * </code>
 *
 * See {@link ezcAuthenticationSessionOptions} for options you can set to
 * session objects.
 *
 * @package Authentication
 * @version //autogen//
 * @mainclass
 */
class ezcAuthenticationSession
{
    /**
     * Successful authentication; normal behaviour is to skip the other filters.
     *
     * This should be the same value as ezcAuthenticationFilter::STATUS_OK.
     */
    const STATUS_OK = 0;

    /**
     * The session is empty; normal behaviour is to continue with the other filters.
     */
    const STATUS_EMPTY = 1;

    /**
     * The session expired; normal behaviour is to regenerate the session ID.
     */
    const STATUS_EXPIRED = 2;

    /**
     * Options for authentication filters.
     *
     * @var ezcAuthenticationFilterOptions
     */
    protected $options;

    /**
     * Creates a new object of this class.
     *
     * @param ezcAuthenticationSessionOptions $options Options for this class
     */
    public function __construct( ezcAuthenticationSessionOptions $options = null )
    {
        $this->options = ( $options === null ) ? new ezcAuthenticationSessionOptions() : $options;
    }

    /**
     * Runs through the session and returns a status code when finished.
     *
     * @param ezcAuthenticationCredentials $credentials Authentication credentials
     * @return int
     */
    public function run( $credentials )
    {
        $this->start();

        $now = $_SERVER["REQUEST_TIME"];

        // inactivity
        if ( isset( $_SESSION[$this->options->lastActivityTimestampKey] ) &&
             $now - $_SESSION[$this->options->lastActivityTimestampKey] >= $this->options->idleTimeout
           )
        {
            $this->destroy();
            $this->regenerateId();
            return self::STATUS_EXPIRED;
        }

        // max session timeout
        if ( isset( $_SESSION[$this->options->timestampKey] ) &&
             $now - $_SESSION[$this->options->timestampKey] >= $this->options->validity
           )
        {
            $this->destroy();
            $this->regenerateId();
            return self::STATUS_EXPIRED;
        }

        if ( $this->load() !== null )
        {
            $_SESSION[$this->options->lastActivityTimestampKey] = time();
            return self::STATUS_OK;
        }

        return self::STATUS_EMPTY;
    }

    /**
     * Runs through the session and returns true if the session is correct.
     *
     * When using the session, it is often desirable to take advantage of the
     * fact that the authenticated state of the user is kept in the session and
     * not create and initialize the other filters (which might slow things
     * down on every request).
     *
     * The application can be structured like this:
     * <code>
     * $session = new ezcAuthenticationSession();
     * $session->start();
     *
     * $credentials = new ezcAuthenticationPasswordCredentials( $user, $pass );
     *
     * $authenticated = false;
     * if ( !$session->isValid( $credentials ) )
     * {
     *     // create the authentication object
     *     $authentication = new ezcAuthentication( $credentials );
     *     $authentication->session = $session;
     *
     *     // create filters and add them to the authentication object
     *     $authentication->addFilter( new ezcAuthenticationOpenidFilter() );
     *
     *     // run the authentication object
     *     if ( !$authentication->run() )
     *     {
     *         $status = $authentication->getStatus();
     *         // build an error message based on $status
     *     }
     *     else
     *     {
     *         $authenticated = true;
     *     }
     * }
     * else
     * {
     *     $authenticated = true;
     * }
     *
     * if ( $authenticated )
     * {
     *     // the authentication succeeded and the user can see his content
     * }
     * else
     * {
     *     // inform the user that the authentication failed (with the error
     *     // message that was created earlier)
     * }
     * </code>
     *
     * In this way, the creation and initialization of the authentication
     * filters is not performed if the credentials are stored in the session.
     *
     * @param ezcAuthenticationCredentials $credentials Authentication credentials
     * @return bool
     */
    public function isValid( $credentials )
    {
        return ( $this->run( $credentials ) === self::STATUS_OK );
    }

    /**
     * Starts the session.
     *
     * This function must be called before sending any headers to the client.
     */
    public function start()
    {
        if ( session_id() === '' && PHP_SAPI !== 'cli' )
        {
            session_start();
        }
    }

    /**
     * Loads the authenticated username from the session or null if it doesn't exist.
     *
     * @return string
     */
    public function load()
    {
        return isset( $_SESSION[$this->options->idKey] ) ? $_SESSION[$this->options->idKey] :
                                                                null;
    }

    /**
     * Saves the authenticated username and the current timestamp in the session
     * variables.
     *
     * @param string $data Information to save in the session, usually username
     */
    public function save( $data )
    {
        $_SESSION[$this->options->idKey] = $data;
        $_SESSION[$this->options->timestampKey] = time();
        $_SESSION[$this->options->lastActivityTimestampKey] = time();
    }

    /**
     * Removes the variables used by this class from the session variables.
     */
    public function destroy()
    {
        unset( $_SESSION[$this->options->idKey] );
        unset( $_SESSION[$this->options->timestampKey] );
        unset( $_SESSION[$this->options->lastActivityTimestampKey] );
    }

    /**
     * Regenerates the session ID.
     */
    public function regenerateId()
    {
        if ( !headers_sent() )
        {
            // ???? seems that PHPSESSID is not regenerated if session is destroyed first????
            // session_destroy();
            session_regenerate_id();
        }
    }

    /**
     * Sets the options of this class to $options.
     *
     * @param ezcAuthenticationSessionOptions $options Options for this class
     */
    public function setOptions( ezcAuthenticationSessionOptions $options )
    {
        $this->options = $options;
    }

    /**
     * Returns the options of this class.
     *
     * @return ezcAuthenticationSessionOptions
     */
    public function getOptions()
    {
        return $this->options;
    }
}
?>
