mirror of
https://github.com/Yubico/yubiadmin.git
synced 2025-02-27 08:54:15 +01:00
Re-structured code.
This commit is contained in:
parent
f3c6be25e6
commit
7038ebe7fe
@ -2,7 +2,7 @@ import os
|
|||||||
from wsgiref.simple_server import make_server
|
from wsgiref.simple_server import make_server
|
||||||
from webob.dec import wsgify
|
from webob.dec import wsgify
|
||||||
|
|
||||||
from yubiadmin.util import render
|
from yubiadmin.util.app import render
|
||||||
from yubiadmin.apps import apps
|
from yubiadmin.apps import apps
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from yubiadmin.util import App, DBConfigForm
|
from yubiadmin.util.app import App
|
||||||
|
from yubiadmin.util.form import DBConfigForm
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'app'
|
'app'
|
||||||
@ -19,7 +20,8 @@ class YubikeyKsm(App):
|
|||||||
"""
|
"""
|
||||||
Database Settings
|
Database Settings
|
||||||
"""
|
"""
|
||||||
return self.render_forms(request, [
|
dbform = DBConfigForm('/etc/yubico/ksm/config-db.php',
|
||||||
DBConfigForm('/etc/yubico/ksm/config-db.php')])
|
dbname='ykksm', dbuser='ykksmreader')
|
||||||
|
return self.render_forms(request, [dbform])
|
||||||
|
|
||||||
app = YubikeyKsm()
|
app = YubikeyKsm()
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
import re
|
import re
|
||||||
from wtforms.fields import IntegerField, StringField, Field
|
import os
|
||||||
from wtforms.widgets import TextInput
|
from wtforms.fields import IntegerField
|
||||||
from wtforms.validators import NumberRange
|
from wtforms.validators import NumberRange
|
||||||
from yubiadmin.util import App, DBConfigForm, ConfigForm, FileConfig
|
from yubiadmin.util.app import App
|
||||||
|
from yubiadmin.util.config import ValueHandler, FileConfig
|
||||||
|
from yubiadmin.util.form import ConfigForm, DBConfigForm, ListField
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'app'
|
'app'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
COMMENT = re.compile(r'/\*.*?\*/')
|
||||||
|
VALUE = re.compile(r'\s*[\'"](.*)[\'"]\s*')
|
||||||
|
|
||||||
def yk_read(varname, prefix='', suffix='', flags=None):
|
|
||||||
|
def yk_pattern(varname, prefix='', suffix='', flags=None):
|
||||||
regex = r'(?m)^(?!#)\$baseParams\[\'__YKVAL_%s__\'\]\s*=' \
|
regex = r'(?m)^(?!#)\$baseParams\[\'__YKVAL_%s__\'\]\s*=' \
|
||||||
'\s*%s(.*?)%s\s*;\s*$' % (varname, prefix, suffix)
|
'\s*%s(.*?)%s\s*;\s*$' % (varname, prefix, suffix)
|
||||||
if flags:
|
if flags:
|
||||||
@ -22,141 +27,76 @@ def yk_write(varname, prefix='', suffix=''):
|
|||||||
(varname, prefix, x, suffix)
|
(varname, prefix, x, suffix)
|
||||||
|
|
||||||
|
|
||||||
def yk_read_str(varname):
|
def yk_handler(varname, default):
|
||||||
return yk_read(varname, '[\'"]', '[\'"]')
|
return ValueHandler(yk_pattern(varname), yk_write(varname),
|
||||||
|
default=default)
|
||||||
|
|
||||||
|
|
||||||
def yk_write_str(varname):
|
def strip_quotes(value):
|
||||||
return yk_write(varname, '"', '"')
|
match = VALUE.match(value)
|
||||||
|
if match:
|
||||||
|
return match.group(1)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def strip_comments(value):
|
||||||
|
return COMMENT.sub('', value)
|
||||||
|
|
||||||
|
|
||||||
|
def yk_parse_arraystring(value):
|
||||||
|
value = strip_comments(value).strip()
|
||||||
|
return [strip_quotes(x) for x in value.split(',')]
|
||||||
|
|
||||||
|
|
||||||
|
def yk_array_handler(varname):
|
||||||
|
pattern = yk_pattern(varname, 'array\(', '\)', 's')
|
||||||
|
str_write = yk_write(varname, 'array(' + os.linesep, os.linesep + ')')
|
||||||
|
writer = lambda xs: str_write((',' + os.linesep)
|
||||||
|
.join(['\t"%s"' % x for x in xs]))
|
||||||
|
reader = lambda match: yk_parse_arraystring(match.group(1))
|
||||||
|
return ValueHandler(pattern, writer, reader, [])
|
||||||
|
|
||||||
|
|
||||||
|
ykval_config = FileConfig(
|
||||||
|
'/home/dain/yubico/yubiadmin/ykval-config.php',
|
||||||
|
[
|
||||||
|
('sync_default', yk_handler('SYNC_DEFAULT_LEVEL', 60)),
|
||||||
|
('sync_secure', yk_handler('SYNC_SECURE_LEVEL', 40)),
|
||||||
|
('sync_fast', yk_handler('SYNC_FAST_LEVEL', 1)),
|
||||||
|
('default_timeout', yk_handler('SYNC_DEFAULT_TIMEOUT', 1)),
|
||||||
|
('sync_interval', yk_handler('SYNC_INTERVAL', 10)),
|
||||||
|
('resync_timeout', yk_handler('SYNC_RESYNC_TIMEOUT', 30)),
|
||||||
|
('old_limit', yk_handler('SYNC_OLD_LIMIT', 10)),
|
||||||
|
('sync_pool', yk_array_handler('SYNC_POOL'))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SyncLevelsForm(ConfigForm):
|
class SyncLevelsForm(ConfigForm):
|
||||||
legend = 'Sync Levels'
|
legend = 'Sync Levels'
|
||||||
|
config = ykval_config
|
||||||
|
|
||||||
sync_default = IntegerField('Default', [NumberRange(1, 100)])
|
sync_default = IntegerField('Default', [NumberRange(1, 100)])
|
||||||
sync_secure = IntegerField('Secure', [NumberRange(1, 100)])
|
sync_secure = IntegerField('Secure', [NumberRange(1, 100)])
|
||||||
sync_fast = IntegerField('Fast', [NumberRange(1, 100)])
|
sync_fast = IntegerField('Fast', [NumberRange(1, 100)])
|
||||||
|
|
||||||
config = FileConfig(
|
|
||||||
'/home/dain/yubico/yubiadmin/ykval-config.php',
|
|
||||||
[
|
|
||||||
(
|
|
||||||
'sync_default',
|
|
||||||
yk_read('SYNC_DEFAULT_LEVEL'),
|
|
||||||
yk_write('SYNC_DEFAULT_LEVEL'),
|
|
||||||
60
|
|
||||||
), (
|
|
||||||
'sync_secure',
|
|
||||||
yk_read('SYNC_SECURE_LEVEL'),
|
|
||||||
yk_write('SYNC_SECURE_LEVEL'),
|
|
||||||
40
|
|
||||||
), (
|
|
||||||
'sync_fast',
|
|
||||||
yk_read('SYNC_FAST_LEVEL'),
|
|
||||||
yk_write('SYNC_FAST_LEVEL'),
|
|
||||||
1
|
|
||||||
),
|
|
||||||
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class MiscForm(ConfigForm):
|
class MiscForm(ConfigForm):
|
||||||
legend = 'Misc'
|
legend = 'Misc'
|
||||||
|
config = ykval_config
|
||||||
|
|
||||||
default_timeout = IntegerField('Default Timeout', [NumberRange(0)])
|
default_timeout = IntegerField('Default Timeout', [NumberRange(0)])
|
||||||
|
|
||||||
config = FileConfig(
|
|
||||||
'/home/dain/yubico/yubiadmin/ykval-config.php',
|
|
||||||
[(
|
|
||||||
'default_timeout',
|
|
||||||
yk_read('SYNC_DEFAULT_TIMEOUT'),
|
|
||||||
yk_write('SYNC_DEFAULT_TIMEOUT'),
|
|
||||||
1
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ListField(Field):
|
|
||||||
COMMENT = re.compile(r'/\*.*?\*/')
|
|
||||||
VALUE = re.compile(r'\s*[\'"](.*)[\'"]\s*')
|
|
||||||
widget = TextInput()
|
|
||||||
|
|
||||||
def process_formdata(self, values):
|
|
||||||
if values:
|
|
||||||
self.data = filter(None, [x.strip() for x in values[0].split(',')])
|
|
||||||
|
|
||||||
def process_data(self, value):
|
|
||||||
if value:
|
|
||||||
data = []
|
|
||||||
value = self.COMMENT.sub('', value)
|
|
||||||
for val in value.split(','):
|
|
||||||
match = self.VALUE.match(val)
|
|
||||||
if match:
|
|
||||||
data.append(match.group(1))
|
|
||||||
self.data = data
|
|
||||||
else:
|
|
||||||
self.data = []
|
|
||||||
|
|
||||||
def _value(self):
|
|
||||||
if self.data:
|
|
||||||
return ', '.join(self.data)
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
def yk_array_write(varname):
|
|
||||||
str_write = yk_write(varname, 'array(', ')')
|
|
||||||
return lambda xs: str_write(', '.join(['"%s"' % x for x in xs]))
|
|
||||||
|
|
||||||
|
|
||||||
class SyncPoolForm(ConfigForm):
|
class SyncPoolForm(ConfigForm):
|
||||||
legend = 'Sync Settings'
|
legend = 'Sync Settings'
|
||||||
|
config = ykval_config
|
||||||
|
attrs = {'sync_pool': {'rows': 5, 'class': 'input-xlarge'}}
|
||||||
|
|
||||||
sync_interval = IntegerField('Sync Interval', [NumberRange(1)])
|
sync_interval = IntegerField('Sync Interval', [NumberRange(1)])
|
||||||
resync_timeout = IntegerField('Resync Timeout', [NumberRange(1)])
|
resync_timeout = IntegerField('Resync Timeout', [NumberRange(1)])
|
||||||
old_limit = IntegerField('Old Limit', [NumberRange(1)])
|
old_limit = IntegerField('Old Limit', [NumberRange(1)])
|
||||||
sync_pool = ListField('Servers')
|
sync_pool = ListField('Servers')
|
||||||
sync_pool_add = StringField('Add Server')
|
|
||||||
|
|
||||||
config = FileConfig(
|
|
||||||
'/home/dain/yubico/yubiadmin/ykval-config.php',
|
|
||||||
[
|
|
||||||
(
|
|
||||||
'sync_interval',
|
|
||||||
yk_read('SYNC_INTERVAL'),
|
|
||||||
yk_write('SYNC_INTERVAL'),
|
|
||||||
10
|
|
||||||
), (
|
|
||||||
'resync_timeout',
|
|
||||||
yk_read('SYNC_RESYNC_TIMEOUT'),
|
|
||||||
yk_write('SYNC_RESYNC_TIMEOUT'),
|
|
||||||
30
|
|
||||||
), (
|
|
||||||
'old_limit',
|
|
||||||
yk_read('SYNC_OLD_LIMIT'),
|
|
||||||
yk_write('SYNC_OLD_LIMIT'),
|
|
||||||
10
|
|
||||||
), (
|
|
||||||
'sync_pool',
|
|
||||||
yk_read('SYNC_POOL', 'array\(', '\)', 's'),
|
|
||||||
yk_array_write('SYNC_POOL'),
|
|
||||||
''
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
if super(SyncPoolForm, self).validate():
|
|
||||||
if self.sync_pool_add.data:
|
|
||||||
self.sync_pool.data.append(self.sync_pool_add.data)
|
|
||||||
self.sync_pool_add.process_data(None)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
COMMENT = re.compile(r'/\*.*?\*/')
|
|
||||||
|
|
||||||
|
|
||||||
def remove_comments(content):
|
|
||||||
return COMMENT.sub('', content)
|
|
||||||
|
|
||||||
|
|
||||||
class YubikeyVal(App):
|
class YubikeyVal(App):
|
||||||
@ -179,8 +119,9 @@ class YubikeyVal(App):
|
|||||||
"""
|
"""
|
||||||
Database Settings
|
Database Settings
|
||||||
"""
|
"""
|
||||||
return self.render_forms(request, [
|
dbform = DBConfigForm('/home/dain/yubico/yubiadmin/config-db.php',
|
||||||
DBConfigForm('/home/dain/yubico/yubiadmin/config-db.php')])
|
dbname='ykval', dbuser='ykval_verifier')
|
||||||
|
return self.render_forms(request, [dbform])
|
||||||
|
|
||||||
def syncpool(self, request):
|
def syncpool(self, request):
|
||||||
"""
|
"""
|
||||||
@ -189,8 +130,7 @@ class YubikeyVal(App):
|
|||||||
sync_pool_form = SyncPoolForm()
|
sync_pool_form = SyncPoolForm()
|
||||||
form_page = self.render_forms(request, [sync_pool_form])
|
form_page = self.render_forms(request, [sync_pool_form])
|
||||||
|
|
||||||
print 'Sync pool: %s' % \
|
print 'Sync pool: %r' % sync_pool_form.config['sync_pool']
|
||||||
remove_comments(sync_pool_form.config['sync_pool'])
|
|
||||||
return form_page
|
return form_page
|
||||||
|
|
||||||
def ksms(self, request):
|
def ksms(self, request):
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
import os
|
|
||||||
import re
|
|
||||||
from UserDict import DictMixin
|
|
||||||
from wtforms import Form, StringField, IntegerField, PasswordField
|
|
||||||
from wtforms.widgets import PasswordInput
|
|
||||||
from wtforms.validators import Optional, NumberRange
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'App',
|
|
||||||
'FileConfig',
|
|
||||||
'ConfigForm',
|
|
||||||
'DBConfigForm',
|
|
||||||
'render',
|
|
||||||
'populate_forms',
|
|
||||||
]
|
|
||||||
|
|
||||||
cwd = os.path.dirname(__file__)
|
|
||||||
base_dir = os.path.abspath(os.path.join(cwd, os.pardir))
|
|
||||||
template_dir = os.path.join(base_dir, 'templates')
|
|
||||||
env = Environment(loader=FileSystemLoader(template_dir))
|
|
||||||
|
|
||||||
|
|
||||||
def render(tmpl, **kwargs):
|
|
||||||
template = env.get_template('%s.html' % tmpl)
|
|
||||||
return template.render(**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def populate_forms(forms, data):
|
|
||||||
if not data:
|
|
||||||
for form in forms:
|
|
||||||
form.load()
|
|
||||||
else:
|
|
||||||
errors = False
|
|
||||||
for form in forms:
|
|
||||||
form.process(data)
|
|
||||||
errors = not form.validate() or errors
|
|
||||||
if not errors:
|
|
||||||
for form in forms:
|
|
||||||
form.save()
|
|
||||||
else:
|
|
||||||
print 'Errors!'
|
|
||||||
|
|
||||||
|
|
||||||
class App(object):
|
|
||||||
name = None
|
|
||||||
sections = []
|
|
||||||
|
|
||||||
def render_forms(self, request, forms):
|
|
||||||
populate_forms(forms, request.params)
|
|
||||||
return render('form', target=request.path, fieldsets=forms)
|
|
||||||
|
|
||||||
|
|
||||||
class ValueHandler(object):
|
|
||||||
def __init__(self, pattern, writer, default=None, group=1):
|
|
||||||
self.pattern = re.compile(pattern)
|
|
||||||
self.writer = writer
|
|
||||||
self.default = default
|
|
||||||
self.group = group
|
|
||||||
|
|
||||||
def read(self, content):
|
|
||||||
match = self.pattern.search(content)
|
|
||||||
if match:
|
|
||||||
return match.group(self.group)
|
|
||||||
return self.default
|
|
||||||
|
|
||||||
def write(self, content, value):
|
|
||||||
if value is None:
|
|
||||||
value = ''
|
|
||||||
if self.pattern.search(content):
|
|
||||||
content = self.pattern.sub(self.writer(value), content, 1)
|
|
||||||
else:
|
|
||||||
content += os.linesep + self.writer(value)
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
class FileConfig(DictMixin):
|
|
||||||
"""
|
|
||||||
Maps key-value pairs to a backing config file.
|
|
||||||
You can manually edit the file by modifying self.content.
|
|
||||||
"""
|
|
||||||
def __init__(self, filename, params=[]):
|
|
||||||
self.filename = filename
|
|
||||||
self.params = {}
|
|
||||||
for param in params:
|
|
||||||
self.add_param(*param)
|
|
||||||
|
|
||||||
def read(self):
|
|
||||||
try:
|
|
||||||
with open(self.filename, 'r') as file:
|
|
||||||
self.content = file.read()
|
|
||||||
except IOError as e:
|
|
||||||
print e
|
|
||||||
self.content = ''
|
|
||||||
|
|
||||||
def commit(self):
|
|
||||||
with open(self.filename, 'w+') as file:
|
|
||||||
file.write(self.content)
|
|
||||||
|
|
||||||
def add_param(self, key, pattern, writer, default=None, group=1):
|
|
||||||
self.params[key] = ValueHandler(pattern, writer, default, group)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return self.params[key].read(self.content)
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
self.content = self.params[key].write(self.content, value)
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return self.params.keys()
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
|
||||||
del self.params[key]
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigForm(Form):
|
|
||||||
"""
|
|
||||||
Form that can load and save data to a config.
|
|
||||||
"""
|
|
||||||
config = None
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
self.config.read()
|
|
||||||
for field in self:
|
|
||||||
if field.id in self.config:
|
|
||||||
field.process_data(self.config[field.id])
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
self.config.read()
|
|
||||||
for field in self:
|
|
||||||
if field.id in self.config:
|
|
||||||
self.config[field.id] = field.data
|
|
||||||
self.config.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def db_read(varname):
|
|
||||||
return r'\$db%s=\'(.*)\';' % varname
|
|
||||||
|
|
||||||
|
|
||||||
def db_write(varname):
|
|
||||||
return lambda x: '$db%s=\'%s\';' % (varname, x)
|
|
||||||
|
|
||||||
|
|
||||||
class DBConfigForm(ConfigForm):
|
|
||||||
"""
|
|
||||||
Complete form for editing a dbconfig-common generated for PHP.
|
|
||||||
"""
|
|
||||||
legend = 'Database'
|
|
||||||
dbtype = StringField('DB type')
|
|
||||||
dbserver = StringField('Host')
|
|
||||||
dbport = IntegerField('Port', [Optional(), NumberRange(1, 65535)])
|
|
||||||
dbname = StringField('DB name')
|
|
||||||
dbuser = StringField('DB username')
|
|
||||||
dbpass = PasswordField('DB password',
|
|
||||||
widget=PasswordInput(hide_value=False))
|
|
||||||
|
|
||||||
config = FileConfig(
|
|
||||||
'/dev/null',
|
|
||||||
[
|
|
||||||
('dbtype', db_read('type'), db_write('type'), 'mysql'),
|
|
||||||
('dbserver', db_read('server'), db_write('server'), 'localhost'),
|
|
||||||
('dbport', db_read('port'), db_write('port'), ''),
|
|
||||||
('dbname', db_read('name'), db_write('name'), 'ykval'),
|
|
||||||
('dbuser', db_read('user'), db_write('user'), 'ykval_verifier'),
|
|
||||||
('dbpass', db_read('pass'), db_write('pass'), ''),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, filename, *args, **kwargs):
|
|
||||||
self.__class__.config.filename = filename
|
|
||||||
super(DBConfigForm, self).__init__(*args, **kwargs)
|
|
0
yubiadmin/util/__init__.py
Normal file
0
yubiadmin/util/__init__.py
Normal file
43
yubiadmin/util/app.py
Normal file
43
yubiadmin/util/app.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import os
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'App',
|
||||||
|
'render',
|
||||||
|
'populate_forms',
|
||||||
|
]
|
||||||
|
|
||||||
|
cwd = os.path.dirname(__file__)
|
||||||
|
base_dir = os.path.abspath(os.path.join(cwd, os.pardir, os.pardir))
|
||||||
|
template_dir = os.path.join(base_dir, 'templates')
|
||||||
|
env = Environment(loader=FileSystemLoader(template_dir))
|
||||||
|
|
||||||
|
|
||||||
|
def render(tmpl, **kwargs):
|
||||||
|
template = env.get_template('%s.html' % tmpl)
|
||||||
|
return template.render(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def populate_forms(forms, data):
|
||||||
|
if not data:
|
||||||
|
for form in forms:
|
||||||
|
form.load()
|
||||||
|
else:
|
||||||
|
errors = False
|
||||||
|
for form in forms:
|
||||||
|
form.process(data)
|
||||||
|
errors = not form.validate() or errors
|
||||||
|
if not errors:
|
||||||
|
for form in forms:
|
||||||
|
form.save()
|
||||||
|
else:
|
||||||
|
print 'Errors!'
|
||||||
|
|
||||||
|
|
||||||
|
class App(object):
|
||||||
|
name = None
|
||||||
|
sections = []
|
||||||
|
|
||||||
|
def render_forms(self, request, forms, template='form'):
|
||||||
|
populate_forms(forms, request.params)
|
||||||
|
return render(template, target=request.path, fieldsets=forms)
|
71
yubiadmin/util/config.py
Normal file
71
yubiadmin/util/config.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from UserDict import DictMixin
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ValueHandler',
|
||||||
|
'FileConfig'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ValueHandler(object):
|
||||||
|
def __init__(self, pattern, writer, reader=lambda x: x.group(1),
|
||||||
|
default=None):
|
||||||
|
self.pattern = re.compile(pattern)
|
||||||
|
self.writer = writer
|
||||||
|
self.reader = reader
|
||||||
|
self.default = default
|
||||||
|
|
||||||
|
def read(self, content):
|
||||||
|
match = self.pattern.search(content)
|
||||||
|
if match:
|
||||||
|
return self.reader(match)
|
||||||
|
return self.default
|
||||||
|
|
||||||
|
def write(self, content, value):
|
||||||
|
if value is None:
|
||||||
|
value = ''
|
||||||
|
if self.pattern.search(content):
|
||||||
|
content = self.pattern.sub(self.writer(value), content, 1)
|
||||||
|
else:
|
||||||
|
content += os.linesep + self.writer(value)
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
class FileConfig(DictMixin):
|
||||||
|
"""
|
||||||
|
Maps key-value pairs to a backing config file.
|
||||||
|
You can manually edit the file by modifying self.content.
|
||||||
|
"""
|
||||||
|
def __init__(self, filename, params=[]):
|
||||||
|
self.filename = filename
|
||||||
|
self.params = {}
|
||||||
|
for param in params:
|
||||||
|
self.add_param(*param)
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
try:
|
||||||
|
with open(self.filename, 'r') as file:
|
||||||
|
self.content = file.read()
|
||||||
|
except IOError as e:
|
||||||
|
print e
|
||||||
|
self.content = ''
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
with open(self.filename, 'w+') as file:
|
||||||
|
file.write(self.content)
|
||||||
|
|
||||||
|
def add_param(self, key, handler):
|
||||||
|
self.params[key] = handler
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.params[key].read(self.content)
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.content = self.params[key].write(self.content, value)
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
return self.params.keys()
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
del self.params[key]
|
85
yubiadmin/util/form.py
Normal file
85
yubiadmin/util/form.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
from wtforms import Form, StringField, IntegerField, PasswordField, Field
|
||||||
|
from wtforms.widgets import PasswordInput, TextArea
|
||||||
|
from wtforms.validators import Optional, NumberRange
|
||||||
|
from yubiadmin.util.config import ValueHandler, FileConfig
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ListField',
|
||||||
|
'ConfigForm',
|
||||||
|
'DBConfigForm'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ListField(Field):
|
||||||
|
widget = TextArea()
|
||||||
|
|
||||||
|
def process_formdata(self, values):
|
||||||
|
if values:
|
||||||
|
self.data = filter(None, [x.strip() for x in values[0].split()])
|
||||||
|
|
||||||
|
def _value(self):
|
||||||
|
if self.data:
|
||||||
|
return '\n'.join(self.data)
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigForm(Form):
|
||||||
|
"""
|
||||||
|
Form that can load and save data to a config.
|
||||||
|
"""
|
||||||
|
config = None
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
self.config.read()
|
||||||
|
for field in self:
|
||||||
|
if field.id in self.config:
|
||||||
|
field.process_data(self.config[field.id])
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self.config.read()
|
||||||
|
for field in self:
|
||||||
|
if field.id in self.config:
|
||||||
|
self.config[field.id] = field.data
|
||||||
|
self.config.commit()
|
||||||
|
|
||||||
|
|
||||||
|
class DBConfigForm(ConfigForm):
|
||||||
|
"""
|
||||||
|
Complete form for editing a dbconfig-common generated for PHP.
|
||||||
|
"""
|
||||||
|
legend = 'Database'
|
||||||
|
dbtype = StringField('DB type')
|
||||||
|
dbserver = StringField('Host')
|
||||||
|
dbport = IntegerField('Port', [Optional(), NumberRange(1, 65535)])
|
||||||
|
dbname = StringField('DB name')
|
||||||
|
dbuser = StringField('DB username')
|
||||||
|
dbpass = PasswordField('DB password',
|
||||||
|
widget=PasswordInput(hide_value=False))
|
||||||
|
|
||||||
|
def db_handler(self, varname, default):
|
||||||
|
pattern = r'\$%s=\'(.*)\';' % varname
|
||||||
|
writer = lambda x: '$%s=\'%s\';' % (varname, x)
|
||||||
|
return ValueHandler(pattern, writer, default=default)
|
||||||
|
|
||||||
|
def __init__(self, filename, *args, **kwargs):
|
||||||
|
if not self.config:
|
||||||
|
self.config = FileConfig(
|
||||||
|
filename,
|
||||||
|
[
|
||||||
|
('dbtype', self.db_handler(
|
||||||
|
'dbtype', kwargs.pop('dbtype', 'mysql'))),
|
||||||
|
('dbserver', self.db_handler(
|
||||||
|
'dbserver', kwargs.pop('dbserver', 'localhost'))),
|
||||||
|
('dbport', self.db_handler(
|
||||||
|
'dbport', kwargs.pop('dbport', ''))),
|
||||||
|
('dbname', self.db_handler(
|
||||||
|
'dbname', kwargs.pop('dbname', ''))),
|
||||||
|
('dbuser', self.db_handler(
|
||||||
|
'dbuser', kwargs.pop('dbuser', ''))),
|
||||||
|
('dbpass', self.db_handler(
|
||||||
|
'dbpass', kwargs.pop('dbpass', ''))),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
super(DBConfigForm, self).__init__(*args, **kwargs)
|
Loading…
x
Reference in New Issue
Block a user