Implement plugin ordering configuration
[cascardo/ipsilon.git] / ipsilon / admin / common.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 from ipsilon.util.data import Store
21 from ipsilon.util.page import Page
22 from ipsilon.util.user import UserSession
23 from ipsilon.util.plugin import PluginObject
24 import cherrypy
25 from ipsilon.login.common import FACILITY as LOGIN_FACILITY
26
27
28 def admin_protect(fn):
29
30     def check(*args, **kwargs):
31         if UserSession().get_user().is_admin:
32             return fn(*args, **kwargs)
33
34         raise cherrypy.HTTPError(403)
35
36     return check
37
38
39 class LoginPluginPage(Page):
40
41     def __init__(self, obj, site, baseurl):
42         super(LoginPluginPage, self).__init__(site)
43         self._obj = obj
44         self.url = '%s/%s' % (baseurl, obj.name)
45
46         # Get the defaults
47         self.plugin_config = obj.get_config_desc()
48         if not self.plugin_config:
49             self.plugin_config = []
50
51         # Now overlay the actual config
52         for option in self.plugin_config:
53             self.plugin_config[option][2] = obj.get_config_value(option)
54
55     @admin_protect
56     def GET(self, *args, **kwargs):
57         return self._template('admin/login_plugin.html',
58                               title='%s plugin' % self._obj.name,
59                               name='admin_login_%s_form' % self._obj.name,
60                               action=self.url,
61                               options=self.plugin_config)
62
63     @admin_protect
64     def POST(self, *args, **kwargs):
65
66         message = "Nothing was modified."
67         message_type = "info"
68         new_values = dict()
69
70         for key, value in kwargs.iteritems():
71             if key in self.plugin_config:
72                 if value != self.plugin_config[key][2]:
73                     cherrypy.log.error("Storing [%s]: %s = %s" %
74                                        (self._obj.name, key, value))
75                     new_values[key] = value
76
77         if len(new_values) != 0:
78             # First we try to save in the database
79             try:
80                 store = Store()
81                 store.save_plugin_config(LOGIN_FACILITY,
82                                          self._obj.name, new_values)
83                 message = "New configuration saved."
84                 message_type = "success"
85             except Exception:  # pylint: disable=broad-except
86                 message = "Failed to save data!"
87                 message_type = "error"
88
89             # And only if it succeeds we change the live object
90             for name, value in new_values.items():
91                 self._obj.set_config_value(name, value)
92                 self.plugin_config[name][2] = value
93
94         return self._template('admin/login_plugin.html',
95                               message=message,
96                               message_type=message_type,
97                               title='%s plugin' % self._obj.name,
98                               name='admin_login_%s_form' % self._obj.name,
99                               action=self.url,
100                               options=self.plugin_config)
101
102     def root(self, *args, **kwargs):
103         cherrypy.log.error("method: %s" % cherrypy.request.method)
104         op = getattr(self, cherrypy.request.method, self.GET)
105         if callable(op):
106             return op(*args, **kwargs)
107
108
109 class LoginPluginsOrder(Page):
110
111     def __init__(self, site, baseurl):
112         super(LoginPluginsOrder, self).__init__(site)
113         self.url = '%s/order' % baseurl
114
115     @admin_protect
116     def GET(self, *args, **kwargs):
117         return self._template('admin/login_order.html',
118                               title='login plugins order',
119                               name='admin_login_order_form',
120                               action=self.url,
121                               options=self._site[LOGIN_FACILITY]['enabled'])
122
123     @admin_protect
124     def POST(self, *args, **kwargs):
125         message = "Nothing was modified."
126         message_type = "info"
127         valid = self._site[LOGIN_FACILITY]['enabled']
128
129         if 'order' in kwargs:
130             order = kwargs['order'].split(',')
131             if len(order) != 0:
132                 new_values = []
133                 try:
134                     for v in order:
135                         val = v.strip()
136                         if val not in valid:
137                             error = "Invalid plugin name: %s" % val
138                             raise ValueError(error)
139                         new_values.append(val)
140                     if len(new_values) < len(valid):
141                         for val in valid:
142                             if val not in new_values:
143                                 new_values.append(val)
144
145                     po = PluginObject()
146                     po.name = "global"
147                     globalconf = dict()
148                     globalconf['order'] = ','.join(new_values)
149                     po.set_config(globalconf)
150                     po.save_plugin_config(LOGIN_FACILITY)
151
152                     # When all is saved update also live config
153                     self._site[LOGIN_FACILITY]['enabled'] = new_values
154
155                     message = "New configuration saved."
156                     message_type = "success"
157
158                 except ValueError, e:
159                     message = str(e)
160                     message_type = "error"
161
162                 except Exception, e:  # pylint: disable=broad-except
163                     message = "Failed to save data!"
164                     message_type = "error"
165
166         return self._template('admin/login_order.html',
167                               message=message,
168                               message_type=message_type,
169                               title='login plugins order',
170                               name='admin_login_order_form',
171                               action=self.url,
172                               options=self._site[LOGIN_FACILITY]['enabled'])
173
174     def root(self, *args, **kwargs):
175         cherrypy.log.error("method: %s" % cherrypy.request.method)
176         op = getattr(self, cherrypy.request.method, self.GET)
177         if callable(op):
178             return op(*args, **kwargs)
179
180
181 class LoginPlugins(Page):
182     def __init__(self, site, baseurl):
183         super(LoginPlugins, self).__init__(site)
184         self.url = '%s/login' % baseurl
185
186         for plugin in self._site[LOGIN_FACILITY]['available']:
187             cherrypy.log.error('Admin login plugin: %s' % plugin)
188             obj = self._site[LOGIN_FACILITY]['available'][plugin]
189             self.__dict__[plugin] = LoginPluginPage(obj, self._site, self.url)
190
191         self.order = LoginPluginsOrder(self._site, self.url)
192
193
194 class Admin(Page):
195
196     def __init__(self, *args, **kwargs):
197         super(Admin, self).__init__(*args, **kwargs)
198         self.url = '%s/admin' % self.basepath
199         self.login = LoginPlugins(self._site, self.url)
200
201     def root(self, *args, **kwargs):
202         login_plugins = self._site[LOGIN_FACILITY]
203         return self._template('admin/index.html', title='Administration',
204                               available=login_plugins['available'],
205                               enabled=login_plugins['enabled'])