]>
Commit | Line | Data |
---|---|---|
2cd9af74 MT |
1 | #!/usr/bin/python |
2 | ||
bdaf6b46 | 3 | import datetime |
e96e445b | 4 | import ldap |
2cd9af74 MT |
5 | import logging |
6 | import tornado.web | |
7 | ||
f6ed3d4d | 8 | from . import handlers_base as base |
786e9ca8 MT |
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 | ||
2cd9af74 | 16 | |
c4f1a618 | 17 | class AvatarHandler(base.BaseHandler): |
76582150 MT |
18 | always_cache = True |
19 | ||
0cddf220 | 20 | def get(self, uid): |
2cd9af74 MT |
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 | ||
0cddf220 | 29 | logging.debug("Querying for avatar of %s" % uid) |
2cd9af74 | 30 | |
f6ed3d4d | 31 | # Fetch user account |
0cddf220 | 32 | account = self.backend.accounts.get_by_uid(uid) |
f6ed3d4d | 33 | if not account: |
0cddf220 | 34 | raise tornado.web.HTTPError(404, "Could not find account %s" % uid) |
2cd9af74 | 35 | |
f6ed3d4d MT |
36 | # Allow downstream to cache this for 60 minutes |
37 | self.set_expires(3600) | |
2cd9af74 | 38 | |
f6ed3d4d MT |
39 | # Resize avatar |
40 | avatar = account.get_avatar(size) | |
2cd9af74 | 41 | |
f6ed3d4d MT |
42 | # If there is no avatar, we serve a default image |
43 | if not avatar: | |
0cddf220 MT |
44 | logging.debug("No avatar uploaded for %s" % account) |
45 | ||
3f9f12f0 | 46 | return self.redirect(self.static_url("img/default-avatar.jpg")) |
2cd9af74 | 47 | |
f6ed3d4d | 48 | # Set headers about content |
0cddf220 | 49 | self.set_header("Content-Disposition", "inline; filename=\"%s.jpg\"" % account.uid) |
2cd9af74 MT |
50 | self.set_header("Content-Type", "image/jpeg") |
51 | ||
f6ed3d4d | 52 | # Deliver payload |
2cd9af74 | 53 | self.finish(avatar) |
786e9ca8 MT |
54 | |
55 | ||
bdaf6b46 MT |
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: | |
44b4640b MT |
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) | |
bdaf6b46 MT |
68 | else: |
69 | date = datetime.date.today() | |
70 | ||
71 | self.render("people/calls.html", account=account, date=date) | |
72 | ||
73 | ||
68ece434 MT |
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 | ||
786e9ca8 MT |
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 | |
51907e45 | 112 | accounts = self.backend.accounts.search(q) |
786e9ca8 MT |
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 | ||
e96e445b MT |
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 | ||
5cc10421 MT |
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) | |
9bbf48b8 | 175 | except TypeError: |
5cc10421 MT |
176 | pass |
177 | ||
e96e445b MT |
178 | |
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 | ||
3ea97943 MT |
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 | ||
786e9ca8 MT |
238 | class AccountsListModule(ui_modules.UIModule): |
239 | def render(self, accounts=None): | |
240 | if accounts is None: | |
51907e45 | 241 | accounts = self.backend.accounts |
786e9ca8 MT |
242 | |
243 | return self.render_string("people/modules/accounts-list.html", accounts=accounts) | |
244 | ||
245 | ||
246 | class CDRModule(ui_modules.UIModule): | |
bdaf6b46 MT |
247 | def render(self, account, date=None, limit=None): |
248 | cdr = account.get_cdr(date=date, limit=limit) | |
786e9ca8 MT |
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 | ||
68ece434 MT |
260 | class MOSModule(ui_modules.UIModule): |
261 | def render(self, call): | |
262 | return self.render_string("people/modules/mos.html", call=call) | |
263 | ||
264 | ||
786e9ca8 MT |
265 | class RegistrationsModule(ui_modules.UIModule): |
266 | def render(self, account): | |
267 | return self.render_string("people/modules/registrations.html", account=account) |