4645917902b2703cf486cae01deac34423216663
[cascardo/ipsilon.git] / ipsilon / admin / login.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2014  Simo Sorce <simo@redhat.com>
4 #
5 # see file 'COPYING' for use and warranty information
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import cherrypy
21 from ipsilon.util.page import admin_protect
22 from ipsilon.util.plugin import PluginObject
23 from ipsilon.admin.common import AdminPluginPage
24 from ipsilon.admin.common import AdminPage
25 from ipsilon.login.common import FACILITY
26
27
28 def save_enabled_plugins(names):
29     po = PluginObject()
30     po.name = "global"
31     globalconf = dict()
32     globalconf['order'] = ','.join(names)
33     po.set_config(globalconf)
34     po.save_plugin_config(FACILITY)
35
36
37 class LoginPluginsOrder(AdminPage):
38
39     def __init__(self, site, parent):
40         super(LoginPluginsOrder, self).__init__(site, form=True)
41         self.url = '%s/order' % parent.url
42         self.menu = [parent]
43
44     def _reorder_plugins(self, order):
45         plugins = self._site[FACILITY]['available']
46         root = self._site[FACILITY]['root']
47         prev_obj = None
48         for name in order:
49             if prev_obj is None:
50                 root.first_login = plugins[name]
51             else:
52                 prev_obj.next_login = plugins[name]
53             prev_obj = plugins[name]
54         prev_obj.next_login = None
55
56     @admin_protect
57     def GET(self, *args, **kwargs):
58         opts = [p.name for p in self._site[FACILITY]['enabled']]
59         return self._template('admin/login_order.html',
60                               title='login plugins order',
61                               name='admin_login_order_form',
62                               menu=self.menu, action=self.url,
63                               options=opts)
64
65     @admin_protect
66     def POST(self, *args, **kwargs):
67         message = "Nothing was modified."
68         message_type = "info"
69         plugins_by_name = {p.name: p for p in self._site[FACILITY]['enabled']}
70
71         if 'order' in kwargs:
72             order = kwargs['order'].split(',')
73             if len(order) != 0:
74                 new_names = []
75                 new_plugins = []
76                 try:
77                     for v in order:
78                         val = v.strip()
79                         if val not in plugins_by_name:
80                             error = "Invalid plugin name: %s" % val
81                             raise ValueError(error)
82                         new_names.append(val)
83                         new_plugins.append(plugins_by_name[val])
84                     if len(new_names) < len(plugins_by_name):
85                         for val in plugins_by_name:
86                             if val not in new_names:
87                                 new_names.append(val)
88                                 new_plugins.append(plugins_by_name[val])
89
90                     save_enabled_plugins(new_names)
91                     self._reorder_plugins(new_names)
92
93                     # When all is saved update also live config. The
94                     # live config is a list of the actual plugin
95                     # objects.
96                     self._site[FACILITY]['enabled'] = new_plugins
97
98                     message = "New configuration saved."
99                     message_type = "success"
100
101                 except ValueError, e:
102                     message = str(e)
103                     message_type = "error"
104
105                 except Exception, e:  # pylint: disable=broad-except
106                     message = "Failed to save data!"
107                     message_type = "error"
108
109         opts = [p.name for p in self._site[FACILITY]['enabled']]
110         return self._template('admin/login_order.html',
111                               message=message,
112                               message_type=message_type,
113                               title='login plugins order',
114                               name='admin_login_order_form',
115                               menu=self.menu, action=self.url,
116                               options=opts)
117
118
119 class LoginPlugins(AdminPage):
120     def __init__(self, site, parent):
121         super(LoginPlugins, self).__init__(site)
122         self._master = parent
123         self.title = 'Login Plugins'
124         self.url = '%s/login' % parent.url
125         self.facility = FACILITY
126         parent.add_subtree('login', self)
127
128         for plugin in self._site[FACILITY]['available']:
129             cherrypy.log.error('Admin login plugin: %s' % plugin)
130             obj = self._site[FACILITY]['available'][plugin]
131             self.__dict__[plugin] = AdminPluginPage(obj, self._site, self)
132
133         self.order = LoginPluginsOrder(self._site, self)
134
135     def root_with_msg(self, message=None, message_type=None):
136         login_plugins = self._site[FACILITY]
137         ordered = []
138         for p in login_plugins['enabled']:
139             ordered.append(p.name)
140         return self._template('admin/login.html', title=self.title,
141                               message=message,
142                               message_type=message_type,
143                               available=login_plugins['available'],
144                               enabled=ordered,
145                               menu=self._master.menu)
146
147     def root(self, *args, **kwargs):
148         return self.root_with_msg()
149
150     @admin_protect
151     def enable(self, plugin):
152         msg = None
153         plugins = self._site[FACILITY]
154         if plugin not in plugins['available']:
155             msg = "Unknown plugin %s" % plugin
156             return self.root_with_msg(msg, "error")
157         obj = plugins['available'][plugin]
158         if obj not in plugins['enabled']:
159             obj.enable(self._site)
160             save_enabled_plugins(list(x.name for x in plugins['enabled']))
161             msg = "Plugin %s enabled" % obj.name
162         return self.root_with_msg(msg, "success")
163     enable.public_function = True
164
165     @admin_protect
166     def disable(self, plugin):
167         msg = None
168         plugins = self._site[FACILITY]
169         if plugin not in plugins['available']:
170             msg = "Unknown plugin %s" % plugin
171             return self.root_with_msg(msg, "error")
172         obj = plugins['available'][plugin]
173         if obj in plugins['enabled']:
174             obj.disable(self._site)
175             save_enabled_plugins(list(x.name for x in plugins['enabled']))
176             msg = "Plugin %s disabled" % obj.name
177         return self.root_with_msg(msg, "success")
178     disable.public_function = True