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:
parent
d690b94982
commit
86c45089ed
@ -88,3 +88,5 @@
|
||||
</div>
|
||||
</form>
|
||||
{%- endmacro -%}
|
||||
|
||||
{{ render_form(fieldsets, target) }}
|
@ -1,3 +0,0 @@
|
||||
<h2>Database settings</h2>
|
||||
|
||||
<p>This is where general settings go.</p>
|
@ -1,3 +0,0 @@
|
||||
<h2>General settings</h2>
|
||||
|
||||
<p>This is where general settings go.</p>
|
@ -1,3 +0,0 @@
|
||||
<h2>KSM settings</h2>
|
||||
|
||||
<p>This is where general settings go.</p>
|
@ -1,3 +0,0 @@
|
||||
{% from "forms.html" import render_form %}
|
||||
|
||||
{{ render_form(fieldsets, '/val/database') }}
|
@ -1,3 +0,0 @@
|
||||
{% from "forms.html" import render_form %}
|
||||
|
||||
{{ render_form(fieldsets, '/val/general') }}
|
@ -1,3 +0,0 @@
|
||||
<h2>KSM settings</h2>
|
||||
|
||||
<p>This is where general settings go.</p>
|
@ -1,3 +0,0 @@
|
||||
<h2>KSM settings</h2>
|
||||
|
||||
<p>This is where general settings go.</p>
|
@ -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__':
|
||||
|
@ -17,6 +17,6 @@ class YubikeyKsm(object):
|
||||
"""
|
||||
Database Settings
|
||||
"""
|
||||
return {}
|
||||
return "Hello world"
|
||||
|
||||
app = YubikeyKsm()
|
||||
|
@ -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
123
yubiadmin/util.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user