1
0
mirror of https://github.com/Yubico/yubiadmin.git synced 2024-12-01 16:24:13 +01:00

Writing/reading config files.

This commit is contained in:
Dain Nilsson 2013-04-25 14:48:24 +02:00
parent d690b94982
commit 86c45089ed
12 changed files with 230 additions and 113 deletions

View File

@ -88,3 +88,5 @@
</div>
</form>
{%- endmacro -%}
{{ render_form(fieldsets, target) }}

View File

@ -1,3 +0,0 @@
<h2>Database settings</h2>
<p>This is where general settings go.</p>

View File

@ -1,3 +0,0 @@
<h2>General settings</h2>
<p>This is where general settings go.</p>

View File

@ -1,3 +0,0 @@
<h2>KSM settings</h2>
<p>This is where general settings go.</p>

View File

@ -1,3 +0,0 @@
{% from "forms.html" import render_form %}
{{ render_form(fieldsets, '/val/database') }}

View File

@ -1,3 +0,0 @@
{% from "forms.html" import render_form %}
{{ render_form(fieldsets, '/val/general') }}

View File

@ -1,3 +0,0 @@
<h2>KSM settings</h2>
<p>This is where general settings go.</p>

View File

@ -1,3 +0,0 @@
<h2>KSM settings</h2>
<p>This is where general settings go.</p>

View File

@ -1,8 +1,8 @@
import os
from wsgiref.simple_server import make_server
from webob.dec import wsgify
from jinja2 import Environment, FileSystemLoader
from yubiadmin.util import render
from yubiadmin.apps import apps
@ -25,14 +25,8 @@ def inspect_app(app):
}
def render_section(app, section, template, **kwargs):
data = app.__getattribute__(section)(**kwargs)
return template.render(**data)
class YubiAdmin(object):
def __init__(self, env):
self.env = env
def __init__(self):
self.apps = {}
for app in apps:
app_data = inspect_app(app)
@ -45,38 +39,29 @@ class YubiAdmin(object):
section_name = request.path_info_pop()
if not module_name:
tmpl = self.env.get_template('index.html')
return tmpl.render(modules=self.modules)
return render('index', modules=self.modules)
app, module = self.apps[module_name]
if not section_name:
section_name = module['sections'][0]['name']
tmpl = self.env.get_template('%s/%s.html' %
(module_name, section_name))
section = next(section for section in module['sections']
if section['name'] == section_name)
data = app.__getattribute__(section_name)(request)
page = tmpl.render(**data)
data.update({
'modules': self.modules,
'module': module,
'section': section,
'title': '%s - %s' % (module_name, section_name),
'page': page
})
tmpl = env.get_template('app_base.html')
return tmpl.render(**data)
return render(
'app_base',
modules=self.modules,
module=module,
section=section,
title='YubiAdmin - %s - %s' % (module_name, section_name),
page=app.__getattribute__(section_name)(request)
)
cwd = os.path.dirname(__file__)
base_dir = os.path.abspath(os.path.join(cwd, os.pardir))
static_dir = os.path.join(base_dir, 'static')
template_dir = os.path.join(base_dir, 'templates')
env = Environment(loader=FileSystemLoader(template_dir))
application = YubiAdmin(env)
application = YubiAdmin()
if __name__ == '__main__':

View File

@ -17,6 +17,6 @@ class YubikeyKsm(object):
"""
Database Settings
"""
return {}
return "Hello world"
app = YubikeyKsm()

View File

@ -1,55 +1,107 @@
from wtforms import Form
from wtforms.fields import StringField, IntegerField
from wtforms.validators import NumberRange
from wtforms.fields import StringField, IntegerField, PasswordField
from wtforms.validators import NumberRange, Optional
from wtforms.widgets import PasswordInput
from yubiadmin.util import App, ConfigForm, FileConfig, render
__all__ = [
'app'
]
class MiscForm(Form):
legend = 'Misc'
default_timeout = IntegerField('Default Timeout', [NumberRange(0)],
default=1)
def load(self):
self.default_timeout.process_data(5)
def save(self):
pass
def yk_read_str(varname):
return r'\$baseParams\[\'__YKVAL_%s__\'\] = [\'"](.*)[\'"];' % varname
class SyncLevelsForm(Form):
def yk_write_str(varname):
return lambda x: '$baseParams[\'__YKVAL_%s__\'] = "%s";' % (varname, x)
def yk_read_int(varname):
return r'\$baseParams\[\'__YKVAL_%s__\'\] = (\d+);' % varname
def yk_write_int(varname):
return lambda x: '$baseParams[\'__YKVAL_%s__\'] = %s;' % (varname, x)
def db_read(varname):
return r'\$db%s=\'(.*)\';' % varname
def db_write(varname):
return lambda x: '$db%s=\'%s\';' % (varname, x)
class SyncLevelsForm(ConfigForm):
legend = 'Sync Levels'
sync_default = IntegerField('Default', [NumberRange(1, 100)], default=60)
sync_secure = IntegerField('Secure', [NumberRange(1, 100)], default=40)
sync_fast = IntegerField('Fast', [NumberRange(1, 100)], default=1)
def load(self):
# TODO: Read config file
self.sync_default.process_data(40)
self.sync_secure.process_data(51)
self.sync_fast.process_data(1)
sync_default = IntegerField('Default', [NumberRange(1, 100)])
sync_secure = IntegerField('Secure', [NumberRange(1, 100)])
sync_fast = IntegerField('Fast', [NumberRange(1, 100)])
def save(self):
# TODO: Save data t config file
pass
config = FileConfig(
'/home/dain/yubico/yubiadmin/ykval-config.php',
[
(
'sync_default',
yk_read_int('SYNC_DEFAULT_LEVEL'),
yk_write_int('SYNC_DEFAULT_LEVEL'),
60
), (
'sync_secure',
yk_read_int('SYNC_SECURE_LEVEL'),
yk_write_int('SYNC_SECURE_LEVEL'),
40
), (
'sync_fast',
yk_read_int('SYNC_FAST_LEVEL'),
yk_write_int('SYNC_FAST_LEVEL'),
1
),
]
)
class DatabaseForm(Form):
class MiscForm(ConfigForm):
legend = 'Misc'
default_timeout = IntegerField('Default Timeout', [NumberRange(0)])
config = FileConfig(
'/home/dain/yubico/yubiadmin/ykval-config.php',
[(
'default_timeout',
yk_read_int('SYNC_DEFAULT_TIMEOUT'),
yk_write_int('SYNC_DEFAULT_TIMEOUT'),
1
)]
)
class DatabaseForm(ConfigForm):
legend = 'Database'
connection_string = StringField('Connection String', default=1)
attrs = {'connection_string': {'class': 'input-xxlarge'}}
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 load(self):
self.connection_string.process_data(
'mysql:dbname=ykval;host=127.0.0.1')
def save(self):
pass
config = FileConfig(
'/home/dain/yubico/yubiadmin/config-db.php',
[
('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'), ''),
]
)
class YubikeyVal(object):
class YubikeyVal(App):
"""
YubiKey Validation Server
@ -59,52 +111,28 @@ class YubikeyVal(object):
name = 'val'
sections = ['general', 'database', 'syncpool', 'ksms']
def _populate_forms(self, forms, data):
if not data:
for form in forms:
form.load()
else:
errors = False
for form in forms:
form.process(data)
errors = form.validate() or errors
if not errors:
for form in forms:
form.save()
def general(self, request):
"""
General
"""
forms = [
SyncLevelsForm(),
MiscForm()
]
self._populate_forms(forms, request.params)
return {'fieldsets': forms}
return self.render_forms(request, [SyncLevelsForm(), MiscForm()])
def database(self, request):
"""
Database Settings
"""
forms = [DatabaseForm()]
self._populate_forms(forms, request.params)
return {'fieldsets': forms}
return self.render_forms(request, [DatabaseForm()])
def syncpool(self, request):
"""
Sync pool
"""
return {}
return render('form', target=request.path)
def ksms(self, request):
"""
Key Store Modules
"""
return {}
return render('form', target=request.path)
app = YubikeyVal()

123
yubiadmin/util.py Normal file
View File

@ -0,0 +1,123 @@
import os
import re
from UserDict import DictMixin
from wtforms import Form
from jinja2 import Environment, FileSystemLoader
__all__ = [
'App',
'FileConfig',
'ConfigForm',
'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):
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):
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()