(Captiveportal, new) code style cleanup

This commit is contained in:
Ad Schellevis 2015-10-28 11:43:33 +01:00
parent ce208015ea
commit 659757500a
8 changed files with 41 additions and 36 deletions

View File

@ -29,7 +29,6 @@
update captive portal statistics
"""
import sys
import ujson
import time
import syslog
import traceback
@ -40,6 +39,7 @@ from lib.arp import ARP
from lib.ipfw import IPFW
from lib.daemonize import Daemonize
class CPBackgroundProcess(object):
""" background process helper class
"""
@ -90,12 +90,12 @@ class CPBackgroundProcess(object):
# cleanup removed static sessions
for dbclient in self.db.list_clients(zoneid):
if dbclient['authenticated_via'] == '---ip---' \
and dbclient['ipAddress'] not in cpzones[zoneid]['allowedaddresses']:
and dbclient['ipAddress'] not in cpzones[zoneid]['allowedaddresses']:
self.ipfw.delete(zoneid, dbclient['ipAddress'])
self.db.del_client(zoneid, dbclient['sessionId'])
elif dbclient['authenticated_via'] == '---mac---' \
and dbclient['macAddress'] not in cpzones[zoneid]['allowedmacaddresses']:
if dbclient['ipAddress'] != '':
and dbclient['macAddress'] not in cpzones[zoneid]['allowedmacaddresses']:
if dbclient['ipAddress'] != '':
self.ipfw.delete(zoneid, dbclient['ipAddress'])
self.db.del_client(zoneid, dbclient['sessionId'])
@ -125,7 +125,7 @@ class CPBackgroundProcess(object):
# check if hardtimeout is set and overrun for this session
if 'hardtimeout' in cpzone_info and str(cpzone_info['hardtimeout']).isdigit():
# hardtimeout should be set and we should have collected some session data from the client
if int(cpzone_info['hardtimeout']) > 0 and float(db_client['startTime']) > 0:
if int(cpzone_info['hardtimeout']) > 0 and float(db_client['startTime']) > 0:
if (time.time() - float(db_client['startTime'])) / 60 > int(cpzone_info['hardtimeout']):
drop_session_reason = "session %s hit hardtimeout" % db_client['sessionId']
@ -148,12 +148,12 @@ class CPBackgroundProcess(object):
# session accounting
if db_client['acc_session_timeout'] is not None \
and time.time() - float(db_client['startTime']) > db_client['acc_session_timeout'] :
and time.time() - float(db_client['startTime']) > db_client['acc_session_timeout']:
drop_session_reason = "accounting limit reached for session %s" % db_client['sessionId']
elif db_client['authenticated_via'] == '---mac---':
# detect mac changes
current_ip = self.arp.get_address_by_mac(db_client['macAddress'])
if current_ip != None:
if current_ip is not None:
if db_client['ipAddress'] != '':
# remove old ip
self.ipfw.delete(zoneid, db_client['ipAddress'])
@ -187,6 +187,7 @@ class CPBackgroundProcess(object):
if not address_active:
self.ipfw.delete(zoneid, registered_address)
def main():
""" Background process loop, runs as backend daemon for all zones. only one should be active at all times.
The main job of this procedure is to sync the administration with the actual situation in the ipfw firewall.

View File

@ -37,7 +37,7 @@ import StringIO
from lib import OPNSenseConfig
response = dict()
source_directory = '/usr/local/opnsense/scripts/OPNsense/CaptivePortal/htdocs_default'
source_directory = '/usr/local/opnsense/scripts/OPNsense/CaptivePortal/htdocs_default'
output_data = StringIO.StringIO()
@ -67,10 +67,10 @@ with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as
# read standard template from disk
for root, dirs, files in os.walk(source_directory):
for filename in files:
filename = '%s/%s' % (root,filename)
filename = '%s/%s' % (root, filename)
output_filename = filename[len(source_directory)+1:]
if output_filename not in user_filenames:
zf.writestr(output_filename, open(filename,'rb').read())
zf.writestr(output_filename, open(filename, 'rb').read())
response['payload'] = output_data.getvalue().encode('base64')
response['size'] = len(response['payload'])

View File

@ -29,6 +29,7 @@ import stat
import xml.etree.ElementTree
from ConfigParser import ConfigParser
class Config(object):
""" handle to captive portal config (/usr/local/etc/captiveportal.conf)
"""
@ -50,17 +51,16 @@ class Config(object):
self._conf_handle.read(self._cnf_filename)
self.last_updated = mod_time
def get_zones(self):
""" return list of configured zones
:return: dictionary index by zoneid, containing dictionaries with zone properties
"""
result = dict()
self._update()
if self._conf_handle != None:
if self._conf_handle is not None:
for section in self._conf_handle.sections():
if section.find('zone_') == 0:
zoneid=section.split('_')[1]
zoneid = section.split('_')[1]
result[zoneid] = dict()
for item in self._conf_handle.items(section):
result[zoneid][item[0]] = item[1]
@ -86,10 +86,12 @@ class Config(object):
return self._conf_handle.get(section, 'content')
return None
class OPNSenseConfig(object):
""" Read configuration data from config.xml
"""
def __init__(self):
self.rootNode = None
self.load_config()
def load_config(self):
@ -106,7 +108,7 @@ class OPNSenseConfig(object):
templates = self.rootNode.findall("./OPNsense/captiveportal/templates/template")
if templates is not None:
for template in templates:
if template.find('fileid') is not None and template.find('content') is not None :
if template.find('fileid') is not None and template.find('content') is not None:
if template.find('fileid').text == fileid:
return template.find('content').text

View File

@ -66,7 +66,7 @@ class ARP(object):
if address in self._arp_table:
self._arp_table[address]['intf'].append(physical_intf)
else:
self._arp_table[address] = {'mac': mac, 'intf': [physical_intf],'expires' : expires}
self._arp_table[address] = {'mac': mac, 'intf': [physical_intf], 'expires': expires}
def list_items(self):
""" return parsed arp list

View File

@ -37,6 +37,7 @@ class DB(object):
""" construct new database connection, open and make sure the sqlite file exists
:return:
"""
self._connection = None
self.open()
self.create()
@ -73,14 +74,14 @@ class DB(object):
cur.executescript(open(init_script_filename, 'rb').read())
cur.close()
def sessions_per_address(self, zoneid, ip_address = None, mac_address = None):
def sessions_per_address(self, zoneid, ip_address=None, mac_address=None):
""" fetch session(s) per (mac) address
:param zoneid: cp zone number
:param ip_address: ip address
:return: active status (boolean)
"""
cur = self._connection.cursor()
request = {'zoneid':zoneid, 'ip_address': ip_address, 'mac_address': mac_address}
request = {'zoneid': zoneid, 'ip_address': ip_address, 'mac_address': mac_address}
cur.execute("""select cc.sessionid sessionId
, cc.authenticated_via authenticated_via
from cp_clients cc
@ -94,7 +95,7 @@ class DB(object):
result = []
for row in cur.fetchall():
result.append({'sessionId':row[0], 'authenticated_via': row[1]})
result.append({'sessionId': row[0], 'authenticated_via': row[1]})
return result
def add_client(self, zoneid, authenticated_via, username, ip_address, mac_address):
@ -144,7 +145,6 @@ class DB(object):
""", {'zoneid': zoneid, 'sessionid': sessionid, 'ip_address': ip_address})
self._connection.commit()
def del_client(self, zoneid, sessionid):
""" mark (administrative) client for removal
:param zoneid: zone id
@ -340,7 +340,7 @@ class DB(object):
:return: string "add"/"update" to signal the performed action to the client
"""
cur = self._connection.cursor()
qry_params = {'zoneid': zoneid, 'sessionid' : sessionid, 'session_timeout': session_timeout}
qry_params = {'zoneid': zoneid, 'sessionid': sessionid, 'session_timeout': session_timeout}
sql_update = """update session_restrictions
set session_timeout = :session_timeout
where zoneid = :zoneid and sessionid = :sessionid"""

View File

@ -57,14 +57,16 @@ if parameters['output_type'] != 'json':
'ipAddress': 'ip_address',
'macAddress': 'mac_address',
'total_bytes': 'total_bytes',
'idletime' : 'idletime',
'idletime': 'idletime',
'totaltime': 'totaltime'
}
print '%(sessionId)-30s %(userName)-20s %(ipAddress)-20s %(macAddress)-20s %(total_bytes)-15s %(idletime)-10s %(totaltime)-10s' % heading
print '%(sessionId)-30s %(userName)-20s %(ipAddress)-20s %(macAddress)-20s '\
+ '%(total_bytes)-15s %(idletime)-10s %(totaltime)-10s' % heading
for item in response:
item['total_bytes'] = (item['bytes_out'] + item['bytes_in'])
item['idletime'] = time.time() - item['last_accessed']
item['totaltime'] = time.time() - item['startTime']
print '%(sessionId)-30s %(userName)-20s %(ipAddress)-20s %(macAddress)-20s %(total_bytes)-15s %(idletime)-10d %(totaltime)-10d' % item
print '%(sessionId)-30s %(userName)-20s %(ipAddress)-20s %(macAddress)-20s '\
+ '%(total_bytes)-15s %(idletime)-10d %(totaltime)-10d' % item
else:
print(ujson.dumps(response))

View File

@ -31,8 +31,6 @@
"""
import os
import sys
import ujson
import binascii
import zipfile
import StringIO
from lib import Config
@ -43,7 +41,7 @@ if len(sys.argv) > 1:
target_directory = '/var/captiveportal/zone%s/htdocs/' % zoneid
template_data = cnf.fetch_template_data(sys.argv[1])
if template_data is not None and len(template_data) > 20:
print ('overlay user template package for zone %s' % zoneid )
print ('overlay user template package for zone %s' % zoneid)
zip_content = template_data.decode('base64')
input_data = StringIO.StringIO(zip_content)
with zipfile.ZipFile(input_data, mode='r', compression=zipfile.ZIP_DEFLATED) as zf_in:
@ -57,7 +55,7 @@ if len(sys.argv) > 1:
f_out.write(zf_in.read(zf_info.filename))
os.chmod(target_filename, 0444)
# write zone settings
filename ='%sjs/zone.js' % target_directory
filename = '%sjs/zone.js' % target_directory
with open(filename, 'wb') as f_out:
f_out.write('var zoneid = %s' % zoneid)
os.chmod(filename, 0444)

View File

@ -36,16 +36,17 @@ import binascii
import StringIO
import zipfile
import ujson
import md5
from hashlib import md5
htdocs_default_root = '/usr/local/opnsense/scripts/OPNsense/CaptivePortal/htdocs_default'
def load_exclude_list():
""" load exclude list, files that should be removed from the input stream
"""
result = []
filename = '%s/exclude.list' % htdocs_default_root
for line in open(filename, 'r').read().split('\n'):
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)
@ -53,12 +54,13 @@ def load_exclude_list():
response = dict()
zip_content = None
if len(sys.argv) < 2:
response['error'] = 'Filename parameter missing'
else:
input_filename = '/tmp/%s' % os.path.basename(sys.argv[1])
try:
zip_content = open(input_filename,'r').read().decode('base64')
zip_content = open(input_filename, 'r').read().decode('base64')
except binascii.Error:
# not in base64
response['error'] = 'Not a base64 encoded file'
@ -81,17 +83,17 @@ if 'error' not in response:
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.replace('index.html', ''), '')
# ignore internal osx metadata files, maybe we need to ignore some others (windows?) as well
# here.
if filename.split('/')[0] in ('__MACOSX') or filename.split('/')[-1] == '.DS_Store':
if filename.split('/')[0] == '__MACOSX' or filename.split('/')[-1] == '.DS_Store':
continue
if 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):
md5_src = md5.new(open(src_filename, 'rb').read()).hexdigest()
md5_new = md5.new(file_data).hexdigest()
md5_src = md5(open(src_filename, 'rb').read()).hexdigest()
md5_new = md5(file_data).hexdigest()
if md5_src != md5_new:
# changed file
zf_out.writestr(filename, file_data)
@ -99,7 +101,7 @@ if 'error' not in response:
# new file, always write
zf_out.writestr(filename, file_data)
if 'error' not in response:
response['payload'] = output_data.getvalue().encode('base64').strip().replace('\n' ,'')
response['payload'] = output_data.getvalue().encode('base64').strip().replace('\n', '')
response['size'] = len(response['payload'])
print(ujson.dumps(response))