comparison libervia_server/__init__.py @ 438:582c435dab6b

server side: new log system is used
author Goffi <goffi@goffi.org>
date Thu, 08 May 2014 17:21:30 +0200
parents e63fc04efef7
children b64e528fb524
comparison
equal deleted inserted replaced
437:fa3b65b68971 438:582c435dab6b
20 from twisted.application import internet, service 20 from twisted.application import internet, service
21 from twisted.internet import glib2reactor 21 from twisted.internet import glib2reactor
22 glib2reactor.install() 22 glib2reactor.install()
23 from twisted.internet import reactor, defer 23 from twisted.internet import reactor, defer
24 from twisted.web import server 24 from twisted.web import server
25 from twisted.web import error as weberror
26 from twisted.web.static import File 25 from twisted.web.static import File
27 from twisted.web.resource import Resource, NoResource 26 from twisted.web.resource import Resource, NoResource
28 from twisted.web.util import Redirect, redirectTo 27 from twisted.web.util import Redirect, redirectTo
29 from twisted.python.components import registerAdapter 28 from twisted.python.components import registerAdapter
30 from twisted.python.failure import Failure 29 from twisted.python.failure import Failure
31 from twisted.words.protocols.jabber.jid import JID 30 from twisted.words.protocols.jabber.jid import JID
32 from txjsonrpc.web import jsonrpc 31 from txjsonrpc.web import jsonrpc
33 from txjsonrpc import jsonrpclib 32 from txjsonrpc import jsonrpclib
34 33
35 from logging import debug, info, warning, error 34 from sat.core.log import getLogger
35 log = getLogger(__name__)
36 import re 36 import re
37 import glob 37 import glob
38 import os.path 38 import os.path
39 import sys 39 import sys
40 import tempfile 40 import tempfile
113 reactor.callLater(self.ID_LIFETIME, self.purgeID, action_tuple) 113 reactor.callLater(self.ID_LIFETIME, self.purgeID, action_tuple)
114 114
115 def purgeID(self, action_tuple): 115 def purgeID(self, action_tuple):
116 """Called when an action_id has not be handled in time""" 116 """Called when an action_id has not be handled in time"""
117 if action_tuple in self.waiting_ids: 117 if action_tuple in self.waiting_ids:
118 warning ("action of action_id %s [%s] has not been managed, action_id is now ignored" % action_tuple) 118 log.warning ("action of action_id %s [%s] has not been managed, action_id is now ignored" % action_tuple)
119 del self.waiting_ids[action_tuple] 119 del self.waiting_ids[action_tuple]
120 120
121 def actionResultCb(self, answer_type, action_id, data, profile): 121 def actionResultCb(self, answer_type, action_id, data, profile):
122 """Manage the actionResult signal""" 122 """Manage the actionResult signal"""
123 action_tuple = (action_id, profile) 123 action_tuple = (action_id, profile)
348 """Return history for the from_jid/to_jid couple""" 348 """Return history for the from_jid/to_jid couple"""
349 sat_session = ISATSession(self.session) 349 sat_session = ISATSession(self.session)
350 profile = sat_session.profile 350 profile = sat_session.profile
351 sat_jid = sat_session.jid 351 sat_jid = sat_session.jid
352 if not sat_jid: 352 if not sat_jid:
353 error("No jid saved for this profile") 353 log.error("No jid saved for this profile")
354 return {} 354 return {}
355 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost(): 355 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost():
356 error("Trying to get history from a different jid, maybe a hack attempt ?") 356 log.error("Trying to get history from a different jid, maybe a hack attempt ?")
357 return {} 357 return {}
358 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, profile) 358 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, profile)
359 def show(result_dbus): 359 def show(result_dbus):
360 result = [] 360 result = []
361 for line in result_dbus: 361 for line in result_dbus:
374 profile = ISATSession(self.session).profile 374 profile = ISATSession(self.session).profile
375 try: 375 try:
376 if room_jid != "": 376 if room_jid != "":
377 room_jid = JID(room_jid).userhost() 377 room_jid = JID(room_jid).userhost()
378 except: 378 except:
379 warning('Invalid room jid') 379 log.warning('Invalid room jid')
380 return 380 return
381 d = self.asyncBridgeCall("joinMUC", room_jid, nick, {}, profile) 381 d = self.asyncBridgeCall("joinMUC", room_jid, nick, {}, profile)
382 return d 382 return d
383 383
384 def jsonrpc_inviteMUC(self, contact_jid, room_jid): 384 def jsonrpc_inviteMUC(self, contact_jid, room_jid):
385 """Invite a user to a Multi-User Chat room""" 385 """Invite a user to a Multi-User Chat room"""
386 profile = ISATSession(self.session).profile 386 profile = ISATSession(self.session).profile
387 try: 387 try:
388 room_jid = JID(room_jid).userhost() 388 room_jid = JID(room_jid).userhost()
389 except: 389 except:
390 warning('Invalid room jid') 390 log.warning('Invalid room jid')
391 return 391 return
392 room_id = room_jid.split("@")[0] 392 room_id = room_jid.split("@")[0]
393 service = room_jid.split("@")[1] 393 service = room_jid.split("@")[1]
394 self.sat_host.bridge.inviteMUC(contact_jid, service, room_id, {}, profile) 394 self.sat_host.bridge.inviteMUC(contact_jid, service, room_id, {}, profile)
395 395
397 """Quit a Multi-User Chat room""" 397 """Quit a Multi-User Chat room"""
398 profile = ISATSession(self.session).profile 398 profile = ISATSession(self.session).profile
399 try: 399 try:
400 room_jid = JID(room_jid) 400 room_jid = JID(room_jid)
401 except: 401 except:
402 warning('Invalid room jid') 402 log.warning('Invalid room jid')
403 return 403 return
404 self.sat_host.bridge.mucLeave(room_jid.userhost(), profile) 404 self.sat_host.bridge.mucLeave(room_jid.userhost(), profile)
405 405
406 def jsonrpc_getRoomsJoined(self): 406 def jsonrpc_getRoomsJoined(self):
407 """Return list of room already joined by user""" 407 """Return list of room already joined by user"""
415 profile = ISATSession(self.session).profile 415 profile = ISATSession(self.session).profile
416 try: 416 try:
417 if room_jid != "": 417 if room_jid != "":
418 room_jid = JID(room_jid).userhost() 418 room_jid = JID(room_jid).userhost()
419 except: 419 except:
420 warning('Invalid room jid') 420 log.warning('Invalid room jid')
421 return 421 return
422 self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile) 422 self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile)
423 423
424 def jsonrpc_getTarotCardsPaths(self): 424 def jsonrpc_getTarotCardsPaths(self):
425 """Give the path of all the tarot cards""" 425 """Give the path of all the tarot cards"""
444 profile = ISATSession(self.session).profile 444 profile = ISATSession(self.session).profile
445 try: 445 try:
446 if room_jid != "": 446 if room_jid != "":
447 room_jid = JID(room_jid).userhost() 447 room_jid = JID(room_jid).userhost()
448 except: 448 except:
449 warning('Invalid room jid') 449 log.warning('Invalid room jid')
450 return 450 return
451 self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile) 451 self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile)
452 452
453 def jsonrpc_getEntityData(self, jid, keys): 453 def jsonrpc_getEntityData(self, jid, keys):
454 """Get cached data for an entit 454 """Get cached data for an entit
503 def jsonrpc_setParam(self, name, value, category): 503 def jsonrpc_setParam(self, name, value, category):
504 profile = ISATSession(self.session).profile 504 profile = ISATSession(self.session).profile
505 if category in self.authorized_params and name in self.authorized_params[category]: 505 if category in self.authorized_params and name in self.authorized_params[category]:
506 return self.sat_host.bridge.setParam(name, value, category, C.SECURITY_LIMIT, profile) 506 return self.sat_host.bridge.setParam(name, value, category, C.SECURITY_LIMIT, profile)
507 else: 507 else:
508 warning("Trying to set parameter '%s' in category '%s' without authorization!!!" 508 log.warning("Trying to set parameter '%s' in category '%s' without authorization!!!"
509 % (name, category)) 509 % (name, category))
510 510
511 def jsonrpc_launchAction(self, callback_id, data): 511 def jsonrpc_launchAction(self, callback_id, data):
512 #FIXME: any action can be launched, this can be a huge security issue if callback_id can be guessed 512 #FIXME: any action can be launched, this can be a huge security issue if callback_id can be guessed
513 # a security system with authorised callback_id must be implemented, similar to the one for authorised params 513 # a security system with authorised callback_id must be implemented, similar to the one for authorised params
630 self.profiles_waiting[_login] = request 630 self.profiles_waiting[_login] = request
631 d = self.asyncBridgeCall("asyncConnect", _login) 631 d = self.asyncBridgeCall("asyncConnect", _login)
632 return d 632 return d
633 633
634 def profile_pass_errback(ignore): 634 def profile_pass_errback(ignore):
635 error("INTERNAL ERROR: can't check profile password") 635 log.error("INTERNAL ERROR: can't check profile password")
636 request.write("AUTH ERROR") 636 request.write("AUTH ERROR")
637 request.finish() 637 request.finish()
638 638
639 d = self.asyncBridgeCall("asyncGetParamA", "Password", "Connection", profile_key=_login) 639 d = self.asyncBridgeCall("asyncGetParamA", "Password", "Connection", profile_key=_login)
640 d.addCallbacks(profile_pass_cb, profile_pass_errback) 640 d.addCallbacks(profile_pass_cb, profile_pass_errback)
666 if reason == "ConflictError": 666 if reason == "ConflictError":
667 request.write('ALREADY EXISTS') 667 request.write('ALREADY EXISTS')
668 elif reason == "InternalError": 668 elif reason == "InternalError":
669 request.write('INTERNAL') 669 request.write('INTERNAL')
670 else: 670 else:
671 error('Unknown registering error: %s' % (reason,)) 671 log.error('Unknown registering error: %s' % (reason,))
672 request.write('Unknown error (%s)' % reason) 672 request.write('Unknown error (%s)' % reason)
673 request.finish() 673 request.finish()
674 674
675 d = self.asyncBridgeCall("registerSatAccount", email, password, profile) 675 d = self.asyncBridgeCall("registerSatAccount", email, password, profile)
676 d.addCallback(registered) 676 d.addCallback(registered)
696 696
697 self.__cleanWaiting(profile) 697 self.__cleanWaiting(profile)
698 _session = request.getSession() 698 _session = request.getSession()
699 sat_session = ISATSession(_session) 699 sat_session = ISATSession(_session)
700 if sat_session.profile: 700 if sat_session.profile:
701 error (('/!\\ Session has already a profile, this should NEVER happen !')) 701 log.error (('/!\\ Session has already a profile, this should NEVER happen !'))
702 return result('SESSION_ACTIVE') 702 return result('SESSION_ACTIVE')
703 sat_session.profile = profile 703 sat_session.profile = profile
704 self.sat_host.prof_connected.add(profile) 704 self.sat_host.prof_connected.add(profile)
705 705
706 def onExpire(): 706 def onExpire():
707 info ("Session expired (profile=%s)" % (profile,)) 707 log.info ("Session expired (profile=%s)" % (profile,))
708 try: 708 try:
709 #We purge the queue 709 #We purge the queue
710 del self.sat_host.signal_handler.queue[profile] 710 del self.sat_host.signal_handler.queue[profile]
711 except KeyError: 711 except KeyError:
712 pass 712 pass
812 def unlock(signal, profile): 812 def unlock(signal, profile):
813 _session.unlock() 813 _session.unlock()
814 try: 814 try:
815 source_defer = self.signalDeferred[profile] 815 source_defer = self.signalDeferred[profile]
816 if source_defer.called and source_defer.result[0] == "disconnected": 816 if source_defer.called and source_defer.result[0] == "disconnected":
817 info(u"[%s] disconnected" % (profile,)) 817 log.info(u"[%s] disconnected" % (profile,))
818 _session.expire() 818 _session.expire()
819 except IndexError: 819 except IndexError:
820 error("Deferred result should be a tuple with fonction name first") 820 log.error("Deferred result should be a tuple with fonction name first")
821 821
822 self.signalDeferred[profile] = defer.Deferred() 822 self.signalDeferred[profile] = defer.Deferred()
823 self.request.notifyFinish().addBoth(unlock, profile) 823 self.request.notifyFinish().addBoth(unlock, profile)
824 return self.signalDeferred[profile] 824 return self.signalDeferred[profile]
825 825
845 if request: 845 if request:
846 self.register._logged(profile, request) 846 self.register._logged(profile, request)
847 847
848 def disconnected(self, profile): 848 def disconnected(self, profile):
849 if not profile in self.sat_host.prof_connected: 849 if not profile in self.sat_host.prof_connected:
850 error("'disconnected' signal received for a not connected profile") 850 log.error("'disconnected' signal received for a not connected profile")
851 return 851 return
852 self.sat_host.prof_connected.remove(profile) 852 self.sat_host.prof_connected.remove(profile)
853 if profile in self.signalDeferred: 853 if profile in self.signalDeferred:
854 self.signalDeferred[profile].callback(("disconnected",)) 854 self.signalDeferred[profile].callback(("disconnected",))
855 del self.signalDeferred[profile] 855 del self.signalDeferred[profile]
1069 try: 1069 try:
1070 with open(os.path.expanduser(self.ssl_certificate)) as keyAndCert: 1070 with open(os.path.expanduser(self.ssl_certificate)) as keyAndCert:
1071 try: 1071 try:
1072 cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read()) 1072 cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read())
1073 except OpenSSL.crypto.Error as e: 1073 except OpenSSL.crypto.Error as e:
1074 error(_("The file '%s' must contain both private and public parts of the certificate") % self.ssl_certificate) 1074 log.error(_("The file '%s' must contain both private and public parts of the certificate") % self.ssl_certificate)
1075 raise e 1075 raise e
1076 except IOError as e: 1076 except IOError as e:
1077 error(_("The file '%s' doesn't exist") % self.ssl_certificate) 1077 log.error(_("The file '%s' doesn't exist") % self.ssl_certificate)
1078 raise e 1078 raise e
1079 reactor.listenSSL(self.port_https, self.site, cert.options()) 1079 reactor.listenSSL(self.port_https, self.site, cert.options())
1080 if self.connection_type in ('http', 'both'): 1080 if self.connection_type in ('http', 'both'):
1081 if self.connection_type == 'both' and self.redirect_to_https: 1081 if self.connection_type == 'both' and self.redirect_to_https:
1082 reactor.listenTCP(self.port, server.Site(RedirectToHTTPS(self.port, self.port_https_ext))) 1082 reactor.listenTCP(self.port, server.Site(RedirectToHTTPS(self.port, self.port_https_ext)))