Mercurial > libervia-web
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): |