aaab947d2b3e9c9f2797fc05e2ed6074d8010cd5
[cascardo/ipsilon.git] / ipsilon / util / user.py
1 # Copyright (C) 2013  Simo Sorce <simo@redhat.com>
2 #
3 # see file 'COPYING' for use and warranty information
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 from ipsilon.util.data import UserStore
19 from ipsilon.util.log import Log
20 import cherrypy
21
22
23 class Site(object):
24     def __init__(self, value):
25         # implement lookup of sites id for link/name
26         self.link = value
27         self.name = value
28
29
30 class User(object):
31     def __init__(self, username):
32         if username is None:
33             self.name = None
34             self._userdata = dict()
35         else:
36             self._userdata = self._get_user_data(username)
37             self.name = username
38
39     def _get_user_data(self, username):
40         store = UserStore()
41         return store.load_user_preferences(username)
42
43     def reset(self):
44         self.name = None
45         self._userdata = dict()
46
47     @property
48     def is_anonymous(self):
49         if self.name:
50             return False
51         return True
52
53     @property
54     def is_admin(self):
55         if 'is_admin' in self._userdata:
56             if str(self._userdata['is_admin']) == '1':
57                 return True
58         return False
59
60     @is_admin.setter
61     def is_admin(self, value):
62         if value is True:
63             self._userdata['is_admin'] = '1'
64         else:
65             self._userdata['is_admin'] = '0'
66
67     @property
68     def fullname(self):
69         if 'fullname' in self._userdata:
70             return self._userdata['fullname']
71         else:
72             return self.name
73
74     @fullname.setter
75     def fullname(self, value):
76         self._userdata['fullname'] = value
77
78     @property
79     def email(self):
80         if 'email' in self._userdata:
81             return self._userdata['email']
82         else:
83             return None
84
85     @property
86     def sites(self):
87         if 'sites' in self._userdata:
88             d = []
89             for site in self._userdata['sites']:
90                 d.append(Site(site))
91         else:
92             return []
93
94     @sites.setter
95     def sites(self):
96         # TODO: implement setting sites via the user object ?
97         raise AttributeError
98
99     def save_plugin_data(self, plugin, data):
100         store = UserStore()
101         store.save_plugin_data(plugin, self.name, data)
102
103     def load_plugin_data(self, plugin):
104         store = UserStore()
105         return store.load_plugin_data(plugin, self.name)
106
107
108 class UserSession(Log):
109     def __init__(self):
110         self.user = self.get_data('user', 'name')
111         self.userattrs = self.get_user_attrs()
112
113     def get_user(self):
114         return User(self.user)
115
116     def remote_login(self):
117         if cherrypy.request.login:
118             self.login(cherrypy.request.login)
119         else:
120             self.nuke_data('user')
121
122     def login(self, username, userattrs=None):
123         if self.user == username:
124             if userattrs and not self.get_user_attrs():
125                 self.save_user_attrs(userattrs)
126             return
127
128         # REMOTE_USER changed, replace user
129         self.nuke_data('user')
130         self.save_data('user', 'name', username)
131         self.user = username
132
133         # Save additional data provided by the login manager
134         self.nuke_data('userattrs')
135         if userattrs:
136             self.save_user_attrs(userattrs)
137
138         cherrypy.log('LOGIN SUCCESSFUL: %s' % username)
139
140     def logout(self, user):
141         if user is not None:
142             if not type(user) is User:
143                 raise TypeError
144             # Completely reset user data
145             cherrypy.log.error('%s %s' % (user.name, user.fullname))
146             user.reset()
147
148         # Destroy current session in all cases
149         cherrypy.lib.sessions.expire()
150
151     def get_user_attrs(self):
152         userattrs = dict()
153         if 'userattrs' in cherrypy.session:
154             userattrs = cherrypy.session['userattrs']
155         return userattrs
156
157     def save_user_attrs(self, userattrs):
158         cherrypy.session['userattrs'] = userattrs
159         self.debug('Saved user attrs')
160         self.userattrs = userattrs
161
162     def _get_provider_attr_name(self, provider):
163         return '%s_data' % provider
164
165     def get_provider_data(self, provider):
166         attr = self._get_provider_attr_name(provider)
167         data = None
168         if attr in cherrypy.session:
169             data = cherrypy.session[attr]
170         return data
171
172     def save_provider_data(self, provider, data):
173         attr = self._get_provider_attr_name(provider)
174         cherrypy.session[attr] = data
175         self.debug('Saved %s provider data' % provider)
176
177     def save_data(self, facility, name, data):
178         """ Save named data in the session so it can be retrieved later """
179         if facility not in cherrypy.session:
180             cherrypy.session[facility] = dict()
181         cherrypy.session[facility][name] = data
182         self.debug('Saved session data named [%s:%s]' % (facility, name))
183
184     def get_data(self, facility, name):
185         """ Get named data in the session if available """
186         if facility not in cherrypy.session:
187             return None
188         if name not in cherrypy.session[facility]:
189             return None
190         return cherrypy.session[facility][name]
191
192     def nuke_data(self, facility, name=None):
193         if facility not in cherrypy.session:
194             return
195         if name:
196             if name not in cherrypy.session[facility]:
197                 return
198             cherrypy.session[facility][name] = None
199             del cherrypy.session[facility][name]
200             self.debug('Nuked session data named [%s:%s]' % (facility, name))
201         else:
202             del cherrypy.session[facility]
203             self.debug('Nuked session facility [%s]' % (facility,))