<?php
/**
* @copyright	Copyright (C) 2017 SiteGuarding.com
* @license		GNU/GPL, see LICENSE.php
* @contact		team@siteguarding.com
* @author		SiteGuarding.com
*/

defined( '_JEXEC' ) or die( 'Restricted access' );

if(class_exists('JPlugin')) {
    class DynamicParentAccessLogging extends JPlugin {}
} else {
    class DynamicParentAccessLogging extends Joomla\CMS\Plugin\CMSPlugin {}
}

/**
 * WAF Access Logging Authentication Plugin
 */
	
class plgauthenticationAccessLogging extends DynamicParentAccessLogging
{	
	/**
	 * Load the language file on instantiation.
	 *
	 * @var    boolean
	 * @since  3.1
	 */
	protected $autoloadLanguage = true;
    private $maxLogFile = 5;
	
	public function __construct() {
		if (!defined('DIRSEP'))
		{
			if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') define('DIRSEP', '\\');
			else define('DIRSEP', '/');
		}
		
		if (!defined('_SITEGUARDING_WAP_LOG_FOLDER'))
        {
            $log_folder = JPATH_ADMINISTRATOR . DIRSEP.'siteguarding_logs'.DIRSEP;
            define('_SITEGUARDING_WAP_LOG_FOLDER', $log_folder);
            if (!file_exists($log_folder))
            {
                mkdir($log_folder);
            }
            
            if (!file_exists(_SITEGUARDING_WAP_LOG_FOLDER.'.htaccess')) $this->CreateFile(_SITEGUARDING_WAP_LOG_FOLDER.'.htaccess', "<Limit GET POST>\norder deny,allow\ndeny from all\n</Limit>");
        }
        
        if (!defined('_SITEGUARDING_WAP_LOGFILE_ACCESS')) define('_SITEGUARDING_WAP_LOGFILE_ACCESS', _SITEGUARDING_WAP_LOG_FOLDER.'access.log');
	}
	
	
	public function isAdmin() {
		$app   = (class_exists('\Joomla\CMS\Factory')) ? \Joomla\CMS\Factory::getApplication() : JFactory::getApplication();
		if (JVERSION < 4) {
			return $app->isAdmin();
		}
		return $app->isClient('admin');
	}
	
	public function onUserAuthenticate($credentials, $options, &$response)
	{

		if (!$this->isAdmin()) return;
		// Joomla does not like blank passwords
		if (empty($credentials['password'])){
			return;
		}

		
		
		$result = $this->loginCheck($credentials);
		if ($result) {

			$match = $this->verifyPass( $credentials);
			if ($match === true) {
				// succesfull login
				    $row = array();
					$row['date'] = time();
					$row['ip_address'] = $_SERVER['REMOTE_ADDR'];
					$row['username'] = $credentials['username'];				
					$this->SaveLog(_SITEGUARDING_WAP_LOGFILE_ACCESS, implode("|", $row));
			} 
		} 
	}
	
    public function SaveLog($log_file, $content)
    {
        $log_filesize = filesize($log_file);
        if ( $log_filesize > $this->maxLogFile * 1024 * 1024)
        {
            // Cut log file
    	    $log_file_tmp = $log_file.".tmp";
            
            $fp1 = fopen($log_file, "rb");
            $fp2 = fopen($log_file_tmp, "wb");
            
            $pos = $log_filesize * 0.7;     // 30%
            fseek($fp1, $pos);
            
            while (!feof($fp1)) {
                $buffer = fread($fp1, 4096 * 32);
                fwrite($fp2, $buffer);
            }
            
            fclose($fp1);
            fclose($fp2);
        }
        
        $fp = fopen($log_file, 'a');
        fwrite($fp, $content."\n");
        fclose($fp);
    }
	
	public function loginCheck($credentials)
	{
		// Get a database object
		$db		= JFactory::getDbo();
		$query	= $db->getQuery(true);

		$query->select('id, password');
		$query->from('#__users');
		$query->where('username=' . $db->quote($credentials['username']));

		$db->setQuery($query);
		$result = $db->loadObject();
		
		return $result;
	}
	
	public function verifyPass($credentials)
	{
		$result = $this->loginCheck($credentials);
		return JUserHelper::verifyPassword($credentials['password'], $result->password, $result->id);
	}
	
    public function CreateFile($file, $content)
    {
        if (file_exists($file)) unlink($file);
        $fp = fopen($file, 'w');
        $status = fwrite($fp, $content);
        fclose($fp);
    
        return $status;
    }
				
	
}

