mirror of
https://github.com/opnsense/core.git
synced 2026-05-28 04:34:51 -04:00
Services: Captive Portal - various (style) cleanups
o slightly refactor strip_template.py including our exclude.list to skip library files and internal files. o replace htdocs_default directory references to use relative paths o change ServiceController to implement our standard ApiMutableServiceControllerBase and add missing status call o array() -> [] style fixes o add jquery-3.5.1.min.js into htdocs_default, keep legacy version for existing templates
This commit is contained in:
parent
caaa30de30
commit
d8519a06a8
11 changed files with 89 additions and 140 deletions
1
plist
1
plist
|
|
@ -1057,6 +1057,7 @@
|
|||
/usr/local/opnsense/scripts/captiveportal/htdocs_default/index.html
|
||||
/usr/local/opnsense/scripts/captiveportal/htdocs_default/js/bootstrap.min.js
|
||||
/usr/local/opnsense/scripts/captiveportal/htdocs_default/js/jquery-1.11.2.min.js
|
||||
/usr/local/opnsense/scripts/captiveportal/htdocs_default/js/jquery-3.5.1.min.js
|
||||
/usr/local/opnsense/scripts/captiveportal/lib/__init__.py
|
||||
/usr/local/opnsense/scripts/captiveportal/lib/arp.py
|
||||
/usr/local/opnsense/scripts/captiveportal/lib/daemonize.py
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Deciso B.V.
|
||||
* Copyright (C) 2015-2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -28,9 +28,8 @@
|
|||
|
||||
namespace OPNsense\CaptivePortal\Api;
|
||||
|
||||
use OPNsense\Base\ApiControllerBase;
|
||||
use OPNsense\Base\ApiMutableServiceControllerBase;
|
||||
use OPNsense\Base\UIModelGrid;
|
||||
use OPNsense\CaptivePortal\CaptivePortal;
|
||||
use OPNsense\Core\AppConfig;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
|
@ -40,43 +39,20 @@ use OPNsense\Core\SanitizeFilter;
|
|||
* Class ServiceController
|
||||
* @package OPNsense\CaptivePortal
|
||||
*/
|
||||
class ServiceController extends ApiControllerBase
|
||||
class ServiceController extends ApiMutableServiceControllerBase
|
||||
{
|
||||
/**
|
||||
* reconfigure captive portal
|
||||
*/
|
||||
public function reconfigureAction()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$backend = new Backend();
|
||||
$bckresult = trim($backend->configdRun("filter reload"));
|
||||
if ($bckresult == "OK") {
|
||||
// generate captive portal config
|
||||
$bckresult = trim($backend->configdRun('template reload OPNsense/Captiveportal'));
|
||||
if ($bckresult == "OK") {
|
||||
$mdlCP = new CaptivePortal();
|
||||
if ($mdlCP->isEnabled()) {
|
||||
$bckresult = trim($backend->configdRun("captiveportal restart"));
|
||||
if ($bckresult == "OK") {
|
||||
$status = "ok";
|
||||
} else {
|
||||
$status = "error reloading captive portal";
|
||||
}
|
||||
} else {
|
||||
$backend->configdRun("captiveportal stop");
|
||||
$status = "ok";
|
||||
}
|
||||
} else {
|
||||
$status = "error reloading captive portal template";
|
||||
}
|
||||
} else {
|
||||
$status = "error reloading captive portal rules (" . $bckresult . ")";
|
||||
}
|
||||
protected static $internalServiceClass = '\OPNsense\CaptivePortal\CaptivePortal';
|
||||
protected static $internalServiceTemplate = 'OPNsense/Captiveportal';
|
||||
protected static $internalServiceName = 'captiveportal';
|
||||
|
||||
return array("status" => $status);
|
||||
} else {
|
||||
return array("status" => "failed");
|
||||
}
|
||||
protected function serviceEnabled()
|
||||
{
|
||||
return $this->getModel()->isEnabled();
|
||||
}
|
||||
|
||||
protected function invokeFirewallReload()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -87,15 +63,10 @@ class ServiceController extends ApiControllerBase
|
|||
public function getTemplateAction($fileid = null)
|
||||
{
|
||||
// get template name
|
||||
if ($fileid != null) {
|
||||
$templateFileId = (new SanitizeFilter())->sanitize($fileid, 'alnum');
|
||||
} else {
|
||||
$templateFileId = 'default';
|
||||
}
|
||||
$templateFileId = $fileid != null ? (new SanitizeFilter())->sanitize($fileid, 'alnum') : 'default';
|
||||
|
||||
// request template data and output result (zipfile)
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdpRun("captiveportal fetch_template", array($templateFileId));
|
||||
$response = (new Backend())->configdpRun("captiveportal fetch_template", [$templateFileId]) ?? '';
|
||||
$result = json_decode($response, true);
|
||||
if ($result != null) {
|
||||
$response = $result['payload'];
|
||||
|
|
@ -116,55 +87,48 @@ class ServiceController extends ApiControllerBase
|
|||
public function saveTemplateAction()
|
||||
{
|
||||
if ($this->request->isPost() && $this->request->hasPost("name")) {
|
||||
Config::getInstance()->lock();
|
||||
$content = $this->request->getPost("content", "striptags", "");
|
||||
$templateName = $this->request->getPost("name", "striptags");
|
||||
$mdlCP = new CaptivePortal();
|
||||
if ($this->request->hasPost("uuid")) {
|
||||
$uuid = $this->request->getPost("uuid", "striptags");
|
||||
$template = $mdlCP->getNodeByReference('templates.template.' . $uuid);
|
||||
$template = $this->getModel()->getNodeByReference('templates.template.' . $uuid);
|
||||
if ($template == null) {
|
||||
return array("name" => $templateName, "error" => "node not found");
|
||||
return ["name" => $templateName, "error" => "node not found"];
|
||||
}
|
||||
} else {
|
||||
$template = $mdlCP->getTemplateByName($templateName);
|
||||
$template = $this->getModel()->getTemplateByName($templateName);
|
||||
}
|
||||
|
||||
// cleanse input content, we only want to save changed files into our config
|
||||
if (
|
||||
strlen($this->request->getPost("content", "striptags", "")) > 20
|
||||
|| strlen((string)$template->content) == 0
|
||||
) {
|
||||
if (strlen($content) > 20 || strlen((string)$template->content) == 0) {
|
||||
$temp_filename = (new AppConfig())->application->tempDir;
|
||||
$temp_filename .= '/cp_' . $template->getAttributes()['uuid'] . '.tmp';
|
||||
file_put_contents($temp_filename, $this->request->getPost("content", "striptags", ""));
|
||||
file_put_contents($temp_filename, $content);
|
||||
// strip defaults and unchanged files from template (standard js libs, etc)
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdpRun("captiveportal strip_template", array($temp_filename));
|
||||
$response = (new Backend())->configdpRun("captiveportal strip_template", [$temp_filename]) ?? '';
|
||||
unlink($temp_filename);
|
||||
$result = json_decode($response, true);
|
||||
if ($result != null && !array_key_exists('error', $result)) {
|
||||
if (is_array($result) && !array_key_exists('error', $result)) {
|
||||
$template->content = $result['payload'];
|
||||
} else {
|
||||
return array("name" => $templateName, "error" => $result['error']);
|
||||
return ["name" => $templateName, "error" => $result['error']];
|
||||
}
|
||||
}
|
||||
|
||||
$template->name = $templateName;
|
||||
$valMsgs = $mdlCP->performValidation();
|
||||
$errorMsg = "";
|
||||
foreach ($valMsgs as $field => $msg) {
|
||||
if ($errorMsg != "") {
|
||||
$errorMsg .= " , ";
|
||||
}
|
||||
$errorMsg .= $msg->getMessage();
|
||||
$errorMsg = [];
|
||||
foreach ($this->getModel()->performValidation() as $validation_message) {
|
||||
$errorMsg[] = (string)$validation_message;
|
||||
}
|
||||
|
||||
if ($errorMsg != "") {
|
||||
return array("name" => (string)$template->name, "error" => $errorMsg);
|
||||
if (!empty($errorMsg)) {
|
||||
return ["name" => (string)$template->name, "error" => implode("\n", $errorMsg)];
|
||||
} else {
|
||||
// data is valid, save and return.
|
||||
$mdlCP->serializeToConfig();
|
||||
$this->getModel()->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
return array("name" => (string)$template->name);
|
||||
return ["name" => (string)$template->name];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
@ -177,13 +141,13 @@ class ServiceController extends ApiControllerBase
|
|||
*/
|
||||
public function delTemplateAction($uuid)
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
$result = ["result" => "failed"];
|
||||
if ($this->request->isPost()) {
|
||||
$mdlCP = new CaptivePortal();
|
||||
Config::getInstance()->lock();
|
||||
if ($uuid != null) {
|
||||
if ($mdlCP->templates->template->del($uuid)) {
|
||||
if ($this->getModel()->templates->template->del($uuid)) {
|
||||
// if item is removed, serialize to config and save
|
||||
$mdlCP->serializeToConfig();
|
||||
$this->getModel()->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
$result['result'] = 'deleted';
|
||||
} else {
|
||||
|
|
@ -201,12 +165,7 @@ class ServiceController extends ApiControllerBase
|
|||
*/
|
||||
public function searchTemplatesAction()
|
||||
{
|
||||
$mdlCP = new CaptivePortal();
|
||||
$grid = new UIModelGrid($mdlCP->templates->template);
|
||||
return $grid->fetchBindRequest(
|
||||
$this->request,
|
||||
array("name", "fileid"),
|
||||
"name"
|
||||
);
|
||||
$grid = new UIModelGrid($this->getModel()->templates->template);
|
||||
return $grid->fetchBindRequest($this->request, ["name", "fileid"], "name");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2015-2024 Deciso B.V.
|
||||
* Copyright (C) 2015-2025 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
|
|
@ -47,10 +47,8 @@ class SessionController extends ApiControllerBase
|
|||
*/
|
||||
public function listAction($zoneid = 0)
|
||||
{
|
||||
$mdlCP = new CaptivePortal();
|
||||
$cpZone = $mdlCP->getByZoneID($zoneid);
|
||||
if ($cpZone != null) {
|
||||
$allClientsRaw = (new Backend())->configdpRun("captiveportal list_clients", [$cpZone->zoneid]);
|
||||
if ((new CaptivePortal())->getByZoneID($zoneid) != null) {
|
||||
$allClientsRaw = (new Backend())->configdpRun("captiveportal list_clients", [$zoneid]);
|
||||
return json_decode($allClientsRaw ?? '', true);
|
||||
} else {
|
||||
// illegal zone, return empty response
|
||||
|
|
@ -80,8 +78,7 @@ class SessionController extends ApiControllerBase
|
|||
public function zonesAction()
|
||||
{
|
||||
$response = [];
|
||||
$mdlCP = new CaptivePortal();
|
||||
foreach ($mdlCP->zones->zone->iterateItems() as $zone) {
|
||||
foreach ((new CaptivePortal())->zones->zone->iterateItems() as $zone) {
|
||||
$response[(string)$zone->zoneid] = (string)$zone->description;
|
||||
}
|
||||
asort($response);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2015 Deciso B.V.
|
||||
* Copyright (C) 2015-2025 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
|
|
@ -97,10 +97,6 @@ class SettingsController extends ApiMutableModelControllerBase
|
|||
*/
|
||||
public function searchZonesAction()
|
||||
{
|
||||
return $this->searchBase(
|
||||
"zones.zone",
|
||||
null,
|
||||
"description"
|
||||
);
|
||||
return $this->searchBase("zones.zone", null, "description");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2015 Deciso B.V.
|
||||
* Copyright (C) 2015-2025 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
|
|
@ -45,9 +45,8 @@ class VoucherController extends ApiControllerBase
|
|||
*/
|
||||
public function listProvidersAction()
|
||||
{
|
||||
$result = array();
|
||||
$authFactory = new AuthenticationFactory();
|
||||
foreach ($authFactory->listServers() as $authName => $authProps) {
|
||||
$result = [];
|
||||
foreach ((new AuthenticationFactory())->listServers() as $authName => $authProps) {
|
||||
if ($authProps['type'] == 'voucher') {
|
||||
$result[] = $authName;
|
||||
}
|
||||
|
|
@ -62,12 +61,11 @@ class VoucherController extends ApiControllerBase
|
|||
*/
|
||||
public function listVoucherGroupsAction($provider)
|
||||
{
|
||||
$authFactory = new AuthenticationFactory();
|
||||
$auth = $authFactory->get(urldecode($provider));
|
||||
$auth = (new AuthenticationFactory())->get(urldecode($provider));
|
||||
if ($auth != null && method_exists($auth, 'listVoucherGroups')) {
|
||||
return $auth->listVoucherGroups();
|
||||
} else {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,12 +77,11 @@ class VoucherController extends ApiControllerBase
|
|||
*/
|
||||
public function listVouchersAction($provider, $group)
|
||||
{
|
||||
$authFactory = new AuthenticationFactory();
|
||||
$auth = $authFactory->get(urldecode($provider));
|
||||
$auth = (new AuthenticationFactory())->get(urldecode($provider));
|
||||
if ($auth != null && method_exists($auth, 'listVouchers')) {
|
||||
return $auth->listVouchers(urldecode($group));
|
||||
} else {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,14 +94,13 @@ class VoucherController extends ApiControllerBase
|
|||
public function dropVoucherGroupAction($provider, $group)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$authFactory = new AuthenticationFactory();
|
||||
$auth = $authFactory->get(urldecode($provider));
|
||||
$auth = (new AuthenticationFactory())->get(urldecode($provider));
|
||||
if ($auth != null && method_exists($auth, 'dropVoucherGroup')) {
|
||||
$auth->dropVoucherGroup(urldecode($group));
|
||||
return array("status" => "drop");
|
||||
}
|
||||
}
|
||||
return array("status" => "error");
|
||||
return ["status" => "error"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -116,13 +112,12 @@ class VoucherController extends ApiControllerBase
|
|||
public function dropExpiredVouchersAction($provider, $group)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$authFactory = new AuthenticationFactory();
|
||||
$auth = $authFactory->get(urldecode($provider));
|
||||
$auth = (new AuthenticationFactory())->get(urldecode($provider));
|
||||
if ($auth != null && method_exists($auth, 'dropExpired')) {
|
||||
return array("status" => "drop", "count" => $auth->dropExpired(urldecode($group)));
|
||||
}
|
||||
}
|
||||
return array("status" => "error");
|
||||
return ["status" => "error"];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -133,10 +128,9 @@ class VoucherController extends ApiControllerBase
|
|||
*/
|
||||
public function generateVouchersAction($provider)
|
||||
{
|
||||
$response = array("status" => "error");
|
||||
$response = ["status" => "error"];
|
||||
if ($this->request->isPost()) {
|
||||
$authFactory = new AuthenticationFactory();
|
||||
$auth = $authFactory->get(urldecode($provider));
|
||||
$auth = (new AuthenticationFactory())->get(urldecode($provider));
|
||||
if ($auth != null && method_exists($auth, 'generateVouchers')) {
|
||||
$count = $this->request->getPost('count', 'int', 0);
|
||||
$validity = $this->request->getPost('validity', 'int', 0);
|
||||
|
|
@ -162,11 +156,10 @@ class VoucherController extends ApiControllerBase
|
|||
*/
|
||||
public function expireVoucherAction($provider)
|
||||
{
|
||||
$response = array("status" => "error");
|
||||
$response = ["status" => "error"];
|
||||
$username = $this->request->getPost('username', 'string', null);
|
||||
if ($this->request->isPost() && $username != null) {
|
||||
$authFactory = new AuthenticationFactory();
|
||||
$auth = $authFactory->get(urldecode($provider));
|
||||
$auth = (new AuthenticationFactory())->get(urldecode($provider));
|
||||
if ($auth != null && method_exists($auth, 'expireVoucher')) {
|
||||
$auth->expireVoucher($username);
|
||||
$response['status'] = 'ok';
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
updateServiceControlUI('captiveportal');
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -181,7 +183,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{ partial('layout_partials/base_apply_button', {'data_endpoint': '/api/captiveportal/service/reconfigure'}) }}
|
||||
{{ partial('layout_partials/base_apply_button', {'data_endpoint': '/api/captiveportal/service/reconfigure', 'data_service_widget': 'captiveportal'}) }}
|
||||
|
||||
{# include dialogs #}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogZone,'id':formGridZone['edit_dialog_id'],'label':lang._('Edit zone')])}}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
|
||||
Copyright (c) 2015-2025 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -38,7 +38,7 @@ from io import BytesIO
|
|||
from lib import OPNsenseConfig
|
||||
|
||||
response = dict()
|
||||
source_directory = '/usr/local/opnsense/scripts/captiveportal/htdocs_default'
|
||||
source_directory = '%s/htdocs_default' % os.path.realpath(os.path.dirname(__file__))
|
||||
|
||||
output_data = BytesIO()
|
||||
|
||||
|
|
@ -71,8 +71,7 @@ with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as
|
|||
filename = '%s/%s' % (root, filename)
|
||||
output_filename = filename[len(source_directory)+1:]
|
||||
if output_filename not in user_filenames:
|
||||
tmp = open(filename, 'rb').read()
|
||||
zf.writestr(output_filename, tmp)
|
||||
zf.writestr(output_filename, open(filename, 'rb').read())
|
||||
|
||||
response['payload'] = base64.b64encode(output_data.getvalue()).decode()
|
||||
response['size'] = len(response['payload'])
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# This list contains the filenames that may not be overwritten by the user when creating custom templates.
|
||||
# All items in this list won't be stored in the config.xml by our framework
|
||||
css/bootstrap-theme.min
|
||||
css/bootstrap.css.map
|
||||
css/bootstrap.min.css
|
||||
fonts/glyphicons-halflings-regular.eot
|
||||
|
|
@ -8,3 +9,5 @@ fonts/glyphicons-halflings-regular.ttf
|
|||
fonts/glyphicons-halflings-regular.woff
|
||||
fonts/glyphicons-halflings-regular.woff2
|
||||
js/bootstrap.min.js
|
||||
js/jquery-1.11.2.min.js
|
||||
js/jquery-3.5.1.min.js
|
||||
|
|
|
|||
2
src/opnsense/scripts/captiveportal/htdocs_default/js/jquery-3.5.1.min.js
vendored
Normal file
2
src/opnsense/scripts/captiveportal/htdocs_default/js/jquery-3.5.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
|
||||
Copyright (c) 2015-2025 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
--------------------------------------------------------------------------------------
|
||||
read a user provided base64 encoded zip file and generate a new one without standard
|
||||
files. (strips javascript etc)
|
||||
Filename should be provided by user parameter and must be available in /tmp/
|
||||
Filename should be provided by user parameter and must be available in /var/lib/php/tmp
|
||||
"""
|
||||
import sys
|
||||
import os.path
|
||||
|
|
@ -39,19 +39,7 @@ import base64
|
|||
from io import BytesIO
|
||||
from hashlib import md5
|
||||
|
||||
htdocs_default_root = '/usr/local/opnsense/scripts/captiveportal/htdocs_default'
|
||||
|
||||
|
||||
def load_exclude_list():
|
||||
""" load exclude list, files that should be removed from the input stream
|
||||
"""
|
||||
result = []
|
||||
excl_filename = '%s/exclude.list' % htdocs_default_root
|
||||
for line in open(excl_filename, 'r').read().split('\n'):
|
||||
line = line.strip()
|
||||
if len(line) > 1 and line[0] != '#':
|
||||
result.append(line)
|
||||
return result
|
||||
htdocs_default_root = '%s/htdocs_default' % os.path.realpath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
response = dict()
|
||||
|
|
@ -71,7 +59,8 @@ else:
|
|||
response['error'] = 'Error reading file'
|
||||
|
||||
if 'error' not in response:
|
||||
exclude_list = load_exclude_list()
|
||||
with open('%s/exclude.list' % htdocs_default_root, 'r') as f_in:
|
||||
exclude_list = [x.strip() for x in f_in if len(x) > 2 and not x.strip().startswith('#')]
|
||||
input_data = BytesIO(zip_content)
|
||||
output_data = BytesIO()
|
||||
with zipfile.ZipFile(input_data, mode='r', compression=zipfile.ZIP_DEFLATED) as zf_in:
|
||||
|
|
@ -81,16 +70,17 @@ if 'error' not in response:
|
|||
for zf_info in zf_in.infolist():
|
||||
if zf_info.filename.find('index.html') > -1:
|
||||
if index_location is None or len(index_location) > len(zf_info.filename):
|
||||
index_location = zf_info.filename
|
||||
index_location = zf_info.filename.replace('index.html', '')
|
||||
if index_location is not None:
|
||||
for zf_info in zf_in.infolist():
|
||||
if zf_info.filename[-1] != '/':
|
||||
filename = zf_info.filename.replace(index_location.replace('index.html', ''), '')
|
||||
filename = zf_info.filename.replace(index_location, '')
|
||||
# ignore internal osx metadata files, maybe we need to ignore some others (windows?) as well
|
||||
# here.
|
||||
if filename.split('/')[0] == '__MACOSX' or filename.split('/')[-1] == '.DS_Store':
|
||||
skip_list = set(['__MACOSX', '.DS_Store', '._.'])
|
||||
if len(set(filename.split('/')).intersection(skip_list)) > 0:
|
||||
continue
|
||||
if filename not in exclude_list:
|
||||
elif filename not in exclude_list:
|
||||
file_data = zf_in.read(zf_info.filename)
|
||||
src_filename = '%s/%s' % (htdocs_default_root, filename)
|
||||
if os.path.isfile(src_filename):
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ type:script
|
|||
message:restarting captiveportal services
|
||||
description:Restart Captive Portal service
|
||||
|
||||
[status]
|
||||
command:/usr/local/sbin/pluginctl -s captiveportal status
|
||||
parameters:
|
||||
type:script_output
|
||||
message:request captiveportal status
|
||||
|
||||
|
||||
[fetch_template]
|
||||
command:/usr/local/opnsense/scripts/captiveportal/fetch_template.py
|
||||
parameters:%s
|
||||
|
|
|
|||
Loading…
Reference in a new issue