X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Fadmin%2Fcommon.py;h=9c82142daf14566a6297215a08c0f033d01f2f75;hp=28972374433aa54b6c738f08bdeb0350a04c5036;hb=b7b80c5c0fc1895e85aae3acbfcbbc593a42697f;hpb=667901638f082e05b4ac61a14f4ddc07ec987742 diff --git a/ipsilon/admin/common.py b/ipsilon/admin/common.py index 2897237..9c82142 100755 --- a/ipsilon/admin/common.py +++ b/ipsilon/admin/common.py @@ -17,129 +17,145 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from ipsilon.util.data import Store +import cherrypy from ipsilon.util.page import Page from ipsilon.util.page import admin_protect -from ipsilon.util.plugin import PluginObject -import cherrypy -from ipsilon.login.common import FACILITY as LOGIN_FACILITY - +from ipsilon.util import config as pconfig -class LoginPluginPage(Page): - def __init__(self, obj, site, baseurl): - super(LoginPluginPage, self).__init__(site) - self._obj = obj - self.url = '%s/%s' % (baseurl, obj.name) +class AdminPage(Page): - # Get the defaults - self.plugin_config = obj.get_config_desc() - if not self.plugin_config: - self.plugin_config = [] - - # Now overlay the actual config - for option in self.plugin_config: - self.plugin_config[option][2] = obj.get_config_value(option) + def __init__(self, *args, **kwargs): + super(AdminPage, self).__init__(*args, **kwargs) + self.default_headers.update({ + 'Cache-Control': 'no-cache, must-revalidate', + 'Pragma': 'no-cache', + 'Expires': 'Thu, 01 Dec 1994 16:00:00 GMT', + }) + self.auth_protect = True + + +class AdminPluginConfig(AdminPage): + + def __init__(self, po, site, parent): + super(AdminPluginConfig, self).__init__(site, form=True) + self._po = po + self.title = '%s plugin' % po.name + self.url = '%s/%s' % (parent.url, po.name) + self.facility = parent.facility + self.menu = [parent] + self.back = parent.url + + def root_with_msg(self, message=None, message_type=None): + return self._template('admin/plugin_config.html', title=self.title, + menu=self.menu, action=self.url, back=self.back, + message=message, message_type=message_type, + name='admin_%s_%s_form' % (self.facility, + self._po.name), + config=self._po.get_config_obj()) @admin_protect def GET(self, *args, **kwargs): - return self._template('admin/login_plugin.html', - title='%s plugin' % self._obj.name, - name='admin_login_%s_form' % self._obj.name, - action=self.url, - options=self.plugin_config) + return self.root_with_msg() @admin_protect def POST(self, *args, **kwargs): message = "Nothing was modified." message_type = "info" - new_values = dict() - - for key, value in kwargs.iteritems(): - if key in self.plugin_config: - if value != self.plugin_config[key][2]: - cherrypy.log.error("Storing [%s]: %s = %s" % - (self._obj.name, key, value)) - new_values[key] = value - - if len(new_values) != 0: + new_db_values = dict() + + conf = self._po.get_config_obj() + + for name, option in conf.iteritems(): + if name in kwargs: + value = kwargs[name] + if isinstance(option, pconfig.List): + value = [x.strip() for x in value.split('\n')] + elif isinstance(option, pconfig.Condition): + value = True + else: + if isinstance(option, pconfig.Condition): + value = False + elif isinstance(option, pconfig.Choice): + value = list() + for a in option.get_allowed(): + aname = '%s_%s' % (name, a) + if aname in kwargs: + value.append(a) + else: + continue + + if value != option.get_value(): + cherrypy.log.error("Storing [%s]: %s = %s" % + (self._po.name, name, value)) + option.set_value(value) + new_db_values[name] = option.export_value() + + if len(new_db_values) != 0: # First we try to save in the database try: - store = Store() - store.save_plugin_config(LOGIN_FACILITY, - self._obj.name, new_values) + self._po.save_plugin_config(new_db_values) message = "New configuration saved." message_type = "success" except Exception: # pylint: disable=broad-except message = "Failed to save data!" message_type = "error" - # And only if it succeeds we change the live object - for name, value in new_values.items(): - self._obj.set_config_value(name, value) - self.plugin_config[name][2] = value - - return self._template('admin/login_plugin.html', - message=message, - message_type=message_type, - title='%s plugin' % self._obj.name, - name='admin_login_%s_form' % self._obj.name, - action=self.url, - options=self.plugin_config) + # Then refresh the actual objects + self._po.refresh_plugin_config() - def root(self, *args, **kwargs): - cherrypy.log.error("method: %s" % cherrypy.request.method) - op = getattr(self, cherrypy.request.method, self.GET) - if callable(op): - return op(*args, **kwargs) + return self.root_with_msg(message=message, + message_type=message_type) -class LoginPluginsOrder(Page): +class AdminPluginsOrder(AdminPage): - def __init__(self, site, baseurl): - super(LoginPluginsOrder, self).__init__(site) - self.url = '%s/order' % baseurl + def __init__(self, site, parent, facility): + super(AdminPluginsOrder, self).__init__(site, form=True) + self.parent = parent + self.facility = facility + self.url = '%s/order' % parent.url + self.menu = [parent] @admin_protect def GET(self, *args, **kwargs): - return self._template('admin/login_order.html', - title='login plugins order', - name='admin_login_order_form', - action=self.url, - options=self._site[LOGIN_FACILITY]['enabled']) + return self.parent.root_with_msg() + + def _get_enabled_list(self): + cur = list() + for p in self._site[self.facility].available.values(): + if p.is_enabled: + cur.append(p.name) + return cur @admin_protect def POST(self, *args, **kwargs): message = "Nothing was modified." message_type = "info" - valid = self._site[LOGIN_FACILITY]['enabled'] + cur_enabled = self._get_enabled_list() if 'order' in kwargs: order = kwargs['order'].split(',') if len(order) != 0: - new_values = [] + new_order = [] try: for v in order: val = v.strip() - if val not in valid: + if val not in cur_enabled: error = "Invalid plugin name: %s" % val raise ValueError(error) - new_values.append(val) - if len(new_values) < len(valid): - for val in valid: - if val not in new_values: - new_values.append(val) - - po = PluginObject() - po.name = "global" - globalconf = dict() - globalconf['order'] = ','.join(new_values) - po.set_config(globalconf) - po.save_plugin_config(LOGIN_FACILITY) - - # When all is saved update also live config - self._site[LOGIN_FACILITY]['enabled'] = new_values + new_order.append(val) + if len(new_order) < len(cur_enabled): + for val in cur_enabled: + if val not in new_order: + new_order.append(val) + + self.parent.save_enabled_plugins(new_order) + + # When all is saved update also live config. The + # live config is the ordered list of plugin names. + self._site[self.facility].refresh_enabled() message = "New configuration saved." message_type = "success" @@ -152,43 +168,124 @@ class LoginPluginsOrder(Page): message = "Failed to save data!" message_type = "error" - return self._template('admin/login_order.html', - message=message, - message_type=message_type, - title='login plugins order', - name='admin_login_order_form', - action=self.url, - options=self._site[LOGIN_FACILITY]['enabled']) + return self.parent.root_with_msg(message=message, + message_type=message_type) + + +class AdminPlugins(AdminPage): + def __init__(self, name, site, parent, facility, ordered=True): + super(AdminPlugins, self).__init__(site) + self._master = parent + self.name = name + self.title = '%s plugins' % name + self.url = '%s/%s' % (parent.url, name) + self.facility = facility + self.template = 'admin/plugins.html' + self.order = None + parent.add_subtree(name, self) + + for plugin in self._site[facility].available: + cherrypy.log.error('Admin info plugin: %s' % plugin) + obj = self._site[facility].available[plugin] + page = AdminPluginConfig(obj, self._site, self) + if hasattr(obj, 'admin'): + obj.admin.mount(page) + self.add_subtree(plugin, page) + + if ordered: + self.order = AdminPluginsOrder(self._site, self, facility) + + def save_enabled_plugins(self, names): + self._site[self.facility].save_enabled(names) + + def root_with_msg(self, message=None, message_type=None): + plugins = self._site[self.facility] + + targs = {'title': self.title, + 'menu': self._master.menu, + 'message': message, + 'message_type': message_type, + 'available': plugins.available, + 'enabled': plugins.enabled, + 'baseurl': self.url, + 'newurl': self.url} + if self.order: + targs['order_name'] = '%s_order_form' % self.name + targs['order_action'] = self.order.url + + # pylint: disable=star-args + return self._template(self.template, **targs) def root(self, *args, **kwargs): - cherrypy.log.error("method: %s" % cherrypy.request.method) - op = getattr(self, cherrypy.request.method, self.GET) - if callable(op): - return op(*args, **kwargs) - - -class LoginPlugins(Page): - def __init__(self, site, baseurl): - super(LoginPlugins, self).__init__(site) - self.url = '%s/login' % baseurl - - for plugin in self._site[LOGIN_FACILITY]['available']: - cherrypy.log.error('Admin login plugin: %s' % plugin) - obj = self._site[LOGIN_FACILITY]['available'][plugin] - self.__dict__[plugin] = LoginPluginPage(obj, self._site, self.url) - - self.order = LoginPluginsOrder(self._site, self.url) - + return self.root_with_msg() -class Admin(Page): + @admin_protect + def enable(self, plugin): + msg = None + plugins = self._site[self.facility] + if plugin not in plugins.available: + msg = "Unknown plugin %s" % plugin + return self.root_with_msg(msg, "error") + obj = plugins.available[plugin] + if not obj.is_enabled: + obj.enable() + obj.save_enabled_state() + msg = "Plugin %s enabled" % obj.name + return self.root_with_msg(msg, "success") + enable.public_function = True - def __init__(self, *args, **kwargs): - super(Admin, self).__init__(*args, **kwargs) - self.url = '%s/admin' % self.basepath - self.login = LoginPlugins(self._site, self.url) + @admin_protect + def disable(self, plugin): + msg = None + plugins = self._site[self.facility] + if plugin not in plugins.available: + msg = "Unknown plugin %s" % plugin + return self.root_with_msg(msg, "error") + obj = plugins.available[plugin] + if obj.is_enabled: + obj.disable() + obj.save_enabled_state() + msg = "Plugin %s disabled" % obj.name + return self.root_with_msg(msg, "success") + disable.public_function = True + + +class Admin(AdminPage): + + def __init__(self, site, mount): + super(Admin, self).__init__(site) + self.title = 'Home' + self.mount = mount + self.url = '%s/%s' % (self.basepath, mount) + self.menu = [self] def root(self, *args, **kwargs): - login_plugins = self._site[LOGIN_FACILITY] - return self._template('admin/index.html', title='Administration', - available=login_plugins['available'], - enabled=login_plugins['enabled']) + return self._template('admin/index.html', + title='Configuration', + baseurl=self.url, + menu=self.menu) + + def add_subtree(self, name, page): + self.__dict__[name] = page + self.menu.append(page) + + def del_subtree(self, name): + self.menu.remove(self.__dict__[name]) + del self.__dict__[name] + + def get_menu_urls(self): + urls = dict() + for item in self.menu: + name = getattr(item, 'name', None) + if name: + urls['%s_url' % name] = cherrypy.url('/%s/%s' % (self.mount, + name)) + return urls + + @admin_protect + def scheme(self): + cherrypy.response.headers.update({'Content-Type': 'image/svg+xml'}) + urls = self.get_menu_urls() + # pylint: disable=star-args + return self._template('admin/ipsilon-scheme.svg', **urls) + scheme.public_function = True