Merge the login and info plugins configurations
authorSimo Sorce <simo@redhat.com>
Tue, 31 Mar 2015 20:35:15 +0000 (16:35 -0400)
committerRob Crittenden <rcritten@redhat.com>
Wed, 29 Apr 2015 17:30:04 +0000 (13:30 -0400)
Having separate login and info plugins configuration pages doesn't
really make a lot of sense. As a first step moving towards login stacks
put login and info plugin configuration into a common "Login Stack"
menu item.

https://fedorahosted.org/ipsilon/ticket/117

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Rob Crittenden <rcritten@redhat.com>
ipsilon/admin/common.py
ipsilon/admin/info.py
ipsilon/admin/login.py
ipsilon/admin/loginstack.py [new file with mode: 0644]
ipsilon/root.py
templates/admin/ipsilon-scheme.svg
templates/admin/loginstack.html [new file with mode: 0644]

index 76d3fd6..743c71c 100644 (file)
@@ -218,6 +218,9 @@ class AdminPlugins(AdminPage):
         self.order = None
         parent.add_subtree(name, self)
 
+        if self._site[facility] is None:
+            return
+
         for plugin in self._site[facility].available:
             cherrypy.log.error('Admin info plugin: %s' % plugin)
             obj = self._site[facility].available[plugin]
index 38c8d54..4bc85c4 100644 (file)
@@ -1,10 +1,10 @@
 # Copyright (C) 2014  Ipsilon Contributors see COPYING for license
 
-from ipsilon.admin.common import AdminPlugins
+from ipsilon.admin.loginstack import LoginStackPlugins
 from ipsilon.info.common import FACILITY
 
 
-class InfoPlugins(AdminPlugins):
+class InfoPlugins(LoginStackPlugins):
     def __init__(self, site, parent):
         super(InfoPlugins, self).__init__('info', site, parent, FACILITY)
         self.title = 'Info Plugins'
index 0223758..deb1e3d 100644 (file)
@@ -1,10 +1,10 @@
 # Copyright (C) 2014  Ipsilon Contributors see COPYING for license
 
-from ipsilon.admin.common import AdminPlugins
+from ipsilon.admin.loginstack import LoginStackPlugins
 from ipsilon.login.common import FACILITY
 
 
-class LoginPlugins(AdminPlugins):
+class LoginPlugins(LoginStackPlugins):
     def __init__(self, site, parent):
         super(LoginPlugins, self).__init__('login', site, parent, FACILITY)
         self.title = 'Login Plugins'
diff --git a/ipsilon/admin/loginstack.py b/ipsilon/admin/loginstack.py
new file mode 100644 (file)
index 0000000..1faa089
--- /dev/null
@@ -0,0 +1,71 @@
+# Copyright (C) 2014  Ipsilon Contributors see COPYING for license
+
+from ipsilon.admin.common import AdminPlugins
+
+
+FACILITY = 'login stack'
+
+
+class LoginStackPlugins(AdminPlugins):
+
+    def __init__(self, name, site, parent, facility, **kwargs):
+        super(LoginStackPlugins, self).__init__(name, site, parent,
+                                                facility,  **kwargs)
+        self.parent = parent
+
+    def root_with_msg(self, message=None, message_type=None, changed=None):
+        return self.parent.root_with_msg(message, message_type, changed)
+
+
+class LoginStack(AdminPlugins):
+    def __init__(self, site, parent):
+        self.children = []
+        site[FACILITY] = None
+        super(LoginStack, self).__init__('loginstack', site, parent, FACILITY)
+        self.title = 'Login Stack'
+        self.template = 'admin/loginstack.html'
+
+    def add_subtree(self, name, page):
+        self.__dict__[name] = page
+        self.children.append(page)
+
+    def del_subtree(self, name):
+        self.children.remove(self.__dict__[name])
+        del self.__dict__[name]
+
+    def get_children_urls(self):
+        urls = dict()
+        for item in self.children:
+            name = getattr(item, 'name', None)
+            if name:
+                urls['%s_url' % name] = cherrypy.url('/%s/%s' % (self.mount,
+                                                                 name))
+        return urls
+
+    def root_with_msg(self, message=None, message_type=None, changed=None):
+        # Force the url to be that of the Login Stack
+        kwargs = {'title': self.title,
+                  'menu': self._master.menu,
+                  'message': message,
+                  'message_type': message_type,
+                  'newurl': self.url,
+                  'sections': list()}
+        for child in self.children:
+            plugins = child._site[child.facility]
+
+            if changed is None:
+                changed = dict()
+
+            targs = {'title': child.title,
+                     'available': plugins.available,
+                     'enabled': plugins.enabled,
+                     'changed': changed,
+                     'baseurl': child.url}
+            if child.order:
+                targs['order_name'] = '%s_order_form' % child.name
+                targs['order_action'] = child.order.url
+
+            kwargs['sections'].append(targs)
+
+        # pylint: disable=star-args
+        return self._template(self.template, **kwargs)
index 93b6cd4..6326436 100644 (file)
@@ -21,6 +21,7 @@ from ipsilon.login.common import Login
 from ipsilon.login.common import Logout
 from ipsilon.admin.common import Admin
 from ipsilon.providers.common import LoadProviders
+from ipsilon.admin.loginstack import LoginStack
 from ipsilon.admin.info import InfoPlugins
 from ipsilon.admin.login import LoginPlugins
 from ipsilon.admin.providers import ProviderPlugins
@@ -57,8 +58,9 @@ class Root(Page):
         # after all plugins are setup we can instantiate the admin pages
         self.admin = Admin(self._site, 'admin')
         self.rest = Rest(self._site, 'rest')
-        InfoPlugins(self._site, self.admin)
-        LoginPlugins(self._site, self.admin)
+        self.stack = LoginStack(self._site, self.admin)
+        LoginPlugins(self._site, self.stack)
+        InfoPlugins(self._site, self.stack)
         ProviderPlugins(self._site, self.admin)
         RestProviderPlugins(self._site, self.rest)
 
index 6f7fec7..ef2ae80 100644 (file)
@@ -541,7 +541,7 @@ rect:hover { fill-opacity:0;stroke-opacity:1.0; }
        inkscape:connector-curvature="0"
        sodipodi:nodetypes="cscccsccc" />
     <a
-       xlink:href="{{ info_url }}"
+       xlink:href="{{ loginstack_url }}"
        style="fill-opacity:0;stroke-opacity:0"
        target="_parent"
        id="info_plugins">
@@ -645,7 +645,7 @@ rect:hover { fill-opacity:0;stroke-opacity:1.0; }
          y="490" />
     </a>
     <a
-       xlink:href="{{ login_url }}"
+       xlink:href="{{ loginstack_url }}"
        style="fill-opacity:0;stroke-opacity:0"
        target="_parent"
        id="login_plugins">
diff --git a/templates/admin/loginstack.html b/templates/admin/loginstack.html
new file mode 100644 (file)
index 0000000..da394e3
--- /dev/null
@@ -0,0 +1,117 @@
+{% extends "master-admin.html" %}
+{% block main %}
+{% if user.is_admin %}
+
+    <div class = "row">
+        <div class="col-md-6 col-sm-6 col-xs-6" role="alert">
+          {% if message and message_type != 'success' %}
+            <div class="alert alert-{{message_type}}">
+                <p>{{ message }}</p>
+            </div>
+          {% endif %}
+        </div>
+    </div>
+
+  {% for s in sections %}
+    <div class = "row">
+        <div class="col-md-6 col-sm-6 col-xs-6">
+            <h2>{{ s["title"] }}</h2>
+        </div>
+    </div>
+    {% for p in s["enabled"] %}
+      {% set highlight = "hl-enabled" %}
+      {% if p in s["changed"] %}
+        {% if s["changed"][p] == 'enabled' %}
+        {% set highlight = "hl-enabled-new" %}
+        {% elif s["changed"][p] == 'reordered' %}
+        {% set highlight = "hl-enabled-flash" %}
+        {% endif %}
+      {% endif %}
+      <div class="row ipsilon-row {{ highlight }}">
+        <div class="col-md-3 col-sm-3 col-xs-5">
+          <p><strong>{{ p }}</strong></p>
+        </div>
+        <div class="col-md-7 col-sm-7 col-xs-5">
+          <div class="row">
+          <div class="col-md-6 col-sm-6 col-xs-12">
+              <p class="text-info"><a href="{{ s["baseurl"] }}/disable/{{ p }}">Disable</a></p>
+          </div>
+          <div class="col-md-6 col-sm-6 col-xs-12">
+            {%- if s["available"][p].get_config_obj() %}
+              <p class="text-primary"><a href="{{ s["baseurl"] }}/{{ p }}">Configure</a></p>
+            {% endif %}
+          </div>
+          </div>
+        </div>
+        <div class="col-md-2 col-sm-2 col-xs-1">
+          {%- if not (loop.first and loop.last) %}
+          <form role="form" id="{{ s["order_name"] }}" action="{{ s["order_action"] }}" method="post" enctype="application/x-www-form-urlencoded">
+            {%- set outer_loop = loop %}
+            {%- for move in ['&uarr;', '&darr;'] %}
+              {%- if move == '&uarr;' %}
+                {%- if outer_loop.first %}
+                  {%- set state='disabled' %}
+                {%- else %}
+                  {%- set state='btn-default' %}
+                  {%- set idx0=outer_loop.index0-1 %}
+                  {%- set idx1=outer_loop.index0 %}
+                {%- endif %}
+              {%- else %}
+                {%- if outer_loop.last %}
+                  {%- set state='disabled' %}
+                {%- else %}
+                  {%- set state='btn-default' %}
+                  {%- set idx0=outer_loop.index0 %}
+                  {%- set idx1=outer_loop.index0+1 %}
+                {%- endif %}
+              {%- endif %}
+              <button id="submit" class="btn {{ state }}" name="order" type="submit" value="
+              {%- for i in range(s["enabled"]|length) %}
+                {%- if i == idx0 -%}
+                  {{- s["enabled"][idx1] -}}
+                {%- elif i == idx1 -%}
+                  {{- s["enabled"][idx0] -}}
+                {%- else -%}
+                  {{- s["enabled"][i] -}}
+                {%- endif -%}
+                {%- if not loop.last -%},{%- endif -%}
+              {%- endfor -%}
+              ">{{ move }}</button>
+            {%- endfor %}
+          </form>
+          {%- endif %}
+        </div>
+      </div>
+    {% endfor %}
+
+    {% for p in s["available"] if not p in s["enabled"] %}
+      {% set highlight = "hl-disabled" %}
+      {% if p in s["changed"] %}
+        {% if s["changed"][p] == 'disabled' %}
+        {% set highlight = "hl-disabled-new" %}
+        {% endif %}
+      {% endif %}
+      <div class="row ipsilon-row {{ highlight }}">
+        <div class="col-md-3 col-sm-3 col-xs-5">
+            <strong>{{ p }}</strong>
+        </div>
+        <div class="col-md-7 col-sm-7 col-xs-6">
+          <div class="row">
+          <div class="col-md-6 col-sm-6 col-xs-12">
+              <a class="text-info" href="{{ s["baseurl"] }}/enable/{{ p }}">Enable</a>
+          </div>
+          <div class="col-md-6 col-sm-6 col-xs-12">
+            {%- if s["available"][p].get_config_obj() %}
+              <span class="text-muted">Configure</span>
+            {% endif %}
+          </div>
+          </div>
+        </div>
+        <div class="col-md-2 col-sm-2 col-xs-1">
+        </div>
+      </div>
+    {% endfor %}
+  {% endfor %}
+
+{% endif %}
+{% endblock %}