comparison src/server/server.py @ 750:8ac862f6e5b3

browser and server sides: allow to connect with a JID that is not registered on the local server
author souliane <souliane@mailoo.org>
date Mon, 20 Jul 2015 10:16:10 +0200
parents 25984ca4aef2
children 2ddd85551612
comparison
equal deleted inserted replaced
749:7168a9873dde 750:8ac862f6e5b3
23 from twisted.web.static import File 23 from twisted.web.static import File
24 from twisted.web.resource import Resource, NoResource, EncodingResourceWrapper 24 from twisted.web.resource import Resource, NoResource, EncodingResourceWrapper
25 from twisted.web.util import Redirect, redirectTo 25 from twisted.web.util import Redirect, redirectTo
26 from twisted.python.components import registerAdapter 26 from twisted.python.components import registerAdapter
27 from twisted.python.failure import Failure 27 from twisted.python.failure import Failure
28 from twisted.words.protocols.jabber.jid import JID 28 from twisted.words.protocols.jabber import jid
29 29
30 from txjsonrpc.web import jsonrpc 30 from txjsonrpc.web import jsonrpc
31 from txjsonrpc import jsonrpclib 31 from txjsonrpc import jsonrpclib
32 32
33 from sat.core.log import getLogger 33 from sat.core.log import getLogger
482 sat_session = ISATSession(self.session) 482 sat_session = ISATSession(self.session)
483 profile = sat_session.profile 483 profile = sat_session.profile
484 sat_jid = sat_session.jid 484 sat_jid = sat_session.jid
485 if not sat_jid: 485 if not sat_jid:
486 # we keep a session cache for jid to avoir jid spoofing 486 # we keep a session cache for jid to avoir jid spoofing
487 sat_jid = sat_session.jid = JID(self.sat_host.bridge.getParamA("JabberID", "Connection", profile_key=profile)) 487 sat_jid = sat_session.jid = jid.JID(self.sat_host.bridge.getParamA("JabberID", "Connection", profile_key=profile))
488 if JID(from_jid).userhost() != sat_jid.userhost() and JID(to_jid).userhost() != sat_jid.userhost(): 488 if jid.JID(from_jid).userhost() != sat_jid.userhost() and jid.JID(to_jid).userhost() != sat_jid.userhost():
489 log.error(u"Trying to get history from a different jid (given (browser): {}, real (backend): {}), maybe a hack attempt ?".format(from_jid, sat_jid)) 489 log.error(u"Trying to get history from a different jid (given (browser): {}, real (backend): {}), maybe a hack attempt ?".format(from_jid, sat_jid))
490 return {} 490 return {}
491 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, search, profile) 491 d = self.asyncBridgeCall("getHistory", from_jid, to_jid, size, between, search, profile)
492 492
493 def show(result_dbus): 493 def show(result_dbus):
524 524
525 def jsonrpc_mucLeave(self, room_jid): 525 def jsonrpc_mucLeave(self, room_jid):
526 """Quit a Multi-User Chat room""" 526 """Quit a Multi-User Chat room"""
527 profile = ISATSession(self.session).profile 527 profile = ISATSession(self.session).profile
528 try: 528 try:
529 room_jid = JID(room_jid) 529 room_jid = jid.JID(room_jid)
530 except: 530 except:
531 log.warning('Invalid room jid') 531 log.warning('Invalid room jid')
532 return 532 return
533 self.sat_host.bridge.mucLeave(room_jid.userhost(), profile) 533 self.sat_host.bridge.mucLeave(room_jid.userhost(), profile)
534 534
783 - C.ALREADY_WAITING: a request has already been submitted for this profile 783 - C.ALREADY_WAITING: a request has already been submitted for this profile
784 - server.NOT_DONE_YET: the profile is being processed, the return 784 - server.NOT_DONE_YET: the profile is being processed, the return
785 value will be given by self._logged or auth_eb 785 value will be given by self._logged or auth_eb
786 """ 786 """
787 try: 787 try:
788 login_ = request.args['login'][0] 788 login = request.args['login'][0]
789 password_ = request.args['login_password'][0] 789 password = request.args['login_password'][0]
790 except KeyError: 790 except KeyError:
791 return C.BAD_REQUEST 791 return C.BAD_REQUEST
792 792
793 if login_.startswith('@'): 793 if login.startswith('@'): # this is checked by javascript but also here for security reason
794 raise Exception('No profile_key allowed') 794 raise Exception('No profile_key allowed')
795 795
796 profile_check = self.sat_host.bridge.getProfileName(login_) 796 try:
797 if ((not profile_check or profile_check != login_) or 797 profile = self.sat_host.bridge.getProfileName(login)
798 (not password_ and profile_check not in self.sat_host.empty_password_allowed_warning_dangerous_list)): 798 except Exception as e:
799 return C.PROFILE_AUTH_ERROR 799 try: # try to connect using XMPP credentials instead of SàT profile credentials
800 # profiles with empty passwords are restricted to local frontends 800 jid.JID(login)
801 801 except (RuntimeError, jid.InvalidFormat, AttributeError):
802 if self.waiting_profiles.getRequest(login_): 802 return C.PROFILE_AUTH_ERROR
803 profile = login
804 connect_method = "asyncConnectWithXMPPCredentials"
805 else:
806 if profile != login:
807 return C.PROFILE_AUTH_ERROR
808 if not password and profile not in self.sat_host.empty_password_allowed_warning_dangerous_list:
809 return C.PROFILE_AUTH_ERROR # profiles with empty passwords are restricted to local frontends
810 connect_method = "asyncConnect"
811
812 if self.waiting_profiles.getRequest(profile):
803 return C.ALREADY_WAITING 813 return C.ALREADY_WAITING
804 814
805 def auth_eb(failure): 815 def auth_eb(failure):
806 fault = failure.value.faultString 816 fault = failure.value.faultString
807 self.waiting_profiles.purgeRequest(login_) 817 self.waiting_profiles.purgeRequest(profile)
808 if fault == 'PasswordError': 818 if fault in ('PasswordError', 'ProfileUnknownError'):
809 log.info(u"Profile %s doesn't exist or the submitted password is wrong" % login_) 819 log.info(u"Profile %s doesn't exist or the submitted password is wrong" % profile)
810 request.write(C.PROFILE_AUTH_ERROR) 820 request.write(C.PROFILE_AUTH_ERROR)
811 elif fault == 'SASLAuthError': 821 elif fault == 'SASLAuthError':
812 log.info(u"The XMPP password of profile %s is wrong" % login_) 822 log.info(u"The XMPP password of profile %s is wrong" % profile)
813 request.write(C.XMPP_AUTH_ERROR) 823 request.write(C.XMPP_AUTH_ERROR)
814 elif fault == 'NoReply': 824 elif fault == 'NoReply':
815 log.info(_("Did not receive a reply (the timeout expired or the connection is broken)")) 825 log.info(_("Did not receive a reply (the timeout expired or the connection is broken)"))
816 request.write(C.NO_REPLY) 826 request.write(C.NO_REPLY)
817 else: 827 else:
818 log.error(u'Unmanaged fault string %s in errback for the connection of profile %s' % (fault, login_)) 828 log.error(u'Unmanaged fault string %s in errback for the connection of profile %s' % (fault, profile))
819 request.write(C.UNKNOWN_ERROR % fault) 829 request.write(C.UNKNOWN_ERROR % fault)
820 request.finish() 830 request.finish()
821 831
822 self.waiting_profiles.setRequest(request, login_) 832 self.waiting_profiles.setRequest(request, profile)
823 d = self.asyncBridgeCall("asyncConnect", login_, password_) 833 d = self.asyncBridgeCall(connect_method, profile, password)
824 d.addCallbacks(lambda connected: self._logged(login_, request) if connected else None, auth_eb) 834 d.addCallbacks(lambda connected: self._logged(profile, request) if connected else None, auth_eb)
825 835
826 return server.NOT_DONE_YET 836 return server.NOT_DONE_YET
827 837
828 838
829 def _registerNewAccount(self, request): 839 def _registerNewAccount(self, request):