Mercurial > libervia-web
comparison src/server/server.py @ 481:bbdc5357dc00
browser and server sides: refactor HTTP request result values + handle "NoReply" error
author | souliane <souliane@mailoo.org> |
---|---|
date | Sun, 15 Jun 2014 17:52:08 +0200 |
parents | d6daa00ba564 |
children | 437eefa53a01 |
comparison
equal
deleted
inserted
replaced
480:50b286866739 | 481:bbdc5357dc00 |
---|---|
178 self.session = request.getSession() | 178 self.session = request.getSession() |
179 profile = ISATSession(self.session).profile | 179 profile = ISATSession(self.session).profile |
180 if not profile: | 180 if not profile: |
181 #user is not identified, we return a jsonrpc fault | 181 #user is not identified, we return a jsonrpc fault |
182 parsed = jsonrpclib.loads(request.content.read()) | 182 parsed = jsonrpclib.loads(request.content.read()) |
183 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia | 183 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')) | 184 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) |
185 return jsonrpc.JSONRPC.render(self, request) | 185 return jsonrpc.JSONRPC.render(self, request) |
186 | 186 |
187 def jsonrpc_getProfileJid(self): | 187 def jsonrpc_getProfileJid(self): |
188 """Return the jid of the profile""" | 188 """Return the jid of the profile""" |
584 if method not in ['isRegistered', 'registerParams', 'getMenus']: | 584 if method not in ['isRegistered', 'registerParams', 'getMenus']: |
585 #if we don't call these methods, we need to be identified | 585 #if we don't call these methods, we need to be identified |
586 profile = ISATSession(_session).profile | 586 profile = ISATSession(_session).profile |
587 if not profile: | 587 if not profile: |
588 #user is not identified, we return a jsonrpc fault | 588 #user is not identified, we return a jsonrpc fault |
589 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia | 589 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia |
590 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) | 590 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) |
591 self.request = request | 591 self.request = request |
592 return jsonrpc.JSONRPC.render(self, request) | 592 return jsonrpc.JSONRPC.render(self, request) |
593 | 593 |
594 def loginOrRegister(self, request): | 594 def loginOrRegister(self, request): |
595 """This method is called with the POST information from the registering form. | 595 """This method is called with the POST information from the registering form. |
596 | 596 |
597 @param request: request of the register form | 597 @param request: request of the register form |
598 @return: a constant indicating the state: | 598 @return: a constant indicating the state: |
599 - BAD REQUEST: something is wrong in the request (bad arguments) | 599 - C.BAD_REQUEST: something is wrong in the request (bad arguments) |
600 - a return value from self._loginAccount or self._registerNewAccount | 600 - a return value from self._loginAccount or self._registerNewAccount |
601 """ | 601 """ |
602 try: | 602 try: |
603 submit_type = request.args['submit_type'][0] | 603 submit_type = request.args['submit_type'][0] |
604 except KeyError: | 604 except KeyError: |
605 return "BAD REQUEST" | 605 return C.BAD_REQUEST |
606 | 606 |
607 if submit_type == 'register': | 607 if submit_type == 'register': |
608 return self._registerNewAccount(request) | 608 return self._registerNewAccount(request) |
609 elif submit_type == 'login': | 609 elif submit_type == 'login': |
610 return self._loginAccount(request) | 610 return self._loginAccount(request) |
612 | 612 |
613 def _loginAccount(self, request): | 613 def _loginAccount(self, request): |
614 """Try to authenticate the user with the request information. | 614 """Try to authenticate the user with the request information. |
615 @param request: request of the register form | 615 @param request: request of the register form |
616 @return: a constant indicating the state: | 616 @return: a constant indicating the state: |
617 - BAD REQUEST: something is wrong in the request (bad arguments) | 617 - C.BAD_REQUEST: something is wrong in the request (bad arguments) |
618 - PROFILE AUTH ERROR: either the profile (login) or the profile password is wrong | 618 - C.PROFILE_AUTH_ERROR: either the profile (login) or the profile password is wrong |
619 - XMPP AUTH ERROR: the profile is authenticated but the XMPP password is wrong | 619 - C.XMPP_AUTH_ERROR: the profile is authenticated but the XMPP password is wrong |
620 - ALREADY WAITING: a request has already been submitted for this profile | 620 - C.ALREADY_WAITING: a request has already been submitted for this profile |
621 - server.NOT_DONE_YET: the profile is being processed, the return | 621 - server.NOT_DONE_YET: the profile is being processed, the return |
622 value will be given by self._logged or auth_eb | 622 value will be given by self._logged or auth_eb |
623 """ | 623 """ |
624 try: | 624 try: |
625 login_ = request.args['login'][0] | 625 login_ = request.args['login'][0] |
626 password_ = request.args['login_password'][0] | 626 password_ = request.args['login_password'][0] |
627 except KeyError: | 627 except KeyError: |
628 return "BAD REQUEST" | 628 return C.BAD_REQUEST |
629 | 629 |
630 if login_.startswith('@'): | 630 if login_.startswith('@'): |
631 raise Exception('No profile_key allowed') | 631 raise Exception('No profile_key allowed') |
632 | 632 |
633 profile_check = self.sat_host.bridge.getProfileName(login_) | 633 profile_check = self.sat_host.bridge.getProfileName(login_) |
634 if ((not profile_check or profile_check != login_) or | 634 if ((not profile_check or profile_check != login_) or |
635 (not password_ and profile_check not in self.sat_host.empty_password_allowed_warning_dangerous_list)): | 635 (not password_ and profile_check not in self.sat_host.empty_password_allowed_warning_dangerous_list)): |
636 return "PROFILE AUTH ERROR" | 636 return C.PROFILE_AUTH_ERROR |
637 # profiles with empty passwords are restricted to local frontends | 637 # profiles with empty passwords are restricted to local frontends |
638 | 638 |
639 if login_ in self.profiles_waiting: | 639 if login_ in self.profiles_waiting: |
640 return "ALREADY WAITING" | 640 return C.ALREADY_WAITING |
641 | 641 |
642 def auth_eb(failure): | 642 def auth_eb(failure): |
643 fault = failure.value.faultString | 643 fault = failure.value.faultString |
644 self.__cleanWaiting(login_) | 644 self.__cleanWaiting(login_) |
645 if fault == 'PasswordError': | 645 if fault == 'PasswordError': |
646 log.info("Profile %s doesn't exist or the submitted password is wrong" % login_) | 646 log.info("Profile %s doesn't exist or the submitted password is wrong" % login_) |
647 request.write("PROFILE AUTH ERROR") | 647 request.write(C.PROFILE_AUTH_ERROR) |
648 elif fault == 'SASLAuthError': | 648 elif fault == 'SASLAuthError': |
649 log.info("The XMPP password of profile %s is wrong" % login_) | 649 log.info("The XMPP password of profile %s is wrong" % login_) |
650 request.write("XMPP AUTH ERROR") | 650 request.write(C.XMPP_AUTH_ERROR) |
651 elif fault == 'NoReply': | |
652 log.info(_("Did not receive a reply (the timeout expired or the connection is broken)")) | |
653 request.write(C.NO_REPLY) | |
651 else: | 654 else: |
652 log.error('Unmanaged fault string %s in errback for the connection of profile %s' % (fault, login_)) | 655 log.error('Unmanaged fault string %s in errback for the connection of profile %s' % (fault, login_)) |
653 request.write('UNMANAGED FAULT STRING: %s' % str(fault)) | 656 request.write(C.UNKNOWN_ERROR % fault) |
654 request.finish() | 657 request.finish() |
655 | 658 |
656 self.profiles_waiting[login_] = request | 659 self.profiles_waiting[login_] = request |
657 d = self.asyncBridgeCall("asyncConnect", login_, password_) | 660 d = self.asyncBridgeCall("asyncConnect", login_, password_) |
658 d.addCallbacks(lambda connected: self._logged(login_, request) if connected else None, auth_eb) | 661 d.addCallbacks(lambda connected: self._logged(login_, request) if connected else None, auth_eb) |
661 | 664 |
662 def _registerNewAccount(self, request): | 665 def _registerNewAccount(self, request): |
663 """Create a new account, or return error | 666 """Create a new account, or return error |
664 @param request: request of the register form | 667 @param request: request of the register form |
665 @return: a constant indicating the state: | 668 @return: a constant indicating the state: |
666 - BAD REQUEST: something is wrong in the request (bad arguments) | 669 - C.BAD_REQUEST: something is wrong in the request (bad arguments) |
667 - REGISTRATION: new account has been successfully registered | 670 - C.REGISTRATION_SUCCEED: new account has been successfully registered |
668 - ALREADY EXISTS: the given profile already exists | 671 - C.ALREADY_EXISTS: the given profile already exists |
669 - INTERNAL or 'Unknown error (...)' | 672 - C.INTERNAL_ERROR or C.UNKNOWN_ERROR |
670 - server.NOT_DONE_YET: the profile is being processed, the return | 673 - server.NOT_DONE_YET: the profile is being processed, the return |
671 value will be given later (one of those previously described) | 674 value will be given later (one of those previously described) |
672 """ | 675 """ |
673 try: | 676 try: |
674 profile = login = request.args['register_login'][0] | 677 profile = login = request.args['register_login'][0] |
675 password = request.args['register_password'][0] | 678 password = request.args['register_password'][0] |
676 email = request.args['email'][0] | 679 email = request.args['email'][0] |
677 except KeyError: | 680 except KeyError: |
678 return "BAD REQUEST" | 681 return C.BAD_REQUEST |
679 if not re.match(r'^[a-z0-9_-]+$', login, re.IGNORECASE) or \ | 682 if not re.match(r'^[a-z0-9_-]+$', login, re.IGNORECASE) or \ |
680 not re.match(r'^.+@.+\..+', email, re.IGNORECASE) or \ | 683 not re.match(r'^.+@.+\..+', email, re.IGNORECASE) or \ |
681 len(password) < C.PASSWORD_MIN_LENGTH: | 684 len(password) < C.PASSWORD_MIN_LENGTH: |
682 return "BAD REQUEST" | 685 return C.BAD_REQUEST |
683 | 686 |
684 def registered(result): | 687 def registered(result): |
685 request.write('REGISTRATION') | 688 request.write(C.REGISTRATION_SUCCEED) |
686 request.finish() | 689 request.finish() |
687 | 690 |
688 def registeringError(failure): | 691 def registeringError(failure): |
689 reason = failure.value.faultString | 692 reason = failure.value.faultString |
690 if reason == "ConflictError": | 693 if reason == "ConflictError": |
691 request.write('ALREADY EXISTS') | 694 request.write(C.ALREADY_EXISTS) |
692 elif reason == "InternalError": | 695 elif reason == "InternalError": |
693 request.write('INTERNAL') | 696 request.write(C.INTERNAL_ERROR) |
694 else: | 697 else: |
695 log.error('Unknown registering error: %s' % (reason,)) | 698 log.error('Unknown registering error: %s' % (reason,)) |
696 request.write('Unknown error (%s)' % reason) | 699 request.write(C.UNKNOWN_ERROR % reason) |
697 request.finish() | 700 request.finish() |
698 | 701 |
699 d = self.asyncBridgeCall("registerSatAccount", email, password, profile) | 702 d = self.asyncBridgeCall("registerSatAccount", email, password, profile) |
700 d.addCallback(registered) | 703 d.addCallback(registered) |
701 d.addErrback(registeringError) | 704 d.addErrback(registeringError) |
712 """Set everything when a user just logged in | 715 """Set everything when a user just logged in |
713 | 716 |
714 @param profile | 717 @param profile |
715 @param request | 718 @param request |
716 @return: a constant indicating the state: | 719 @return: a constant indicating the state: |
717 - LOGGED | 720 - C.PROFILE_LOGGED |
718 - SESSION_ACTIVE | 721 - C.SESSION_ACTIVE |
719 """ | 722 """ |
720 self.__cleanWaiting(profile) | 723 self.__cleanWaiting(profile) |
721 _session = request.getSession() | 724 _session = request.getSession() |
722 sat_session = ISATSession(_session) | 725 sat_session = ISATSession(_session) |
723 if sat_session.profile: | 726 if sat_session.profile: |
724 log.error(('/!\\ Session has already a profile, this should NEVER happen!')) | 727 log.error(('/!\\ Session has already a profile, this should NEVER happen!')) |
725 request.write('SESSION_ACTIVE') | 728 request.write(C.SESSION_ACTIVE) |
726 request.finish() | 729 request.finish() |
727 return | 730 return |
728 sat_session.profile = profile | 731 sat_session.profile = profile |
729 self.sat_host.prof_connected.add(profile) | 732 self.sat_host.prof_connected.add(profile) |
730 | 733 |
738 #and now we disconnect the profile | 741 #and now we disconnect the profile |
739 self.sat_host.bridge.disconnect(profile) | 742 self.sat_host.bridge.disconnect(profile) |
740 | 743 |
741 _session.notifyOnExpire(onExpire) | 744 _session.notifyOnExpire(onExpire) |
742 | 745 |
743 request.write('LOGGED') | 746 request.write(C.PROFILE_LOGGED) |
744 request.finish() | 747 request.finish() |
745 | 748 |
746 def jsonrpc_isConnected(self): | 749 def jsonrpc_isConnected(self): |
747 _session = self.request.getSession() | 750 _session = self.request.getSession() |
748 profile = ISATSession(_session).profile | 751 profile = ISATSession(_session).profile |
750 | 753 |
751 def jsonrpc_asyncConnect(self): | 754 def jsonrpc_asyncConnect(self): |
752 _session = self.request.getSession() | 755 _session = self.request.getSession() |
753 profile = ISATSession(_session).profile | 756 profile = ISATSession(_session).profile |
754 if profile in self.profiles_waiting: | 757 if profile in self.profiles_waiting: |
755 raise jsonrpclib.Fault(1, 'Already waiting') # FIXME: define some standard error codes for libervia | 758 raise jsonrpclib.Fault(1, C.ALREADY_WAITING) # FIXME: define some standard error codes for libervia |
756 self.profiles_waiting[profile] = self.request | 759 self.profiles_waiting[profile] = self.request |
757 self.sat_host.bridge.asyncConnect(profile) | 760 self.sat_host.bridge.asyncConnect(profile) |
758 return server.NOT_DONE_YET | 761 return server.NOT_DONE_YET |
759 | 762 |
760 def jsonrpc_isRegistered(self): | 763 def jsonrpc_isRegistered(self): |
886 _session = request.getSession() | 889 _session = request.getSession() |
887 parsed = jsonrpclib.loads(request.content.read()) | 890 parsed = jsonrpclib.loads(request.content.read()) |
888 profile = ISATSession(_session).profile | 891 profile = ISATSession(_session).profile |
889 if not profile: | 892 if not profile: |
890 #user is not identified, we return a jsonrpc fault | 893 #user is not identified, we return a jsonrpc fault |
891 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia | 894 fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia |
892 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) | 895 return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) |
893 self.request = request | 896 self.request = request |
894 return jsonrpc.JSONRPC.render(self, request) | 897 return jsonrpc.JSONRPC.render(self, request) |
895 | 898 |
896 | 899 |
938 with open(filepath, 'w') as f: | 941 with open(filepath, 'w') as f: |
939 f.write(request.args[self.NAME][0]) | 942 f.write(request.args[self.NAME][0]) |
940 | 943 |
941 def finish(d): | 944 def finish(d): |
942 error = isinstance(d, Exception) or isinstance(d, Failure) | 945 error = isinstance(d, Exception) or isinstance(d, Failure) |
943 request.write('KO' if error else 'OK') | 946 request.write(C.UPLOAD_KO if error else C.UPLOAD_OK) |
944 # TODO: would be great to re-use the original Exception class and message | 947 # TODO: would be great to re-use the original Exception class and message |
945 # but it is lost in the middle of the backtrace and encapsulated within | 948 # but it is lost in the middle of the backtrace and encapsulated within |
946 # a DBusException instance --> extract the data from the backtrace? | 949 # a DBusException instance --> extract the data from the backtrace? |
947 request.finish() | 950 request.finish() |
948 | 951 |