Refactor login plugin enablement code
authorSimo Sorce <simo@redhat.com>
Wed, 26 Mar 2014 21:31:19 +0000 (17:31 -0400)
committerSimo Sorce <simo@redhat.com>
Fri, 28 Mar 2014 18:12:09 +0000 (14:12 -0400)
This allows us to finally implement the plugin enable/disable configuration
buttons and enable/disable plugins on the fly.

Signed-off-by: Simo Sorce <simo@redhat.com>
ipsilon/admin/login.py
ipsilon/login/common.py
templates/admin/login.html

index b8325c8..d11c1f1 100755 (executable)
@@ -114,9 +114,43 @@ class LoginPlugins(Page):
 
         self.order = LoginPluginsOrder(self._site, self)
 
 
         self.order = LoginPluginsOrder(self._site, self)
 
-    def root(self, *args, **kwargs):
+    def root_with_msg(self, message=None, message_type=None):
         login_plugins = self._site[FACILITY]
         login_plugins = self._site[FACILITY]
+        ordered = []
+        for p in login_plugins['enabled']:
+            ordered.append(p.name)
         return self._template('admin/login.html', title=self.title,
         return self._template('admin/login.html', title=self.title,
+                              message=message,
+                              message_type=message_type,
                               available=login_plugins['available'],
                               available=login_plugins['available'],
-                              enabled=login_plugins['enabled'],
+                              enabled=ordered,
                               menu=self._master.menu)
                               menu=self._master.menu)
+
+    def root(self, *args, **kwargs):
+        return self.root_with_msg()
+
+    def enable(self, plugin):
+        msg = None
+        plugins = self._site[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 not in plugins['enabled']:
+            obj.enable(self._site)
+            msg = "Plugin %s enabled" % obj.name
+        return self.root_with_msg(msg, "success")
+    enable.exposed = True
+
+    def disable(self, plugin):
+        msg = None
+        plugins = self._site[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 in plugins['enabled']:
+            obj.disable(self._site)
+            msg = "Plugin %s disabled" % obj.name
+        return self.root_with_msg(msg, "success")
+    disable.exposed = True
index d290521..f0efebd 100755 (executable)
@@ -68,6 +68,61 @@ class LoginManagerBase(PluginObject):
 
         raise cherrypy.HTTPRedirect(ref)
 
 
         raise cherrypy.HTTPRedirect(ref)
 
+    def _debug(self, fact):
+        if cherrypy.config.get('debug', False):
+            cherrypy.log(fact)
+
+    def get_tree(self, site):
+        raise NotImplementedError
+
+    def enable(self, site):
+        plugins = site[FACILITY]
+        if self in plugins['enabled']:
+            return
+
+        # configure self
+        if self.name in plugins['config']:
+            self.set_config(plugins['config'][self.name])
+
+        # and add self to the root
+        root = plugins['root']
+        root.add_subtree(self.name, self.get_tree(site))
+
+        # finally add self in login chain
+        prev_obj = None
+        for prev_obj in plugins['enabled']:
+            if prev_obj.next_login:
+                break
+        if prev_obj:
+            while prev_obj.next_login:
+                prev_obj = prev_obj.next_login
+            prev_obj.next_login = self
+        if not root.first_login:
+            root.first_login = self
+
+        plugins['enabled'].append(self)
+        self._debug('Login plugin enabled: %s' % self.name)
+
+    def disable(self, site):
+        plugins = site[FACILITY]
+        if self not in plugins['enabled']:
+            return
+
+        #remove self from chain
+        root = plugins['root']
+        if root.first_login == self:
+            root.first_login = self.next_login
+        elif root.first_login:
+            prev_obj = root.first_login
+            while prev_obj.next_login != self:
+                prev_obj = prev_obj.next_login
+            if prev_obj:
+                prev_obj.next_login = self.next_login
+        self.next_login = None
+
+        plugins['enabled'].remove(self)
+        self._debug('Login plugin disabled: %s' % self.name)
+
 
 class LoginPageBase(Page):
 
 
 class LoginPageBase(Page):
 
@@ -95,22 +150,15 @@ class Login(Page):
         available = plugins['available'].keys()
         self._debug('Available login managers: %s' % str(available))
 
         available = plugins['available'].keys()
         self._debug('Available login managers: %s' % str(available))
 
-        prev_obj = None
+        plugins['root'] = self
         for item in plugins['whitelist']:
             self._debug('Login plugin in whitelist: %s' % item)
             if item not in plugins['available']:
                 continue
         for item in plugins['whitelist']:
             self._debug('Login plugin in whitelist: %s' % item)
             if item not in plugins['available']:
                 continue
-            self._debug('Login plugin enabled: %s' % item)
-            plugins['enabled'].append(item)
-            obj = plugins['available'][item]
-            if prev_obj:
-                prev_obj.next_login = obj
-            else:
-                self.first_login = obj
-            prev_obj = obj
-            if item in plugins['config']:
-                obj.set_config(plugins['config'][item])
-            self.__dict__[item] = obj.get_tree(self._site)
+            plugins['available'][item].enable(self._site)
+
+    def add_subtree(self, name, page):
+        self.__dict__[name] = page
 
     def root(self, *args, **kwargs):
         if self.first_login:
 
     def root(self, *args, **kwargs):
         if self.first_login:
index 1957a7f..9f51d02 100644 (file)
@@ -2,16 +2,21 @@
 {% block main %}
 {% if user.is_admin %}
     <h2>Login plugins</h2>
 {% block main %}
 {% if user.is_admin %}
     <h2>Login plugins</h2>
+    {% if message %}
+    <div class="alert alert-{{message_type}}">
+        <p>{{ message }}</p>
+    </div>
+    {% endif %}
 
     {% for p in available %}
         <div class="row">
         <div class="col-md-3 col-sm-3 col-xs-6">{{ p }}</div>
         <div class="col-md-3 col-sm-3 col-xs-6">
         {% if p in enabled %}
 
     {% for p in available %}
         <div class="row">
         <div class="col-md-3 col-sm-3 col-xs-6">{{ p }}</div>
         <div class="col-md-3 col-sm-3 col-xs-6">
         {% if p in enabled %}
-            <a class="btn btn-default" href="{{ basepath }}/admin/login/{{ p }}/disable">Disable</a>
+            <a class="btn btn-default" href="{{ basepath }}/admin/login/disable/{{ p }}">Disable</a>
             <a class="btn btn-default" href="{{ basepath }}/admin/login/{{ p }}">Configure</a>
         {% else %}
             <a class="btn btn-default" href="{{ basepath }}/admin/login/{{ p }}">Configure</a>
         {% else %}
-            <a class="btn btn-default" href="{{ basepath }}/admin/login/{{ p }}/enable">Enable</a>
+            <a class="btn btn-default" href="{{ basepath }}/admin/login/enable/{{ p }}">Enable</a>
         {% endif %}
         </div>
         </div>
         {% endif %}
         </div>
         </div>