From 095e8937a29c6279b86e6ea5fcf5c0b94c0e1943 Mon Sep 17 00:00:00 2001 From: agamsatria Date: Fri, 13 Sep 2024 00:43:46 +0700 Subject: [PATCH 1/2] Paket vpn tunnel remot --- system/controllers/home.php | 10 +- system/controllers/order.php | 7 + system/controllers/pool.php | 126 +++++++++++ system/controllers/services.php | 374 ++++++++++++++++++++++++++++++++ system/controllers/settings.php | 10 + system/updates.json | 6 + ui/ui/app-localisation.tpl | 8 + ui/ui/customers-add.tpl | 1 + ui/ui/customers-edit.tpl | 1 + ui/ui/plan.tpl | 10 +- ui/ui/port-add.tpl | 51 +++++ ui/ui/port-edit.tpl | 49 +++++ ui/ui/port.tpl | 76 +++++++ ui/ui/recharge.tpl | 1 + ui/ui/scripts/custom.js | 23 +- ui/ui/sections/header.tpl | 4 + ui/ui/user-ui/dashboard.tpl | 25 ++- ui/ui/user-ui/orderPlan.tpl | 104 +++++++++ ui/ui/vpn-add.tpl | 188 ++++++++++++++++ ui/ui/vpn-edit.tpl | 255 ++++++++++++++++++++++ ui/ui/vpn.tpl | 179 +++++++++++++++ 21 files changed, 1502 insertions(+), 6 deletions(-) create mode 100644 ui/ui/port-add.tpl create mode 100644 ui/ui/port-edit.tpl create mode 100644 ui/ui/port.tpl create mode 100644 ui/ui/vpn-add.tpl create mode 100644 ui/ui/vpn-edit.tpl create mode 100644 ui/ui/vpn.tpl diff --git a/system/controllers/home.php b/system/controllers/home.php index a71d340e..20e1d1b6 100644 --- a/system/controllers/home.php +++ b/system/controllers/home.php @@ -317,7 +317,15 @@ if (!empty($_SESSION['nux-mac']) && !empty($_SESSION['nux-ip'] && !empty($_SESSI } } } - + +$tcf = ORM::for_table('tbl_customers_fields') + ->where('customer_id', $user['id']) + ->find_many(); +$vpn = ORM::for_table('tbl_port_pool') + ->find_one(); +$ui->assign('cf', $tcf); +$ui->assign('vpn', $vpn); + $ui->assign('unpaid', ORM::for_table('tbl_payment_gateway') ->where('username', $user['username']) ->where('status', 1) diff --git a/system/controllers/order.php b/system/controllers/order.php index 0d4b2a3c..988db104 100644 --- a/system/controllers/order.php +++ b/system/controllers/order.php @@ -113,12 +113,19 @@ switch ($action) { ->where('type', 'Hotspot') ->where('prepaid', 'yes') ->find_many(); + $plans_vpn = ORM::for_table('tbl_plans') + ->where('plan_type', $account_type) + ->where('enabled', '1')->where('is_radius', 0) + ->where('type', 'VPN') + ->where('prepaid', 'yes') + ->find_many(); } $ui->assign('routers', $routers); $ui->assign('radius_pppoe', $radius_pppoe); $ui->assign('radius_hotspot', $radius_hotspot); $ui->assign('plans_pppoe', $plans_pppoe); $ui->assign('plans_hotspot', $plans_hotspot); + $ui->assign('plans_vpn', $plans_vpn); run_hook('customer_view_order_plan'); #HOOK $ui->display('user-ui/orderPlan.tpl'); break; diff --git a/system/controllers/pool.php b/system/controllers/pool.php index 5528e751..ba599f22 100644 --- a/system/controllers/pool.php +++ b/system/controllers/pool.php @@ -147,6 +147,132 @@ switch ($action) { } else { r2(U . 'pool/edit/' . $id, 'e', $msg); } + + case 'port': + $ui->assign('xfooter', ''); + + $name = _post('name'); + if ($name != '') { + $query = ORM::for_table('tbl_port_pool')->where_like('pool_name', '%' . $name . '%')->order_by_desc('id'); + $d = Paginator::findMany($query, ['name' => $name]); + } else { + $query = ORM::for_table('tbl_port_pool')->order_by_desc('id'); + $d = Paginator::findMany($query); + } + + $ui->assign('d', $d); + run_hook('view_port'); #HOOK + $ui->display('port.tpl'); + break; + + case 'add-port': + $r = ORM::for_table('tbl_routers')->find_many(); + $ui->assign('r', $r); + run_hook('view_add_port'); #HOOK + $ui->display('port-add.tpl'); + break; + + case 'edit-port': + $id = $routes['2']; + $d = ORM::for_table('tbl_port_pool')->find_one($id); + if ($d) { + $ui->assign('d', $d); + run_hook('view_edit_port'); #HOOK + $ui->display('port-edit.tpl'); + } else { + r2(U . 'pool/port', 'e', Lang::T('Account Not Found')); + } + break; + + case 'delete-port': + $id = $routes['2']; + run_hook('delete_port'); #HOOK + $d = ORM::for_table('tbl_port_pool')->find_one($id); + if ($d) { + $d->delete(); + + r2(U . 'pool/port', 's', Lang::T('Data Deleted Successfully')); + } + break; + + case 'sync': + $pools = ORM::for_table('tbl_port_pool')->find_many(); + $log = ''; + foreach ($pools as $pool) { + if ($pool['routers'] != 'radius') { + (new MikrotikPppoe())->update_pool($pool, $pool); + $log .= 'DONE: ' . $pool['port_name'] . ': ' . $pool['range_port'] . '
'; + } + } + r2(U . 'pool/list', 's', $log); + break; + case 'add-port-post': + $name = _post('name'); + $port_range = _post('port_range'); + $public_ip = _post('public_ip'); + $routers = _post('routers'); + run_hook('add_pool'); #HOOK + $msg = ''; + if (Validator::Length($name, 30, 2) == false) { + $msg .= 'Name should be between 3 to 30 characters' . '
'; + } + if ($port_range == '' or $routers == '') { + $msg .= Lang::T('All field is required') . '
'; + } + + $d = ORM::for_table('tbl_port_pool')->where('routers', $routers)->find_one(); + if ($d) { + $msg .= Lang::T('Routers already have ports, each router can only have 1 port range!') . '
'; + } + if ($msg == '') { + $b = ORM::for_table('tbl_port_pool')->create(); + $b->public_ip = $public_ip; + $b->port_name = $name; + $b->range_port = $port_range; + $b->routers = $routers; + $b->save(); + r2(U . 'pool/port', 's', Lang::T('Data Created Successfully')); + } else { + r2(U . 'pool/add-port', 'e', $msg); + } + break; + + + case 'edit-port-post': + $name = _post('name'); + $public_ip = _post('public_ip'); + $range_port = _post('range_port'); + $routers = _post('routers'); + run_hook('edit_port'); #HOOK + $msg = ''; + $msg = ''; + if (Validator::Length($name, 30, 2) == false) { + $msg .= 'Name should be between 3 to 30 characters' . '
'; + } + if ($range_port == '' or $routers == '') { + $msg .= Lang::T('All field is required') . '
'; + } + + $id = _post('id'); + $d = ORM::for_table('tbl_port_pool')->find_one($id); + $old = ORM::for_table('tbl_port_pool')->find_one($id); + if (!$d) { + $msg .= Lang::T('Data Not Found') . '
'; + } + + if ($msg == '') { + $d->port_name = $name; + $d->public_ip = $public_ip; + $d->range_port = $range_port; + $d->routers = $routers; + $d->save(); + + + + r2(U . 'pool/port', 's', Lang::T('Data Updated Successfully')); + } else { + r2(U . 'pool/edit-port/' . $id, 'e', $msg); + } break; default: diff --git a/system/controllers/services.php b/system/controllers/services.php index aaa69635..9bc32e5e 100644 --- a/system/controllers/services.php +++ b/system/controllers/services.php @@ -901,6 +901,380 @@ switch ($action) { r2(U . 'services/balance-add', 'e', $msg); } break; + case 'vpn': + $ui->assign('_title', Lang::T('VPN Plans')); + $ui->assign('xfooter', ''); + + $name = _post('name'); + $name = _req('name'); + $type1 = _req('type1'); + $type2 = _req('type2'); + $type3 = _req('type3'); + $bandwidth = _req('bandwidth'); + $valid = _req('valid'); + $device = _req('device'); + $status = _req('status'); + $router = _req('router'); + $ui->assign('type1', $type1); + $ui->assign('type2', $type2); + $ui->assign('type3', $type3); + $ui->assign('bandwidth', $bandwidth); + $ui->assign('valid', $valid); + $ui->assign('device', $device); + $ui->assign('status', $status); + $ui->assign('router', $router); + + $append_url = "&type1=" . urlencode($type1) + . "&type2=" . urlencode($type2) + . "&type3=" . urlencode($type3) + . "&bandwidth=" . urlencode($bandwidth) + . "&valid=" . urlencode($valid) + . "&device=" . urlencode($device) + . "&status=" . urlencode($status) + . "&router=" . urlencode($router); + + $bws = ORM::for_table('tbl_plans')->distinct()->select("id_bw")->where('tbl_plans.type', 'VPN')->findArray(); + $ids = array_column($bws, 'id_bw'); + if(count($ids)){ + $ui->assign('bws', ORM::for_table('tbl_bandwidth')->select("id")->select('name_bw')->where_id_in($ids)->findArray()); + }else{ + $ui->assign('bws', []); + } + $ui->assign('type2s', ORM::for_table('tbl_plans')->getEnum("plan_type")); + $ui->assign('type3s', ORM::for_table('tbl_plans')->getEnum("typebp")); + $ui->assign('valids', ORM::for_table('tbl_plans')->getEnum("validity_unit")); + $ui->assign('routers', array_column(ORM::for_table('tbl_plans')->distinct()->select("routers")->whereNotEqual('routers', '')->findArray(), 'routers')); + $devices = []; + $files = scandir($DEVICE_PATH); + foreach ($files as $file) { + $ext = pathinfo($file, PATHINFO_EXTENSION); + if ($ext == 'php') { + $devices[] = pathinfo($file, PATHINFO_FILENAME); + } + } + $ui->assign('devices', $devices); + $query = ORM::for_table('tbl_bandwidth') + ->left_outer_join('tbl_plans', array('tbl_bandwidth.id', '=', 'tbl_plans.id_bw')) + ->where('tbl_plans.type', 'VPN'); + if (!empty($type1)) { + $query->where('tbl_plans.prepaid', $type1); + } + if (!empty($type2)) { + $query->where('tbl_plans.plan_type', $type2); + } + if (!empty($type3)) { + $query->where('tbl_plans.typebp', $type3); + } + if (!empty($bandwidth)) { + $query->where('tbl_plans.id_bw', $bandwidth); + } + if (!empty($valid)) { + $query->where('tbl_plans.validity_unit', $valid); + } + if (!empty($router)) { + if ($router == 'radius') { + $query->where('tbl_plans.is_radius', '1'); + } else { + $query->where('tbl_plans.routers', $router); + } + } + if (!empty($device)) { + $query->where('tbl_plans.device', $device); + } + if (in_array($status, ['0', '1'])) { + $query->where('tbl_plans.enabled', $status); + } + if ($name != '') { + $query->where_like('tbl_plans.name_plan', '%' . $name . '%'); + } + $d = Paginator::findMany($query, ['name' => $name], 20, $append_url); + + $ui->assign('d', $d); + run_hook('view_list_vpn'); #HOOK + $ui->display('vpn.tpl'); + break; + + case 'vpn-add': + $ui->assign('_title', Lang::T('VPN Plans')); + $d = ORM::for_table('tbl_bandwidth')->find_many(); + $ui->assign('d', $d); + $r = ORM::for_table('tbl_routers')->find_many(); + $ui->assign('r', $r); + $devices = []; + $files = scandir($DEVICE_PATH); + foreach ($files as $file) { + $ext = pathinfo($file, PATHINFO_EXTENSION); + if ($ext == 'php') { + $devices[] = pathinfo($file, PATHINFO_FILENAME); + } + } + $ui->assign('devices', $devices); + run_hook('view_add_vpn'); #HOOK + $ui->display('vpn-add.tpl'); + break; + + case 'vpn-edit': + $ui->assign('_title', Lang::T('VPN Plans')); + $id = $routes['2']; + $d = ORM::for_table('tbl_plans')->find_one($id); + if ($d) { + if (empty($d['device'])) { + if ($d['is_radius']) { + $d->device = 'Radius'; + } else { + $d->device = 'MikrotikVpn'; + } + $d->save(); + } + $ui->assign('d', $d); + $p = ORM::for_table('tbl_pool')->where('routers', ($d['is_radius']) ? 'radius' : $d['routers'])->find_many(); + $ui->assign('p', $p); + $b = ORM::for_table('tbl_bandwidth')->find_many(); + $ui->assign('b', $b); + $r = []; + if ($d['is_radius']) { + $r = ORM::for_table('tbl_routers')->find_many(); + } + $ui->assign('r', $r); + $devices = []; + $files = scandir($DEVICE_PATH); + foreach ($files as $file) { + $ext = pathinfo($file, PATHINFO_EXTENSION); + if ($ext == 'php') { + $devices[] = pathinfo($file, PATHINFO_FILENAME); + } + } + $ui->assign('devices', $devices); + //select expired plan + if ($d['is_radius']) { + $exps = ORM::for_table('tbl_plans')->selects('id', 'name_plan')->where('type', 'VPN')->where("is_radius", 1)->findArray(); + } else { + $exps = ORM::for_table('tbl_plans')->selects('id', 'name_plan')->where('type', 'VPN')->where("routers", $d['routers'])->findArray(); + } + $ui->assign('exps', $exps); + run_hook('view_edit_vpn'); #HOOK + $ui->display('vpn-edit.tpl'); + } else { + r2(U . 'services/vpn', 'e', Lang::T('Account Not Found')); + } + break; + + case 'vpn-delete': + $id = $routes['2']; + + $d = ORM::for_table('tbl_plans')->find_one($id); + if ($d) { + run_hook('delete_vpn'); #HOOK + + $dvc = Package::getDevice($d); + if ($_app_stage != 'demo') { + if (file_exists($dvc)) { + require_once $dvc; + (new $d['device'])->remove_plan($d); + } else { + new Exception(Lang::T("Devices Not Found")); + } + } + $d->delete(); + + r2(U . 'services/vpn', 's', Lang::T('Data Deleted Successfully')); + } + break; + + case 'vpn-add-post': + $name = _post('name_plan'); + $plan_type = _post('plan_type'); + $radius = _post('radius'); + $id_bw = _post('id_bw'); + $price = _post('price'); + $validity = _post('validity'); + $validity_unit = _post('validity_unit'); + $routers = _post('routers'); + $device = _post('device'); + $pool = _post('pool_name'); + $enabled = _post('enabled'); + $prepaid = _post('prepaid'); + $expired_date = _post('expired_date'); + + + $msg = ''; + if (Validator::UnsignedNumber($validity) == false) { + $msg .= 'The validity must be a number' . '
'; + } + if (Validator::UnsignedNumber($price) == false) { + $msg .= 'The price must be a number' . '
'; + } + if ($name == '' or $id_bw == '' or $price == '' or $validity == '' or $pool == '') { + $msg .= Lang::T('All field is required') . '
'; + } + if (empty($radius)) { + if ($routers == '') { + $msg .= Lang::T('All field is required') . '
'; + } + } + + $d = ORM::for_table('tbl_plans')->where('name_plan', $name)->find_one(); + if ($d) { + $msg .= Lang::T('Name Plan Already Exist') . '
'; + } + run_hook('add_vpn'); #HOOK + if ($msg == '') { + $b = ORM::for_table('tbl_bandwidth')->where('id', $id_bw)->find_one(); + if ($b['rate_down_unit'] == 'Kbps') { + $unitdown = 'K'; + $raddown = '000'; + } else { + $unitdown = 'M'; + $raddown = '000000'; + } + if ($b['rate_up_unit'] == 'Kbps') { + $unitup = 'K'; + $radup = '000'; + } else { + $unitup = 'M'; + $radup = '000000'; + } + $rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown; + $radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown . '/' . $b['burst']; + $rate = trim($rate . " " . $b['burst']); + $d = ORM::for_table('tbl_plans')->create(); + $d->type = 'VPN'; + $d->name_plan = $name; + $d->id_bw = $id_bw; + $d->price = $price; + $d->plan_type = $plan_type; + $d->validity = $validity; + $d->validity_unit = $validity_unit; + $d->pool = $pool; + if (!empty($radius)) { + $d->is_radius = 1; + $d->routers = ''; + } else { + $d->is_radius = 0; + $d->routers = $routers; + } + if ($prepaid == 'no') { + if ($expired_date > 28 && $expired_date < 1) { + $expired_date = 20; + } + $d->expired_date = $expired_date; + } else { + $d->expired_date = 0; + } + $d->enabled = $enabled; + $d->prepaid = $prepaid; + $d->device = $device; + $d->save(); + + $dvc = Package::getDevice($d); + if ($_app_stage != 'demo') { + if (file_exists($dvc)) { + require_once $dvc; + (new $d['device'])->add_plan($d); + } else { + new Exception(Lang::T("Devices Not Found")); + } + } + r2(U . 'services/vpn', 's', Lang::T('Data Created Successfully')); + } else { + r2(U . 'services/vpn-add', 'e', $msg); + } + break; + + case 'edit-vpn-post': + $id = _post('id'); + $plan_type = _post('plan_type'); + $name = _post('name_plan'); + $id_bw = _post('id_bw'); + $price = _post('price'); + $validity = _post('validity'); + $validity_unit = _post('validity_unit'); + $routers = _post('routers'); + $device = _post('device'); + $pool = _post('pool_name'); + $plan_expired = _post('plan_expired'); + $enabled = _post('enabled'); + $prepaid = _post('prepaid'); + $expired_date = _post('expired_date'); + $on_login = _post('on_login'); + $on_logout = _post('on_logout'); + + $msg = ''; + if (Validator::UnsignedNumber($validity) == false) { + $msg .= 'The validity must be a number' . '
'; + } + if (Validator::UnsignedNumber($price) == false) { + $msg .= 'The price must be a number' . '
'; + } + if ($name == '' or $id_bw == '' or $price == '' or $validity == '' or $pool == '') { + $msg .= Lang::T('All field is required') . '
'; + } + + $d = ORM::for_table('tbl_plans')->where('id', $id)->find_one(); + $old = ORM::for_table('tbl_plans')->where('id', $id)->find_one(); + if ($d) { + } else { + $msg .= Lang::T('Data Not Found') . '
'; + } + run_hook('edit_vpn'); #HOOK + if ($msg == '') { + $b = ORM::for_table('tbl_bandwidth')->where('id', $id_bw)->find_one(); + if ($b['rate_down_unit'] == 'Kbps') { + $unitdown = 'K'; + $raddown = '000'; + } else { + $unitdown = 'M'; + $raddown = '000000'; + } + if ($b['rate_up_unit'] == 'Kbps') { + $unitup = 'K'; + $radup = '000'; + } else { + $unitup = 'M'; + $radup = '000000'; + } + $rate = $b['rate_up'] . $unitup . "/" . $b['rate_down'] . $unitdown; + $radiusRate = $b['rate_up'] . $radup . '/' . $b['rate_down'] . $raddown . '/' . $b['burst']; + $rate = trim($rate . " " . $b['burst']); + + $d->name_plan = $name; + $d->id_bw = $id_bw; + $d->price = $price; + $d->plan_type = $plan_type; + $d->validity = $validity; + $d->validity_unit = $validity_unit; + $d->routers = $routers; + $d->pool = $pool; + $d->plan_expired = $plan_expired; + $d->enabled = $enabled; + $d->prepaid = $prepaid; + $d->device = $device; + $d->on_login = $on_login; + $d->on_logout = $on_logout; + if ($prepaid == 'no') { + if ($expired_date > 28 && $expired_date < 1) { + $expired_date = 20; + } + $d->expired_date = $expired_date; + } else { + $d->expired_date = 0; + } + $d->save(); + + $dvc = Package::getDevice($d); + if ($_app_stage != 'demo') { + if (file_exists($dvc)) { + require_once $dvc; + (new $d['device'])->update_plan($old, $d); + } else { + new Exception(Lang::T("Devices Not Found")); + } + } + r2(U . 'services/vpn', 's', Lang::T('Data Updated Successfully')); + } else { + r2(U . 'services/vpn-edit/' . $id, 'e', $msg); + } + break; default: $ui->display('a404.tpl'); } diff --git a/system/controllers/settings.php b/system/controllers/settings.php index 33e4abe9..96cb497b 100644 --- a/system/controllers/settings.php +++ b/system/controllers/settings.php @@ -295,6 +295,16 @@ switch ($action) { $d->value = _post('pppoe_plan'); $d->save(); } + $d = ORM::for_table('tbl_appconfig')->where('setting', 'vpn_plan')->find_one(); + if ($d) { + $d->value = _post('vpn_plan'); + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'vpn_plan'; + $d->value = _post('vpn_plan'); + $d->save(); + } $currency_code = $_POST['currency_code']; $d = ORM::for_table('tbl_appconfig')->where('setting', 'currency_code')->find_one(); diff --git a/system/updates.json b/system/updates.json index bce2f4ef..8d66fc0c 100644 --- a/system/updates.json +++ b/system/updates.json @@ -155,5 +155,11 @@ "2024.8.28" : [ "ALTER TABLE `tbl_routers` ADD `status` ENUM('Online', 'Offline') DEFAULT 'Online' AFTER `coordinates`;", "ALTER TABLE `tbl_routers` ADD `last_seen` DATETIME AFTER `status`;" + ], + "2024.9.13" : [ + "ALTER TABLE `tbl_plans` CHANGE `type` `type` ENUM('Hotspot','PPPOE','VPN','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;", + "ALTER TABLE `tbl_customers` CHANGE `service_type` `service_type` ENUM('Hotspot','PPPoE','VPN','Others') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'Others' COMMENT 'For selecting user type';", + "ALTER TABLE `tbl_transactions` CHANGE `type` `type` ENUM('Hotspot','PPPOE','VPN','Balance') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;", + "CREATE TABLE IF NOT EXISTS `tbl_port_pool` ( `id` int(10) NOT NULL AUTO_INCREMENT , `public_ip` varchar(40) NOT NULL, `port_name` varchar(40) NOT NULL, `range_port` varchar(40) NOT NULL, `routers` varchar(40) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;" ] } \ No newline at end of file diff --git a/ui/ui/app-localisation.tpl b/ui/ui/app-localisation.tpl index 936c3abb..571d5588 100644 --- a/ui/ui/app-localisation.tpl +++ b/ui/ui/app-localisation.tpl @@ -128,6 +128,14 @@ {Lang::T('Change title in user Plan order')} +
+ +
+ +
+ {Lang::T('Change title in user Plan order')} +
diff --git a/ui/ui/customers-edit.tpl b/ui/ui/customers-edit.tpl index e1ce53f8..0ed074b4 100644 --- a/ui/ui/customers-edit.tpl +++ b/ui/ui/customers-edit.tpl @@ -75,6 +75,7 @@ +
diff --git a/ui/ui/plan.tpl b/ui/ui/plan.tpl index 3cca5861..32111f4a 100644 --- a/ui/ui/plan.tpl +++ b/ui/ui/plan.tpl @@ -95,9 +95,13 @@ {/if} {if $ds['type'] == 'Hotspot'} - {$ds['namebp']} - {else} - {$ds['namebp']} + {$ds['namebp']} + {/if} + {if $ds['type'] == 'PPPOE'} + {$ds['namebp']} + {/if} + {if $ds['type'] == 'VPN'} + {$ds['namebp']} {/if} {$ds['type']} {Lang::dateAndTimeFormat($ds['recharged_on'],$ds['recharged_time'])} diff --git a/ui/ui/port-add.tpl b/ui/ui/port-add.tpl new file mode 100644 index 00000000..b689a896 --- /dev/null +++ b/ui/ui/port-add.tpl @@ -0,0 +1,51 @@ +{include file="sections/header.tpl"} + +
+
+
+
{Lang::T('Add Port Pool')}
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + Or {Lang::T('Cancel')} +
+
+
+ +
+
+
+
+ +{include file="sections/footer.tpl"} diff --git a/ui/ui/port-edit.tpl b/ui/ui/port-edit.tpl new file mode 100644 index 00000000..46413314 --- /dev/null +++ b/ui/ui/port-edit.tpl @@ -0,0 +1,49 @@ +{include file="sections/header.tpl"} + +
+
+
+
{Lang::T('Edit Port')}
+
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ + Or {Lang::T('Cancel')} +
+
+
+ +
+
+
+
+ +{include file="sections/footer.tpl"} diff --git a/ui/ui/port.tpl b/ui/ui/port.tpl new file mode 100644 index 00000000..77fd2661 --- /dev/null +++ b/ui/ui/port.tpl @@ -0,0 +1,76 @@ +{include file="sections/header.tpl"} + +
+
+
+
+
+ sync +
+ {Lang::T('Port Pool')} - VPN Tunnels +
+
+
+
+ +
+   +
+
+ + + + + + + + + + + + + {foreach $d as $ds} + + + + + + + + + {/foreach} + +
{Lang::T('Port Name')}{Lang::T('Public IP')}{Lang::T('Range Port')}{Lang::T('Routers')}{Lang::T('Manage')}ID
{$ds['port_name']}{$ds['public_ip']}{$ds['range_port']}{$ds['routers']} + {Lang::T('Edit')} + + {$ds['id']}
+
+ {include file="pagination.tpl"} +
+

{Lang::T('Create expired Internet Plan')}

+

{Lang::T('When customer expired, you can move it to Expired Internet Plan')}

+
+
+
+
+
+ +{include file="sections/footer.tpl"} diff --git a/ui/ui/recharge.tpl b/ui/ui/recharge.tpl index b896ab50..96370d58 100644 --- a/ui/ui/recharge.tpl +++ b/ui/ui/recharge.tpl @@ -22,6 +22,7 @@
+
diff --git a/ui/ui/scripts/custom.js b/ui/ui/scripts/custom.js index 844f5ffc..87734583 100644 --- a/ui/ui/scripts/custom.js +++ b/ui/ui/scripts/custom.js @@ -96,7 +96,7 @@ $(function() { }); }; - }else{ + } else if ($('#POE').is(':checked')) { $.ajax({ type: "POST", dataType: "html", @@ -117,6 +117,27 @@ $(function() { } }); }); + } else { + $.ajax({ + type: "POST", + dataType: "html", + url: "index.php?_route=autoload/server", + success: function(msg){ + $("#server").html(msg); + } + }); + $("#server").change(function(){ + var server = $("#server").val(); + $.ajax({ + type: "POST", + dataType: "html", + url: "index.php?_route=autoload/plan", + data: "jenis=VPN&server="+server, + success: function(msg){ + $("#plan").html(msg); + } + }); + }); } }); }); diff --git a/ui/ui/sections/header.tpl b/ui/ui/sections/header.tpl index 34b7f1e9..bb5f8525 100644 --- a/ui/ui/sections/header.tpl +++ b/ui/ui/sections/header.tpl @@ -1283,6 +1283,8 @@ href="{$_url}services/hotspot">Hotspot
  • PPPOE
  • +
  • VPN
  • Bandwidth
  • {if $_c['enable_balance'] == 'yes'} @@ -1341,6 +1343,8 @@ href="{$_url}routers">Routers
  • IP Pool
  • +
  • Port Pool
  • {Lang::T('Routers Maps')}
  • {$_MENU_NETWORK} diff --git a/ui/ui/user-ui/dashboard.tpl b/ui/ui/user-ui/dashboard.tpl index 361e6487..65e24c39 100644 --- a/ui/ui/user-ui/dashboard.tpl +++ b/ui/ui/user-ui/dashboard.tpl @@ -88,6 +88,8 @@ Hotspot {elseif $_user.service_type == 'PPPoE'} PPPoE + {elseif $_user.service_type == 'VPN'} + VPN {elseif $_user.service_type == 'Others' || $_user.service_type == null} Others {/if} @@ -165,8 +167,10 @@
    {if $_bill['type'] == 'Hotspot'} {if $_c['hotspot_plan']==''}Hotspot Plan{else}{$_c['hotspot_plan']}{/if} - {else} + {else if $_bill['type'] == 'PPPOE'} {if $_c['pppoe_plan']==''}PPPOE Plan{else}{$_c['pppoe_plan']}{/if} + {else if $_bill['type'] == 'VPN'} + {if $_c['pppoe_plan']==''}VPN Plan{else}{$_c['vpn_plan']}{/if} {/if}
    @@ -215,6 +219,25 @@ {$_bill['plan_type']} + {if $_bill['type'] == 'VPN' && $_bill['routers'] == $vpn['routers']} + + {Lang::T('Public IP')} + {$vpn['public_ip']} / {$vpn['port_name']} + + + {Lang::T('Private IP')} + {$_user['pppoe_ip']} + + {foreach $cf as $tcf} + + {if $tcf['field_name'] == 'Winbox' or $tcf['field_name'] == 'Api' or $tcf['field_name'] == 'Web'} + {$tcf['field_name']} - Port + {$tcf['field_value']} + + {/if} + {/foreach} + {/if} + {if $nux_ip neq ''} {Lang::T('Current IP')} diff --git a/ui/ui/user-ui/orderPlan.tpl b/ui/ui/user-ui/orderPlan.tpl index f79ed4dd..9db514ff 100644 --- a/ui/ui/user-ui/orderPlan.tpl +++ b/ui/ui/user-ui/orderPlan.tpl @@ -226,6 +226,7 @@ {/if} {foreach $routers as $router} {if Validator::isRouterHasPlan($plans_hotspot, $router['name']) || Validator::isRouterHasPlan($plans_pppoe, + $router['name']) || Validator::isRouterHasPlan($plans_vpn, $router['name'])}
    {$router['name']}
    @@ -338,9 +339,62 @@ {/if} {/foreach}
    + {/if} + {if $_user['service_type'] == 'VPN' && Validator::countRouterPlan($plans_vpn,$router['name'])>0} +
    {if $_c['vpn_plan']==''}VPN Plan{else}{$_c['vpn_plan']}{/if}
    +
    + {foreach $plans_vpn as $plan} + {if $router['name'] eq $plan['routers']} +
    +
    +
    {$plan['name_plan']}
    +
    +
    + + + + + + + + + + + + + + + +
    {Lang::T('Type')}{$plan['type']}
    {Lang::T('Price')}{Lang::moneyFormat($plan['price'])}
    {Lang::T('Validity')}{$plan['validity']} {$plan['validity_unit']}
    +
    +
    +
    +
    + {Lang::T('Buy')} + {if $_c['enable_balance'] == 'yes' && $_user['balance']>=$plan['price']} + {Lang::T('Pay With Balance')} + {/if} +
    + {if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && + $_user['balance']>=$plan['price']} + {Lang::T('Buy for friend')} + {/if} +
    +
    +
    + {/if} + {/foreach} +
    {/if} {if $_user['service_type'] == 'Others' || $_user['service_type'] == '' && (Validator::countRouterPlan($plans_hotspot, $router['name'])>0 || Validator::countRouterPlan($plans_pppoe, + $router['name'])>0 || Validator::countRouterPlan($plans_vpn, $router['name'])>0)}
    {if $_c['hotspot_plan']==''}Hotspot Plan{else}{$_c['hotspot_plan']}{/if}
    @@ -443,6 +497,56 @@ {/if} {/foreach} +
    {if $_c['vpn_plan']==''}VPN Plan{else}{$_c['vpn_plan']}{/if}
    +
    + {foreach $plans_vpn as $plan} + {if $router['name'] eq $plan['routers']} +
    +
    +
    {$plan['name_plan']}
    +
    +
    + + + + + + + + + + + + + + + +
    {Lang::T('Type')}{$plan['type']}
    {Lang::T('Price')}{Lang::moneyFormat($plan['price'])}
    {Lang::T('Validity')}{$plan['validity']} {$plan['validity_unit']}
    +
    +
    +
    +
    + {Lang::T('Buy')} + {if $_c['enable_balance'] == 'yes' && $_user['balance']>=$plan['price']} + {Lang::T('Pay With Balance')} + {/if} +
    + {if $_c['enable_balance'] == 'yes' && $_c['allow_balance_transfer'] == 'yes' && + $_user['balance']>=$plan['price']} + {Lang::T('Buy for friend')} + {/if} +
    +
    +
    + {/if} + {/foreach} +
    {/if} {/if} diff --git a/ui/ui/vpn-add.tpl b/ui/ui/vpn-add.tpl new file mode 100644 index 00000000..ae26a8ac --- /dev/null +++ b/ui/ui/vpn-add.tpl @@ -0,0 +1,188 @@ +{include file="sections/header.tpl"} + +
    +
    +
    +
    {Lang::T('Add Service Plan')}
    +
    +
    +
    + +
    + {Lang::T('Enable')} + {Lang::T('Disable')} +
    +
    +
    + +
    + {Lang::T('Prepaid')} + {Lang::T('Postpaid')} +
    +
    +
    + +
    + {Lang::T('Personal')} + {Lang::T('Business')} +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + {$_c['currency_code']} + +
    +
    + {if $_c['enable_tax'] == 'yes'} + {if $_c['tax_rate'] == 'custom'} +

    {number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates + will be added')}

    + {else} +

    {number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates + will be added')}

    + {/if} + {/if} +
    +
    + +
    + +
    +
    + +
    +

    {Lang::T('1 Period = 1 Month, Expires the 20th of each month')} +

    +
    + +
    + +
    + +

    {Lang::T('Cannot be change after saved')}

    +
    +
    +
    + +
    + +
    +
    +
    +
    + + Or {Lang::T('Cancel')} +
    +
    +
    +
    +
    +
    +
    + +{if $_c['radius_enable']} + {literal} + + {/literal} +{/if} +{include file="sections/footer.tpl"} diff --git a/ui/ui/vpn-edit.tpl b/ui/ui/vpn-edit.tpl new file mode 100644 index 00000000..53428605 --- /dev/null +++ b/ui/ui/vpn-edit.tpl @@ -0,0 +1,255 @@ +{include file="sections/header.tpl"} + +
    +
    +
    +
    +
    {Lang::T('Edit Service Plan')} || {$d['name_plan']}
    +
    + +
    + +
    + {Lang::T('Enable')} + {Lang::T('Disable')} +
    +
    +
    + +
    + + {Lang::T('Prepaid')} + {Lang::T('Postpaid')} +
    +
    +
    + +
    + + {Lang::T('Personal')} + {Lang::T('Business')} +
    +
    + {if $_c['radius_enable'] and $d['is_radius']} +
    + +
    + +
    +
    + {/if} +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + {$_c['currency_code']} + +
    +
    + {if $_c['enable_tax'] == 'yes'} + {if $_c['tax_rate'] == 'custom'} +

    {number_format($_c['custom_tax_rate'], 2)} % {Lang::T('Tax Rates + will be added')}

    + {else} +

    {number_format($_c['tax_rate'] * 100, 2)} % {Lang::T('Tax Rates + will be added')}

    + {/if} + {/if} + +
    +
    + +
    + +
    +
    + +

    {Lang::T('1 Period = 1 Month, Expires the 20th of each month')}

    +
    + +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + {Lang::T('Expired Action')} {Lang::T('Optional')} +
    + +
    + +

    + {Lang::T('When Expired, customer will be move to selected internet plan')}

    +
    +
    +
    +
    +
    + {if !$d['is_radius']} +
    +
    +
    {Lang::T('on-login / on-up')}
    +
    + +
    +
    +
    +
    {Lang::T('on-logout / on-down')}
    +
    + +
    +
    +
    + {/if} +
    +
    +
    + + Or {Lang::T('Cancel')} +
    +
    +
    + + + + + + + + + + + + + + +{include file="sections/footer.tpl"} diff --git a/ui/ui/vpn.tpl b/ui/ui/vpn.tpl new file mode 100644 index 00000000..6047e446 --- /dev/null +++ b/ui/ui/vpn.tpl @@ -0,0 +1,179 @@ +{include file="sections/header.tpl"} + +
    +
    +
    +
    +
    + sync +
    {Lang::T('VPN Package')} +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + {foreach $d as $ds} + + + + + + + + + + + + + + + {/foreach} + +
    {Lang::T('Internet Plan')} + {Lang::T('Expired')}
    {Lang::T('Name')}{Lang::T('Type')}{Lang::T('Bandwidth')}{Lang::T('Price')}{Lang::T('Validity')}{Lang::T('IP Pool')}{Lang::T('Internet Plan')}{Lang::T('Date')}{Lang::T('Location')}{Lang::T('Device')}{Lang::T('Manage')}ID
    {$ds['name_plan']}{$ds['plan_type']} {if $ds['prepaid'] != 'yes'}{Lang::T('Postpaid')}{else}{Lang::T('Prepaid')}{/if}{$ds['name_bw']}{Lang::moneyFormat($ds['price'])}{$ds['validity']} {$ds['validity_unit']}{$ds['pool']}{if $ds['plan_expired']}{Lang::T('Yes')}{else}{Lang::T('No')} + {/if}{if $ds['prepaid'] == no}{$ds['expired_date']}{/if} + {if $ds['is_radius']} + RADIUS + {else} + {if $ds['routers']!=''} + {$ds['routers']} + {/if} + {/if} + {$ds['device']} + {Lang::T('Edit')} + + {$ds['id']}
    +
    + +
    +
    +
    + +{include file="sections/footer.tpl"} From f5d9649f97e512751dbcb1eec8c1c40925c31fde Mon Sep 17 00:00:00 2001 From: AGSTR <144728914+agstrxyz@users.noreply.github.com> Date: Fri, 13 Sep 2024 00:46:40 +0700 Subject: [PATCH 2/2] Add files via upload --- system/devices/MikrotikVpn.php | 504 +++++++++++++++++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100644 system/devices/MikrotikVpn.php diff --git a/system/devices/MikrotikVpn.php b/system/devices/MikrotikVpn.php new file mode 100644 index 00000000..6edeed2c --- /dev/null +++ b/system/devices/MikrotikVpn.php @@ -0,0 +1,504 @@ + 'Mikrotik Vpn', + 'description' => 'To handle connection between PHPNuxBill with Mikrotik VPN', + 'author' => 'agstr', + 'url' => [ + 'Github' => 'https://github.com/agstrxyz', + 'Telegram' => 'https://t.me/agstrxyz', + 'Youtube' => 'https://www.youtube.com/@agstrxyz', + '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)) { + $this->addVpnUser($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('remote-address', $customer['pppoe_ip']); + }else{ + $setRequest->setArgument('remote-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); + if(isset($isChangePlan) && $isChangePlan){ + $this->removeVpnActive($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removeVpnActive($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->removeVpnActive($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removeVpnActive($client, $customer['pppoe_username']); + } + return; + } + } + $this->removeVpnUser($client, $customer['username'], $customer['id']); + if (!empty($customer['pppoe_username'])) { + $this->removeVpnUser($client, $customer['pppoe_username'], $customer['id']); + } + $this->removeVpnActive($client, $customer['username']); + if (!empty($customer['pppoe_username'])) { + $this->removeVpnActive($client, $customer['pppoe_username']); + } + } + + public function change_username($plan, $from, $to) + { + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + $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); + $this->removeVpnActive($client, $from); + } + } + + function add_plan($plan) + { + $mikrotik = $this->info($plan['routers']); + $client = $this->getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']); + + + $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 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 removeVpnUser($client, $username, $cstid) + { + 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); + $this->rmNat($client, $cstid); + } + + function addVpnUser($client, $plan, $customer) + { + $setRequest = new RouterOS\Request('/ppp/secret/add'); + $setRequest->setArgument('service', 'any'); + $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'])) { + $ips = $customer['pppoe_ip']; + $setRequest->setArgument('remote-address', $customer['pppoe_ip']); + } else { + $ips = $this->checkIpAddr($plan['pool'], $customer['id']); + $setRequest->setArgument('remote-address', $ips); + + } + $this->addNat($client, $plan, $customer, $ips); + $client->sendSync($setRequest); + $customer->service_type = 'VPN'; + $customer->pppoe_ip = $ips; + $customer->save(); + } + + function removeVpnActive($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 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) + ); + } + + function addNat($client, $plan, $cust, $ips) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $this->checkPort($cust['id'], 'Winbox', $plan['routers']); + $this->checkPort($cust['id'], 'Api', $plan['routers']); + $this->checkPort($cust['id'], 'Web', $plan['routers']); + $tcf = ORM::for_table('tbl_customers_fields') + ->where('customer_id', $cust['id']) + ->find_many(); + + foreach ($tcf as $cf) { + $dst = $cf['field_value']; + $cmnt = $cf['field_name']; + if ($cmnt == 'Winbox') { + $tp = '8291'; } + if ($cmnt == 'Web') { + $tp = '80'; } + if ($cmnt == 'Api') { + $tp = '8728'; } + if ($cmnt == 'Winbox' || $cmnt == 'Web' || $cmnt == 'Api') { + $addRequest = new RouterOS\Request('/ip/firewall/nat/add'); + $client->sendSync( + $addRequest + ->setArgument('chain', 'dstnat') + ->setArgument('protocol', 'tcp') + ->setArgument('dst-port', $dst) + ->setArgument('action', 'dst-nat') + ->setArgument('to-addresses', $ips) + ->setArgument('to-ports', $tp) + ->setArgument('address', $ip) + ->setArgument('comment', $cmnt.' || '.$cust['username']) + ); + } + } + } + + function rmNat($client, $cstid) + { + global $_app_stage; + if ($_app_stage == 'demo') { + return null; + } + $tcf = ORM::for_table('tbl_customers_fields') + ->where('customer_id', $cstid) + ->find_many(); + $cst = ORM::for_table('tbl_customers')->find_one($cstid); + $printRequest = new RouterOS\Request('/ip/firewall/nat/print'); + $printRequest->setQuery(RouterOS\Query::where('to-addresses', $cst['pppoe_ip'])); + $nats = $client->sendSync($printRequest); + foreach ($nats as $nat) { + $id = $client->sendSync($printRequest)->getProperty('.id'); + $removeRequest = new RouterOS\Request('/ip/firewall/nat/remove'); + $removeRequest->setArgument('numbers', $id); + $client->sendSync($removeRequest); + } + } + + + function checkPort($id, $portn, $router) + { + $tcf = ORM::for_table('tbl_customers_fields') + ->where('customer_id', $id) + ->where('field_name', $portn) + ->find_one(); + $ports = ORM::for_table('tbl_port_pool') + ->where('routers', $router) + ->find_one(); + $port = explode('-',$ports['range_port']); + if (empty($tcf) && !empty($ports)) { + repeat: + $portr = rand($port['0'], $port['1']); + if (ORM::for_table('tbl_customers_fields')->where('field_value', $portr)->find_one()) { + if($portr == $port['1']) + { + return; + } + goto repeat; + } + $cf = ORM::for_table('tbl_customers_fields')->create(); + $cf->customer_id = $id; + $cf->field_name = $portn; + $cf->field_value = $portr; + $cf->save(); + } + } + + function checkIpAddr($pname, $id) { + $c = ORM::for_table('tbl_customers')->find_one($id); + $ipp = ORM::for_table('tbl_pool') + ->where('pool_name', $pname) + ->find_one(); + $ip_r = explode('-',$ipp['range_ip']); + $ip_1 = explode('.',$ip_r['0']); + $ip_2 = explode('.',$ip_r['1']); + repeat: + $ipt = rand($ip_1['3'], $ip_2['3']); + $ips = $ip_1['0'].'.'.$ip_1['1'].'.'.$ip_1['2'].'.'.$ipt; + if (empty($c['pppoe_ip'])) { + if (ORM::for_table('tbl_customers')->where('pppoe_ip' ,$ips)->find_one()) { + if ($ip_2['3'] == $ipt) + { + return; + } + goto repeat; + } + return $ips; + } + } + +}