]> git.ipfire.org Git - ipfire.org.git/blob - src/web/people.py
people: Add module for SIP status
[ipfire.org.git] / src / web / people.py
1 #!/usr/bin/python
2
3 import datetime
4 import ldap
5 import logging
6 import tornado.web
7
8 from . import handlers_base as base
9 from . import ui_modules
10
11 class IndexHandler(base.BaseHandler):
12 @tornado.web.authenticated
13 def get(self):
14 self.render("people/index.html")
15
16
17 class AvatarHandler(base.BaseHandler):
18 always_cache = True
19
20 def get(self, uid):
21 # Get the desired size of the avatar file
22 size = self.get_argument("size", 0)
23
24 try:
25 size = int(size)
26 except (TypeError, ValueError):
27 size = None
28
29 logging.debug("Querying for avatar of %s" % uid)
30
31 # Fetch user account
32 account = self.backend.accounts.get_by_uid(uid)
33 if not account:
34 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
35
36 # Allow downstream to cache this for 60 minutes
37 self.set_expires(3600)
38
39 # Resize avatar
40 avatar = account.get_avatar(size)
41
42 # If there is no avatar, we serve a default image
43 if not avatar:
44 logging.debug("No avatar uploaded for %s" % account)
45
46 return self.redirect(self.static_url("img/default-avatar.jpg"))
47
48 # Set headers about content
49 self.set_header("Content-Disposition", "inline; filename=\"%s.jpg\"" % account.uid)
50 self.set_header("Content-Type", "image/jpeg")
51
52 # Deliver payload
53 self.finish(avatar)
54
55
56 class CallsHandler(base.BaseHandler):
57 @tornado.web.authenticated
58 def get(self, uid, date=None):
59 account = self.backend.accounts.get_by_uid(uid)
60 if not account:
61 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
62
63 if date:
64 try:
65 date = datetime.datetime.strptime(date, "%Y-%m-%d").date()
66 except ValueError:
67 raise tornado.web.HTTPError(400, "Invalid date: %s" % date)
68 else:
69 date = datetime.date.today()
70
71 self.render("people/calls.html", account=account, date=date)
72
73
74 class CallHandler(base.BaseHandler):
75 @tornado.web.authenticated
76 def get(self, uid, uuid):
77 call = self.backend.talk.freeswitch.get_call_by_uuid(uuid)
78 if not call:
79 raise tornado.web.HTTPError(404, "Could not find call %s" % uuid)
80
81 # XXX limit
82
83 self.render("people/call.html", call=call)
84
85
86 class RegistrationsHandler(base.BaseHandler):
87 @tornado.web.authenticated
88 def get(self, uid):
89 # Get own account
90 if self.current_user.uid == uid:
91 account = self.current_user
92
93 # Admins can access all other users, too
94 elif self.current_user.is_admin():
95 account = self.backend.accounts.get_by_uid(uid)
96 if not account:
97 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
98
99 # Otherwise, no access is permitted
100 else:
101 raise tornado.web.HTTPError(403)
102
103 self.render("people/registrations.html", account=account)
104
105
106 class SearchHandler(base.BaseHandler):
107 @tornado.web.authenticated
108 def get(self):
109 q = self.get_argument("q")
110
111 # Perform the search
112 accounts = self.backend.accounts.search(q)
113
114 # Redirect when only one result was found
115 if len(accounts) == 1:
116 self.redirect("/users/%s" % accounts[0].uid)
117 return
118
119 self.render("people/search.html", q=q, accounts=accounts)
120
121
122 class UsersHandler(base.BaseHandler):
123 @tornado.web.authenticated
124 def get(self):
125 self.render("people/users.html")
126
127
128 class UserHandler(base.BaseHandler):
129 @tornado.web.authenticated
130 def get(self, uid):
131 account = self.backend.accounts.get_by_uid(uid)
132 if not account:
133 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
134
135 self.render("people/user.html", account=account)
136
137
138 class UserEditHandler(base.BaseHandler):
139 @tornado.web.authenticated
140 def get(self, uid):
141 account = self.backend.accounts.get_by_uid(uid)
142 if not account:
143 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
144
145 # Check for permissions
146 if not account.can_be_managed_by(self.current_user):
147 raise tornado.web.HTTPError(403, "%s cannot manage %s" % (self.current_user, account))
148
149 self.render("people/user-edit.html", account=account)
150
151 @tornado.web.authenticated
152 def post(self, uid):
153 account = self.backend.accounts.get_by_uid(uid)
154 if not account:
155 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
156
157 # Check for permissions
158 if not account.can_be_managed_by(self.current_user):
159 raise tornado.web.HTTPError(403, "%s cannot manage %s" % (self.current_user, account))
160
161 # Unfortunately this cannot be wrapped into a transaction
162 try:
163 account.first_name = self.get_argument("first_name")
164 account.last_name = self.get_argument("last_name")
165 account.address = self.get_argument("address")
166
167 # Avatar
168 try:
169 filename, data, mimetype = self.get_file("avatar")
170
171 if not mimetype.startswith("image/"):
172 raise tornado.web.HTTPError(400, "Avatar is not an image file: %s" % mimetype)
173
174 account.upload_avatar(data)
175 except TypeError:
176 pass
177
178 # Email
179 account.mail_routing_address = self.get_argument("mail_routing_address", None)
180
181 # Telephone
182 account.phone_numbers = self.get_argument("phone_numbers", "").splitlines()
183 account.sip_routing_address = self.get_argument("sip_routing_address", None)
184 except ldap.STRONG_AUTH_REQUIRED as e:
185 raise tornado.web.HTTPError(403, "%s" % e) from e
186
187 # Redirect back to user page
188 self.redirect("/users/%s" % account.uid)
189
190
191 class UserPasswdHandler(base.BaseHandler):
192 @tornado.web.authenticated
193 def get(self, uid):
194 account = self.backend.accounts.get_by_uid(uid)
195 if not account:
196 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
197
198 # Check for permissions
199 if not account.can_be_managed_by(self.current_user):
200 raise tornado.web.HTTPError(403, "%s cannot manage %s" % (self.current_user, account))
201
202 self.render("people/passwd.html", account=account)
203
204 @tornado.web.authenticated
205 def post(self, uid):
206 account = self.backend.accounts.get_by_uid(uid)
207 if not account:
208 raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
209
210 # Check for permissions
211 if not account.can_be_managed_by(self.current_user):
212 raise tornado.web.HTTPError(403, "%s cannot manage %s" % (self.current_user, account))
213
214 # Get current password
215 password = self.get_argument("password")
216
217 # Get new password
218 password1 = self.get_argument("password1")
219 password2 = self.get_argument("password2")
220
221 # Passwords must match
222 if not password1 == password2:
223 raise tornado.web.HTTPError(400, "Passwords do not match")
224
225 # XXX Check password complexity
226
227 # Check if old password matches
228 if not account.check_password(password):
229 raise tornado.web.HTTPError(403, "Incorrect password for %s" % account)
230
231 # Save new password
232 account.passwd(password1)
233
234 # Redirect back to user's page
235 self.redirect("/users/%s" % account.uid)
236
237
238 class AccountsListModule(ui_modules.UIModule):
239 def render(self, accounts=None):
240 if accounts is None:
241 accounts = self.backend.accounts
242
243 return self.render_string("people/modules/accounts-list.html", accounts=accounts)
244
245
246 class CDRModule(ui_modules.UIModule):
247 def render(self, account, date=None, limit=None):
248 cdr = account.get_cdr(date=date, limit=limit)
249
250 return self.render_string("people/modules/cdr.html", account=account, cdr=cdr)
251
252
253 class ChannelsModule(ui_modules.UIModule):
254 def render(self, account):
255 channels = self.backend.talk.freeswitch.get_sip_channels(account)
256
257 return self.render_string("people/modules/channels.html", account=account, channels=channels)
258
259
260 class MOSModule(ui_modules.UIModule):
261 def render(self, call):
262 return self.render_string("people/modules/mos.html", call=call)
263
264
265 class RegistrationsModule(ui_modules.UIModule):
266 def render(self, account):
267 return self.render_string("people/modules/registrations.html", account=account)
268
269
270 class SIPStatusModule(ui_modules.UIModule):
271 def render(self, account):
272 return self.render_string("people/modules/sip-status.html", account=account)