]>
git.ipfire.org Git - ipfire.org.git/blob - src/web/people.py
10 from .. import countries
14 from . import ui_modules
16 class IndexHandler(auth
.CacheMixin
, base
.BaseHandler
):
17 @tornado.web
.authenticated
19 self
.render("people/index.html")
22 class AvatarHandler(base
.BaseHandler
):
24 # Get the desired size of the avatar file
25 size
= self
.get_argument("size", 0)
29 except (TypeError, ValueError):
32 logging
.debug("Querying for avatar of %s" % uid
)
35 account
= self
.backend
.accounts
.get_by_uid(uid
)
37 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
39 # Allow downstream to cache this for 60 minutes
40 self
.set_expires(3600)
43 avatar
= account
.get_avatar(size
)
45 # If there is no avatar, we serve a default image
47 logging
.debug("No avatar uploaded for %s" % account
)
49 return self
.redirect(self
.static_url("img/default-avatar.jpg"))
52 type = imghdr
.what(None, avatar
)
54 # Set headers about content
55 self
.set_header("Content-Disposition", "inline; filename=\"%s.%s\"" % (account
.uid
, type))
56 self
.set_header("Content-Type", "image/%s" % type)
62 class CallsHandler(auth
.CacheMixin
, base
.BaseHandler
):
63 @tornado.web
.authenticated
64 def get(self
, uid
, date
=None):
65 account
= self
.backend
.accounts
.get_by_uid(uid
)
67 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
71 date
= datetime
.datetime
.strptime(date
, "%Y-%m-%d").date()
73 raise tornado
.web
.HTTPError(400, "Invalid date: %s" % date
)
75 date
= datetime
.date
.today()
77 self
.render("people/calls.html", account
=account
, date
=date
)
80 class CallHandler(auth
.CacheMixin
, base
.BaseHandler
):
81 @tornado.web
.authenticated
82 def get(self
, uid
, uuid
):
83 account
= self
.backend
.accounts
.get_by_uid(uid
)
85 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
87 call
= self
.backend
.talk
.freeswitch
.get_call_by_uuid(uuid
)
89 raise tornado
.web
.HTTPError(404, "Could not find call %s" % uuid
)
93 self
.render("people/call.html", account
=account
, call
=call
)
96 class ConferencesHandler(auth
.CacheMixin
, base
.BaseHandler
):
97 @tornado.web
.authenticated
99 self
.render("people/conferences.html", conferences
=self
.backend
.talk
.conferences
)
102 class SearchHandler(auth
.CacheMixin
, base
.BaseHandler
):
103 @tornado.web
.authenticated
105 q
= self
.get_argument("q")
108 accounts
= self
.backend
.accounts
.search(q
)
110 # Redirect when only one result was found
111 if len(accounts
) == 1:
112 self
.redirect("/users/%s" % accounts
[0].uid
)
115 self
.render("people/search.html", q
=q
, accounts
=accounts
)
118 class SSHKeysIndexHandler(auth
.CacheMixin
, base
.BaseHandler
):
119 @tornado.web
.authenticated
121 account
= self
.backend
.accounts
.get_by_uid(uid
)
123 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
125 self
.render("people/ssh-keys/index.html", account
=account
)
128 class SSHKeysDownloadHandler(auth
.CacheMixin
, base
.BaseHandler
):
129 @tornado.web
.authenticated
130 def get(self
, uid
, hash_sha256
):
131 account
= self
.backend
.accounts
.get_by_uid(uid
)
133 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
136 key
= account
.get_ssh_key_by_hash_sha256(hash_sha256
)
138 raise tornado
.web
.HTTPError(404, "Could not find key: %s" % hash_sha256
)
141 self
.add_header("Content-Type", "text/plain")
143 self
.finish(key
.keydata
)
146 class SSHKeysUploadHandler(auth
.CacheMixin
, base
.BaseHandler
):
147 @tornado.web
.authenticated
149 account
= self
.backend
.accounts
.get_by_uid(uid
)
151 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
153 # Check for permissions
154 if not account
.can_be_managed_by(self
.current_user
):
155 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
157 self
.render("people/ssh-keys/upload.html", account
=account
)
159 @tornado.web
.authenticated
161 account
= self
.backend
.accounts
.get_by_uid(uid
)
163 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
165 # Check for permissions
166 if not account
.can_be_managed_by(self
.current_user
):
167 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
169 key
= self
.get_argument("key")
172 password
= self
.get_argument("password")
173 if not account
.check_password(password
):
174 raise tornado
.web
.HTTPError(403, "Incorrect password for %s" % account
)
176 # Try to add new SSH key
178 account
.add_ssh_key(key
)
180 except sshpubkeys
.InvalidKeyException
as e
:
181 self
.render("people/ssh-keys/error-invalid-key.html", account
=account
, exception
=e
)
184 self
.redirect("/users/%s/ssh-keys" % account
.uid
)
187 class SSHKeysDeleteHandler(auth
.CacheMixin
, base
.BaseHandler
):
188 @tornado.web
.authenticated
189 def get(self
, uid
, hash_sha256
):
190 account
= self
.backend
.accounts
.get_by_uid(uid
)
192 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
195 key
= account
.get_ssh_key_by_hash_sha256(hash_sha256
)
197 raise tornado
.web
.HTTPError(404, "Could not find key: %s" % hash_sha256
)
199 self
.render("people/ssh-keys/delete.html", account
=account
, key
=key
)
201 @tornado.web
.authenticated
202 def post(self
, uid
, hash_sha256
):
203 account
= self
.backend
.accounts
.get_by_uid(uid
)
205 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
208 key
= account
.get_ssh_key_by_hash_sha256(hash_sha256
)
210 raise tornado
.web
.HTTPError(404, "Could not find key: %s" % hash_sha256
)
213 password
= self
.get_argument("password")
214 if not account
.check_password(password
):
215 raise tornado
.web
.HTTPError(403, "Incorrect password for %s" % account
)
218 account
.delete_ssh_key(key
.keydata
)
220 self
.redirect("/users/%s/ssh-keys" % account
.uid
)
223 class SIPHandler(auth
.CacheMixin
, base
.BaseHandler
):
224 @tornado.web
.authenticated
226 account
= self
.backend
.accounts
.get_by_uid(uid
)
228 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
230 # Check for permissions
231 if not account
.can_be_managed_by(self
.current_user
):
232 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
234 self
.render("people/sip.html", account
=account
)
237 class UsersHandler(auth
.CacheMixin
, base
.BaseHandler
):
238 @tornado.web
.authenticated
240 # Only staff can see other users
241 if not self
.current_user
.is_staff():
242 raise tornado
.web
.HTTPError(403)
244 self
.render("people/users.html")
247 class UserHandler(auth
.CacheMixin
, base
.BaseHandler
):
248 @tornado.web
.authenticated
250 account
= self
.backend
.accounts
.get_by_uid(uid
)
252 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
254 self
.render("people/user.html", account
=account
)
257 class UserEditHandler(auth
.CacheMixin
, base
.BaseHandler
):
258 @tornado.web
.authenticated
260 account
= self
.backend
.accounts
.get_by_uid(uid
)
262 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
264 # Check for permissions
265 if not account
.can_be_managed_by(self
.current_user
):
266 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
268 self
.render("people/user-edit.html", account
=account
, countries
=countries
.get_all())
270 @tornado.web
.authenticated
272 account
= self
.backend
.accounts
.get_by_uid(uid
)
274 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
276 # Check for permissions
277 if not account
.can_be_managed_by(self
.current_user
):
278 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
280 # Unfortunately this cannot be wrapped into a transaction
282 account
.first_name
= self
.get_argument("first_name")
283 account
.last_name
= self
.get_argument("last_name")
284 account
.street
= self
.get_argument("street", None)
285 account
.city
= self
.get_argument("city", None)
286 account
.postal_code
= self
.get_argument("postal_code", None)
287 account
.country_code
= self
.get_argument("country_code", None)
291 filename
, data
, mimetype
= self
.get_file("avatar")
293 if not mimetype
.startswith("image/"):
294 raise tornado
.web
.HTTPError(400, "Avatar is not an image file: %s" % mimetype
)
296 account
.upload_avatar(data
)
301 account
.mail_routing_address
= self
.get_argument("mail_routing_address", None)
304 account
.phone_numbers
= self
.get_argument("phone_numbers", "").splitlines()
305 account
.sip_routing_address
= self
.get_argument("sip_routing_address", None)
306 except ldap
.STRONG_AUTH_REQUIRED
as e
:
307 raise tornado
.web
.HTTPError(403, "%s" % e
) from e
309 # Redirect back to user page
310 self
.redirect("/users/%s" % account
.uid
)
313 class UserPasswdHandler(auth
.CacheMixin
, base
.BaseHandler
):
314 @tornado.web
.authenticated
316 account
= self
.backend
.accounts
.get_by_uid(uid
)
318 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
320 # Check for permissions
321 if not account
.can_be_managed_by(self
.current_user
):
322 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
324 self
.render("people/passwd.html", account
=account
)
326 @tornado.web
.authenticated
328 account
= self
.backend
.accounts
.get_by_uid(uid
)
330 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
332 # Check for permissions
333 if not account
.can_be_managed_by(self
.current_user
):
334 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
336 # Get current password
337 password
= self
.get_argument("password")
340 password1
= self
.get_argument("password1")
341 password2
= self
.get_argument("password2")
343 # Passwords must match
344 if not password1
== password2
:
345 raise tornado
.web
.HTTPError(400, "Passwords do not match")
347 # XXX Check password complexity
349 # Check if old password matches
350 if not account
.check_password(password
):
351 raise tornado
.web
.HTTPError(403, "Incorrect password for %s" % account
)
354 account
.passwd(password1
)
356 # Redirect back to user's page
357 self
.redirect("/users/%s" % account
.uid
)
360 class AccountsListModule(ui_modules
.UIModule
):
361 def render(self
, accounts
=None):
363 accounts
= self
.backend
.accounts
365 return self
.render_string("people/modules/accounts-list.html", accounts
=accounts
)
368 class CDRModule(ui_modules
.UIModule
):
369 def render(self
, account
, date
=None, limit
=None):
370 cdr
= account
.get_cdr(date
=date
, limit
=limit
)
372 return self
.render_string("people/modules/cdr.html",
373 account
=account
, cdr
=list(cdr
))
376 class ChannelsModule(ui_modules
.UIModule
):
377 def render(self
, account
):
378 return self
.render_string("people/modules/channels.html",
379 account
=account
, channels
=account
.sip_channels
)
382 class MOSModule(ui_modules
.UIModule
):
383 def render(self
, call
):
384 return self
.render_string("people/modules/mos.html", call
=call
)
387 class PasswordModule(ui_modules
.UIModule
):
388 def render(self
, account
=None):
389 return self
.render_string("people/modules/password.html", account
=account
)
391 def javascript_files(self
):
392 return "js/zxcvbn.js"
394 def embedded_javascript(self
):
395 return self
.render_string("people/modules/password.js")
398 class RegistrationsModule(ui_modules
.UIModule
):
399 def render(self
, account
):
400 return self
.render_string("people/modules/registrations.html", account
=account
)
403 class SIPStatusModule(ui_modules
.UIModule
):
404 def render(self
, account
):
405 return self
.render_string("people/modules/sip-status.html", account
=account
)