comparison src/server/server.py @ 679:a90cc8fc9605

merged branch frontends_multi_profiles
author Goffi <goffi@goffi.org>
date Wed, 18 Mar 2015 16:15:18 +0100
parents 3eb3a2c0c011 a8fddccf5b84
children e6bb64bd6b4d
comparison
equal deleted inserted replaced
590:1bffc4c244c3 679:a90cc8fc9605
32 32
33 from sat.core.log import getLogger 33 from sat.core.log import getLogger
34 log = getLogger(__name__) 34 log = getLogger(__name__)
35 from sat_frontends.bridge.DBus import DBusBridgeFrontend, BridgeExceptionNoService, const_TIMEOUT as BRIDGE_TIMEOUT 35 from sat_frontends.bridge.DBus import DBusBridgeFrontend, BridgeExceptionNoService, const_TIMEOUT as BRIDGE_TIMEOUT
36 from sat.core.i18n import _, D_ 36 from sat.core.i18n import _, D_
37 from sat.core import exceptions
37 from sat.tools.xml_tools import paramsXML2XMLUI 38 from sat.tools.xml_tools import paramsXML2XMLUI
38 39
39 import re 40 import re
40 import glob 41 import glob
41 import os.path 42 import os.path
182 parsed = jsonrpclib.loads(request.content.read()) 183 parsed = jsonrpclib.loads(request.content.read())
183 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia 184 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia
184 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) # pylint: disable=E1103 185 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) # pylint: disable=E1103
185 return jsonrpc.JSONRPC.render(self, request) 186 return jsonrpc.JSONRPC.render(self, request)
186 187
187 def jsonrpc_getProfileJid(self):
188 """Return the jid of the profile"""
189 sat_session = ISATSession(self.session)
190 profile = sat_session.profile
191 sat_session.jid = JID(self.sat_host.bridge.getParamA("JabberID", "Connection", profile_key=profile))
192 return sat_session.jid.full()
193
194 def jsonrpc_disconnect(self): 188 def jsonrpc_disconnect(self):
195 """Disconnect the profile""" 189 """Disconnect the profile"""
196 sat_session = ISATSession(self.session) 190 sat_session = ISATSession(self.session)
197 profile = sat_session.profile 191 profile = sat_session.profile
198 self.sat_host.bridge.disconnect(profile) 192 self.sat_host.bridge.disconnect(profile)
216 def jsonrpc_updateContact(self, entity, name, groups): 210 def jsonrpc_updateContact(self, entity, name, groups):
217 """Update contact's roster item""" 211 """Update contact's roster item"""
218 profile = ISATSession(self.session).profile 212 profile = ISATSession(self.session).profile
219 self.sat_host.bridge.updateContact(entity, name, groups, profile) 213 self.sat_host.bridge.updateContact(entity, name, groups, profile)
220 214
221 def jsonrpc_subscription(self, sub_type, entity, name, groups): 215 def jsonrpc_subscription(self, sub_type, entity):
222 """Confirm (or infirm) subscription, 216 """Confirm (or infirm) subscription,
223 and setup user roster in case of subscription""" 217 and setup user roster in case of subscription"""
224 profile = ISATSession(self.session).profile 218 profile = ISATSession(self.session).profile
225 self.sat_host.bridge.subscription(sub_type, entity, profile) 219 self.sat_host.bridge.subscription(sub_type, entity, profile)
226 if sub_type == 'subscribed':
227 self.sat_host.bridge.updateContact(entity, name, groups, profile)
228 220
229 def jsonrpc_getWaitingSub(self): 221 def jsonrpc_getWaitingSub(self):
230 """Return list of room already joined by user""" 222 """Return list of room already joined by user"""
231 profile = ISATSession(self.session).profile 223 profile = ISATSession(self.session).profile
232 return self.sat_host.bridge.getWaitingSub(profile) 224 return self.sat_host.bridge.getWaitingSub(profile)
225
226 def jsonrpc_getWaitingConf(self):
227 """Return list of waiting confirmations"""
228 profile = ISATSession(self.session).profile
229 return self.sat_host.bridge.getWaitingConf(profile)
233 230
234 def jsonrpc_setStatus(self, presence, status): 231 def jsonrpc_setStatus(self, presence, status):
235 """Change the presence and/or status 232 """Change the presence and/or status
236 @param presence: value from ("", "chat", "away", "dnd", "xa") 233 @param presence: value from ("", "chat", "away", "dnd", "xa")
237 @param status: any string to describe your status 234 @param status: any string to describe your status
244 profile = ISATSession(self.session).profile 241 profile = ISATSession(self.session).profile
245 return self.asyncBridgeCall("sendMessage", to_jid, msg, subject, type_, options, profile) 242 return self.asyncBridgeCall("sendMessage", to_jid, msg, subject, type_, options, profile)
246 243
247 def jsonrpc_sendMblog(self, type_, dest, text, extra={}): 244 def jsonrpc_sendMblog(self, type_, dest, text, extra={}):
248 """ Send microblog message 245 """ Send microblog message
249 @param type_: one of "PUBLIC", "GROUP" 246 @param type_ (unicode): one of "PUBLIC", "GROUP"
250 @param dest: destinees (list of groups, ignored for "PUBLIC") 247 @param dest (tuple(unicode)): recipient groups (ignored for "PUBLIC")
251 @param text: microblog's text 248 @param text (unicode): microblog's text
252 """ 249 """
253 profile = ISATSession(self.session).profile 250 profile = ISATSession(self.session).profile
254 extra['allow_comments'] = 'True' 251 extra['allow_comments'] = 'True'
255 252
256 if not type_: # auto-detect 253 if not type_: # auto-detect
258 255
259 if type_ in ("PUBLIC", "GROUP") and text: 256 if type_ in ("PUBLIC", "GROUP") and text:
260 if type_ == "PUBLIC": 257 if type_ == "PUBLIC":
261 #This text if for the public microblog 258 #This text if for the public microblog
262 log.debug("sending public blog") 259 log.debug("sending public blog")
263 return self.sat_host.bridge.sendGroupBlog("PUBLIC", [], text, extra, profile) 260 return self.sat_host.bridge.sendGroupBlog("PUBLIC", (), text, extra, profile)
264 else: 261 else:
265 log.debug("sending group blog") 262 log.debug("sending group blog")
266 dest = dest if isinstance(dest, list) else [dest] 263 dest = dest if isinstance(dest, list) else [dest]
267 return self.sat_host.bridge.sendGroupBlog("GROUP", dest, text, extra, profile) 264 return self.sat_host.bridge.sendGroupBlog("GROUP", dest, text, extra, profile)
268 else: 265 else:
317 @return list of couple (microblog data, list of microblog data)""" 314 @return list of couple (microblog data, list of microblog data)"""
318 profile = ISATSession(self.session).profile 315 profile = ISATSession(self.session).profile
319 d = self.asyncBridgeCall("getGroupBlogsWithComments", publisher_jid, item_ids, {}, max_comments, profile) 316 d = self.asyncBridgeCall("getGroupBlogsWithComments", publisher_jid, item_ids, {}, max_comments, profile)
320 return d 317 return d
321 318
322 def jsonrpc_getMassiveMblogs(self, publishers_type, publishers_list, rsm=None): 319 def jsonrpc_getMassiveMblogs(self, publishers_type, publishers, rsm=None):
323 """Get lasts microblogs posted by several contacts at once 320 """Get lasts microblogs posted by several contacts at once
324 @param publishers_type: one of "ALL", "GROUP", "JID" 321
325 @param publishers_list: list of publishers type (empty list of all, list of groups or list of jids) 322 @param publishers_type (unicode): one of "ALL", "GROUP", "JID"
326 @param max_item: number of items to ask 323 @param publishers (tuple(unicode)): tuple of publishers (empty list for all, list of groups or list of jids)
327 @return: dictionary key=publisher's jid, value=list of microblog data (dict)""" 324 @param rsm (dict): TODO
325 @return: dict{unicode: list[dict])
326 key: publisher's jid
327 value: list of microblog data (dict)
328 """
328 profile = ISATSession(self.session).profile 329 profile = ISATSession(self.session).profile
329 if rsm is None: 330 if rsm is None:
330 rsm = {'max': unicode(C.RSM_MAX_ITEMS)} 331 rsm = {'max': unicode(C.RSM_MAX_ITEMS)}
331 d = self.asyncBridgeCall("getMassiveGroupBlogs", publishers_type, publishers_list, rsm, profile) 332 d = self.asyncBridgeCall("getMassiveGroupBlogs", publishers_type, publishers, rsm, profile)
332 self.sat_host.bridge.massiveSubscribeGroupBlogs(publishers_type, publishers_list, profile) 333 self.sat_host.bridge.massiveSubscribeGroupBlogs(publishers_type, publishers, profile)
333 return d 334 return d
334 335
335 def jsonrpc_getMblogComments(self, service, node, rsm=None): 336 def jsonrpc_getMblogComments(self, service, node, rsm=None):
336 """Get all comments of given node 337 """Get all comments of given node
337 @param service: jid of the service hosting the node 338 @param service: jid of the service hosting the node
352 """Return history for the from_jid/to_jid couple""" 353 """Return history for the from_jid/to_jid couple"""
353 sat_session = ISATSession(self.session) 354 sat_session = ISATSession(self.session)
354 profile = sat_session.profile 355 profile = sat_session.profile
355 sat_jid = sat_session.jid 356 sat_jid = sat_session.jid
356 if not sat_jid: 357 if not sat_jid:
357 log.error("No jid saved for this profile") 358 # we keep a session cache for jid to avoir jid spoofing
358 return {} 359 sat_jid = sat_session.jid = JID(self.sat_host.bridge.getParamA("JabberID", "Connection", profile_key=profile))
359 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost(): 360 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost():
360 log.error("Trying to get history from a different jid, maybe a hack attempt ?") 361 log.error("Trying to get history from a different jid (given (browser): {}, real (backend): {}), maybe a hack attempt ?".format(from_jid, sat_jid))
361 return {} 362 return {}
362 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, search, profile) 363 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, search, profile)
363 364
364 def show(result_dbus): 365 def show(result_dbus):
365 result = [] 366 result = []
375 def jsonrpc_joinMUC(self, room_jid, nick): 376 def jsonrpc_joinMUC(self, room_jid, nick):
376 """Join a Multi-User Chat room 377 """Join a Multi-User Chat room
377 @room_jid: leave empty string to generate a unique name 378 @room_jid: leave empty string to generate a unique name
378 """ 379 """
379 profile = ISATSession(self.session).profile 380 profile = ISATSession(self.session).profile
380 try:
381 if room_jid != "":
382 room_jid = JID(room_jid).userhost()
383 except:
384 log.warning('Invalid room jid')
385 return
386 d = self.asyncBridgeCall("joinMUC", room_jid, nick, {}, profile) 381 d = self.asyncBridgeCall("joinMUC", room_jid, nick, {}, profile)
387 return d 382 return d
388 383
389 def jsonrpc_inviteMUC(self, contact_jid, room_jid): 384 def jsonrpc_inviteMUC(self, contact_jid, room_jid):
390 """Invite a user to a Multi-User Chat room""" 385 """Invite a user to a Multi-User Chat room"""
411 def jsonrpc_getRoomsJoined(self): 406 def jsonrpc_getRoomsJoined(self):
412 """Return list of room already joined by user""" 407 """Return list of room already joined by user"""
413 profile = ISATSession(self.session).profile 408 profile = ISATSession(self.session).profile
414 return self.sat_host.bridge.getRoomsJoined(profile) 409 return self.sat_host.bridge.getRoomsJoined(profile)
415 410
411 def jsonrpc_getRoomsSubjects(self):
412 """Return list of room subjects"""
413 profile = ISATSession(self.session).profile
414 return self.sat_host.bridge.getRoomsSubjects(profile)
415
416 def jsonrpc_launchTarotGame(self, other_players, room_jid=""): 416 def jsonrpc_launchTarotGame(self, other_players, room_jid=""):
417 """Create a room, invite the other players and start a Tarot game 417 """Create a room, invite the other players and start a Tarot game
418 @param room_jid: leave empty string to generate a unique room name 418 @param room_jid: leave empty string to generate a unique room name
419 """ 419 """
420 profile = ISATSession(self.session).profile 420 profile = ISATSession(self.session).profile
453 except: 453 except:
454 log.warning('Invalid room jid') 454 log.warning('Invalid room jid')
455 return 455 return
456 self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile) 456 self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile)
457 457
458 def jsonrpc_getEntitiesData(self, jids, keys):
459 """Get cached data for several entities at once
460
461 @param jids: list jids from who we wants data, or empty list for all jids in cache
462 @param keys: name of data we want (list)
463 @return: requested data"""
464 if not C.ALLOWED_ENTITY_DATA.issuperset(keys):
465 raise exceptions.PermissionError("Trying to access unallowed data (hack attempt ?)")
466 profile = ISATSession(self.session).profile
467 try:
468 return self.sat_host.bridge.getEntitiesData(jids, keys, profile)
469 except Exception as e:
470 raise Failure(jsonrpclib.Fault(C.ERRNUM_BRIDGE_ERRBACK, unicode(e)))
471
458 def jsonrpc_getEntityData(self, jid, keys): 472 def jsonrpc_getEntityData(self, jid, keys):
459 """Get cached data for an entit 473 """Get cached data for an entity
474
460 @param jid: jid of contact from who we want data 475 @param jid: jid of contact from who we want data
461 @param keys: name of data we want (list) 476 @param keys: name of data we want (list)
462 @return: requested data""" 477 @return: requested data"""
463 profile = ISATSession(self.session).profile 478 if not C.ALLOWED_ENTITY_DATA.issuperset(keys):
464 return self.sat_host.bridge.getEntityData(jid, keys, profile) 479 raise exceptions.PermissionError("Trying to access unallowed data (hack attempt ?)")
465 480 profile = ISATSession(self.session).profile
466 def jsonrpc_getCard(self, jid): 481 try:
482 return self.sat_host.bridge.getEntityData(jid, keys, profile)
483 except Exception as e:
484 raise Failure(jsonrpclib.Fault(C.ERRNUM_BRIDGE_ERRBACK, unicode(e)))
485
486 def jsonrpc_getCard(self, jid_):
467 """Get VCard for entiry 487 """Get VCard for entiry
468 @param jid: jid of contact from who we want data 488 @param jid_: jid of contact from who we want data
469 @return: id to retrieve the profile""" 489 @return: id to retrieve the profile"""
470 profile = ISATSession(self.session).profile 490 profile = ISATSession(self.session).profile
471 return self.sat_host.bridge.getCard(jid, profile) 491 return self.sat_host.bridge.getCard(jid_, profile)
472 492
473 def jsonrpc_getAccountDialogUI(self): 493 def jsonrpc_getAccountDialogUI(self):
474 """Get the dialog for managing user account 494 """Get the dialog for managing user account
475 @return: XML string of the XMLUI""" 495 @return: XML string of the XMLUI"""
476 profile = ISATSession(self.session).profile 496 profile = ISATSession(self.session).profile
754 if sat_session.profile: 774 if sat_session.profile:
755 log.error(('/!\\ Session has already a profile, this should NEVER happen!')) 775 log.error(('/!\\ Session has already a profile, this should NEVER happen!'))
756 request.write(C.SESSION_ACTIVE) 776 request.write(C.SESSION_ACTIVE)
757 request.finish() 777 request.finish()
758 return 778 return
779 # we manage profile server side to avoid profile spoofing
759 sat_session.profile = profile 780 sat_session.profile = profile
760 self.sat_host.prof_connected.add(profile) 781 self.sat_host.prof_connected.add(profile)
761 782
762 def onExpire(): 783 def onExpire():
763 log.info("Session expired (profile=%s)" % (profile,)) 784 log.info("Session expired (profile=%s)" % (profile,))
1075 1096
1076 def putChild(path, resource): 1097 def putChild(path, resource):
1077 """Add a child to the root resource""" 1098 """Add a child to the root resource"""
1078 root.putChild(path, EncodingResourceWrapper(resource, [server.GzipEncoderFactory()])) 1099 root.putChild(path, EncodingResourceWrapper(resource, [server.GzipEncoderFactory()]))
1079 1100
1080 putChild('', Redirect('libervia.html')) 1101 putChild('', Redirect(C.LIBERVIA_MAIN_PAGE))
1102 putChild('test', Redirect('libervia_test.html'))
1081 putChild('json_signal_api', self.signal_handler) 1103 putChild('json_signal_api', self.signal_handler)
1082 putChild('json_api', MethodHandler(self)) 1104 putChild('json_api', MethodHandler(self))
1083 putChild('register_api', _register) 1105 putChild('register_api', _register)
1084 putChild('upload_radiocol', _upload_radiocol) 1106 putChild('upload_radiocol', _upload_radiocol)
1085 putChild('upload_avatar', _upload_avatar) 1107 putChild('upload_avatar', _upload_avatar)