diff --git a/.gitignore b/.gitignore index 99dbdb61..2b53984b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ system/devices/** !system/devices/Radius.php !system/devices/RadiusRest.php !system/devices/MikrotikPppoe.php +!system/devices/MikrotikPppoeCustom.php !system/devices/MikrotikHotspot.php /.vs docker-compose.yml diff --git a/system/devices/MikrotikPppoe.php b/system/devices/MikrotikPppoe.php index 4cbff181..6f291c48 100644 --- a/system/devices/MikrotikPppoe.php +++ b/system/devices/MikrotikPppoe.php @@ -39,30 +39,14 @@ class MikrotikPppoe }else{ $setRequest = new RouterOS\Request('/ppp/secret/set'); $setRequest->setArgument('numbers', $cid); - if (!empty($customer['pppoe_password'])) { - $setRequest->setArgument('password', $customer['pppoe_password']); - } else { - $setRequest->setArgument('password', $customer['password']); - } - if (!empty($customer['pppoe_username'])) { - $setRequest->setArgument('name', $customer['pppoe_username']); - } else { - $setRequest->setArgument('name', $customer['username']); - } - if (!empty($customer['pppoe_ip'])) { - $setRequest->setArgument('local-address', $customer['pppoe_ip']); - }else{ - $setRequest->setArgument('local-address', '0.0.0.0'); - } + $setRequest->setArgument('password', $customer['password']); + $setRequest->setArgument('name', $customer['username']); $setRequest->setArgument('profile', $plan['name_plan']); $setRequest->setArgument('comment', $customer['fullname'] . ' | ' . $customer['email'] . ' | ' . implode(', ', User::getBillNames($customer['id']))); $client->sendSync($setRequest); //disconnect then if(isset($isChangePlan) && $isChangePlan){ $this->removePpoeActive($client, $customer['username']); - if (!empty($customer['pppoe_username'])) { - $this->removePpoeActive($client, $customer['pppoe_username']); - } } } } @@ -76,20 +60,11 @@ class MikrotikPppoe if($p){ $this->add_customer($customer, $p); $this->removePpoeActive($client, $customer['username']); - if (!empty($customer['pppoe_username'])) { - $this->removePpoeActive($client, $customer['pppoe_username']); - } return; } } - $this->removePpoeUser($client, $customer['username']); - if (!empty($customer['pppoe_username'])) { - $this->removePpoeUser($client, $customer['pppoe_username']); - } $this->removePpoeActive($client, $customer['username']); - if (!empty($customer['pppoe_username'])) { - $this->removePpoeActive($client, $customer['pppoe_username']); - } + $this->removePpoeUser($client, $customer['username']); } // customer change username @@ -150,15 +125,7 @@ class MikrotikPppoe function getIdByCustomer($customer, $client){ $printRequest = new RouterOS\Request('/ppp/secret/print'); $printRequest->setQuery(RouterOS\Query::where('name', $customer['username'])); - $id = $client->sendSync($printRequest)->getProperty('.id'); - if(empty($id)){ - if (!empty($customer['pppoe_username'])) { - $printRequest = new RouterOS\Request('/ppp/secret/print'); - $printRequest->setQuery(RouterOS\Query::where('name', $customer['pppoe_username'])); - $id = $client->sendSync($printRequest)->getProperty('.id'); - } - } - return $id; + return $client->sendSync($printRequest)->getProperty('.id'); } function update_plan($old_name, $new_plan) @@ -327,19 +294,8 @@ class MikrotikPppoe $setRequest->setArgument('service', 'pppoe'); $setRequest->setArgument('profile', $plan['name_plan']); $setRequest->setArgument('comment', $customer['fullname'] . ' | ' . $customer['email'] . ' | ' . implode(', ', User::getBillNames($customer['id']))); - if (!empty($customer['pppoe_password'])) { - $setRequest->setArgument('password', $customer['pppoe_password']); - } else { - $setRequest->setArgument('password', $customer['password']); - } - if (!empty($customer['pppoe_username'])) { - $setRequest->setArgument('name', $customer['pppoe_username']); - } else { - $setRequest->setArgument('name', $customer['username']); - } - if (!empty($customer['pppoe_ip'])) { - $setRequest->setArgument('local-address', $customer['pppoe_ip']); - } + $setRequest->setArgument('password', $customer['password']); + $setRequest->setArgument('name', $customer['username']); $client->sendSync($setRequest); } diff --git a/system/devices/MikrotikPppoeCustom.php b/system/devices/MikrotikPppoeCustom.php new file mode 100644 index 00000000..83406144 --- /dev/null +++ b/system/devices/MikrotikPppoeCustom.php @@ -0,0 +1,407 @@ + 'Mikrotik PPPOE Custom', + 'description' => 'To handle connection between PHPNuxBill with Mikrotik PPPOE using Custom Username, IP and Password', + 'author' => 'ibnux', + 'url' => [ + 'Github' => 'https://github.com/hotspotbilling/phpnuxbill/', + 'Telegram' => 'https://t.me/phpnuxbill', + 'Donate' => 'https://paypal.me/ibnux' + ] + ]; + } + + function add_customer($customer, $plan) + { + global $isChangePlan; + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $cid = self::getIdByCustomer($customer, $client); + if (empty($cid)) { + //customer not exists, add it + $this->addPpoeUser($client, $plan, $customer); + }else{ + $setRequest = new RouterOS\Request('/ppp/secret/set'); + $setRequest->setArgument('numbers', $cid); + if (!empty($customer['pppoe_password'])) { + $setRequest->setArgument('password', $customer['pppoe_password']); + } else { + $setRequest->setArgument('password', $customer['password']); + } + if (!empty($customer['pppoe_username'])) { + $setRequest->setArgument('name', $customer['pppoe_username']); + } else { + $setRequest->setArgument('name', $customer['username']); + } + if (!empty($customer['pppoe_ip'])) { + $setRequest->setArgument('local-address', $customer['pppoe_ip']); + }else{ + $setRequest->setArgument('local-address', '0.0.0.0'); + } + $setRequest->setArgument('profile', $plan['name_plan']); + $setRequest->setArgument('comment', $customer['fullname'] . ' | ' . $customer['email'] . ' | ' . implode(', ', User::getBillNames($customer['id']))); + $client->sendSync($setRequest); + //disconnect then + if(isset($isChangePlan) && $isChangePlan){ + $this->removePpoeActive($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removePpoeActive($client, $customer['pppoe_username']); + } + } + } + } + + function remove_customer($customer, $plan) + { + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + if (!empty($plan['plan_expired'])) { + $p = ORM::for_table("tbl_plans")->find_one($plan['plan_expired']); + if($p){ + $this->add_customer($customer, $p); + $this->removePpoeActive($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removePpoeActive($client, $customer['pppoe_username']); + } + return; + } + } + $this->removePpoeUser($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removePpoeUser($client, $customer['pppoe_username']); + } + $this->removePpoeActive($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removePpoeActive($client, $customer['pppoe_username']); + } + } + + // customer change username + public function change_username($plan, $from, $to) + { + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + //check if customer exists + $printRequest = new RouterOS\Request('/ppp/secret/print'); + $printRequest->setQuery(RouterOS\Query::where('name', $from)); + $cid = $client->sendSync($printRequest)->getProperty('.id'); + if (!empty($cid)) { + $setRequest = new RouterOS\Request('/ppp/secret/set'); + $setRequest->setArgument('numbers', $cid); + $setRequest->setArgument('name', $to); + $client->sendSync($setRequest); + //disconnect then + $this->removePpoeActive($client, $from); + } + } + + function add_plan($plan) + { + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + + //Add Pool + + $bw = ORM::for_table("tbl_bandwidth")->find_one($plan['id_bw']); + if ($bw['rate_down_unit'] == 'Kbps') { + $unitdown = 'K'; + } else { + $unitdown = 'M'; + } + if ($bw['rate_up_unit'] == 'Kbps') { + $unitup = 'K'; + } else { + $unitup = 'M'; + } + $rate = $bw['rate_up'] . $unitup . "/" . $bw['rate_down'] . $unitdown; + if(!empty(trim($bw['burst']))){ + $rate .= ' '.$bw['burst']; + } + $pool = ORM::for_table("tbl_pool")->where("pool_name", $plan['pool'])->find_one(); + $addRequest = new RouterOS\Request('/ppp/profile/add'); + $client->sendSync( + $addRequest + ->setArgument('name', $plan['name_plan']) + ->setArgument('local-address', (!empty($pool['local_ip'])) ? $pool['local_ip']: $pool['pool_name']) + ->setArgument('remote-address', $pool['pool_name']) + ->setArgument('rate-limit', $rate) + ); + } + + /** + * Function to ID by username from Mikrotik + */ + function getIdByCustomer($customer, $client){ + $printRequest = new RouterOS\Request('/ppp/secret/print'); + $printRequest->setQuery(RouterOS\Query::where('name', $customer['username'])); + $id = $client->sendSync($printRequest)->getProperty('.id'); + if(empty($id)){ + if (!empty($customer['pppoe_username'])) { + $printRequest = new RouterOS\Request('/ppp/secret/print'); + $printRequest->setQuery(RouterOS\Query::where('name', $customer['pppoe_username'])); + $id = $client->sendSync($printRequest)->getProperty('.id'); + } + } + return $id; + } + + function update_plan($old_name, $new_plan) + { + $mikrotik = $this->info($new_plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + + $printRequest = new RouterOS\Request( + '/ppp profile print .proplist=.id', + RouterOS\Query::where('name', $old_name['name_plan']) + ); + $profileID = $client->sendSync($printRequest)->getProperty('.id'); + if (empty($profileID)) { + $this->add_plan($new_plan); + } else { + $bw = ORM::for_table("tbl_bandwidth")->find_one($new_plan['id_bw']); + if ($bw['rate_down_unit'] == 'Kbps') { + $unitdown = 'K'; + } else { + $unitdown = 'M'; + } + if ($bw['rate_up_unit'] == 'Kbps') { + $unitup = 'K'; + } else { + $unitup = 'M'; + } + $rate = $bw['rate_up'] . $unitup . "/" . $bw['rate_down'] . $unitdown; + if(!empty(trim($bw['burst']))){ + $rate .= ' '.$bw['burst']; + } + $pool = ORM::for_table("tbl_pool")->where("pool_name", $new_plan['pool'])->find_one(); + $setRequest = new RouterOS\Request('/ppp/profile/set'); + $client->sendSync( + $setRequest + ->setArgument('numbers', $profileID) + ->setArgument('local-address', (!empty($pool['local_ip'])) ? $pool['local_ip']: $pool['pool_name']) + ->setArgument('remote-address', $pool['pool_name']) + ->setArgument('rate-limit', $rate) + ->setArgument('on-up', $new_plan['on_login']) + ->setArgument('on-down', $new_plan['on_logout']) + ); + } + } + + function remove_plan($plan) + { + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $printRequest = new RouterOS\Request( + '/ppp profile print .proplist=.id', + RouterOS\Query::where('name', $plan['name_plan']) + ); + $profileID = $client->sendSync($printRequest)->getProperty('.id'); + + $removeRequest = new RouterOS\Request('/ppp/profile/remove'); + $client->sendSync( + $removeRequest + ->setArgument('numbers', $profileID) + ); + } + + function add_pool($pool){ + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $mikrotik = $this->info($pool['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $addRequest = new RouterOS\Request('/ip/pool/add'); + $client->sendSync( + $addRequest + ->setArgument('name', $pool['pool_name']) + ->setArgument('ranges', $pool['range_ip']) + ); + } + + function update_pool($old_pool, $new_pool){ + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $mikrotik = $this->info($new_pool['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $printRequest = new RouterOS\Request( + '/ip pool print .proplist=.id', + RouterOS\Query::where('name', $old_pool['pool_name']) + ); + $poolID = $client->sendSync($printRequest)->getProperty('.id'); + if (empty($poolID)) { + $this->add_pool($new_pool); + } else { + $setRequest = new RouterOS\Request('/ip/pool/set'); + $client->sendSync( + $setRequest + ->setArgument('numbers', $poolID) + ->setArgument('name', $new_pool['pool_name']) + ->setArgument('ranges', $new_pool['range_ip']) + ); + } + } + + function remove_pool($pool){ + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $mikrotik = $this->info($pool['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $printRequest = new RouterOS\Request( + '/ip pool print .proplist=.id', + RouterOS\Query::where('name', $pool['pool_name']) + ); + $poolID = $client->sendSync($printRequest)->getProperty('.id'); + $removeRequest = new RouterOS\Request('/ip/pool/remove'); + $client->sendSync( + $removeRequest + ->setArgument('numbers', $poolID) + ); + } + + + function online_customer($customer, $router_name) + { + $mikrotik = $this->info($router_name); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $printRequest = new RouterOS\Request( + '/ppp active print', + RouterOS\Query::where('user', $customer['username']) + ); + return $client->sendSync($printRequest)->getProperty('.id'); + } + + function info($name) + { + return ORM::for_table('tbl_routers')->where('name', $name)->find_one(); + } + + function getClient($ip, $user, $pass) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $iport = explode(":", $ip); + return new RouterOS\Client($iport[0], $user, $pass, ($iport[1]) ? $iport[1] : null); + } + + function removePpoeUser($client, $username) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $printRequest = new RouterOS\Request('/ppp/secret/print'); + //$printRequest->setArgument('.proplist', '.id'); + $printRequest->setQuery(RouterOS\Query::where('name', $username)); + $id = $client->sendSync($printRequest)->getProperty('.id'); + $removeRequest = new RouterOS\Request('/ppp/secret/remove'); + $removeRequest->setArgument('numbers', $id); + $client->sendSync($removeRequest); + } + + function addPpoeUser($client, $plan, $customer) + { + $setRequest = new RouterOS\Request('/ppp/secret/add'); + $setRequest->setArgument('service', 'pppoe'); + $setRequest->setArgument('profile', $plan['name_plan']); + $setRequest->setArgument('comment', $customer['fullname'] . ' | ' . $customer['email'] . ' | ' . implode(', ', User::getBillNames($customer['id']))); + if (!empty($customer['pppoe_password'])) { + $setRequest->setArgument('password', $customer['pppoe_password']); + } else { + $setRequest->setArgument('password', $customer['password']); + } + if (!empty($customer['pppoe_username'])) { + $setRequest->setArgument('name', $customer['pppoe_username']); + } else { + $setRequest->setArgument('name', $customer['username']); + } + if (!empty($customer['pppoe_ip'])) { + $setRequest->setArgument('local-address', $customer['pppoe_ip']); + } + $client->sendSync($setRequest); + } + + function removePpoeActive($client, $username) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $onlineRequest = new RouterOS\Request('/ppp/active/print'); + $onlineRequest->setArgument('.proplist', '.id'); + $onlineRequest->setQuery(RouterOS\Query::where('name', $username)); + $id = $client->sendSync($onlineRequest)->getProperty('.id'); + + $removeRequest = new RouterOS\Request('/ppp/active/remove'); + $removeRequest->setArgument('numbers', $id); + $client->sendSync($removeRequest); + } + + function getIpHotspotUser($client, $username) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $printRequest = new RouterOS\Request( + '/ip hotspot active print', + RouterOS\Query::where('user', $username) + ); + return $client->sendSync($printRequest)->getProperty('address'); + } + + function addIpToAddressList($client, $ip, $listName, $comment = '') + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $addRequest = new RouterOS\Request('/ip/firewall/address-list/add'); + $client->sendSync( + $addRequest + ->setArgument('address', $ip) + ->setArgument('comment', $comment) + ->setArgument('list', $listName) + ); + } + + function removeIpFromAddressList($client, $ip) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $printRequest = new RouterOS\Request( + '/ip firewall address-list print .proplist=.id', + RouterOS\Query::where('address', $ip) + ); + $id = $client->sendSync($printRequest)->getProperty('.id'); + $removeRequest = new RouterOS\Request('/ip/firewall/address-list/remove'); + $client->sendSync( + $removeRequest + ->setArgument('numbers', $id) + ); + } +} diff --git a/version.json b/version.json index ddfab6f6..1bd146b2 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "2024.8.30" + "version": "2024.9.6" } \ No newline at end of file