Mercurial > libervia-web
comparison src/server/server.py @ 554:471b6babe960
server_side: set a timeout to reset the waiting connection requests after 5 minutes
author | souliane <souliane@mailoo.org> |
---|---|
date | Sun, 21 Sep 2014 14:09:59 +0200 |
parents | 8492c2bb463b |
children | db1b330c1eb1 |
comparison
equal
deleted
inserted
replaced
553:8492c2bb463b | 554:471b6babe960 |
---|---|
562 """Tell the backend to leave OTR handling to Libervia.""" | 562 """Tell the backend to leave OTR handling to Libervia.""" |
563 profile = ISATSession(self.session).profile | 563 profile = ISATSession(self.session).profile |
564 return self.sat_host.bridge.skipOTR(profile) | 564 return self.sat_host.bridge.skipOTR(profile) |
565 | 565 |
566 | 566 |
567 class WaitingRequests(dict): | |
568 | |
569 def setRequest(self, request, profile): | |
570 """Add the given profile to the waiting list. | |
571 | |
572 @param request (server.Request): the connection request | |
573 @param profile (str): %(doc_profile)s | |
574 """ | |
575 dc = reactor.callLater(C.TIMEOUT, self.purgeRequest, profile) | |
576 self[profile] = (request, dc) | |
577 | |
578 def purgeRequest(self, profile): | |
579 """Remove the given profile from the waiting list. | |
580 | |
581 @param profile (str): %(doc_profile)s | |
582 """ | |
583 try: | |
584 dc = self[profile][1] | |
585 except KeyError: | |
586 return | |
587 if dc.active(): | |
588 dc.cancel() | |
589 del self[profile] | |
590 | |
591 def getRequest(self, profile): | |
592 """Get the waiting request for the given profile. | |
593 | |
594 @param profile (str): %(doc_profile)s | |
595 @return: the waiting request or None | |
596 """ | |
597 return self[profile][0] if profile in self else None | |
598 | |
599 | |
567 class Register(JSONRPCMethodManager): | 600 class Register(JSONRPCMethodManager): |
568 """This class manage the registration procedure with SàT | 601 """This class manage the registration procedure with SàT |
569 It provide an api for the browser, check password and setup the web server""" | 602 It provide an api for the browser, check password and setup the web server""" |
570 | 603 |
571 def __init__(self, sat_host): | 604 def __init__(self, sat_host): |
572 JSONRPCMethodManager.__init__(self, sat_host) | 605 JSONRPCMethodManager.__init__(self, sat_host) |
573 self.profiles_waiting = {} | 606 self.profiles_waiting = {} |
574 self.request = None | 607 self.request = None |
575 | 608 self.waiting_profiles = WaitingRequests() |
576 def getWaitingRequest(self, profile): | |
577 """Tell if a profile is trying to log in""" | |
578 if profile in self.profiles_waiting: | |
579 return self.profiles_waiting[profile] | |
580 else: | |
581 return None | |
582 | 609 |
583 def render(self, request): | 610 def render(self, request): |
584 """ | 611 """ |
585 Render method with some hacks: | 612 Render method with some hacks: |
586 - if login is requested, try to login with form data | 613 - if login is requested, try to login with form data |
645 if ((not profile_check or profile_check != login_) or | 672 if ((not profile_check or profile_check != login_) or |
646 (not password_ and profile_check not in self.sat_host.empty_password_allowed_warning_dangerous_list)): | 673 (not password_ and profile_check not in self.sat_host.empty_password_allowed_warning_dangerous_list)): |
647 return C.PROFILE_AUTH_ERROR | 674 return C.PROFILE_AUTH_ERROR |
648 # profiles with empty passwords are restricted to local frontends | 675 # profiles with empty passwords are restricted to local frontends |
649 | 676 |
650 if login_ in self.profiles_waiting: | 677 if self.waiting_profiles.getRequest(login_): |
651 return C.ALREADY_WAITING | 678 return C.ALREADY_WAITING |
652 | 679 |
653 def auth_eb(failure): | 680 def auth_eb(failure): |
654 fault = failure.value.faultString | 681 fault = failure.value.faultString |
655 self.__cleanWaiting(login_) | 682 self.waiting_profiles.purgeRequest(login_) |
656 if fault == 'PasswordError': | 683 if fault == 'PasswordError': |
657 log.info("Profile %s doesn't exist or the submitted password is wrong" % login_) | 684 log.info("Profile %s doesn't exist or the submitted password is wrong" % login_) |
658 request.write(C.PROFILE_AUTH_ERROR) | 685 request.write(C.PROFILE_AUTH_ERROR) |
659 elif fault == 'SASLAuthError': | 686 elif fault == 'SASLAuthError': |
660 log.info("The XMPP password of profile %s is wrong" % login_) | 687 log.info("The XMPP password of profile %s is wrong" % login_) |
665 else: | 692 else: |
666 log.error('Unmanaged fault string %s in errback for the connection of profile %s' % (fault, login_)) | 693 log.error('Unmanaged fault string %s in errback for the connection of profile %s' % (fault, login_)) |
667 request.write(C.UNKNOWN_ERROR % fault) | 694 request.write(C.UNKNOWN_ERROR % fault) |
668 request.finish() | 695 request.finish() |
669 | 696 |
670 self.profiles_waiting[login_] = request | 697 self.waiting_profiles.setRequest(request, login_) |
671 d = self.asyncBridgeCall("asyncConnect", login_, password_) | 698 d = self.asyncBridgeCall("asyncConnect", login_, password_) |
672 d.addCallbacks(lambda connected: self._logged(login_, request) if connected else None, auth_eb) | 699 d.addCallbacks(lambda connected: self._logged(login_, request) if connected else None, auth_eb) |
673 | 700 |
674 return server.NOT_DONE_YET | 701 return server.NOT_DONE_YET |
702 | |
675 | 703 |
676 def _registerNewAccount(self, request): | 704 def _registerNewAccount(self, request): |
677 """Create a new account, or return error | 705 """Create a new account, or return error |
678 @param request: request of the register form | 706 @param request: request of the register form |
679 @return: a constant indicating the state: | 707 @return: a constant indicating the state: |
714 d = self.asyncBridgeCall("registerSatAccount", email, password, profile) | 742 d = self.asyncBridgeCall("registerSatAccount", email, password, profile) |
715 d.addCallback(registered) | 743 d.addCallback(registered) |
716 d.addErrback(registeringError) | 744 d.addErrback(registeringError) |
717 return server.NOT_DONE_YET | 745 return server.NOT_DONE_YET |
718 | 746 |
719 def __cleanWaiting(self, login): | |
720 """Remove login from waiting queue""" | |
721 try: | |
722 del self.profiles_waiting[login] | |
723 except KeyError: | |
724 pass | |
725 | |
726 def _logged(self, profile, request): | 747 def _logged(self, profile, request): |
727 """Set everything when a user just logged in | 748 """Set everything when a user just logged in |
728 | 749 |
729 @param profile | 750 @param profile |
730 @param request | 751 @param request |
731 @return: a constant indicating the state: | 752 @return: a constant indicating the state: |
732 - C.PROFILE_LOGGED | 753 - C.PROFILE_LOGGED |
733 - C.SESSION_ACTIVE | 754 - C.SESSION_ACTIVE |
734 """ | 755 """ |
735 self.__cleanWaiting(profile) | 756 self.waiting_profiles.purgeRequest(profile) |
736 _session = request.getSession() | 757 _session = request.getSession() |
737 sat_session = ISATSession(_session) | 758 sat_session = ISATSession(_session) |
738 if sat_session.profile: | 759 if sat_session.profile: |
739 log.error(('/!\\ Session has already a profile, this should NEVER happen!')) | 760 log.error(('/!\\ Session has already a profile, this should NEVER happen!')) |
740 request.write(C.SESSION_ACTIVE) | 761 request.write(C.SESSION_ACTIVE) |
764 return self.sat_host.bridge.isConnected(profile) | 785 return self.sat_host.bridge.isConnected(profile) |
765 | 786 |
766 def jsonrpc_asyncConnect(self): | 787 def jsonrpc_asyncConnect(self): |
767 _session = self.request.getSession() | 788 _session = self.request.getSession() |
768 profile = ISATSession(_session).profile | 789 profile = ISATSession(_session).profile |
769 if profile in self.profiles_waiting: | 790 if self.waiting_profiles.getRequest(profile): |
770 raise jsonrpclib.Fault(1, C.ALREADY_WAITING) # FIXME: define some standard error codes for libervia | 791 raise jsonrpclib.Fault(1, C.ALREADY_WAITING) # FIXME: define some standard error codes for libervia |
771 self.profiles_waiting[profile] = self.request | 792 self.waiting_profiles.setRequest(self.request, profile) |
772 self.sat_host.bridge.asyncConnect(profile) | 793 self.sat_host.bridge.asyncConnect(profile) |
773 return server.NOT_DONE_YET | 794 return server.NOT_DONE_YET |
774 | 795 |
775 def jsonrpc_isRegistered(self): | 796 def jsonrpc_isRegistered(self): |
776 """ | 797 """ |
875 self.queue[profile].append((function_name, args[:-1])) | 896 self.queue[profile].append((function_name, args[:-1])) |
876 return genericCb | 897 return genericCb |
877 | 898 |
878 def connected(self, profile): | 899 def connected(self, profile): |
879 assert(self.register) # register must be plugged | 900 assert(self.register) # register must be plugged |
880 request = self.register.getWaitingRequest(profile) | 901 request = self.register.waiting_profiles.getRequest(profile) |
881 if request: | 902 if request: |
882 self.register._logged(profile, request) | 903 self.register._logged(profile, request) |
883 | 904 |
884 def disconnected(self, profile): | 905 def disconnected(self, profile): |
885 if not profile in self.sat_host.prof_connected: | 906 if not profile in self.sat_host.prof_connected: |