diff --git a/README.md b/README.md
index e753164f4..09717c4fb 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,8 @@ UCRM plugins are compatible with UCRM 2.10.0+
| ----------- | ------------- |
| [SMS Gateway Integration](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/sms-twilio) | Integrates Twilio SMS gateway which enables UCRM to send SMS to clients triggered by custom defined events, e.g. client's service gets suspended. |
| [QuickBooks Online](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/quickbooks-online) | Sync financial data from UCRM into QB Online |
-| [MKT Queue Sync](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/mkt-queue-sync) | Sync UCRM Service Data rate with Mikrotik Simple Queue by service IP Address and client's service speed set in UCRM |
| [FIO CZ](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/fio_cz) | Automatic payments import and matching with clients - from WISP's FIO bank account |
| [Client Signup](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/ucrm-client-signup) | Enables any visitor to register as a new client through a public web form |
-| [RouterOS packet manager](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/routeros-packet-manager) | Sync UCRM Service Data rate with Router-OS |
-| [Packetlogic packet manager](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/packetlogic-packet-manager) | Sync UCRM Entities and Service Data Rate with Procera |
| [KMZ Map](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/kmz-map) | Provides a frontend Google Map for clients to view tower coverage. |
| [Invoice CSV Export](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/invoice-csv-export) | Configurable export of invoices into CSV, can be used for a manual export to 3rd party accounting tools. |
| [Revenue Report](https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/revenue-report) | Revenue report grouped by products or services, shown under the Reporting main menu section. |
diff --git a/plugins.json b/plugins.json
index f72d35dec..affda2bb4 100644
--- a/plugins.json
+++ b/plugins.json
@@ -65,19 +65,6 @@
"author": "Charuwts, LLC",
"zipUrl": "https:\/\/github.com\/Ubiquiti-App\/UCRM-plugins\/raw\/master\/plugins\/kmz-map\/kmz-map.zip"
},
- {
- "name": "packetlogic-packet-manager",
- "displayName": "PacketLogic Packet Manager",
- "description": "UCRM Plugin that synchronizes customers with Procera Networks PacketLogic system.",
- "url": "https:\/\/github.com\/Ubiquiti-App\/UCRM-plugins\/tree\/master\/plugins\/packetlogic-packet-manager",
- "version": "1.0.3",
- "ucrmVersionCompliancy": {
- "min": "2.10.0-beta1",
- "max": "2.1.0"
- },
- "author": "Shaun Wilkinson",
- "zipUrl": "https:\/\/github.com\/Ubiquiti-App\/UCRM-plugins\/raw\/master\/plugins\/packetlogic-packet-manager\/packetlogic-packet-manager.zip"
- },
{
"name": "quickbooks-online",
"displayName": "QuickBooks Online export",
diff --git a/plugins/mkt-queue-sync/README.md b/plugins/mkt-queue-sync/README.md
deleted file mode 100644
index 1fb3d5cc0..000000000
--- a/plugins/mkt-queue-sync/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# Mikrotik Queue Sync
-
-Plugin para sincronizar velocidades configuradas en planes de servicios de UCRM a colas simples en Mikrotik.
-Plugin to do traffic shaping in Mikrotik, synchronizing UCRM service plan speed with simple queues.
-
-## ¿Como funciona?
-* Descargar e instalar el plugin. / Download and install de plugin
-* Configurar el plugin / Config the plugin
-
-## Configuraciones a realizar / Configurations to do
-## Ajustes de Plugin
-
-| Item | Descripción | Description |
-| ----------- | ------------- | ------------- |
-| Mikrotik IP Address | Direccion IP del router Mikrotik | IP address of the Mikrotik router |
-| API PORT | Solo es necesario en caso de que el Puerto API sea diferente a 8728 | Only needed when Api port is different than 8728 |
-| Mikrotik Username | Usuario del router Mikrotik | Mikrotik router username |
-| Mikrotik Password | Contrseña del router Mikrotik | Mikrotik router password |
-| Burst Limit Percentage | Porcentaje para calcular el Burst-Limit sobre el Max-Limit de cada Plan (Valores Validos 0 a 100)* | Percentage used to calc the Burst-Limit over the Max-Limit of each plan (Valid Values 0 to 100)* |
-| Burst Time | Tiempo de burst utilizado en cada cola (Valores Validos 1 a 99)* | Burst time used in each queue (Valid values 1 to 99)* |
-| Limit At % | Porcentaje para calcular el Limit-At sobre el Max-Limit de cada Plan (Valores Validos 1 a 99)* | Percentage used to calc the Limit-At over the Max-Limit of each plan (Valid Values 1 to 99)* |
-| Add Queue? | Si esta seteado se agregaran las colas al Mikrotik en caso de que las mismas no existan | If set the queues will be added to Mikrotik if they don't exist |
-| UNMS API Token | Solo necesario si se utiliza UNMS V1 o superior** | Only needed when running UNMS V1 or later** |
-
-* Los valores Burst Limit Percentage, Burst Time y Limit At %, deben ser cargados en formato UU/DD (Siendo UU el valor correspondiendo a Upload y DD el correspondiente a Download)
-Por ejemplo para limit At 20% de Subida y 50% de Bajada, la configuracion seria: 20/50
-
-* The values settings for Burst Limit Percentage, Burst Time y Limit At %, should be set in format UU/DD (Where UU is the Upload value and DD is Download)
-For example for a limit-At 20% for upload and 50% for download, setting should be: 20/50
-
-** This version handles multiple devices / Esta version puede manejar multiples dispositivos:
-* Para hacer una sincronizacion selectiva (IP xxx sincronizar con Mikrotik yyy) se debe generar un address list llamado sync_with_ucrm, conteniendo todas las ip's o rangos de IP que se desean sincronizar con este equipo.
-* To do a selective sync (IP xxx sync with Mikrotik yyy) you must create an address-list called sync_with_ucrm, which should contain the ip's or ip ranges to sync with that Mikrotik
-
-* This version could be automatically executed by webhooks, you should create a webhook with url: http://localhost/crm/_plugins/mkt-queue-sync/public.php and Webhook event type: service.edit
-* Esta version es compatible con ejecucion automatica a traves de webhooks, se debe crear un webhook con url: http://localhost/crm/_plugins/mkt-queue-sync/public.php y tipo de eventos webhook: service.edit
-
-** Existe una version PRO del complemento disponible a demanda, la cual maneja suspension, eliminacion automatica de colas/address-list relacionadas a servicios finalizados y creacion de address-list relacionadas a los planes de servicios (Solo contactame!!)
-** A PRO version of the plugin is available on demand which handles Suspend feature for multiple devices, autoremove feature to remove queues/address-list for terminated services and creation of address-list with service-plans. (Just contact me!!)
-
-** Al usar UNMS V1 o superior, se debe de crear una clave API en UNMS -> Settings -> Users, esta clave API debera ser cargada en la configuracion del plugin.
-Tambien debe ser cargada su rango de red en la seccion Network del UNMS.
-
-** When using UNMS V1 or later, it's necesary to creat an API password in UNMS -> Settings -> Users, and this passwords should be set in the plugin config.
-Also your network should be loaded in the UNMS Network section.
-
-***Si te gusto mi trabajo o te ha sido de utilidad y crees que me merezco un cafe https://www.paypal.me/fgampel***
-
-***If you like the script or it helped you out and you think I deserve a coffee https://www.paypal.me/fgampel***
-
-[Mikrotik Queue Wiki](https://wiki.mikrotik.com/wiki/Manual:Queue)
diff --git a/plugins/mkt-queue-sync/mkt-queue-sync.zip b/plugins/mkt-queue-sync/mkt-queue-sync.zip
deleted file mode 100644
index 806023d90..000000000
Binary files a/plugins/mkt-queue-sync/mkt-queue-sync.zip and /dev/null differ
diff --git a/plugins/mkt-queue-sync/src/.gitignore b/plugins/mkt-queue-sync/src/.gitignore
deleted file mode 100644
index cf5a6af97..000000000
--- a/plugins/mkt-queue-sync/src/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-vendor/
-data/
-ucrm.json
-.ucrm-plugin-running
-.ucrm-plugin-execution-requested
diff --git a/plugins/mkt-queue-sync/src/classes/Http.php b/plugins/mkt-queue-sync/src/classes/Http.php
deleted file mode 100644
index 6fedce073..000000000
--- a/plugins/mkt-queue-sync/src/classes/Http.php
+++ /dev/null
@@ -1,17 +0,0 @@
-client = $client;
- }*/
-
- public function __construct($clients)
- {
- $countConstruct = 0;
- foreach ($clients as $client) {
- //echo '
'; var_dump($client); echo '
';
- $this->client[$countConstruct] = $client;
- $countConstruct++;
- }
-
- foreach ($this->client as $test) {
- // echo ''; var_dump($test); echo '
';
- }
- }
-
- public static function create($logger, ?int $devQty): self
- {
- $config = (new PluginConfigManager())->loadConfig();
- isset($config['apiport']) ? [] : $config['apiport'] = (int) 8728;
- foreach (explode(',', $config['mktip']) as $mktIp) {
- try {
- $client[$devQty] = new Client(
- [
- 'host' => $mktIp,
- 'user' => $config['mktusr'],
- 'pass' => (string) $config['mktpass'],
- 'port' => (int) $config['apiport'],
- ]
- );
- } catch (Exception | ConfigException | ClientException $e) {
- echo '
ERROR EN LA CONEXION A MIKROTIK IP: ' . $mktIp . '
';
- echo $e->getMessage();
- //echo "
EL PROGRAMA NO CONTINUARA
";
- $logger->appendLog('ERROR EN LA CONEXION A MIKROTIK IP: ' . $mktIp);
- $logger->appendLog($e->getMessage());
- //$logger->appendLog("EL PROGRAMA NO CONTINUARA!!!");
- }
- }
-
- return new self($client);
- }
-
- public function wr(int $deviceNum, string $endpoint, $attrs = null): array
- {
- is_null($attrs) ? $response = $this->getClient($deviceNum)->wr([$endpoint]) : $response = $this->getClient($deviceNum)->wr([$endpoint, $attrs]);
- return $response;
- }
-
- public function print(int $deviceNum, string $endpoint): array
- {
- //$deviceNum = 0;
- return $this->getClient($deviceNum)->write(new Query(sprintf('%s/print', $endpoint)))->read();
- }
-
- public function remove(int $deviceNum, string $endpoint, array $ids): array
- {
- //$deviceNum = 1;
- if (! $ids) {
- return [];
- }
-
- $query = new Query(sprintf('%s/remove', $endpoint));
- foreach ($ids as $id) {
- $query->add(sprintf('=.id=%s', $id));
- $result = $this->getClient($deviceNum)->write($query)->read();
- }
- //var_dump($query);
- return $result;
- }
-
- public function add(int $deviceNum, string $endpoint, array $sentences): void
- {
- //$deviceNum = 1;
- foreach ($sentences as $sentence) {
- $sentence = array_filter($sentence);
-
- $query = new Query(sprintf('%s/add', $endpoint));
- $orders = '';
- foreach ($sentence as $key => $item) {
- $query->add(sprintf('=%s=%s', $key, $item));
- }
-
- $this->getClient($deviceNum)->write($query)->read();
- }
- }
-
- public function addAddressList(int $deviceNum, string $endpoint, array $sentences, string $commentPrefix = 'ucrm_mktsync_'): void
- {
- //$deviceNum = 1;
- foreach ($sentences as $sentence) {
- $sentence = array_filter($sentence);
-
- if (
- $commentPrefix
- && $sentence['comment'] ?? false
- ) {
- $sentence['comment'] = sprintf('%s%s', $commentPrefix, $sentence['comment']);
- }
-
- $query = new Query(sprintf('%s/add', $endpoint));
-
- foreach ($sentence as $key => $item) {
- $query->add(sprintf('=%s=%s', $key, $item));
- }
-
- $this->getClient($deviceNum)->write($query)->read();
- }
- }
-
- public function set(int $deviceNum, string $endpoint, array $sentences): void
- {
- //$deviceNum = 1;
- foreach ($sentences as $sentence) {
- $query = new Query(sprintf('%s/set', $endpoint));
- $sentence = array_filter($sentence);
-
- foreach ($sentence as $key => $item) {
- $query->add(sprintf('=%s=%s', $key, $item));
- }
-
- $this->getClient($deviceNum)->write($query)->read();
- }
- }
-
- public function getClient($deviceNum): Client
- {
- return $this->client[$deviceNum];
- }
-}
diff --git a/plugins/mkt-queue-sync/src/classes/Synchronizer.php b/plugins/mkt-queue-sync/src/classes/Synchronizer.php
deleted file mode 100644
index 7e2771ace..000000000
--- a/plugins/mkt-queue-sync/src/classes/Synchronizer.php
+++ /dev/null
@@ -1,524 +0,0 @@
-ucrmApi = UcrmApi::create();
- $this->logger = PluginLogManager::create();
- $this->pluginConfigManager = PluginConfigManager::create();
- if ((new UcrmOptionsManager())->loadOptions()->unmsLocalUrl !== null) {
- $this->unmsApi = UnmsApi::create($this->logger); //Enable only for UNMS v1
- $this->ucrmVersion = 3;
- } else {
- $this->ucrmVersion = 2; // UCRM v2
- }
- $config = (new PluginConfigManager())->loadConfig();
- $this->ip_in_range = Ip_In_Range::create();
- $this->mktDevices = 0;
- $this->routerOsApi = RouterOsApi::create($this->logger, $this->mktDevices);
- $this->sumDownloadLimitAt = $this->sumUploadLimitAt = $this->sumDownloadVendido = $this->sumUploadVendido = 0;
- $this->timeStamp = new DateTime();
- }
-
- public function sync(): void
- {
- $this->logger->appendLog('Running Plugin ' . $this->timeStamp->format('d-m-Y H:i:s'));
- $this->mktDevices = 1;
- $deviceNum = 0;
- do {
- // Retrieve UCRM Config.
- $this->optionsData = $this->pluginConfigManager->loadConfig();
- $this->debug = $this->optionsData['debugMode'];
-
- if (! $this->validateConfig($this->optionsData)[0]) {
- $this->logger->appendLog('Missing value in plugin configuration');
- foreach ($this->validateConfig($this->optionsData) as $Exception) {
- $this->logger->appendLog((string) $Exception);
- }
- throw new ConfigurationException('Missing value in plugin configuration.');
- }
-
- $this->logger->appendLog('Synchronization started');
-
- if ($this->debug) {
- $this->logger->appendLog('Mikrotik Connect Data obtained in importer');
- $this->logger->appendLog('IP:' . $this->optionsData['mktip']);
- $this->logger->appendLog('Usuario:' . $this->optionsData['mktusr']);
- $this->logger->appendLog('Password:' . $this->optionsData['mktpass']);
- }
-
- /******************************************************************************
- * SYNC SERVICES *
- ******************************************************************************/
-
- $this->servicePlans = $this->ucrmApi->get('service-plans'); //Get service Plans for Burst Management
-
- /*------------------ GET MIKROTIK ADDRESS-LIST SYNC LIST --------------------*/
- $syncList = $this->findAndFilterNetworksToSyncOnRouter($deviceNum);
-
- /*------------------------ GET MIKROTIK QUEUE LIST --------------------------*/
-
- $attrsmktQueueList = [
- 'target',
- 'max-limit',
- 'limit-at',
- 'priority',
- 'burst-limit',
- 'burst-threshold',
- 'burst-time',
- ];
-
- $mktQueueList = $this->createIndex($this->getSectionList($deviceNum, '/queue/simple', $attrsmktQueueList), $attrsmktQueueList);
-
- /*------------------------ GET UCRM SERVICES LIST --------------------------*/
-
- $this->ucrmServiceList = $this->createIndex($this->getUcrmServiceList($attrsmktQueueList), $attrsmktQueueList);
-
- /*--------------- COMPARE DIFFERENCES BETWEEN UCRM & MKT -------------------*/
-
- $remoteLocalDiffList = array_diff_key($this->ucrmServiceList, $mktQueueList);
-
- /*------------------------ GET UCRM SERVICES LIST --------------------------*/
-
- $attrsForAddOrModifyList = [
- 'target',
- ];
-
- $queueAddOrModifyList = $this->createIndex($remoteLocalDiffList, $attrsForAddOrModifyList);
-
- /*--------------------- GET ARRAY WITH QUEUES TO ADD ----------------------*/
- $queueAddList = array_diff_key($queueAddOrModifyList, $this->createIndex($this->getSectionList($deviceNum, '/queue/simple', $attrsForAddOrModifyList), $attrsForAddOrModifyList));
- if (! empty($syncList)) {
- $queueAddList = $this->filterQueueAddListWithSyncList($queueAddList, $syncList);
- }
-
- empty(! $queueAddList) ? $preparedQueueAddList = $this->prepareArrayToAdd($queueAddList) : [];
-
- (isset($preparedQueueAddList) && $this->optionsData['addQueue']) ? $this->routerOsApi->add($deviceNum, '/queue/simple', $preparedQueueAddList) : [];
-
- /*--------------------- GET ARRAY WITH QUEUES TO SET ----------------------*/
- $queueSetList = array_diff_key($queueAddOrModifyList, $queueAddList);
-
- empty(! $queueSetList) ? $preparedQueueSetList = $this->prepareArrayToSet($deviceNum, $queueSetList) : [];
-
- isset($preparedQueueSetList) ? $this->routerOsApi->set($deviceNum, '/queue/simple', $preparedQueueSetList) : [];
-
- /******************************************************************************
- * FINAL OF THE CODE *
- ******************************************************************************/
-
- $this->logger->appendLog('Synchronization correctly ended / Sincronizado Correctamente');
- $this->logger->appendLog(sprintf('Sumatoria de Download LimitAt: %s', $this->formatSpeedForStats($this->sumDownloadLimitAt)));
- $this->logger->appendLog(sprintf('Sumatoria de Upload LimitAt: %s', $this->formatSpeedForStats($this->sumUploadLimitAt)));
- $this->logger->appendLog(sprintf('Sumatoria de DownloadVendido: %s', $this->formatSpeedForStats($this->sumDownloadVendido)));
- $this->logger->appendLog(sprintf('Sumatoria de UploadVendido: %s', $this->formatSpeedForStats($this->sumUploadVendido)));
-
- //Incremet to move on the next device (If exists)
- $deviceNum++;
- } while ($deviceNum < $this->mktDevices);
- }
-
- private function getUcrmServiceList($attrs): array
- {
- $ucrmServiceList = $this->ucrmApi->get('clients/services', [
- 'statuses[0]' => 1,
- 'statuses[1]' => 0,
- 'statuses[2]' => 3,
- 'statuses[3]' => 4,
- 'statuses[4]' => 6,
- ]);
- $ucrmServiceList = $this->formatUcrmListIpAddress($ucrmServiceList);
- $ucrmServiceList = $this->formatUcrmListMaxLimit($ucrmServiceList);
- $ucrmServiceList = $this->formatUcrmListLimitAt($ucrmServiceList);
- $ucrmServiceList = $this->formatUcrmListPriority($ucrmServiceList);
- $ucrmServiceList = $this->formatUcrmListBurstLimit($ucrmServiceList);
- $ucrmServiceList = $this->formatUcrmListBurstThreshold($ucrmServiceList);
- $ucrmServiceList = $this->formatUcrmListBurstTime($ucrmServiceList);
-
- return $ucrmServiceList;
- }
-
- private function formatUcrmListIpAddress($ucrmServiceList): array
- {
- if ($this->ucrmVersion == 2) { //IF UCRM V2
- foreach ($ucrmServiceList as $ucrmService) {
- if (isset($ucrmService['ipRanges'][0])) {
- (strpos($ucrmService['ipRanges'][0], '/')) ? $ucrmService['target'] = $ucrmService['address'] = $ucrmService['ipRanges'][0] : $ucrmService['target'] = $ucrmService['address'] = $ucrmService['ipRanges'][0] . '/32';
- $ucrmFormatedList[] = $ucrmService;
- } else {
- $this->logger->appendLog('Service ID: ' . $ucrmService['id'] . ' has no ip address set');
- }
- }
- return $ucrmFormatedList;
- } // IF UCRM V3 - UNMS V1
- foreach ($ucrmServiceList as $ucrmService) {
- if (isset($ucrmService['unmsClientSiteId'])) {
- $clientSiteIps = $this->unmsApi->get(
- 'devices/ips',
- [
- 'siteId' => $ucrmService['unmsClientSiteId'],
- ]
- );
- if (isset($clientSiteIps[0])) {
- (strpos($clientSiteIps[0], '/')) ? $ucrmService['target'] = $ucrmService['address'] = $clientSiteIps[0] : $ucrmService['target'] = $ucrmService['address'] = $clientSiteIps[0] . '/32';
- $ucrmFormatedList[] = $ucrmService;
- } else {
- $this->logger->appendLog('Service ID: ' . $ucrmService['id'] . ' has no ip address set');
- }
- }
- }
- return $ucrmFormatedList;
- }
-
- private function formatUcrmListMaxLimit($ucrmServiceList): array
- {
- foreach ($ucrmServiceList as $ucrmService) {
- $ucrmService['max-limit'] = $this->formatSpeedForMikrotik(($ucrmService['uploadSpeed'])) . '/' . $this->formatSpeedForMikrotik(($ucrmService['downloadSpeed']));
- $this->sumUploadVendido += $this->formatSpeedForMikrotik(($ucrmService['uploadSpeed']));
- $this->sumDownloadVendido += $this->formatSpeedForMikrotik(($ucrmService['downloadSpeed']));
- $ucrmFormatedList[] = $ucrmService;
- }
- return $ucrmFormatedList;
- }
-
- private function formatUcrmListLimitAt($ucrmServiceList): array
- {
- $limitAtPercentages = explode('/', $this->optionsData['limitAtPercentage']);
- foreach ($ucrmServiceList as $ucrmService) {
- $ucrmService['limit-at'] = $this->formatSpeedForMikrotik(($ucrmService['uploadSpeed'])) * $limitAtPercentages[0] / 100 . '/' . $this->formatSpeedForMikrotik(($ucrmService['downloadSpeed'])) * $limitAtPercentages[1] / 100;
- $this->sumUploadLimitAt += $this->formatSpeedForMikrotik(($ucrmService['uploadSpeed'])) * $limitAtPercentages[0] / 100;
- $this->sumDownloadLimitAt += $this->formatSpeedForMikrotik(($ucrmService['downloadSpeed'])) * $limitAtPercentages[1] / 100;
- $ucrmFormatedList[] = $ucrmService;
- }
- return $ucrmFormatedList;
- }
-
- private function formatUcrmListPriority($ucrmServiceList): array
- {
- foreach ($ucrmServiceList as $ucrmService) {
- (isset($this->servicePlans[array_search($ucrmService['servicePlanId'], array_column($this->servicePlans, 'id'))]['dataUsageLimit'])) ? $priority = $this->servicePlans[array_search($ucrmService['servicePlanId'], array_column($this->servicePlans, 'id'))]['dataUsageLimit'] : $priority = 8; //Using Service DataUsageLimit as Priority
- if ($priority < 1 || $priority > 8) {
- $priority = '8';
- }
- $ucrmService['priority'] = $priority . '/' . $priority;
- $ucrmFormatedList[] = $ucrmService;
- }
- return $ucrmFormatedList;
- }
-
- private function formatUcrmListBurstLimit($ucrmServiceList): array
- {
- $burstLimit = explode('/', $this->optionsData['burstLimitPercentage']);
- foreach ($ucrmServiceList as $ucrmService) {
- $ucrmService['burst-limit'] = $this->formatSpeedForMikrotik($ucrmService['uploadSpeed'] + ($ucrmService['uploadSpeed'] * $burstLimit[0] / 100)) . '/' . $this->formatSpeedForMikrotik($ucrmService['downloadSpeed'] + ($ucrmService['downloadSpeed'] * $burstLimit[1] / 100));
- $ucrmFormatedList[] = $ucrmService;
- }
- return $ucrmFormatedList;
- }
-
- private function formatUcrmListBurstThreshold($ucrmServiceList): array
- {
- foreach ($ucrmServiceList as $ucrmService) {
- (isset($this->servicePlans[array_search($ucrmService['servicePlanId'], array_column($this->servicePlans, 'id'))]['uploadBurst'])) ? $uploadBurstThreshold = $this->formatSpeedForMikrotikBurst($this->servicePlans[array_search($ucrmService['servicePlanId'], array_column($this->servicePlans, 'id'))]['uploadBurst']) : $uploadBurstThreshold = 0;
- (isset($this->servicePlans[array_search($ucrmService['servicePlanId'], array_column($this->servicePlans, 'id'))]['downloadBurst'])) ? $downloadBurstThreshold = $this->formatSpeedForMikrotikBurst($this->servicePlans[array_search($ucrmService['servicePlanId'], array_column($this->servicePlans, 'id'))]['downloadBurst']) : $downloadBurstThreshold = 0;
- $ucrmService['burst-threshold'] = $uploadBurstThreshold . '/' . $downloadBurstThreshold;
- $ucrmFormatedList[] = $ucrmService;
- }
- return $ucrmFormatedList;
- }
-
- private function formatUcrmListBurstTime($ucrmServiceList): array
- {
- $burstTime = explode('/', $this->optionsData['burstTime']);
- foreach ($ucrmServiceList as $ucrmService) {
- $ucrmService['burst-time'] = $burstTime[0] . 's' . '/' . $burstTime[1] . 's';
- $ucrmFormatedList[] = $ucrmService;
- }
- return $ucrmFormatedList;
- }
-
- private function prepareArrayToAdd($addList): array
- {
- $attrs = [
- 'target',
- 'max-limit',
- 'limit-at',
- 'priority',
- 'burst-limit',
- 'burst-threshold',
- 'burst-time',
- ];
-
- foreach ($addList as $addListRow) {
- $toAddRow['name'] = $this->getQueueNameFromUcrm($addListRow['clientId'], $addListRow['id']);
- foreach ($attrs as $attribute) {
- $toAddRow[$attribute] = $addListRow[$attribute];
- }
- $readyToAddList[] = $toAddRow;
- }
- return $readyToAddList;
- }
-
- private function prepareArrayToSet($deviceNum, $setList): array
- {
- $attrs = [
- 'max-limit',
- 'limit-at',
- 'priority',
- 'burst-limit',
- 'burst-threshold',
- 'burst-time',
- ];
-
- foreach ($setList as $setListRow) {
- $toSetRow['.id'] = $this->getQueueId($deviceNum, $setListRow['target']);
- $toSetRow['name'] = $this->getQueueNameFromUcrm($setListRow['clientId'], $setListRow['id']);
- foreach ($attrs as $attribute) {
- $toSetRow[$attribute] = $setListRow[$attribute];
- }
- $readyToSetList[] = $toSetRow;
- }
- return $readyToSetList;
- }
-
- private function formatSpeedForMikrotik(float $speed): string
- {
- $speed = $speed * 1000000; //MB to bytes
- return strval($speed);
- }
-
- private function formatSpeedForMikrotikBurst(float $speed): string
- {
- $speed = $speed * 1000; //KB to bytes
- return strval($speed);
- }
-
- private function formatSpeedForStats(float $speed): string
- {
- $speed = round($speed, 0);
- $count = 0;
- while ($speed > 1000) {
- $speed = $speed / 1000;
- $count++;
- }
- switch ($count) {
- case 0:
- return strval($speed) . 'B';
- case 1:
- return strval($speed) . 'KB';
- case 2:
- return strval($speed) . 'MB';
- case 3:
- return strval($speed) . 'GB';
- case 4:
- return strval($speed) . 'TB';
- default:
- return strval($speed) . ' ¿¿¿WTF???';
- }
- }
-
- private function createIndex(array $arr, array $attrs): array
- {
- $index = [];
- foreach ($arr as $row) {
- $key = $this->createIndexKey($row, $attrs);
- $index[$key] = $row;
- }
-
- return $index;
- }
-
- private function createIndexKey(array $item, array $attrs): string
- {
- $res = '';
- foreach ($attrs as $attr) {
- $res .= '_' . (array_key_exists($attr, $item) ? $item[$attr] : '');
- }
-
- return $res;
- }
-
- private function getSectionList(int $devNumber, string $section, array $attributes): array
- {
- $data = $this->getRawSectionList($devNumber, $section, $attributes);
-
- $filtered = [];
- foreach ($data as $row) {
- $filtered[] = $row;
- }
- return $filtered;
- }
-
- private function getRawSectionList(int $devNumber, string $section, array $attributes = []): array
- {
- $result = $this->routerOsApi->print(
- $devNumber,
- $section,
- empty($attributes) ? [] : [
- '.proplist' => sprintf('.id,%s', implode(',', $attributes)),
- ]
- );
-
- return is_array($result) ? $result : [];
- }
-
- private function getQueueId(int $deviceNum, string $ipAddress): string
- {
- $result = $this->routerOsApi->wr(
- $deviceNum,
- '/queue/simple/print',
- '?target=' . $ipAddress
- );
- if (empty($result)) {
- return 'NaN';
- }
- return is_string($result[0]['.id']) ? $result[0]['.id'] : [];
- }
-
- private function getQueueNameFromUcrm(int $clientId, int $ucrmServiceId): string
- {
- $clientInfo = $this->ucrmApi->get(sprintf('clients/%s', $clientId));
- if ($clientInfo['clientType'] == 1) {
- $queueName = $clientInfo['firstName'] . ' ' . $clientInfo['lastName'] . ' - Service ID:' . $ucrmServiceId;
- } elseif ($clientInfo['clientType'] == 2) {
- $queueName = $clientInfo['companyName'] . ' - Service ID: ' . $ucrmServiceId;
- } else {
- $queueName = 'Service ID: ' . $ucrmServiceId;
- }
- return $queueName;
- }
-
- private function validateConfig(array $config): array
- {
- $valid = [];
- $valid[0] = false;
-
- if (preg_match('/^\d{1,2}\W\d{1,2}\z/', $config['burstLimitPercentage'])) {
- if (explode('/', $config['burstLimitPercentage'])[0] < 100 && explode('/', $config['burstLimitPercentage'])[0] >= 0 && explode('/', $config['burstLimitPercentage'])[1] < 100 && explode('/', $config['burstLimitPercentage'])[1] >= 0) {
- $valid[0] = true;
- } else {
- $valid[0] = false;
- $valid[] = 'Burst Limit Percentage should be set between 0 and 99';
- }
- } else {
- $valid[0] = false;
- $valid[] = 'Burst Limit Percentage should be set in format UU/DD, U= Upload percentage, D= Download percentage';
- }
-
- if ($valid[0]) {
- if (preg_match('/^\d{1,2}\W\d{1,2}\z/', $config['burstTime'])) {
- if (explode('/', $config['burstTime'])[0] < 100 && explode('/', $config['burstTime'])[0] > 0 && explode('/', $config['burstTime'])[1] < 100 && explode('/', $config['burstTime'])[1] > 0) {
- if (explode('/', $config['burstTime'])[0] == 0 && explode('/', $config['burstLimitPercentage'])[0] != 0) {
- $valid[0] = false;
- $valid[] = ' Upload Burst Time can\'t be 0 if Upload Burst Limit is configured';
- }
- if (explode('/', $config['burstTime'])[1] == 0 && explode('/', $config['burstLimitPercentage'])[1] != 0) {
- $valid[0] = false;
- $valid[] = ' Download Burst Time can\'t be 0 if Download Burst Limit is configured';
- }
- } else {
- $valid[0] = false;
- $valid[] = 'Burst Time should be set between 1 and 99';
- }
- } else {
- $valid[0] = false;
- $valid[] = 'Burst Time should be set in format UU/DD, U= Upload Burst time, D= Download Burst time';
- }
- }
-
- if ($valid[0]) {
- if (preg_match('/^\d{1,2}\W\d{1,2}\z/', $config['limitAtPercentage'])) {
- if (explode('/', $config['limitAtPercentage'])[0] < 100 && explode('/', $config['limitAtPercentage'])[0] >= 0 && explode('/', $config['limitAtPercentage'])[1] < 100 && explode('/', $config['limitAtPercentage'])[1] >= 0) {
- } else {
- $valid[0] = false;
- $valid[] = 'LimitAt percentage should be set between 1 and 99';
- }
- } else {
- $valid[0] = false;
- $valid[] = 'LimitAt should be set in format UU/DD, U= Upload LimitAt percentage, D= Download LimitAt percentage time';
- }
- }
-
- return $valid;
- }
-
- private function findAndFilterNetworksToSyncOnRouter(int $deviceNum): array
- {
- $filtered = [];
- foreach ($this->routerOsApi->print($deviceNum, '/ip/firewall/address-list') as $address) {
- if (
- array_key_exists('list', $address)
- && Strings::startsWith($address['list'], 'sync_with_ucrm')
- ) {
- $filtered[] = $address['address'];
- }
- }
- return $filtered;
- }
-
- private function filterQueueAddListWithSyncList(array $queueToAdd, array $syncList): array
- {
- $filtered = [];
- foreach ($syncList as $syncRange) {
- (strpos($syncRange, '/')) ? [] : $syncRange = $syncRange . '/32';
- foreach ($queueToAdd as $queue) {
- if ($this->ip_in_range->ip_in_range(substr($queue['address'], 0, -3), $syncRange)) {
- $filtered[] = $queue;
- }
- }
- }
- return $filtered;
- }
-}
diff --git a/plugins/mkt-queue-sync/src/classes/UnmsApi.php b/plugins/mkt-queue-sync/src/classes/UnmsApi.php
deleted file mode 100644
index 9dd489bb5..000000000
--- a/plugins/mkt-queue-sync/src/classes/UnmsApi.php
+++ /dev/null
@@ -1,95 +0,0 @@
-client = $client;
- $this->token = $token;
- }
-
- public static function create($logger): self
- {
- $options = (new UcrmOptionsManager())->loadOptions();
-
- $unmsUrl = ($options->unmsLocalUrl ?: $options->ucrmPublicUrl) ?? '';
- if (! $unmsUrl) {
- throw new ConfigurationException('UCRM URL is missing in plugin configuration.');
- }
-
- $config = (new PluginConfigManager())->loadConfig();
- if (! ($config['unmsApiToken'] ?? false)) {
- $logger->appendLog('UNMS API token is missing in plugin configuration.');
- throw new ConfigurationException('UNMS API token is missing in plugin configuration.');
- }
-
- $unmsApiUrl = sprintf('%s/api/v2.1/', rtrim(str_replace('crm/', 'nms/', $unmsUrl), '/'));
-
- $client = new Client(
- [
- 'base_uri' => $unmsApiUrl,
- // If the URL is localhost over HTTPS, do not verify SSL certificate.
- 'verify' => $options->unmsLocalUrl !== null
- ? false
- : ! Helpers::isUrlSecureLocalhost($unmsApiUrl),
- ]
- );
-
- return new self($client, $config['unmsApiToken']);
- }
-
- public function get(string $endpoint, array $query = []): array
- {
- $response = $this->request(
- 'GET',
- $endpoint,
- [
- 'query' => $query,
- ]
- );
-
- return Json::decode((string) $response->getBody());
- }
-
- private function request(string $method, string $endpoint, array $options = []): Response
- {
- return $this->client->request(
- $method,
- // strip slash character from beginning of endpoint to make sure base API URL is included correctly
- ltrim($endpoint, '/'),
- array_merge(
- $options,
- [
- 'headers' => [
- self::HEADER_AUTH_TOKEN => $this->token,
- ],
- ]
- )
- );
- }
-}
diff --git a/plugins/mkt-queue-sync/src/classes/ip_in_range.php b/plugins/mkt-queue-sync/src/classes/ip_in_range.php
deleted file mode 100644
index d66adb50f..000000000
--- a/plugins/mkt-queue-sync/src/classes/ip_in_range.php
+++ /dev/null
@@ -1,111 +0,0 @@
-
- * 10 January 2008
- * Version: 1.2
- *
- * Source website: http://www.pgregg.com/projects/php/ip_in_range/
- * Version 1.2
- *
- * This software is Donationware - if you feel you have benefited from
- * the use of this tool then please consider a donation. The value of
- * which is entirely left up to your discretion.
- * http://www.pgregg.com/donate/
- *
- * Please do not remove this header, or source attibution from this file.
- */
-
- // decbin32
- // In order to simplify working with IP addresses (in binary) and their
- // netmasks, it is easier to ensure that the binary strings are padded
- // with zeros out to 32 characters - IP addresses are 32 bit numbers
- public function decbin32($dec)
- {
- return str_pad(decbin($dec), 32, '0', STR_PAD_LEFT);
- }
-
- // ip_in_range
- // This function takes 2 arguments, an IP address and a "range" in several
- // different formats.
- // Network ranges can be specified as:
- // 1. Wildcard format: 1.2.3.*
- // 2. CIDR format: 1.2.3/24 OR 1.2.3.4/255.255.255.0
- // 3. Start-End IP format: 1.2.3.0-1.2.3.255
- // The function will return true if the supplied IP is within the range.
- // Note little validation is done on the range inputs - it expects you to
- // use one of the above 3 formats.
- public function ip_in_range($ip, $range)
- {
- if (strpos($range, '/') !== false) {
- // $range is in IP/NETMASK format
- list($range, $netmask) = explode('/', $range, 2);
- if (strpos($netmask, '.') !== false) {
- // $netmask is a 255.255.0.0 format
- $netmask = str_replace('*', '0', $netmask);
- $netmask_dec = ip2long($netmask);
- return ((ip2long($ip) & $netmask_dec) == (ip2long($range) & $netmask_dec));
- }
- // $netmask is a CIDR size block
- // fix the range argument
- $x = explode('.', $range);
- while (count($x) < 4) {
- $x[] = '0';
- }
- list($a, $b, $c, $d) = $x;
- $range = sprintf('%u.%u.%u.%u', empty($a) ? '0' : $a, empty($b) ? '0' : $b, empty($c) ? '0' : $c, empty($d) ? '0' : $d);
- $range_dec = ip2long($range);
- $ip_dec = ip2long($ip);
-
- # Strategy 1 - Create the netmask with 'netmask' 1s and then fill it to 32 with 0s
- #$netmask_dec = bindec(str_pad('', $netmask, '1') . str_pad('', 32-$netmask, '0'));
-
- # Strategy 2 - Use math to create it
- $wildcard_dec = pow(2, (32 - $netmask)) - 1;
- $netmask_dec = ~$wildcard_dec;
-
- return (($ip_dec & $netmask_dec) == ($range_dec & $netmask_dec));
- }
- // range might be 255.255.*.* or 1.2.3.0-1.2.3.255
- if (strpos($range, '*') !== false) { // a.b.*.* format
- // Just convert to A-B format by setting * to 0 for A and 255 for B
- $lower = str_replace('*', '0', $range);
- $upper = str_replace('*', '255', $range);
- $range = "${lower}-${upper}";
- }
-
- if (strpos($range, '-') !== false) { // A-B format
- list($lower, $upper) = explode('-', $range, 2);
- $lower_dec = (float) sprintf('%u', ip2long($lower));
- $upper_dec = (float) sprintf('%u', ip2long($upper));
- $ip_dec = (float) sprintf('%u', ip2long($ip));
- return (($ip_dec >= $lower_dec) && ($ip_dec <= $upper_dec));
- }
-
- echo 'Range argument is not in 1.2.3.4/24 or 1.2.3.4/255.255.255.0 format';
- return false;
- }
-}
diff --git a/plugins/mkt-queue-sync/src/composer.json b/plugins/mkt-queue-sync/src/composer.json
deleted file mode 100644
index af674e5fd..000000000
--- a/plugins/mkt-queue-sync/src/composer.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "description": "UCRM plugin for sync service data rate with Mikrotik Simple Queue",
- "license": "MIT",
- "autoload": {
- "psr-4": {
- "MikrotikQueueSync\\": [
- "classes/"
- ]
- }
- },
- "repositories":[
- {
- "type": "vcs",
- "url": "https://github.com/BenMenking/routeros-api"
- }
- ],
- "require": {
- "ubnt/ucrm-plugin-sdk": "^0.9",
- "nette/utils": "^4.0",
- "evilfreelancer/routeros-api-php": "^1.5"
- }
-}
diff --git a/plugins/mkt-queue-sync/src/composer.lock b/plugins/mkt-queue-sync/src/composer.lock
deleted file mode 100644
index 4814a03d9..000000000
--- a/plugins/mkt-queue-sync/src/composer.lock
+++ /dev/null
@@ -1,1206 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
- "This file is @generated automatically"
- ],
- "content-hash": "229bc2f47043d1b823ffb92f5c8fab43",
- "packages": [
- {
- "name": "evilfreelancer/routeros-api-php",
- "version": "1.5.0",
- "source": {
- "type": "git",
- "url": "https://github.com/EvilFreelancer/routeros-api-php.git",
- "reference": "19d98d72f19067dacf3b7babf66192c5bc2998f4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/EvilFreelancer/routeros-api-php/zipball/19d98d72f19067dacf3b7babf66192c5bc2998f4",
- "reference": "19d98d72f19067dacf3b7babf66192c5bc2998f4",
- "shasum": ""
- },
- "require": {
- "ext-sockets": "*",
- "php": "^7.4|^8.0",
- "spatie/ssh": "^1.8"
- },
- "require-dev": {
- "friendsofphp/php-cs-fixer": "^2.16",
- "larapack/dd": "^1.1",
- "limedeck/phpunit-detailed-printer": "^5.0",
- "orchestra/testbench": "^4.0|^5.0",
- "phpunit/phpunit": "^8.0",
- "rector/rector": "^0.7|^0.8|^0.9",
- "roave/security-advisories": "dev-master",
- "squizlabs/php_codesniffer": "^3.5"
- },
- "type": "library",
- "extra": {
- "laravel": {
- "providers": [
- "RouterOS\\Laravel\\ServiceProvider"
- ],
- "aliases": {
- "RouterOS": "RouterOS\\Laravel\\Facade"
- }
- }
- },
- "autoload": {
- "psr-4": {
- "RouterOS\\": "./src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Paul Rock",
- "email": "paul@drteam.rocks",
- "homepage": "http://drteam.rocks/",
- "role": "Developer"
- }
- ],
- "description": "Modern Mikrotik RouterOS API PHP client for your applications (with Laravel support)",
- "keywords": [
- "PSR-4",
- "facade",
- "laravel",
- "mikrotik",
- "plugin",
- "routeros",
- "socket-client"
- ],
- "support": {
- "issues": "https://github.com/EvilFreelancer/routeros-api-php/issues",
- "source": "https://github.com/EvilFreelancer/routeros-api-php/tree/1.5.0"
- },
- "funding": [
- {
- "url": "https://streamlabs.com/evilfreelancer/tip",
- "type": "custom"
- },
- {
- "url": "https://www.donationalerts.com/r/evilfreelancer",
- "type": "custom"
- },
- {
- "url": "https://ko-fi.com/efreelancer",
- "type": "ko_fi"
- },
- {
- "url": "https://www.patreon.com/efreelancer",
- "type": "patreon"
- }
- ],
- "time": "2022-12-25T20:05:43+00:00"
- },
- {
- "name": "guzzlehttp/guzzle",
- "version": "7.5.0",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba",
- "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "guzzlehttp/promises": "^1.5",
- "guzzlehttp/psr7": "^1.9 || ^2.4",
- "php": "^7.2.5 || ^8.0",
- "psr/http-client": "^1.0",
- "symfony/deprecation-contracts": "^2.2 || ^3.0"
- },
- "provide": {
- "psr/http-client-implementation": "1.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "ext-curl": "*",
- "php-http/client-integration-tests": "^3.0",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23",
- "psr/log": "^1.1 || ^2.0 || ^3.0"
- },
- "suggest": {
- "ext-curl": "Required for CURL handler support",
- "ext-intl": "Required for Internationalized Domain Name (IDN) support",
- "psr/log": "Required for using the Log middleware"
- },
- "type": "library",
- "extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
- },
- "branch-alias": {
- "dev-master": "7.5-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Jeremy Lindblom",
- "email": "jeremeamia@gmail.com",
- "homepage": "https://github.com/jeremeamia"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "Guzzle is a PHP HTTP client library",
- "keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "psr-18",
- "psr-7",
- "rest",
- "web service"
- ],
- "support": {
- "issues": "https://github.com/guzzle/guzzle/issues",
- "source": "https://github.com/guzzle/guzzle/tree/7.5.0"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
- "type": "tidelift"
- }
- ],
- "time": "2022-08-28T15:39:27+00:00"
- },
- {
- "name": "guzzlehttp/promises",
- "version": "1.5.2",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "b94b2807d85443f9719887892882d0329d1e2598"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
- "reference": "b94b2807d85443f9719887892882d0329d1e2598",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "^4.4 || ^5.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.5-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "Guzzle promises library",
- "keywords": [
- "promise"
- ],
- "support": {
- "issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/1.5.2"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
- "type": "tidelift"
- }
- ],
- "time": "2022-08-28T14:55:35+00:00"
- },
- {
- "name": "guzzlehttp/psr7",
- "version": "2.4.4",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
- "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5 || ^8.0",
- "psr/http-factory": "^1.0",
- "psr/http-message": "^1.0",
- "ralouphie/getallheaders": "^3.0"
- },
- "provide": {
- "psr/http-factory-implementation": "1.0",
- "psr/http-message-implementation": "1.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "http-interop/http-factory-tests": "^0.9",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23"
- },
- "suggest": {
- "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
- },
- "type": "library",
- "extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
- },
- "branch-alias": {
- "dev-master": "2.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://sagikazarmark.hu"
- }
- ],
- "description": "PSR-7 message implementation that also provides common utility methods",
- "keywords": [
- "http",
- "message",
- "psr-7",
- "request",
- "response",
- "stream",
- "uri",
- "url"
- ],
- "support": {
- "issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.4.4"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-09T13:19:02+00:00"
- },
- {
- "name": "nette/utils",
- "version": "v4.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/nette/utils.git",
- "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e",
- "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e",
- "shasum": ""
- },
- "require": {
- "php": ">=8.0 <8.3"
- },
- "conflict": {
- "nette/finder": "<3",
- "nette/schema": "<1.2.2"
- },
- "require-dev": {
- "jetbrains/phpstorm-attributes": "dev-master",
- "nette/tester": "^2.4",
- "phpstan/phpstan": "^1.0",
- "tracy/tracy": "^2.9"
- },
- "suggest": {
- "ext-gd": "to use Image",
- "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
- "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
- "ext-json": "to use Nette\\Utils\\Json",
- "ext-mbstring": "to use Strings::lower() etc...",
- "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
- "ext-xml": "to use Strings::length() etc. when mbstring is not available"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause",
- "GPL-2.0-only",
- "GPL-3.0-only"
- ],
- "authors": [
- {
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
- {
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
- }
- ],
- "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
- "homepage": "https://nette.org",
- "keywords": [
- "array",
- "core",
- "datetime",
- "images",
- "json",
- "nette",
- "paginator",
- "password",
- "slugify",
- "string",
- "unicode",
- "utf-8",
- "utility",
- "validation"
- ],
- "support": {
- "issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.0"
- },
- "time": "2023-02-02T10:41:53+00:00"
- },
- {
- "name": "psr/http-client",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-client.git",
- "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
- "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
- "shasum": ""
- },
- "require": {
- "php": "^7.0 || ^8.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Client\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP clients",
- "homepage": "https://github.com/php-fig/http-client",
- "keywords": [
- "http",
- "http-client",
- "psr",
- "psr-18"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-client/tree/master"
- },
- "time": "2020-06-29T06:28:15+00:00"
- },
- {
- "name": "psr/http-factory",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-factory.git",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interfaces for PSR-7 HTTP message factories",
- "keywords": [
- "factory",
- "http",
- "message",
- "psr",
- "psr-17",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-factory/tree/master"
- },
- "time": "2019-04-30T12:38:16+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-message/tree/master"
- },
- "time": "2016-08-06T14:39:51+00:00"
- },
- {
- "name": "ralouphie/getallheaders",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/ralouphie/getallheaders.git",
- "reference": "120b605dfeb996808c31b6477290a714d356e822"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
- "reference": "120b605dfeb996808c31b6477290a714d356e822",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "require-dev": {
- "php-coveralls/php-coveralls": "^2.1",
- "phpunit/phpunit": "^5 || ^6.5"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/getallheaders.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ralph Khattar",
- "email": "ralph.khattar@gmail.com"
- }
- ],
- "description": "A polyfill for getallheaders.",
- "support": {
- "issues": "https://github.com/ralouphie/getallheaders/issues",
- "source": "https://github.com/ralouphie/getallheaders/tree/develop"
- },
- "time": "2019-03-08T08:55:37+00:00"
- },
- {
- "name": "spatie/ssh",
- "version": "1.8.2",
- "source": {
- "type": "git",
- "url": "https://github.com/spatie/ssh.git",
- "reference": "d3576bea064dddb512daee9884eb01daaf8df9dd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/spatie/ssh/zipball/d3576bea064dddb512daee9884eb01daaf8df9dd",
- "reference": "d3576bea064dddb512daee9884eb01daaf8df9dd",
- "shasum": ""
- },
- "require": {
- "php": "^7.4|^8.0",
- "symfony/process": "^4.4|^5.3|^6.0"
- },
- "require-dev": {
- "pestphp/pest": "^1.22",
- "spatie/pest-plugin-snapshots": "^1.1",
- "symfony/var-dumper": "^5.3|6.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Spatie\\Ssh\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Freek Van der Herten",
- "email": "freek@spatie.be",
- "homepage": "https://spatie.be",
- "role": "Developer"
- }
- ],
- "description": "A lightweight package to execute commands over an SSH connection",
- "homepage": "https://github.com/spatie/ssh",
- "keywords": [
- "spatie",
- "ssh"
- ],
- "support": {
- "issues": "https://github.com/spatie/ssh/issues",
- "source": "https://github.com/spatie/ssh/tree/1.8.2"
- },
- "funding": [
- {
- "url": "https://spatie.be/open-source/support-us",
- "type": "custom"
- }
- ],
- "time": "2023-01-17T16:49:02+00:00"
- },
- {
- "name": "symfony/deprecation-contracts",
- "version": "v3.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.3-dev"
- },
- "thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
- }
- },
- "autoload": {
- "files": [
- "function.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "A generic function and convention to trigger deprecation notices",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-01T10:25:55+00:00"
- },
- {
- "name": "symfony/filesystem",
- "version": "v6.2.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "82b6c62b959f642d000456f08c6d219d749215b3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3",
- "reference": "82b6c62b959f642d000456f08c6d219d749215b3",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-mbstring": "~1.8"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Provides basic utilities for the filesystem",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.2.7"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-02-14T08:44:56+00:00"
- },
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.27.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "provide": {
- "ext-ctype": "*"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-11-03T14:55:06+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "v1.27.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "provide": {
- "ext-mbstring": "*"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-11-03T14:55:06+00:00"
- },
- {
- "name": "symfony/process",
- "version": "v6.2.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
- "reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Process\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Executes commands in sub-processes",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/process/tree/v6.2.7"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-02-24T10:42:00+00:00"
- },
- {
- "name": "ubnt/ucrm-plugin-sdk",
- "version": "0.9.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK.git",
- "reference": "02ca1d4ce7fca1bc7f49ef0259a03d0bfedec19f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Ubiquiti-App/UCRM-Plugin-SDK/zipball/02ca1d4ce7fca1bc7f49ef0259a03d0bfedec19f",
- "reference": "02ca1d4ce7fca1bc7f49ef0259a03d0bfedec19f",
- "shasum": ""
- },
- "require": {
- "ext-curl": "*",
- "ext-json": "*",
- "guzzlehttp/guzzle": "^7.5",
- "php": ">=8.1",
- "symfony/filesystem": "^6.2"
- },
- "require-dev": {
- "eloquent/phony-phpunit": "^7.1",
- "eloquent/phpstan-phony": "^0.8.0",
- "ocramius/package-versions": "^2.7",
- "php-coveralls/php-coveralls": "^2.5",
- "phpstan/phpstan": "^1.10",
- "phpstan/phpstan-strict-rules": "^1.2",
- "phpunit/phpunit": "^9.5",
- "symplify/easy-coding-standard": "^10.2"
- },
- "suggest": {
- "ext-zip": "Needed for pack-plugin script."
- },
- "bin": [
- "bin/pack-plugin"
- ],
- "type": "library",
- "autoload": {
- "psr-4": {
- "Ubnt\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "UCRM plugin SDK",
- "homepage": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK",
- "keywords": [
- "sdk",
- "ucrm"
- ],
- "support": {
- "issues": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK/issues",
- "source": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK/tree/0.9.0"
- },
- "time": "2023-03-10T13:26:40+00:00"
- }
- ],
- "packages-dev": [],
- "aliases": [],
- "minimum-stability": "stable",
- "stability-flags": [],
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": [],
- "platform-dev": [],
- "plugin-api-version": "2.3.0"
-}
diff --git a/plugins/mkt-queue-sync/src/main.php b/plugins/mkt-queue-sync/src/main.php
deleted file mode 100644
index 79c76a96c..000000000
--- a/plugins/mkt-queue-sync/src/main.php
+++ /dev/null
@@ -1,13 +0,0 @@
-sync();
-})();
-http_response_code(200); //Response OK when it's called by a webhook.
diff --git a/plugins/mkt-queue-sync/src/manifest.json b/plugins/mkt-queue-sync/src/manifest.json
deleted file mode 100644
index b9f4165ef..000000000
--- a/plugins/mkt-queue-sync/src/manifest.json
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "version": "1",
- "information": {
- "name": "mkt-queue-sync",
- "displayName": "Mikrotik Queue Sync Plugin",
- "description": "Plugin para sincronizar simple queues con los limites de velocidad establecidos en Ucrm - Very basic plugin based on a Ubiquiti plugin, to synchronize Ucrm Services with Miktotik Simple Queue https://wiki.mikrotik.com/wiki/Manual:Queue",
- "url": "https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/mkt-queue-sync",
- "version": "2.4.0",
- "ucrmVersionCompliancy": {
- "min": "2.15.0-beta3",
- "max": null
- },
- "unmsVersionCompliancy": {
- "min": "2.1.0",
- "max": null
- },
- "author": "Franco Johan Gampel - franco@gampel.com.ar"
- },
- "configuration": [
- {
- "key": "mktip",
- "label": "Mikrotik IP Address",
- "description": "Direccion IP de Mikrotik",
- "required": 1
- },
- {
- "key": "apiport",
- "label": "Mikrotik API PORT",
- "description": "Mikrotik API PORT, leave blank if using default",
- "required": 0
- },
- {
- "key": "mktusr",
- "label": "Mikrotik Username",
- "description": "Nombre de Usuario de Mikrotik",
- "required": 1
- },
- {
- "key": "mktpass",
- "label": "Mikrotik Password",
- "description": "Password de Mikrotik",
- "required": 1
- },
- {
- "key": "burstLimitPercentage",
- "label": "Burst Limit Percentage",
- "description": "Burst Limit Percentage calculated over service Max-Limit / Porcentaje de limite de rafaga calculado sobre el limite maximo del servicio | (If not used configure 0/Si no se utiliza configurar en 0) / Formato de Carga UU/DD (U=Upload D=Download)",
- "required": 1
- },
- {
- "key": "burstTime",
- "label": "Burst Time",
- "description": "Burst Time/Tiempo de Rafaga (If not used configure 1/Si no se utiliza configurar en 1) / Formato de Carga UU/DD (U=Upload D=Download)",
- "required": 1
- },
- {
- "key": "limitAtPercentage",
- "label": "Limit At %",
- "description": "Limit at percentage calculated over the max limit Values 1-99 | Porcentaje de Limit At calculado sobre el max-limit valores 1-99 / Formato de Carga UU/DD (U=Upload D=Download)",
- "required": 1
- },
- {
- "key": "addQueue",
- "label": "Add Queue?",
- "description": "Add queue simple in case it does not exist?",
- "required": 0,
- "type": "checkbox"
- },
- {
- "key": "unmsApiToken",
- "label": "UNMS API token",
- "description": "API token created for this plugin in Network section of UNMS only needed when using UNMS v1 | Token API creado para este plugin en la seccion Network de UNMS, solo necesario cuando se utiliza UNMS v1",
- "required": 0,
- "type": "text"
- },
- {
- "key": "debugMode",
- "label": "Debug Mode?",
- "description": "More detailed log info - Informacion de log mas detallada",
- "required": 0,
- "type": "checkbox"
- }
- ],
- "menu": [
- {
- "key": "MikrotikSync",
- "label": "Sync",
- "type": "admin",
- "target": "iframe",
- "parameters": {
- "option": "Sync"
- }
- },
- {
- "key": "MikrotikSync",
- "label": "Reset Plugin Log",
- "type": "admin",
- "target": "iframe",
- "parameters": {
- "option": "reset-log"
- }
- }
- ]
-}
diff --git a/plugins/mkt-queue-sync/src/public.php b/plugins/mkt-queue-sync/src/public.php
deleted file mode 100644
index 6e94863d5..000000000
--- a/plugins/mkt-queue-sync/src/public.php
+++ /dev/null
@@ -1,50 +0,0 @@
-getUser();
-
- if (isset($data['option'])) {
- if ($data['option'] == 'Sync') {
- if (! $user || $user->isClient || ! $user->hasViewPermission(PermissionNames::CLIENTS_SERVICES)) {
- \MikrotikQueueSync\Http::forbidden();
- }
- (new Synchronizer())->sync();
- } elseif ($data['option'] == 'reset-log') {
- if (! $user || $user->isClient || ! $user->hasViewPermission(PermissionNames::CLIENTS_SERVICES)) {
- \MikrotikQueueSync\Http::forbidden();
- }
- $logger = PluginLogManager::create();
- $logger->clearLog();
- echo '
Log Cleared';
- } elseif ($data['option'] == 'WebHook-sZkmt5aIohKXMmRrnI3DfDk') {
- (new Synchronizer())->sync();
- }
- } else {
- if (! $user || $user->isClient || ! $user->hasViewPermission(PermissionNames::CLIENTS_SERVICES)) {
- \MikrotikQueueSync\Http::forbidden();
- }
- (new Synchronizer())->sync();
- }
-})();
-http_response_code(200); //Response OK when it's called by a webhook.
diff --git a/plugins/packetlogic-packet-manager/README.md b/plugins/packetlogic-packet-manager/README.md
deleted file mode 100644
index 712f127fe..000000000
--- a/plugins/packetlogic-packet-manager/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-http://www.atlinkservices.com
-
-packetlogic-packet-manager
-Python-based PacketLogic Packet Manager for UCRM API for PacketLogic Firmware 15.1.5.12 and greater
-
-This is a PacketLogic packet manager for the Ubiquiti CRM that I have customer coded using PacketLogic's Python API that can be downloaded from their website http://download.proceranetworks.com/python-api.html. Feel free to edit this plugin as you see fit, but please reference me!
-
-NOTE: This .egg file must be installed into your Python in order for this to work.
-Files Included
-main.php
-This file calls uexec.py, which will execute the rest of the code for the plugin.
-
-manifest.json
-The basic manifest for a Ubiquiti CRM Plugin. Includes optional fields for having a redundant packet manager in your network.
-
-src/__init__.py
-Placeholder file to specify a sub-directory.
-
-src/ucrmInfo.py
-This is what contains all of the variables and connection information for the UCRM, including the config options set for the plugin. Also has the function ucrmConnect() which connects to the desired URL with the desired headers.
-
-src/globals.py
-This contains some variables called by a lot of the functions and is included in order to function properly.
-
-src/plConfigClients.py
-This contains some functions that are used to add, verify, and remove clients from the PacketLogic.
-
-src/plConfigServices.py
-This contains some functions that are used to add, verify, and remove service plans from the PacketLogic.
-
-src/plConfigInfrastructure.py
-This contains some functions that are used to add and verify open access devices to the PacketLogic.
-
-src/plInit.py
-This contains some functions that are used to Initialize the Procera.
-
-###########
-
-Usage Instructions
-1. Download the corresponding API file for your PacketLogic firmware and install it.
-2. Upload the zip file for the plugin.
-3. Configure the plugin. There are necessary options for telling the PacketLogic what you want it to do.
- - InitRemove - This will remove all prior Ubiquiti-related objects and items from your PacketLogic.
- - InitAdd - This will add all of the vital parent objects to your PacketLogic.
- - Services - This will add all of your service plans to the PacketLogic.
- - Clients - This will add all of your clients to the PacketLogic and add them to their corresponding plans.
- - Infrastructure - This will add all of your open access devices to the PacketLogic.
- - Sync - This will force synchronize the PacketLogic, which will perform all of the above options (except InitRemove).
-4. Enjoy.
-
-###########
-
-Thank you for using my plugin!
diff --git a/plugins/packetlogic-packet-manager/packetlogic-packet-manager.zip b/plugins/packetlogic-packet-manager/packetlogic-packet-manager.zip
deleted file mode 100644
index 807827e78..000000000
Binary files a/plugins/packetlogic-packet-manager/packetlogic-packet-manager.zip and /dev/null differ
diff --git a/plugins/packetlogic-packet-manager/src/main.php b/plugins/packetlogic-packet-manager/src/main.php
deleted file mode 100644
index 4c223020e..000000000
--- a/plugins/packetlogic-packet-manager/src/main.php
+++ /dev/null
@@ -1,8 +0,0 @@
- 2:
- for pcip in clientIP:
- cdip = pcip + "/32"
- else:
- for pcip in clientIP:
- cdip = pcip
-
- # Create Authorized NetObject on active status
- if pst == "1":
- if rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl):
- rs.object_remove("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl)
- elif not rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl):
- o = rs.object_add("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl)
- o.add(pcip)
-
- # Create Unauthorized NetObject on suspended status
- if pst == "2":
- if rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl):
- rs.object_remove("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl)
- elif not rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl):
- o = rs.object_add("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl)
- o.add(pcip)
-
- # Remove NetObject on terminated status
- if pst == "3":
- if rs.object_find("/NetObjects/Ubiquiti_CRM/Services/%s" % pcl):
- if rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl):
- rs.object_remove("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl)
- rs.object_remove("/NetObjects/Ubiquiti_CRM/Services/%s/%s" % (psn, pcl))
- elif rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl):
- rs.object_remove("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl)
- rs.object_remove("/NetObjects/Ubiquiti_CRM/Services/%s/%s" % (psn, pcl))
- elif rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl):
- rs.object_remove("/NetObjects/Ubiquiti_CRM/UCRM_Authorized/%s" % pcl)
- elif rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl):
- rs.object_remove("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized/%s" % pcl)
-
- # Exit the function
- return
-
-# Function to add the customers to their respective package group
-def makeClientPlan(client,plan,devIP):
-
- # UCRM Client Variable
- pcl = str("UCRM_Client_%s" % client)
-
- # UCRM Service Plan
- psn = str("UCRM_%s" % plan)
-
- # Set pdip as the client's device IP
- if len(devIP) < 2:
- for pdip in devIP:
- cdip = pdip + "/32"
- elif len(devIP) > 2:
- for pdip in devIP:
- cdip = pdip + "/32"
- else:
- for pdip in devIP:
- cdip = pdip
-
- # Gather service plan data
- surl = ucrmInfo.ucrmURL + "/service-plans"
- splan = ucrmInfo.ucrmConnect(surl,ucrmInfo.appKey)
-
- # Check to see if the customer's plan matches the one they were on and remove the old one
- for sp in splan:
- oldplan = str("UCRM_" + sp["name"])
-
- if rs.object_find("/NetObjects/Ubiquiti_CRM/Services/%s/%s" % (oldplan,pcl)):
- if oldplan != psn:
- rs.object_remove("/NetObjects/Ubiquiti_CRM/Services/%s/%s" % (oldplan,pcl))
-
- # Check to see if the customer is existing under their plan and add them if not
- if not rs.object_find("/NetObjects/Ubiquiti_CRM/Services/%s/%s" % (psn, pcl)):
- o = rs.object_add("/NetObjects/Ubiquiti_CRM/Services/%s/%s" % (psn, pcl))
- o.add(pdip)
-
- # Exit the function
- return
diff --git a/plugins/packetlogic-packet-manager/src/src/plConfigInfrastructure.py b/plugins/packetlogic-packet-manager/src/src/plConfigInfrastructure.py
deleted file mode 100644
index 2633795e1..000000000
--- a/plugins/packetlogic-packet-manager/src/src/plConfigInfrastructure.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python
-
-# Custom PacketLogic Execution Script for Ubiquiti CRM
-# Creation Date: 06/22/2018
-# Author: Shaun Wilkinson
-# Company: AtLink Services, LLC
-# URL: http://www.atlinkservices.com
-
-# Import system, JSON, and PacketLogic API
-import packetlogic2
-import sys
-from globals import rs
-
-# Function to add devices to the open access list
-def makeOpenAccess(ips):
- for ip in ips:
- fip = ip.split("/")[0]
- fobj = rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Open_Access").items
- fobjf = []
- for fo in fobj:
- stfo = str(fo)
- sfo = "".join(stfo)
- rfo = sfo.split("/")[0]
- fobjf.append(rfo)
- if not fip in fobjf:
- o = rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Open_Access")
- o.add(fip)
-
- # Exit the function after the FOR loop
- return
diff --git a/plugins/packetlogic-packet-manager/src/src/plConfigServices.py b/plugins/packetlogic-packet-manager/src/src/plConfigServices.py
deleted file mode 100644
index fcd160619..000000000
--- a/plugins/packetlogic-packet-manager/src/src/plConfigServices.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/python
-
-# Custom PacketLogic Execution Script for Ubiquiti CRM
-# Creation Date: 06/22/2018
-# Author: Shaun Wilkinson
-# Company: AtLink Services, LLC
-# URL: http://www.atlinkservices.com
-
-# Import system, JSON, and PacketLogic API
-import packetlogic2
-import sys
-from globals import rs
-
-# Function to create the UCRM packages
-def makeServicePlan(plan,download,upload):
-
- psn = plan
- pdn = [(0, 0, ((download * 1000)/8))]
- pldn = ((download * 1000)/8)
- pup = [(0, 0, ((upload * 1000)/8))]
- plup = ((upload * 1000)/8)
-
- so = rs.shapingobject_find("UCRM_%s" % psn)
-
- # Check to see if package speeds are correct, if it exists
- if so:
- if so.limits.inbound.bps != pldn:
- if so.limits.outbound.bps != plup:
- so.limits.inbound.bps = pldn
- so.limits.outbound.bps = plup
- else:
- so.limits.inbound.bps = pldn
- elif so.limits.outbound.bps != plup:
- so.limits.outbound.bps = plup
-
- # Check for service package, then make the package
- if rs.object_find("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn):
- if rs.shapingobject_find("UCRM_%s" % psn):
- if not rs.shapingrule_find("UCRM_%s" % psn):
- sloc = rs.object_find("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- sobj = rs.shapingobject_find("UCRM_%s" % psn)
- o = rs.shapingrule_add("UCRM_%s" % psn)
- o.cond_add(rs.CONDITION_NETOBJECT_LOCAL, rs.CONDITION_OP_EQ, [sloc.id])
- o.set_objects([sobj.id])
- elif rs.shapingrule_find("UCRM_%s" % psn):
- rs.shapingobject_add(("UCRM_%s" % psn), inbound = pdn, outbound = pup, flags = ["counter", "blue"])
- else:
- rs.shapingobject_add(("UCRM_%s" % psn), inbound = pdn, outbound = pup, flags = ["counter", "blue"])
- sloc = rs.object_find("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- sobj = rs.shapingobject_find("UCRM_%s" % psn)
- o = rs.shapingrule_add("UCRM_%s" % psn)
- o.cond_add(rs.CONDITION_NETOBJECT_LOCAL, rs.CONDITION_OP_EQ, [sloc.id])
- o.set_objects([sobj.id])
- elif rs.shapingobject_find("UCRM_%s" % psn):
- if rs.shapingrule_find("UCRM_%s" % psn):
- rs.object_add("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- else:
- rs.object_add("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- sloc = rs.object_find("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- sobj = rs.shapingobject_find("UCRM_%s" % psn)
- o = rs.shapingrule_add("UCRM_%s" % psn)
- o.cond_add(rs.CONDITION_NETOBJECT_LOCAL, rs.CONDITION_OP_EQ, [sloc.id])
- o.set_objects([sobj.id])
- elif rs.shapingrule_find("UCRM_%s" % psn):
- rs.object_add("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- else:
- rs.object_add("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- sloc = rs.object_find("/NetObjects/Ubiquiti_CRM/Services/UCRM_%s" % psn)
- rs.shapingobject_add(("UCRM_%s" % psn), inbound = pdn, outbound = pup, flags = ["counter", "blue"])
- sobj = rs.shapingobject_find("UCRM_%s" % psn)
- o = rs.shapingrule_add("UCRM_%s" % psn)
- o.cond_add(rs.CONDITION_NETOBJECT_LOCAL, rs.CONDITION_OP_EQ, [sloc.id])
- o.set_objects([sobj.id])
-
- # Exit the function
- return
diff --git a/plugins/packetlogic-packet-manager/src/src/plInit.py b/plugins/packetlogic-packet-manager/src/src/plInit.py
deleted file mode 100644
index 685327ab6..000000000
--- a/plugins/packetlogic-packet-manager/src/src/plInit.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/usr/bin/python
-
-# Custom PacketLogic Execution Script for Ubiquiti CRM
-# Creation Date: 06/22/2018
-# Author: Shaun Wilkinson
-# Company: AtLink Services, LLC
-# URL: http://www.atlinkservices.com
-
-import packetlogic2
-import sys
-import re
-from fnmatch import fnmatch
-from globals import rs
-
-# Function for initial PacketLogic Sync, will erase all instances related to UCRM
-def InitializeRemove():
-
- ui = rs.shapingrule_list()
-
- if ui:
- for iui in ui:
- rs.shapingrule_remove(iui)
-
- ui = rs.fwrule_list()
-
- if ui:
- for iui in ui:
- rs.fwrule_remove(iui)
-
- if rs.object_find("/PortObjects/Ubiquiti_CRM"):
- ui = rs.object_list("/PortObjects/Ubiquiti_CRM")
-
- if ui:
- for iui in ui:
- if iui.items:
- for item in iui.items:
- iui.remove(item)
- rs.object_remove(iui)
- rs.object_remove("/PortObjects/Ubiquiti_CRM")
-
- if rs.object_find("/ProtocolObjects/Ubiquiti_CRM"):
- ui = rs.object_list("/ProtocolObjects/Ubiquiti_CRM")
-
- if ui:
- for iui in ui:
- if iui.items:
- for item in iui.items:
- iui.remove(item)
- rs.object_remove(iui)
- rs.object_remove("/ProtocolObjects/Ubiquiti_CRM")
-
- if rs.object_find("/NetObjects/Ubiquiti_CRM"):
- ui = rs.object_list("/NetObjects/Ubiquiti_CRM")
-
- if ui:
- for iui in ui:
- if iui.items:
- for item in iui.items:
- iui.remove(item)
- rs.object_remove(iui)
- rs.object_remove("/NetObjects/Ubiquiti_CRM")
-
- ui = rs.shapingobject_list()
-
- if ui:
- for iui in ui:
- rs.shapingobject_remove(iui)
-
- return
-
-# Function to add all objects to PacketLogic (does not include clients, open access devices, or plans)
-def InitializeAdd():
-
- if not rs.object_find("/PortObjects/Ubiquiti_CRM"):
- rs.object_add("/PortObjects/Ubiquiti_CRM")
-
- if not rs.object_find("/PortObjects/Ubiquiti_CRM/UCRM_DHCP"):
- o = rs.object_add("/PortObjects/Ubiquiti_CRM/UCRM_DHCP")
- o.add("67-68")
-
- if not rs.object_find("/PortObjects/Ubiquiti_CRM/UCRM_DNS"):
- o = rs.object_add("/PortObjects/Ubiquiti_CRM/UCRM_DNS")
- o.add("53")
-
- if not rs.object_find("/PortObjects/Ubiquiti_CRM/UCRM_HTTP"):
- o = rs.object_add("/PortObjects/Ubiquiti_CRM/UCRM_HTTP")
- o.add("81")
-
- if not rs.object_find("/ProtocolObjects/Ubiquiti_CRM"):
- rs.object_add("/ProtocolObjects/Ubiquiti_CRM")
-
- if not rs.object_find("/ProtocolObjects/Ubiquiti_CRM/UCRM_UDP"):
- o = rs.object_add("/ProtocolObjects/Ubiquiti_CRM/UCRM_UDP")
- o.add("UDP")
-
- if not rs.object_find("/ProtocolObjects/Ubiquiti_CRM/UCRM_ICMP"):
- o = rs.object_add("/ProtocolObjects/Ubiquiti_CRM/UCRM_ICMP")
- o.add("ICMP")
-
- if not rs.object_find("/NetObjects/Ubiquiti_CRM"):
- o = rs.object_add("/NetObjects/Ubiquiti_CRM")
- o.set_visible(True)
-
- if not rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Authorized"):
- rs.object_add("/NetObjects/Ubiquiti_CRM/UCRM_Authorized")
-
- if not rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized"):
- rs.object_add("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized")
-
- if not rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Open_Access"):
- rs.object_add("/NetObjects/Ubiquiti_CRM/UCRM_Open_Access")
-
- if not rs.object_find("/NetObjects/Ubiquiti_CRM/Services"):
- rs.object_add("/NetObjects/Ubiquiti_CRM/Services")
-
- if not rs.fwrule_find("UCRM Authorized Users"):
- hn = rs.object_get("/NetObjects/Ubiquiti_CRM/UCRM_Authorized").id
- o = rs.fwrule_add("UCRM Authorized Users", rs.FWRULE_ACTION_ACCEPT, quick=True)
- o.cond_add(rs.CONDITION_NETOBJECT_HOST, rs.CONDITION_OP_EQ, [hn])
-
- if not rs.fwrule_find("UCRM Open Access"):
- hn = rs.object_get("/NetObjects/Ubiquiti_CRM/UCRM_Open_Access").id
- o = rs.fwrule_add("UCRM Open Access", rs.FWRULE_ACTION_ACCEPT, quick=True)
- o.cond_add(rs.CONDITION_NETOBJECT_HOST, rs.CONDITION_OP_EQ, [hn])
-
- if not rs.fwrule_find("UCRM Delinquent Redirect"):
- hn1 = rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized").id
- hn2 = rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Open_Access").id
- hn3 = rs.object_find("/ServiceObjects/Procera Networks Categorization/Categories/Web Browsing").id
- o = rs.fwrule_add("UCRM Delinquent Redirect", rs.FWRULE_ACTION_INJECT, quick=True, inject_data='HTTP/1.1 307 Temporary Redirect\nLocation: http://ucrm.atlinkservices.com:81\nConnection: close')
- o.cond_add(rs.CONDITION_NETOBJECT_CLIENT, rs.CONDITION_OP_EQ, [hn1])
- o.cond_add(rs.CONDITION_NETOBJECT_SERVER, rs.CONDITION_OP_NE, [hn2])
- o.cond_add(rs.CONDITION_SERVICEOBJECT, rs.CONDITION_OP_EQ, [hn3])
-
- if not rs.fwrule_find("UCRM Delinquent Drop"):
- hn1 = rs.object_find("/NetObjects/Ubiquiti_CRM/UCRM_Unauthorized").id
- hn = rs.object_find("/PortObjects/Ubiquiti_CRM/UCRM_HTTP").id
- o = rs.fwrule_add("UCRM Delinquent Drop", rs.FWRULE_ACTION_DROP, quick=True)
- o.cond_add(rs.CONDITION_NETOBJECT_HOST, rs.CONDITION_OP_EQ, [hn1])
- o.cond_add(rs.CONDITION_PORTOBJECT_SERVER, rs.CONDITION_OP_NE, [hn])
-
- if not rs.fwrule_find("UCRM DNS Accept"):
- hn = rs.object_find("/PortObjects/Ubiquiti_CRM/UCRM_DNS").id
- hn1 = rs.object_find("/ProtocolObjects/Ubiquiti_CRM/UCRM_UDP").id
- o = rs.fwrule_add("UCRM DNS Accept", rs.FWRULE_ACTION_ACCEPT, quick=True)
- o.cond_add(rs.CONDITION_PORTOBJECT_SERVER, rs.CONDITION_OP_EQ, [hn])
- o.cond_add(rs.CONDITION_PROTOCOLOBJECT, rs.CONDITION_OP_EQ, [hn1])
-
- if not rs.fwrule_find("UCRM DHCP Accept"):
- hn1 = rs.object_find("/ProtocolObjects/Ubiquiti_CRM/UCRM_UDP").id
- hn = rs.object_find("/PortObjects/Ubiquiti_CRM/UCRM_DHCP").id
- o = rs.fwrule_add("UCRM DHCP Accept", rs.FWRULE_ACTION_ACCEPT, quick=True)
- o.cond_add(rs.CONDITION_PROTOCOLOBJECT, rs.CONDITION_OP_EQ, [hn1])
- o.cond_add(rs.CONDITION_PORTOBJECT_SERVER, rs.CONDITION_OP_EQ, [hn])
-
- if not rs.fwrule_find("UCRM ICMP Accept"):
- hn = rs.object_find("/ProtocolObjects/Ubiquiti_CRM/UCRM_ICMP").id
- o = rs.fwrule_add("UCRM ICMP Accept", rs.FWRULE_ACTION_ACCEPT, quick=True)
- o.cond_add(rs.CONDITION_PROTOCOLOBJECT, rs.CONDITION_OP_EQ, [hn])
-
- return
diff --git a/plugins/packetlogic-packet-manager/src/src/ucrmInfo.py b/plugins/packetlogic-packet-manager/src/src/ucrmInfo.py
deleted file mode 100644
index 90ed56d95..000000000
--- a/plugins/packetlogic-packet-manager/src/src/ucrmInfo.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/python
-
-# Custom PacketLogic Execution Script for Ubiquiti CRM
-# Creation Date: 06/22/2018
-# Author: Shaun Wilkinson
-# Company: AtLink Services, LLC
-# URL: http://www.atlinkservices.com
-
-import sys
-import json
-import requests
-from os import path
-from urllib2 import Request, urlopen
-
-basepath = path.dirname(__file__)
-filepath = path.abspath(path.join(basepath, "..", "data", "config.json"))
-
-appKey = "K5lbrKaIXTav78JCt+QEE0jcmddXUZFkRRBBQglmwGkq8dUD4fb8JYvalGN39pA1"
-
-# Open UCRM settings
-ufile = path.abspath(path.join(basepath, "..", "ucrm.json"))
-with open(ufile) as ucrm:
- uData = json.load(ucrm)
-
-# Open UCRM Config data
-with open(filepath) as config:
- cData = json.load(config)
-
-# Set option variable
-opt = cData["options"]
-
-# Specify the API URL for the UCRM
-try:
- ucrmURL = uData["ucrmLocalUrl"]
-except IndexError:
- if uData["ucrmPublicUrl"].startswith("https://")
- ucrmURL = "https://localhost/"
- else
- ucrmURL = "http://localhost/"
-
-if opt == "Clients":
- configset = "/clients/services"
-if opt == "Services":
- configset = "/service-plans"
-if opt == "Infrastructure":
- configset = "/devices"
-if opt == "InitAdd":
- configset = "/clients/services"
-if opt == "InitRemove":
- configset = "/clients/services"
-if opt == "Sync":
- configset = "/clients/services"
-
-# Define the UCRM Connection function
-def ucrmConnect(url,key):
-
- headers = {
- "Content-Type": "application/json",
- "X-Auth-App-Key": key
- }
-
- cURL = Request(url)
- cURL.add_header("Content-Type","application/json")
- cURL.add_header("X-Auth-App-Key",key)
- # when using loopback interface, certificate won't match anyway
- cURL.setopt(cURL.SSL_VERIFYPEER, false);
- cURL.setopt(cURL.SSL_VERIFYHOST, 0);
- request = urlopen(cURL)
- response = request.read()
- data = json.loads(response)
-
- return data
diff --git a/plugins/packetlogic-packet-manager/src/uexec.py b/plugins/packetlogic-packet-manager/src/uexec.py
deleted file mode 100644
index 4562fc4a9..000000000
--- a/plugins/packetlogic-packet-manager/src/uexec.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/python
-
-# Custom PacketLogic Execution Script for Ubiquiti CRM
-# Creation Date: 06/22/2018
-# Author: Shaun Wilkinson
-# Company: AtLink Services, LLC
-# URL: http://www.atlinkservices.com
-
-# Import sys and PacketLogic API built-ins
-import sys
-import packetlogic2
-from src import ucrmInfo
-from src import plConfigClients
-from src import plConfigServices
-from src import plConfigInfrastructure
-from src import plInit
-from src import globals
-
-# Define synchronization function
-def sync():
- plInit.InitializeAdd()
-
- surl = ucrmInfo.ucrmURL + "/service-plans"
- ss = ucrmInfo.ucrmConnect(surl,ucrmInfo.appKey)
- for svc in ss:
- psn = svc["name"]
- pdn = svc["downloadSpeed"]
- pup = svc["uploadSpeed"]
-
- plConfigServices.makeServicePlan(psn,pdn,pup)
- iurl = ucrmInfo.ucrmURL + "/devices"
- si = ucrmInfo.ucrmConnect(iurl,ucrmInfo.appKey)
- for did in si:
- devid = did["id"]
-
- dIntURL = ucrmInfo.ucrmURL + ("/devices/%d/device-interfaces" % devid)
-
- dc = ucrmInfo.ucrmConnect(dIntURL,ucrmInfo.appKey)
-
- for dip in dc:
- pdip = dip["ipRanges"]
-
- plConfigInfrastructure.makeOpenAccess(pdip)
- curl = ucrmInfo.ucrmURL + "/clients/services"
- sc = ucrmInfo.ucrmConnect(curl,ucrmInfo.appKey)
- for client in sc:
-
- pcl = client["clientId"]
- pst = client["status"]
- psn = client["servicePlanName"]
- pcip = client["ipRanges"]
- psid = client["id"]
-
- plConfigClients.makeClients(pcl,psn,pst,pcip)
- plConfigClients.makeClientPlan(pcl,psn,pcip)
- return
-
-# Check to see what the option variable is, then call the function
-if globals.popt == "InitRemove":
- plInit.InitializeRemove()
-
-if globals.popt == "InitAdd":
- plInit.InitializeAdd()
-
-if globals.popt == "Infrastructure":
- for did in globals.ud:
- devid = did["id"]
-
- dIntURL = ucrmInfo.ucrmURL + ("/devices/%d/device-interfaces" % devid)
-
- dc = ucrmInfo.ucrmConnect(dIntURL,ucrmInfo.appKey)
-
- for dip in dc:
- pdip = dip["ipRanges"]
-
- plConfigInfrastructure.makeOpenAccess(pdip)
-
-if globals.popt == "Clients":
- for client in globals.ud:
-
- pcl = client["clientId"]
- pst = client["status"]
- psn = client["servicePlanName"]
- pcip = client["ipRanges"]
- psid = client["id"]
-
- plConfigClients.makeClients(pcl,psn,pst,pcip)
- plConfigClients.makeClientPlan(pcl,psn,pcip)
-
-if globals.popt == "Services":
- for svc in globals.ud:
- psn = svc["name"]
- pdn = svc["downloadSpeed"]
- pup = svc["uploadSpeed"]
-
- plConfigServices.makeServicePlan(psn,pdn,pup)
-
-if globals.popt == "Sync":
- sync()
-
-# Submit changes to the Procera and close ruleset
-globals.rs.commit()
diff --git a/plugins/routeros-packet-manager/README.md b/plugins/routeros-packet-manager/README.md
deleted file mode 100644
index 87ffd7b3e..000000000
--- a/plugins/routeros-packet-manager/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# RouterOS Packet Manager
-
-This plugin allows using Mikrotik as a packet manager.
-
-https://github.com/csylos/ucrm-ros-pac-man
diff --git a/plugins/routeros-packet-manager/routeros-packet-manager.zip b/plugins/routeros-packet-manager/routeros-packet-manager.zip
deleted file mode 100644
index 997e7c6d1..000000000
Binary files a/plugins/routeros-packet-manager/routeros-packet-manager.zip and /dev/null differ
diff --git a/plugins/routeros-packet-manager/src/main.php b/plugins/routeros-packet-manager/src/main.php
deleted file mode 100644
index ffce2ac56..000000000
--- a/plugins/routeros-packet-manager/src/main.php
+++ /dev/null
@@ -1,15 +0,0 @@
-debug = false;
- $API->connect($mtikIP, $mtikUser, $mtikPass);
-
- // Mark all returned items from the UCRM as separate items
-
- foreach ($ucrmQuery as $result) {
-
- // Convert the download speed to human readable
-
- $cDS = round($result['downloadSpeed'], 3);
-
- if (strpos($cDS, '.') == 1) {
- $cDS = floatval($cDS);
- if ($cDS < 1) {
- $cDS = $cDS * 1000;
- $cDS = strval($cDS);
- $cDS .= 'k';
- } else {
- $cDS = $cDS * 1024;
- $cDS = strval($cDS);
- $cDS .= 'k';
- }
- } else {
- $cDS .= 'M';
- }
-
- // Convert the upload speed to human readable
-
- $cUS = round($result['uploadSpeed'], 3);
-
- if (strpos($cUS, '.') == 1) {
- $cUS = floatval($cUS);
- if ($cUS < 1) {
- $cUS = $cUS * 1000;
- $cUS = strval($cUS);
- $cUS .= 'k';
- } else {
- $cUS = $cUS * 1024;
- $cUS = strval($cUS);
- $cUS .= 'k';
- }
- } else {
- $cUS .= 'M';
- }
-
- // Pull the first IP from the IP Ranges field
-
- $cIP = $result['ipRanges'][0];
-
- // Add /32 to the IP for use in querying the routerboard
-
- $cmIP = $cIP . '/32';
-
- // Mark the client ID
-
- $cID = $result['clientId'];
-
- // Combine the upload and download speed
-
- $maxlimit = $cUS . '/' . $cDS;
-
- // Todays current date in month-day-year format
-
- $curDate = date('m-d-Y');
-
- // Format the upload speed in Mikrotik format
-
- $cUSr = $result['uploadSpeed'] * 1000000;
-
- // Format the download speed in Mikrotik format
-
- $cDSr = $result['downloadSpeed'] * 1000000;
-
- // Combine the ROS upload and ROS download speed
-
- $maxlimitr = $cUSr . '/' . $cDSr;
-
- // Query for a queue named UCRM with the client ID
-
- $API->write('/queue/simple/getall', false);
- $API->write('?name=UCRM' . $cID, true);
- $READ = $API->read(false);
- $ARRAY = $API->parseResponse($READ);
- if (count($ARRAY) > 0) {
-
- // Query for a queue named UCRMXXXX and a matching target IP
-
- $API->write('/queue/simple/getall', false);
- $API->write('?name=UCRM' . $cID, false);
- $API->write('?target=' . $cmIP, true);
- $READ = $API->read(false);
- $ARRAY = $API->parseResponse($READ);
- if (count($ARRAY) > 0) {
-
- // Query for a queue named UCRMXXXX, a matching target IP, and a matching max limit
-
- $API->write('/queue/simple/getall', false);
- $API->write('?name=UCRM' . $cID, false);
- $API->write('?target=' . $cmIP, false);
- $API->write('?max-limit=' . $maxlimitr, true);
- $READ = $API->read(false);
- $ARRAY = $API->parseResponse($READ);
- if (count($ARRAY) > 0) {
-
- // Continue the foreach loop if true
-
- continue;
- }
-
- // Update the queue if the max limit is wrong
-
- $API->write('/queue/simple/set', false);
- $API->write('=.id=UCRM' . $cID, false);
- $API->write('=target=' . $cIP, false);
- $API->write('=max-limit=' . $maxlimit, false);
- $API->write('=comment=Updated ' . $curDate, true);
- $READ = $API->read(false);
- $ARRAY = $API->parseResponse($READ);
- } else {
-
- // Update the queue if the IP is wrong
-
- $API->write('/queue/simple/set', false);
- $API->write('=.id=UCRM' . $cID, false);
- $API->write('=target=' . $cIP, false);
- $API->write('=max-limit=' . $maxlimit, false);
- $API->write('=comment=Updated ' . $curDate, true);
- $READ = $API->read(false);
- $ARRAY = $API->parseResponse($READ);
- }
- } else {
-
- // Add a new queue for the client
-
- $API->write('/queue/simple/add', false);
- $API->write('=name=UCRM' . $cID, false);
- $API->write('=target=' . $cIP, false);
- $API->write('=max-limit=' . $maxlimit, false);
- $API->write('=comment=Added ' . $curDate, true);
- $READ = $API->read(false);
- $ARRAY = $API->parseResponse($READ);
- }
- }
-
- $API->disconnect();
- }
diff --git a/plugins/routeros-packet-manager/src/src/routeros_api_class.php b/plugins/routeros-packet-manager/src/src/routeros_api_class.php
deleted file mode 100644
index 7925f6698..000000000
--- a/plugins/routeros-packet-manager/src/src/routeros_api_class.php
+++ /dev/null
@@ -1,436 +0,0 @@
-disconnect();
- }
-
- /* Check, can be var used in foreach */
- public function isIterable($var)
- {
- return $var !== null
- && (
- is_array($var)
- || $var instanceof Traversable
- || $var instanceof Iterator
- || $var instanceof IteratorAggregate
- );
- }
-
- /**
- * Print text for debug purposes
- *
- * @param string $text Text to print
- */
- public function debug($text)
- {
- if ($this->debug) {
- echo $text . "\n";
- }
- }
-
- /**
- * @param string $length
- */
- public function encodeLength($length)
- {
- if ($length < 0x80) {
- $length = chr($length);
- } elseif ($length < 0x4000) {
- $length |= 0x8000;
- $length = chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
- } elseif ($length < 0x200000) {
- $length |= 0xC00000;
- $length = chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
- } elseif ($length < 0x10000000) {
- $length |= 0xE0000000;
- $length = chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr(
- $length & 0xFF
- );
- } elseif ($length >= 0x10000000) {
- $length = chr(0xF0) . chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(
- ($length >> 8) & 0xFF
- ) . chr($length & 0xFF);
- }
-
- return $length;
- }
-
- /**
- * Login to RouterOS
- *
- * @param string $ip Hostname (IP or domain) of the RouterOS server
- * @param string $login The RouterOS username
- * @param string $password The RouterOS password
- *
- * @return boolean If we are connected or not
- */
- public function connect($ip, $login, $password)
- {
- for ($ATTEMPT = 1; $ATTEMPT <= $this->attempts; $ATTEMPT++) {
- $this->connected = false;
- $PROTOCOL = ($this->ssl ? 'ssl://' : '');
- $context = stream_context_create([
- 'ssl' => [
- 'ciphers' => 'ADH:ALL',
- 'verify_peer' => false,
- 'verify_peer_name' => false,
- ],
- ]);
- $this->debug('Connection attempt #' . $ATTEMPT . ' to ' . $PROTOCOL . $ip . ':' . $this->port . '...');
- $this->socket = @stream_socket_client(
- $PROTOCOL . $ip . ':' . $this->port,
- $this->error_no,
- $this->error_str,
- $this->timeout,
- STREAM_CLIENT_CONNECT,
- $context
- );
- if ($this->socket) {
- socket_set_timeout($this->socket, $this->timeout);
- $this->write('/login');
- $RESPONSE = $this->read(false);
- if (isset($RESPONSE[0]) && $RESPONSE[0] == '!done') {
- $MATCHES = [];
- if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES)) {
- if ($MATCHES[0][0] == 'ret' && strlen($MATCHES[0][1]) == 32) {
- $this->write('/login', false);
- $this->write('=name=' . $login, false);
- $this->write('=response=00' . md5(chr(0) . $password . pack('H*', $MATCHES[0][1])));
- $RESPONSE = $this->read(false);
- if (isset($RESPONSE[0]) && $RESPONSE[0] == '!done') {
- $this->connected = true;
- break;
- }
- }
- }
- }
- fclose($this->socket);
- }
- sleep($this->delay);
- }
-
- if ($this->connected) {
- $this->debug('Connected...');
- } else {
- $this->debug('Error...');
- }
-
- return $this->connected;
- }
-
- /**
- * Disconnect from RouterOS
- */
- public function disconnect()
- {
- // let's make sure this socket is still valid. it may have been closed by something else
- if (is_resource($this->socket)) {
- fclose($this->socket);
- }
- $this->connected = false;
- $this->debug('Disconnected...');
- }
-
- /**
- * Parse response from Router OS
- *
- * @param array $response Response data
- *
- * @return array Array with parsed data
- */
- public function parseResponse($response)
- {
- if (is_array($response)) {
- $PARSED = [];
- $CURRENT = null;
- $singlevalue = null;
- foreach ($response as $x) {
- if (in_array($x, ['!fatal', '!re', '!trap'])) {
- if ($x == '!re') {
- $CURRENT = &$PARSED[];
- } else {
- $CURRENT = &$PARSED[$x][];
- }
- } elseif ($x != '!done') {
- $MATCHES = [];
- if (preg_match_all('/[^=]+/i', $x, $MATCHES)) {
- if ($MATCHES[0][0] == 'ret') {
- $singlevalue = $MATCHES[0][1];
- }
- $CURRENT[$MATCHES[0][0]] = ($MATCHES[0][1] ?? '');
- }
- }
- }
-
- if (empty($PARSED) && ! is_null($singlevalue)) {
- $PARSED = $singlevalue;
- }
-
- return $PARSED;
- }
-
- return [];
- }
-
- /**
- * Parse response from Router OS
- *
- * @param array $response Response data
- *
- * @return array Array with parsed data
- */
- public function parseResponse4Smarty($response)
- {
- if (is_array($response)) {
- $PARSED = [];
- $CURRENT = null;
- $singlevalue = null;
- foreach ($response as $x) {
- if (in_array($x, ['!fatal', '!re', '!trap'])) {
- if ($x == '!re') {
- $CURRENT = &$PARSED[];
- } else {
- $CURRENT = &$PARSED[$x][];
- }
- } elseif ($x != '!done') {
- $MATCHES = [];
- if (preg_match_all('/[^=]+/i', $x, $MATCHES)) {
- if ($MATCHES[0][0] == 'ret') {
- $singlevalue = $MATCHES[0][1];
- }
- $CURRENT[$MATCHES[0][0]] = ($MATCHES[0][1] ?? '');
- }
- }
- }
- foreach ($PARSED as $key => $value) {
- $PARSED[$key] = $this->arrayChangeKeyName($value);
- }
-
- return $PARSED;
- if (empty($PARSED) && ! is_null($singlevalue)) {
- $PARSED = $singlevalue;
- }
- } else {
- return [];
- }
- }
-
- /**
- * Change "-" and "/" from array key to "_"
- *
- * @param array $array Input array
- *
- * @return array Array with changed key names
- */
- public function arrayChangeKeyName(&$array)
- {
- if (is_array($array)) {
- foreach ($array as $k => $v) {
- $tmp = str_replace('-', '_', $k);
- $tmp = str_replace('/', '_', $tmp);
- if ($tmp) {
- $array_new[$tmp] = $v;
- } else {
- $array_new[$k] = $v;
- }
- }
-
- return $array_new;
- }
-
- return $array;
- }
-
- /**
- * Read data from Router OS
- *
- * @param boolean $parse Parse the data? default: true
- *
- * @return array Array with parsed or unparsed data
- */
- public function read($parse = true)
- {
- $RESPONSE = [];
- $receiveddone = false;
- while (true) {
- // Read the first byte of input which gives us some or all of the length
- // of the remaining reply.
- $BYTE = ord(fread($this->socket, 1));
- $LENGTH = 0;
- // If the first bit is set then we need to remove the first four bits, shift left 8
- // and then read another byte in.
- // We repeat this for the second and third bits.
- // If the fourth bit is set, we need to remove anything left in the first byte
- // and then read in yet another byte.
- if ($BYTE & 128) {
- if (($BYTE & 192) == 128) {
- $LENGTH = (($BYTE & 63) << 8) + ord(fread($this->socket, 1));
- } else {
- if (($BYTE & 224) == 192) {
- $LENGTH = (($BYTE & 31) << 8) + ord(fread($this->socket, 1));
- $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
- } else {
- if (($BYTE & 240) == 224) {
- $LENGTH = (($BYTE & 15) << 8) + ord(fread($this->socket, 1));
- $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
- $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
- } else {
- $LENGTH = ord(fread($this->socket, 1));
- $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
- $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
- $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
- }
- }
- }
- } else {
- $LENGTH = $BYTE;
- }
-
- $_ = '';
-
- // If we have got more characters to read, read them in.
- if ($LENGTH > 0) {
- $_ = '';
- $retlen = 0;
- while ($retlen < $LENGTH) {
- $toread = $LENGTH - $retlen;
- $_ .= fread($this->socket, $toread);
- $retlen = strlen($_);
- }
- $RESPONSE[] = $_;
- $this->debug('>>> [' . $retlen . '/' . $LENGTH . '] bytes read.');
- }
-
- // If we get a !done, make a note of it.
- if ($_ == '!done') {
- $receiveddone = true;
- }
-
- $STATUS = socket_get_status($this->socket);
- if ($LENGTH > 0) {
- $this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . ']' . $_);
- }
-
- if ((! $this->connected && ! $STATUS['unread_bytes']) || ($this->connected && ! $STATUS['unread_bytes'] && $receiveddone)) {
- break;
- }
- }
-
- if ($parse) {
- $RESPONSE = $this->parseResponse($RESPONSE);
- }
-
- return $RESPONSE;
- }
-
- /**
- * Write (send) data to Router OS
- *
- * @param string $command A string with the command to send
- * @param mixed $param2 If we set an integer, the command will send this data as a "tag"
- * If we set it to boolean true, the funcion will send the comand and finish
- * If we set it to boolean false, the funcion will send the comand and wait for next command
- * Default: true
- *
- * @return boolean Return false if no command especified
- */
- public function write($command, $param2 = true)
- {
- if ($command) {
- $data = explode("\n", $command);
- foreach ($data as $com) {
- $com = trim($com);
- fwrite($this->socket, $this->encodeLength(strlen($com)) . $com);
- $this->debug('<<< [' . strlen($com) . '] ' . $com);
- }
-
- if (gettype($param2) == 'integer') {
- fwrite($this->socket, $this->encodeLength(strlen('.tag=' . $param2)) . '.tag=' . $param2 . chr(0));
- $this->debug('<<< [' . strlen('.tag=' . $param2) . '] .tag=' . $param2);
- } elseif (gettype($param2) == 'boolean') {
- fwrite($this->socket, ($param2 ? chr(0) : ''));
- }
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Write (send) data to Router OS
- *
- * @param string $com A string with the command to send
- * @param array $arr An array with arguments or queries
- *
- * @return array Array with parsed
- */
- public function comm($com, $arr = [])
- {
- $count = count($arr);
- $this->write($com, ! $arr);
- $i = 0;
- if ($this->isIterable($arr)) {
- foreach ($arr as $k => $v) {
- switch ($k[0]) {
- case '?':
- $el = "${k}=${v}";
- break;
- case '~':
- $el = "${k}~${v}";
- break;
- default:
- $el = "=${k}=${v}";
- break;
- }
-
- $last = ($i++ == $count - 1);
- $this->write($el, $last);
- }
- }
-
- return $this->read();
- }
-}
diff --git a/plugins/routeros-packet-manager/src/src/ucrmInfo.php b/plugins/routeros-packet-manager/src/src/ucrmInfo.php
deleted file mode 100644
index e2113f9a9..000000000
--- a/plugins/routeros-packet-manager/src/src/ucrmInfo.php
+++ /dev/null
@@ -1,99 +0,0 @@
-=5.5"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "^4.4 || ^5.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.5-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "Guzzle promises library",
- "keywords": [
- "promise"
- ],
- "support": {
- "issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/1.5.2"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
- "type": "tidelift"
- }
- ],
- "time": "2022-08-28T14:55:35+00:00"
- },
- {
- "name": "guzzlehttp/psr7",
- "version": "2.4.4",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
- "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5 || ^8.0",
- "psr/http-factory": "^1.0",
- "psr/http-message": "^1.0",
- "ralouphie/getallheaders": "^3.0"
- },
- "provide": {
- "psr/http-factory-implementation": "1.0",
- "psr/http-message-implementation": "1.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "http-interop/http-factory-tests": "^0.9",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23"
- },
- "suggest": {
- "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
- },
- "type": "library",
- "extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
- },
- "branch-alias": {
- "dev-master": "2.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://sagikazarmark.hu"
- }
- ],
- "description": "PSR-7 message implementation that also provides common utility methods",
- "keywords": [
- "http",
- "message",
- "psr-7",
- "request",
- "response",
- "stream",
- "uri",
- "url"
- ],
- "support": {
- "issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.4.4"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-09T13:19:02+00:00"
- },
- {
- "name": "nette/utils",
- "version": "v4.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/nette/utils.git",
- "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e",
- "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e",
- "shasum": ""
- },
- "require": {
- "php": ">=8.0 <8.3"
- },
- "conflict": {
- "nette/finder": "<3",
- "nette/schema": "<1.2.2"
- },
- "require-dev": {
- "jetbrains/phpstorm-attributes": "dev-master",
- "nette/tester": "^2.4",
- "phpstan/phpstan": "^1.0",
- "tracy/tracy": "^2.9"
- },
- "suggest": {
- "ext-gd": "to use Image",
- "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
- "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
- "ext-json": "to use Nette\\Utils\\Json",
- "ext-mbstring": "to use Strings::lower() etc...",
- "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
- "ext-xml": "to use Strings::length() etc. when mbstring is not available"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause",
- "GPL-2.0-only",
- "GPL-3.0-only"
- ],
- "authors": [
- {
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
- {
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
- }
- ],
- "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
- "homepage": "https://nette.org",
- "keywords": [
- "array",
- "core",
- "datetime",
- "images",
- "json",
- "nette",
- "paginator",
- "password",
- "slugify",
- "string",
- "unicode",
- "utf-8",
- "utility",
- "validation"
- ],
- "support": {
- "issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.0"
- },
- "time": "2023-02-02T10:41:53+00:00"
- },
- {
- "name": "psr/http-client",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-client.git",
- "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
- "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
- "shasum": ""
- },
- "require": {
- "php": "^7.0 || ^8.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Client\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP clients",
- "homepage": "https://github.com/php-fig/http-client",
- "keywords": [
- "http",
- "http-client",
- "psr",
- "psr-18"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-client/tree/master"
- },
- "time": "2020-06-29T06:28:15+00:00"
- },
- {
- "name": "psr/http-factory",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-factory.git",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interfaces for PSR-7 HTTP message factories",
- "keywords": [
- "factory",
- "http",
- "message",
- "psr",
- "psr-17",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-factory/tree/master"
- },
- "time": "2019-04-30T12:38:16+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-message/tree/master"
- },
- "time": "2016-08-06T14:39:51+00:00"
- },
- {
- "name": "ralouphie/getallheaders",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/ralouphie/getallheaders.git",
- "reference": "120b605dfeb996808c31b6477290a714d356e822"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
- "reference": "120b605dfeb996808c31b6477290a714d356e822",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "require-dev": {
- "php-coveralls/php-coveralls": "^2.1",
- "phpunit/phpunit": "^5 || ^6.5"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/getallheaders.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ralph Khattar",
- "email": "ralph.khattar@gmail.com"
- }
- ],
- "description": "A polyfill for getallheaders.",
- "support": {
- "issues": "https://github.com/ralouphie/getallheaders/issues",
- "source": "https://github.com/ralouphie/getallheaders/tree/develop"
- },
- "time": "2019-03-08T08:55:37+00:00"
- },
- {
- "name": "spatie/ssh",
- "version": "1.8.2",
- "source": {
- "type": "git",
- "url": "https://github.com/spatie/ssh.git",
- "reference": "d3576bea064dddb512daee9884eb01daaf8df9dd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/spatie/ssh/zipball/d3576bea064dddb512daee9884eb01daaf8df9dd",
- "reference": "d3576bea064dddb512daee9884eb01daaf8df9dd",
- "shasum": ""
- },
- "require": {
- "php": "^7.4|^8.0",
- "symfony/process": "^4.4|^5.3|^6.0"
- },
- "require-dev": {
- "pestphp/pest": "^1.22",
- "spatie/pest-plugin-snapshots": "^1.1",
- "symfony/var-dumper": "^5.3|6.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Spatie\\Ssh\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Freek Van der Herten",
- "email": "freek@spatie.be",
- "homepage": "https://spatie.be",
- "role": "Developer"
- }
- ],
- "description": "A lightweight package to execute commands over an SSH connection",
- "homepage": "https://github.com/spatie/ssh",
- "keywords": [
- "spatie",
- "ssh"
- ],
- "support": {
- "issues": "https://github.com/spatie/ssh/issues",
- "source": "https://github.com/spatie/ssh/tree/1.8.2"
- },
- "funding": [
- {
- "url": "https://spatie.be/open-source/support-us",
- "type": "custom"
- }
- ],
- "time": "2023-01-17T16:49:02+00:00"
- },
- {
- "name": "symfony/deprecation-contracts",
- "version": "v3.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.3-dev"
- },
- "thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
- }
- },
- "autoload": {
- "files": [
- "function.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "A generic function and convention to trigger deprecation notices",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-01T10:25:55+00:00"
- },
- {
- "name": "symfony/filesystem",
- "version": "v6.2.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "82b6c62b959f642d000456f08c6d219d749215b3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3",
- "reference": "82b6c62b959f642d000456f08c6d219d749215b3",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-mbstring": "~1.8"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Provides basic utilities for the filesystem",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.2.7"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-02-14T08:44:56+00:00"
- },
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.27.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "provide": {
- "ext-ctype": "*"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-11-03T14:55:06+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "v1.27.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "provide": {
- "ext-mbstring": "*"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-11-03T14:55:06+00:00"
- },
- {
- "name": "symfony/process",
- "version": "v6.2.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
- "reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Process\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Executes commands in sub-processes",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/process/tree/v6.2.7"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-02-24T10:42:00+00:00"
- },
- {
- "name": "ubnt/ucrm-plugin-sdk",
- "version": "0.9.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK.git",
- "reference": "02ca1d4ce7fca1bc7f49ef0259a03d0bfedec19f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Ubiquiti-App/UCRM-Plugin-SDK/zipball/02ca1d4ce7fca1bc7f49ef0259a03d0bfedec19f",
- "reference": "02ca1d4ce7fca1bc7f49ef0259a03d0bfedec19f",
- "shasum": ""
- },
- "require": {
- "ext-curl": "*",
- "ext-json": "*",
- "guzzlehttp/guzzle": "^7.5",
- "php": ">=8.1",
- "symfony/filesystem": "^6.2"
- },
- "require-dev": {
- "eloquent/phony-phpunit": "^7.1",
- "eloquent/phpstan-phony": "^0.8.0",
- "ocramius/package-versions": "^2.7",
- "php-coveralls/php-coveralls": "^2.5",
- "phpstan/phpstan": "^1.10",
- "phpstan/phpstan-strict-rules": "^1.2",
- "phpunit/phpunit": "^9.5",
- "symplify/easy-coding-standard": "^10.2"
- },
- "suggest": {
- "ext-zip": "Needed for pack-plugin script."
- },
- "bin": [
- "bin/pack-plugin"
- ],
- "type": "library",
- "autoload": {
- "psr-4": {
- "Ubnt\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "UCRM plugin SDK",
- "homepage": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK",
- "keywords": [
- "sdk",
- "ucrm"
- ],
- "support": {
- "issues": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK/issues",
- "source": "https://github.com/Ubiquiti-App/UCRM-Plugin-SDK/tree/0.9.0"
- },
- "time": "2023-03-10T13:26:40+00:00"
- }
- ],
- "packages-dev": [],
- "aliases": [],
- "minimum-stability": "stable",
- "stability-flags": [],
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": [],
- "platform-dev": [],
- "plugin-api-version": "2.3.0"
-}
diff --git a/plugins/routeros-suspension/src/main.php b/plugins/routeros-suspension/src/main.php
deleted file mode 100644
index fb41adecc..000000000
--- a/plugins/routeros-suspension/src/main.php
+++ /dev/null
@@ -1,44 +0,0 @@
-clearLog();
-
- $config = (new PluginConfigManager())->loadConfig();
-
- $ipAddresses = array_map('trim', explode(PHP_EOL, $config['mikrotikIpAddress']));
- $userNames = array_map('trim', explode(PHP_EOL, $config['mikrotikUserName']));
- $passwords = array_map('trim', explode(PHP_EOL, $config['mikrotikPassword'] ?? ''));
-
- if (count($ipAddresses) !== count($userNames)) {
- $log->appendLog('Number of rows in IP Address and User name fields does not match.');
- exit(1);
- }
-
- $configs = [];
- while ($ipAddress = array_shift($ipAddresses)) {
- $configs[] = array_merge($config, [
- 'mikrotikIpAddress' => $ipAddress,
- 'mikrotikUserName' => array_shift($userNames),
- 'mikrotikPassword' => array_shift($passwords) ?? '',
- ]);
- }
-
- foreach ($configs as $config) {
- $error = false;
- try {
- $log->appendLog(sprintf('Process is starting [%s, %s]', $config['mikrotikIpAddress'], $config['mikrotikUserName']));
- (new Suspender($config))->suspend();
- } catch (\Exception $exception) {
- $error = true;
- $log->appendLog(sprintf(' - %s', $exception->getMessage()));
- }
- $log->appendLog(sprintf('Process is finished %s%s', $error ? '[ERROR]' : '[OK]', PHP_EOL));
- }
-})();
diff --git a/plugins/routeros-suspension/src/manifest.json b/plugins/routeros-suspension/src/manifest.json
deleted file mode 100644
index c75a1a358..000000000
--- a/plugins/routeros-suspension/src/manifest.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "version": "1",
- "information": {
- "name": "routeros-suspension",
- "displayName": "Mikrotik RouterOS - suspension",
- "description": "Plugin for handling suspension on RouterOS devices.",
- "url": "https://github.com/Ubiquiti-App/UCRM-plugins/tree/master/plugins/routeros-suspension",
- "version": "1.2.0",
- "ucrmVersionCompliancy": {
- "min": "2.99.99",
- "max": null
- },
- "unmsVersionCompliancy": {
- "min": "2.1.0",
- "max": null
- },
- "author": "Ubiquiti Inc."
- },
- "configuration": [
- {
- "key": "unmsApiToken",
- "label": "UNMS API token",
- "description": "API token created for this plugin in Network section of UNMS",
- "required": 1,
- "type": "text"
- },
- {
- "key": "mikrotikIpAddress",
- "label": "IP Address",
- "description": "IP address of Mikrotik gateway. For more gateways you can use multiple configuration values in IP Address, User name and Password fields. Just put each value on a new line. The number and order of rows must be consistent in all filled fields.",
- "required": 1,
- "type": "textarea"
- },
- {
- "key": "mikrotikUserName",
- "label": "User name",
- "required": 1,
- "type": "textarea"
- },
- {
- "key": "mikrotikPassword",
- "label": "Password",
- "required": 0,
- "type": "textarea"
- },
- {
- "key": "suspensionPageIp",
- "label": "Suspension page IP address",
- "required": 1,
- "type": "text"
- },
- {
- "key": "suspensionPagePort",
- "label": "Suspension page port",
- "required": 1,
- "type": "text"
- }
- ]
-}
diff --git a/plugins/routeros-suspension/src/src/Service/RouterOsApi.php b/plugins/routeros-suspension/src/src/Service/RouterOsApi.php
deleted file mode 100644
index 6a20c1672..000000000
--- a/plugins/routeros-suspension/src/src/Service/RouterOsApi.php
+++ /dev/null
@@ -1,79 +0,0 @@
-client = $client;
- }
-
- public static function create(array $config): self
- {
- $client = new Client(
- [
- 'host' => $config['mikrotikIpAddress'],
- 'user' => $config['mikrotikUserName'],
- 'pass' => (string) $config['mikrotikPassword'],
- ]
- );
-
- return new self($client);
- }
-
- public function print(string $endpoint): array
- {
- return $this->getClient()->write(new Query(sprintf('%s/print', $endpoint)))->read();
- }
-
- public function remove(string $endpoint, array $ids): array
- {
- if (! $ids) {
- return [];
- }
-
- $query = (new Query(sprintf('%s/remove', $endpoint)))
- ->add(sprintf('=.id=%s', implode(',', $ids)));
-
- return $this->getClient()->write($query)->read();
- }
-
- public function add(string $endpoint, array $sentences, string $commentPrefix = 'ucrm_'): void
- {
- foreach ($sentences as $sentence) {
- $sentence = array_filter($sentence);
-
- if (
- $commentPrefix
- && $sentence['comment'] ?? false
- ) {
- $sentence['comment'] = sprintf('%s%s', $commentPrefix, $sentence['comment']);
- }
-
- $query = new Query(sprintf('%s/add', $endpoint));
-
- foreach ($sentence as $key => $item) {
- $query->add(sprintf('=%s=%s', $key, $item));
- }
-
- $this->getClient()->write($query)->read();
- }
- }
-
- public function getClient(): Client
- {
- return $this->client;
- }
-}
diff --git a/plugins/routeros-suspension/src/src/Service/Suspender.php b/plugins/routeros-suspension/src/src/Service/Suspender.php
deleted file mode 100644
index af66384e8..000000000
--- a/plugins/routeros-suspension/src/src/Service/Suspender.php
+++ /dev/null
@@ -1,404 +0,0 @@
-config = $config;
- $this->ucrmApi = UcrmApi::create();
- $this->unmsApi = UnmsApi::create($config);
- $this->routerOsApi = RouterOsApi::create($config);
- }
-
- public function suspend(): void
- {
- if (! $this->validateConfig($this->config)) {
- throw new ConfigurationException('Missing value in plugin configuration.');
- }
-
- $suspensionPageIp = $this->config['suspensionPageIp'];
- $suspensionPagePort = $this->config['suspensionPagePort'];
-
- $this->syncNatRules($suspensionPageIp, (int) $suspensionPagePort);
- $this->syncFilterRules($suspensionPageIp);
- $this->syncAddressList();
- }
-
- private function syncNatRules(string $suspensionPageIp, int $suspensionPagePort): void
- {
- $natDstJumpRules = [
- 'first_dstnat',
- 'general_dstnat',
- 'last_dstnat',
- ];
-
- $natSrcJumpRules = [
- 'first_srcnat',
- 'general_srcnat',
- 'range_srcnat',
- 'last_srcnat',
- ];
-
- $rules = [];
-
- // add jump rules
- foreach ($natDstJumpRules as $jumpRule) {
- $rules[] = [
- 'chain' => 'dstnat',
- 'action' => 'jump',
- 'comment' => $jumpRule,
- 'jump-target' => sprintf('%s%s', self::COMMENT_SIGNATURE, $jumpRule),
- 'out-interface' => '',
- ];
- }
- foreach ($natSrcJumpRules as $jumpRule) {
- $rules[] = [
- 'chain' => 'srcnat',
- 'action' => 'jump',
- 'comment' => $jumpRule,
- 'jump-target' => sprintf('%s%s', self::COMMENT_SIGNATURE, $jumpRule),
- 'out-interface' => '',
- ];
- }
-
- $rules[] = [
- 'chain' => sprintf('%s%s', self::COMMENT_SIGNATURE, 'first_dstnat'),
- 'action' => 'dst-nat',
- 'src-address-list' => self::BLOCKED_USERS_LIST,
- 'dst-port' => 80,
- 'to-ports' => $suspensionPagePort,
- 'protocol' => 'tcp',
- 'comment' => 'blocked_user_redirect',
- 'to-addresses' => $suspensionPageIp,
- 'out-interface' => '',
- ];
-
- $this->setNat($rules);
- }
-
- private function syncFilterRules(string $serverIp): void
- {
- $rules = [
- [
- 'chain' => 'input',
- 'src-address' => $serverIp,
- 'comment' => 'accept_input',
- 'action' => 'accept',
- 'dst-port' => '',
- 'protocol' => '',
- 'src-address-list' => '',
- 'dst-address' => '',
- ],
- [
- 'chain' => 'forward',
- 'src-address' => $serverIp,
- 'comment' => 'accept_forward',
- 'action' => 'accept',
- 'dst-port' => '',
- 'protocol' => '',
- 'src-address-list' => '',
- 'dst-address' => '',
- ],
-
- [
- 'chain' => 'forward',
- 'comment' => 'forward_first',
- 'jump-target' => 'ucrm_forward_first',
- 'action' => 'jump',
- 'dst-port' => '',
- 'protocol' => '',
- 'src-address-list' => '',
- 'dst-address' => '',
- ],
-
- [
- 'chain' => 'forward',
- 'comment' => 'forward_general',
- 'jump-target' => 'ucrm_forward_general',
- 'action' => 'jump',
- 'dst-port' => '',
- 'protocol' => '',
- 'src-address-list' => '',
- 'dst-address' => '',
- ],
-
- [
- 'chain' => 'forward',
- 'comment' => 'forward_drop',
- 'jump-target' => 'ucrm_forward_drop',
- 'action' => 'jump',
- 'dst-port' => '',
- 'protocol' => '',
- 'src-address-list' => '',
- 'dst-address' => '',
- ],
- [
- 'chain' => 'ucrm_forward_general',
- 'comment' => 'blocked_users_allow_dns',
- 'protocol' => 'udp',
- 'dst-port' => 53,
- 'src-address-list' => self::BLOCKED_USERS_LIST,
- 'action' => 'accept',
- 'src-address' => '',
- 'dst-address' => '',
- ],
- [
- 'chain' => 'ucrm_forward_drop',
- 'comment' => 'blocked_users_drop',
- 'src-address-list' => self::BLOCKED_USERS_LIST,
- 'dst-address' => '!' . $serverIp,
- 'action' => 'drop',
- 'src-address' => '',
- 'dst-port' => '',
- 'protocol' => '',
- ],
- ];
-
- $this->setFilterRules($rules);
- }
-
- private function syncAddressList(): void
- {
- $clientSiteIds = [];
-
- foreach ($this->findServicesToSuspend() as $service) {
- if ($service['unmsClientSiteId'] ?? false) {
- $clientSiteIds[] = $service['unmsClientSiteId'];
- }
- }
-
- $this->setIpFirewallAddressList($this->findIpsFromNetwork($clientSiteIds));
- }
-
- private function setNat(array $content): void
- {
- $section = '/ip/firewall/nat';
-
- $attrs = [
- 'chain',
- 'action',
- 'comment',
- 'jump-target',
- 'dst-address',
- 'src-address',
- 'to-addresses',
- 'to-ports',
- 'out-interface',
- ];
-
- $remoteSectionList = $this->getSectionList($section, $attrs);
-
- $remoteList = $this->createIndex($remoteSectionList, $attrs);
- $localList = $this->createIndex($content, $attrs);
- $toRemove = array_diff_key($remoteList, $localList);
- $toAdd = array_diff_key($localList, $remoteList);
-
- $this->routerOsApi->remove($section, array_column($toRemove, '.id'));
- $this->routerOsApi->add($section, $toAdd);
- }
-
- private function setFilterRules(array $content): void
- {
- $section = '/ip/firewall/filter';
- $attrs = [
- 'chain',
- 'comment',
- 'src-address-list',
- 'dst-address',
- 'action',
- 'src-address',
- 'dst-port',
- 'protocol',
- ];
-
- $remoteList = $this->createIndex($this->getSectionList($section, $attrs), $attrs);
- $localList = $this->createIndex($content, $attrs);
-
- $toRemove = array_diff_key($remoteList, $localList);
- $toAdd = array_diff_key($localList, $remoteList);
-
- $this->routerOsApi->remove($section, array_column($toRemove, '.id'));
- $this->routerOsApi->add($section, $toAdd);
- }
-
- private function findServicesToSuspend(): array
- {
- return $this->ucrmApi->get(
- 'clients/services',
- [
- 'statuses' => [self::SERVICE_STATUS_ACTIVE],
- ]
- );
- }
-
- private function findIpsFromNetwork(array $clientSiteIds): array
- {
- $ipAddresses = [];
- foreach ($clientSiteIds as $clientSiteId) {
- $clientSiteIps = $this->unmsApi->get(
- 'devices/ips',
- [
- 'siteId' => $clientSiteId,
- ]
- );
-
- foreach ($clientSiteIps as $clientSiteIp) {
- $ipAddresses[] = $clientSiteIp;
- }
- }
-
- return array_unique($ipAddresses);
- }
-
- private function setIpFirewallAddressList(array $ipAddresses): void
- {
- $attributes = ['list', 'address', 'comment'];
- $routerList = $this->createIndex($this->findAndFilterUcrmIpAddressListOnRouter(), $attributes);
- $crmList = $this->createIndex($this->createCrmIpAddressLists($ipAddresses), $attributes);
-
- $this->removeAddress(array_diff_key($routerList, $crmList));
- $this->addAddress(array_diff_key($crmList, $routerList));
- }
-
- private function removeAddress(array $addresses): array
- {
- return $this->routerOsApi->remove('/ip/firewall/address-list', array_column($addresses, '.id'));
- }
-
- private function addAddress(array $addresses): void
- {
- $this->routerOsApi->add('/ip/firewall/address-list', $addresses);
- }
-
- private function createIndex(array $arr, array $attrs): array
- {
- $index = [];
- foreach ($arr as $row) {
- $key = $this->createIndexKey($row, $attrs);
- $index[$key] = $row;
- }
-
- return $index;
- }
-
- private function createIndexKey(array $item, array $attrs): string
- {
- $res = '';
- foreach ($attrs as $attr) {
- $res .= '_' . (array_key_exists($attr, $item) ? $item[$attr] : '');
- }
-
- return $res;
- }
-
- private function createCrmIpAddressLists(array $ipAddresses): array
- {
- $addressListRows = [];
- foreach ($ipAddresses as $ipAddress) {
- $addressListRows[] = [
- 'list' => self::BLOCKED_USERS_LIST,
- 'address' => $ipAddress,
- 'comment' => 'blocked_users',
- ];
- }
-
- return $addressListRows;
- }
-
- private function findAndFilterUcrmIpAddressListOnRouter(): array
- {
- $filtered = [];
- foreach ($this->routerOsApi->print('/ip/firewall/address-list') as $address) {
- if (
- array_key_exists('comment', $address)
- && Strings::startsWith($address['comment'], self::COMMENT_SIGNATURE)
- ) {
- $address['comment'] = substr($address['comment'], strlen(self::COMMENT_SIGNATURE));
- $filtered[] = $address;
- }
- }
-
- return $filtered;
- }
-
- private function getSectionList(string $section, array $attributes): array
- {
- $data = $this->getRawSectionList($section, $attributes);
-
- $filtered = [];
- foreach ($data as $row) {
- if (array_key_exists('comment', $row) && Strings::startsWith($row['comment'], self::COMMENT_SIGNATURE)) {
- $row['comment'] = substr($row['comment'], strlen(self::COMMENT_SIGNATURE));
- $filtered[] = $row;
- }
- }
-
- return $filtered;
- }
-
- private function getRawSectionList(string $section, array $attributes = []): array
- {
- $result = $this->routerOsApi->print(
- $section,
- empty($attributes) ? [] : [
- '.proplist' => sprintf('.id,%s', implode(',', $attributes)),
- ]
- );
-
- return is_array($result) ? $result : [];
- }
-
- private function validateConfig(array $config): bool
- {
- $configAttributes = [
- 'mikrotikIpAddress',
- 'mikrotikUserName',
- 'mikrotikPassword',
- 'suspensionPageIp',
- 'suspensionPagePort',
- ];
-
- foreach ($configAttributes as $configAttribute) {
- if (! array_key_exists($configAttribute, $config)) {
- return false;
- }
- }
-
- return true;
- }
-}
diff --git a/plugins/routeros-suspension/src/src/Service/UnmsApi.php b/plugins/routeros-suspension/src/src/Service/UnmsApi.php
deleted file mode 100644
index 5e6362bee..000000000
--- a/plugins/routeros-suspension/src/src/Service/UnmsApi.php
+++ /dev/null
@@ -1,92 +0,0 @@
-client = $client;
- $this->token = $token;
- }
-
- public static function create(array $config): self
- {
- $options = (new UcrmOptionsManager())->loadOptions();
-
- $unmsUrl = ($options->unmsLocalUrl ?: $options->ucrmPublicUrl) ?? '';
- if (! $unmsUrl) {
- throw new ConfigurationException('UCRM URL is missing in plugin configuration.');
- }
-
- if (! ($config['unmsApiToken'] ?? false)) {
- throw new ConfigurationException('UNMS API token is missing in plugin configuration.');
- }
-
- $unmsApiUrl = sprintf('%s/api/v2.1/', rtrim(str_replace('crm/', 'nms/', $unmsUrl), '/'));
-
- $client = new Client(
- [
- 'base_uri' => $unmsApiUrl,
- // If the URL is localhost over HTTPS, do not verify SSL certificate.
- 'verify' => $options->unmsLocalUrl !== null
- ? false
- : ! Helpers::isUrlSecureLocalhost($unmsApiUrl),
- ]
- );
-
- return new self($client, $config['unmsApiToken']);
- }
-
- public function get(string $endpoint, array $query = []): array
- {
- $response = $this->request(
- 'GET',
- $endpoint,
- [
- 'query' => $query,
- ]
- );
-
- return Json::decode((string) $response->getBody());
- }
-
- private function request(string $method, string $endpoint, array $options = []): Response
- {
- return $this->client->request(
- $method,
- // strip slash character from beginning of endpoint to make sure base API URL is included correctly
- ltrim($endpoint, '/'),
- array_merge(
- $options,
- [
- 'headers' => [
- self::HEADER_AUTH_TOKEN => $this->token,
- ],
- ]
- )
- );
- }
-}