<?php

/*
  This file defines a phpBB authentication plugion.
  Details on their API can be found here:
  http://wiki.phpbb.com/Authentication_plugins
 */

if (!defined('IN_PHPBB'))
{
	exit;
}

/*
  create_cwis_db() - helper function. Pulls out of the phpBB config
  information the data required to access the CWIS database, creates
  an Axis--Database object, returns it.
 */

function create_cwis_db()
{
    global $config, $phpbb_root_path;
    require_once($phpbb_root_path.'includes/auth/Axis--Database.php');
    return  new Database(
        $config["cwis_db_user"],
        $config["cwis_db_pass"],
        $config["cwis_db_database"],
        $config["cwis_db_server"]);
}

// Pull user data out of the phpBB database
function fetch_user_row($username)
{
    global $db;
    // Check for a phpBB user row:
    $sql = 'SELECT * FROM ' . USERS_TABLE . "
		WHERE username_clean = '" .
        $db->sql_escape(utf8_clean_string($username)) . "'";
    $result = $db->sql_query($sql);
    $row = $db->sql_fetchrow($result);
    $db->sql_freeresult($result);

    return $row;
}

// Create a new phpBB user structure
function create_user_row($username, $password)
{
    global $db, $user, $config;
    // first retrieve default group id
    $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " "
        ."WHERE group_name = '" . $db->sql_escape('REGISTERED') . "' "
        ."AND group_type = " . GROUP_SPECIAL;
    $result = $db->sql_query($sql);
    $row = $db->sql_fetchrow($result);
    $db->sql_freeresult($result);

    if (!$row)
    {
        trigger_error('NO_GROUP');
    }

    // generate user account data
    return array(
        'username'		=> $username,
        'user_password'	=> phpbb_hash($password),
        'user_email'	=> '',
        'group_id'		=> (int) $row['group_id'],
        'user_type'		=> USER_NORMAL,
        'user_ip'		=> $user->ip,
        'user_new'		=> ($config['new_member_post_limit']) ? 1 : 0
        );
}

/**
* Login function -- exists to validate admins when they long in to the
* ACP (administrative control panel). Normal user logins are handled
* with the autologin function defined below.
*/
function login_cwis(&$username, &$password)
{
    global $db, $config, $user;

    // do not allow empty password
    if (!$password)
    {
        return array(
            'status'	=> LOGIN_ERROR_PASSWORD,
            'error_msg'	=> 'NO_PASSWORD_SUPPLIED',
            'user_row'	=> array('user_id' => ANONYMOUS),
            );
    }

    if (!$username)
    {
        return array(
            'status'	=> LOGIN_ERROR_USERNAME,
            'error_msg'	=> 'LOGIN_ERROR_USERNAME',
            'user_row'	=> array('user_id' => ANONYMOUS),
            );
    }

    // Now, pull user data from CWIS:
    $CwisDB = create_cwis_db();
    $CwisDB->Query(
        "SELECT UserId, UserPassword FROM APUsers "
        ."WHERE UserName='".addslashes($username)."'");
    $cwis_user_row = $CwisDB->FetchRow();

    // If there was no such user, or if the password didn't match, bail.
    if ( !isset($cwis_user_row["UserPassword"]) ||
         crypt($password, $cwis_user_row["UserPassword"]) !=
         $cwis_user_row["UserPassword"])
    {
        return array(
            'status'		=> LOGIN_ERROR_EXTERNAL_AUTH,
            'error_msg'		=> 'LOGIN_ERROR_EXTERNAL_AUTH_CWIS',
            'user_row'		=> array('user_id' => ANONYMOUS),
            );
    }

    // Check for a phpBB user row:
    $row = fetch_user_row($username);

    if (!$row)
    {
        // There was no user row, so we must create one:
        $row = create_user_row($username, $password);

        return array(
            'status'		=> LOGIN_SUCCESS_CREATE_PROFILE,
            'error_msg'		=> false,
            'user_row'		=> $row
            );
    }
    else
    {
        // Successful login on an existing account.
        return array(
            'status'		=> LOGIN_SUCCESS,
            'error_msg'		=> false,
            'user_row'		=> $row
            );
    }
}

/*
  Autologin function -- checks for the presence of a login cookie,
  validates the token against the CWIS database, and logs a user in
  when successful.
  Adds new users as required.
 */
function autologin_cwis()
{
    global $db, $config;
    $CookieName = "phpBBLoginToken";
    $CwisDB = create_cwis_db();

    // Fetch users to disable from the CWIS DB:
    $CwisDB->Query(
        "SELECT UserName FROM phpBBSync_LoginData WHERE RemIp='GoAwayMrUser'");
    $UsersToDisable = array();
    while ( $Row = $CwisDB->FetchRow() )
    {
        $UsersToDisable []= $Row;
    }

    // Iterate over them, disabling the ones we find
    foreach ($UsersToDisable as $User)
    {
        $username = array_pop ($User);

        $row = fetch_user_row($username);
        if ($row)
        {
            $sql = 'UPDATE '. USERS_TABLE
                .' SET user_type = ' . USER_INACTIVE
                .' WHERE user_id = '. $row['user_id'];
            $db->sql_query($sql);

            $CwisDB->Query(
                "DELETE FROM phpBBSync_LoginData WHERE UserName='".$username."'");
        }
    }

    if (isset($_COOKIE[$CookieName]))
    {
        $CookieData = unserialize(
            gzuncompress(base64_decode(urldecode($_COOKIE[$CookieName]))));

        if ($CookieData["Version"]==1)
        {
            $CwisDB->Query(
                "SELECT UserName FROM phpBBSync_LoginData "
                ."WHERE RemIp='".$_SERVER["REMOTE_ADDR"]."' "
                ."AND Token=".$CookieData["Token"]);
            $row = $CwisDB->FetchRow();

            $UserName=array_pop($row);

            if ($UserName !== NULL)
            {
                $sql = "SELECT * FROM " . USERS_TABLE . " WHERE "
                    ."username = '".$db->sql_escape($UserName)."'";
                $result = $db->sql_query($sql);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);

                if ($row)
                {
                    return ($row['user_type'] == USER_INACTIVE ||
                            $row['user_type'] == USER_IGNORE) ?
                        array() :
                        $row;
                }

                if (!function_exists('user_add'))
                {
                    global $phpbb_root_path, $phpEx;
                    include($phpbb_root_path . 'includes/functions_user.'
                            . $phpEx);
                }

                $row = create_user_row($UserName, md5($Data["Token"]));

                user_add($row);

                $row = fetch_user_row($UserName);

                if ($row)
                {
                    return $row;
                }
            }
        }
    }
    return array();
}

/*
  validate_session_cwis -- Checks to be sure that a login token still
  exists for authenticated users.  Ends the session if it doesn't.

  For non-authed users, makes sure there isn't a token, and
  regenerates the session (kicking the autologin_cwis) if it does.
 */

function validate_session_cwis($user_row)
{
    return
        (  isset($_COOKIE["phpBBLoginToken"]) && $user_row['user_id'] != ANONYMOUS ) ||
        ( !isset($_COOKIE["phpBBLoginToken"]) && $user_row['user_id'] == ANONYMOUS );
}

/*
  acp_cwis -- function that adds a config entry to the admin control
  panel for the auth_cwis plugin.
 */

function acp_cwis(&$new)
{
    global $user;

    $tpl =
      '<dl>'
      .'<dt><label for="cwis_db_server">CWIS DB Server:</label>'
      .'<dd><input type="text" id="cwis_db_server" size="40" name="config[cwis_db_server]" value="'.$new["cwis_db_server"].'"/></dd>'

      .'</dl><dl>'
      .'<dt><label for="cwis_db_user">CWIS DB User:</label>'
      .'<dd><input type="text" id="cwis_db_user" size="40" name="config[cwis_db_user]" value="'.$new["cwis_db_user"].'"/></dd>'

      .'</dl><dl>'
      .'<dt><label for="cwis_db_pass">CWIS DB Password:</label>'
      .'<dd><input type="text" id="cwis_db_pass" size="40" name="config[cwis_db_pass]" value="'.$new["cwis_db_pass"].'"/></dd>'

      .'</dl><dl>'
      .'<dt><label for="cwis_db_database">CWIS DB Database:</label>'
      .'<dd><input type="text" id="cwis_db_database" size="40" name="config[cwis_db_database]" value="'.$new["cwis_db_database"].'"/></dd>'

      .'</dl><dl>'
      .'<dt><label for="cwis_url">CWIS base url:</label>'
      .'<dd><input type="text" id="cwis_url" size="40" name="config[cwis_url]" value="'.$new["cwis_url"].'"/></dd>'
      .'</dl>'
      ;

    // These are fields required in the config table
    return array(
        'tpl'		=> $tpl,
        'config'	=> array('cwis_db_server', 'cwis_db_user', 'cwis_db_pass', 'cwis_db_database', 'cwis_url')
	);
}

?>