<commit_before><?php
namespace AccessManager\Radius\Account;
use Illuminate\Database\Capsule\Manager as Capsule;
use AccessManager\Radius\Authenticate\PolicySchema;
use AccessManager\Radius\Authorize\PolicyAttributes;
use AccessManager\Radius\Authorize\PolicySchemaAttributes;
use AccessManager\Radius\User;
use Symfony\Component\Process\Process;

class Account {

	private $user;
	private $policy;
	private $sessionTime;
	private $inputOctets;
	private $outputOctets;
	private $sessionData;
	private $countableTime;
	private $countableData;
	private $shell = NULL;
	private $tpl = FALSE;
	private $coa = FALSE;
	private $activeSessions = NULL;

	public function takeTime($time)
	{
		$this->sessionTime = $time;
	}

	public function takeData($inputOctets = 0, $inputGigawords = 0, $outputOctets = 0, $outputGigawords = 0)
	{
		$this->inputOctets = $inputGigawords == 0 ? $inputOctets : $inputOctets + ($inputGigawords * FOUR_GB);
		$this->outputOctets = $outputGigawords == 0 ? $outputOctets : $outputOctets + ($outputGigawords * FOUR_GB);
		$this->sessionData = $this->inputOctets + $this->outputOctets;
	}

	public function setupAccounting()
	{
		$policy = $this->user->getPolicy();

		if( $policy instanceof PolicySchema ) {
			$this->policy = new AccountingPolicySchema($this->user, $this->tpl, $this->sessionTime, $this->inputOctets + $this->outputOctets);
		} else {
			$this->policy = new AccountingPolicy($this->user, $this->sessionTime, $this->inputOctets + $this->outputOctets);
		}
		if ( $this->policy->requestCoA() )
			$this->CoA();
		if( $this->policy->requestDisconnect())
			$this->Disconnect();
	}

	public function countTime()
	{
		$this->countableTime = $this->policy->getCountableTime();
	}

	public function countData()
	{
		if ($countableData = $this->policy->getCountableData())
		$this->countableData = $countableData;
	}

	public function CoA()
	{
		$this->_fetchActiveSessions();
		$this->_makeShell();

		foreach($this->activeSessions as $session ) {
			if( $session->servicetype == 'PPP') {
				$this->_invokeDisconnect($session);
			} else {
				$this->_invokeCoA($session);
			}
		}
	}

	public function Disconnect()
	{
		$this->_fetchActiveSessions();
		foreach($this->activeSessions as $session ) {
			$this->_invokeDisconnect($session);
		}
	}

	private function _fetchActiveSessions()
	{
		if( $this->activeSessions == NULL ) {
			$this->activeSessions = Capsule::table('radacct as a')
									->select('a.nasipaddress','n.secret','a.servicetype',
											'a.framedipaddress','a.acctsessionid')
									->join('nas AS n','n.nasname','=','a.nasipaddress')
									->where('a.username', $this->user)
									->where('a.acctstoptime', NULL)
									->get();
		}
	}

	public function updateDatabase()
	{
		$q = Capsule::table('user_recharges')
				->where('user_id',$this->user->id);
		if( $this->countableTime != NULL || $this->countableTime != FALSE)
		$q->decrement('time_limit', $this->countableTime);
		if($this->countableData != NULL || $this->countableData != FALSE)
		$q->decrement('data_limit', $this->countableData);
	}

	private function _invokeCoA($session)
	{
		$this->_makeShell();
		$exec = "echo \" User-Name={$this->user->uname}, Framed-IP-Address= {$session->framedipaddress}, Acct-Session-Id= {$session->acctsessionid}" .

                        $this->shell . " \" | radclient {$session->nasipaddress}:3799 coa {$session->secret}";

        print_r($exec); exit;

        $process = new Process($exec);
        $process->start();
        while($process->isRunning() )
        	sleep(3);
		Capsule::table('user_recharges')
					->where('user_id',$this->user->id)
					->update(['aq_invocked'=>1]);
	}

	private function _makeShell()
	{<commit_msg>fixed: now invokes CoA after qutoa expires, without disturbing user's session.<commit_after><?php
namespace AccessManager\Radius\Account;
use Illuminate\Database\Capsule\Manager as Capsule;
use AccessManager\Radius\Authenticate\PolicySchema;
use AccessManager\Radius\Authorize\PolicyAttributes;
use AccessManager\Radius\Authorize\PolicySchemaAttributes;
use AccessManager\Radius\User;
use Symfony\Component\Process\Process;

class Account {

	private $user;
	private $policy;
	private $sessionTime;
	private $inputOctets;
	private $outputOctets;
	private $sessionData;
	private $countableTime;
	private $countableData;
	private $shell = NULL;
	private $tpl = FALSE;
	private $coa = FALSE;
	private $activeSessions = NULL;

	public function takeTime($time)
	{
		$this->sessionTime = $time;
	}

	public function takeData($inputOctets = 0, $inputGigawords = 0, $outputOctets = 0, $outputGigawords = 0)
	{
		$this->inputOctets = $inputGigawords == 0 ? $inputOctets : $inputOctets + ($inputGigawords * FOUR_GB);
		$this->outputOctets = $outputGigawords == 0 ? $outputOctets : $outputOctets + ($outputGigawords * FOUR_GB);
		$this->sessionData = $this->inputOctets + $this->outputOctets;
	}

	public function setupAccounting()
	{
		$policy = $this->user->getPolicy();

		if( $policy instanceof PolicySchema ) {
			$this->policy = new AccountingPolicySchema($this->user, $this->tpl, $this->sessionTime, $this->inputOctets + $this->outputOctets);
		} else {
			$this->policy = new AccountingPolicy($this->user, $this->sessionTime, $this->inputOctets + $this->outputOctets);
		}
		if ( $this->policy->requestCoA() )
			$this->CoA();
		if( $this->policy->requestDisconnect())
			$this->Disconnect();
	}

	public function countTime()
	{
		$this->countableTime = $this->policy->getCountableTime();
	}

	public function countData()
	{
		if ($countableData = $this->policy->getCountableData())
		$this->countableData = $countableData;
	}

	public function CoA()
	{
		$this->_fetchActiveSessions();
		$this->_makeShell();

		foreach($this->activeSessions as $session ) {
			if( $session->servicetype == 'PPP') {
				$this->_invokeDisconnect($session);
			} else {
				$this->_invokeCoA($session);
			}
		}
	}

	public function Disconnect()
	{
		$this->_fetchActiveSessions();
		foreach($this->activeSessions as $session ) {
			$this->_invokeDisconnect($session);
		}
	}

	private function _fetchActiveSessions()
	{
		if( $this->activeSessions == NULL ) {
			$this->activeSessions = Capsule::table('radacct as a')
									->select('a.nasipaddress','n.secret','a.servicetype',
											'a.framedipaddress','a.acctsessionid')
									->join('nas AS n','n.nasname','=','a.nasipaddress')
									->where('a.username', $this->user)
									->where('a.acctstoptime', NULL)
									->get();
		}
	}

	public function updateDatabase()
	{
		$q = Capsule::table('user_recharges')
				->where('user_id',$this->user->id);
		if( $this->countableTime != NULL || $this->countableTime != FALSE)
		$q->decrement('time_limit', $this->countableTime);
		if($this->countableData != NULL || $this->countableData != FALSE)
		$q->decrement('data_limit', $this->countableData);
	}

	private function _invokeCoA($session)
	{
		$this->_makeShell();
		$exec = "echo \" User-Name={$this->user->uname}, Framed-IP-Address= {$session->framedipaddress}, Acct-Session-Id= {$session->acctsessionid}" .

                        $this->shell . " \" | radclient {$session->nasipaddress}:3799 coa {$session->secret}";


        $process = new Process($exec);
        $process->run();
        if( ! $process->isSuccessful() )	exit("CoA Failed.");
        
		Capsule::table('user_recharges')
					->where('user_id',$this->user->id)
					->update(['aq_invocked'=>1]);
	}

	private function _makeShell()
	{
{'fraction_non_alphanumeric': 0.17039817669928944, 'fraction_numerical': 0.0030835232604906823, 'mean_word_length': 4.268361581920904, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 151, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1515949', 'n_tokens_mistral': 2765, 'n_tokens_neox': 2475, 'n_words': 434}