pam: use a pam object method instead of pam module function
[cascardo/ipsilon.git] / ipsilon / util / user.py
1 # Copyright (C) 2013 Ipsilon project Contributors, for license see COPYING
2
3 from ipsilon.util.data import UserStore
4 from ipsilon.util.log import Log
5 import cherrypy
6 import logging
7
8
9 class Site(object):
10     def __init__(self, value):
11         # implement lookup of sites id for link/name
12         self.link = value
13         self.name = value
14
15
16 class User(object):
17     def __init__(self, username):
18         if username is None:
19             self.name = None
20             self._userdata = dict()
21         else:
22             self._userdata = self._get_user_data(username)
23             self.name = username
24
25     def _get_user_data(self, username):
26         store = UserStore()
27         return store.load_user_preferences(username)
28
29     def reset(self):
30         self.name = None
31         self._userdata = dict()
32
33     @property
34     def is_anonymous(self):
35         if self.name:
36             return False
37         return True
38
39     @property
40     def is_admin(self):
41         if 'is_admin' in self._userdata:
42             if str(self._userdata['is_admin']) == '1':
43                 return True
44         return False
45
46     @is_admin.setter
47     def is_admin(self, value):
48         if value is True:
49             self._userdata['is_admin'] = '1'
50         else:
51             self._userdata['is_admin'] = '0'
52
53     @property
54     def fullname(self):
55         if 'fullname' in self._userdata:
56             return self._userdata['fullname']
57         else:
58             return self.name
59
60     @fullname.setter
61     def fullname(self, value):
62         self._userdata['fullname'] = value
63
64     @property
65     def email(self):
66         if 'email' in self._userdata:
67             return self._userdata['email']
68         else:
69             return None
70
71     @property
72     def sites(self):
73         if 'sites' in self._userdata:
74             d = []
75             for site in self._userdata['sites']:
76                 d.append(Site(site))
77         else:
78             return []
79
80     @sites.setter
81     def sites(self):
82         # TODO: implement setting sites via the user object ?
83         raise AttributeError
84
85     def save_plugin_data(self, plugin, data):
86         store = UserStore()
87         store.save_plugin_data(plugin, self.name, data)
88
89     def load_plugin_data(self, plugin):
90         store = UserStore()
91         return store.load_plugin_data(plugin, self.name)
92
93
94 class UserSession(Log):
95     def __init__(self):
96         self.user = self.get_data('user', 'name')
97         self.userattrs = self.get_user_attrs()
98
99     def get_user(self):
100         return User(self.user)
101
102     def remote_login(self):
103         if cherrypy.request.login:
104             self.login(cherrypy.request.login)
105         else:
106             self.nuke_data('user')
107
108     def login(self, username, userattrs=None):
109         if self.user == username:
110             if userattrs and not self.get_user_attrs():
111                 self.save_user_attrs(userattrs)
112             return
113
114         # REMOTE_USER changed, replace user
115         self.nuke_data('user')
116         self.save_data('user', 'name', username)
117         self.user = username
118
119         # Save additional data provided by the login manager
120         self.nuke_data('userattrs')
121         if userattrs:
122             self.save_user_attrs(userattrs)
123
124         cherrypy.log('LOGIN SUCCESSFUL: %s' % username)
125
126     def logout(self, user):
127         if user is not None:
128             if not isinstance(user, User):
129                 raise TypeError
130             # Completely reset user data
131             cherrypy.log.error('%s %s' % (user.name, user.fullname),
132                                severity=logging.INFO)
133             user.reset()
134
135         # Destroy current session in all cases
136         cherrypy.lib.sessions.expire()
137
138     def get_user_attrs(self):
139         userattrs = dict()
140         if 'userattrs' in cherrypy.session:
141             userattrs = cherrypy.session['userattrs']
142         return userattrs
143
144     def save_user_attrs(self, userattrs):
145         cherrypy.session['userattrs'] = userattrs
146         self.debug('Saved user attrs')
147         self.userattrs = userattrs
148
149     def _get_provider_attr_name(self, provider):
150         return '%s_data' % provider
151
152     def get_provider_data(self, provider):
153         attr = self._get_provider_attr_name(provider)
154         data = None
155         if attr in cherrypy.session:
156             data = cherrypy.session[attr]
157         return data
158
159     def save_provider_data(self, provider, data):
160         attr = self._get_provider_attr_name(provider)
161         cherrypy.session[attr] = data
162         self.debug('Saved %s provider data' % provider)
163
164     def save_data(self, facility, name, data):
165         """ Save named data in the session so it can be retrieved later """
166         if facility not in cherrypy.session:
167             cherrypy.session[facility] = dict()
168         cherrypy.session[facility][name] = data
169         self.debug('Saved session data named [%s:%s]' % (facility, name))
170
171     def get_data(self, facility, name):
172         """ Get named data in the session if available """
173         if facility not in cherrypy.session:
174             return None
175         if name not in cherrypy.session[facility]:
176             return None
177         return cherrypy.session[facility][name]
178
179     def nuke_data(self, facility, name=None):
180         if facility not in cherrypy.session:
181             return
182         if name:
183             if name not in cherrypy.session[facility]:
184                 return
185             cherrypy.session[facility][name] = None
186             del cherrypy.session[facility][name]
187             self.debug('Nuked session data named [%s:%s]' % (facility, name))
188         else:
189             del cherrypy.session[facility]
190             self.debug('Nuked session facility [%s]' % (facility,))