# HG changeset patch # User souliane # Date 1402847528 -7200 # Node ID bbdc5357dc0006d4e88429126bc139f71c05ec46 # Parent 50b28686673939c23dd1e37dc17f19bb2880a004 browser and server sides: refactor HTTP request result values + handle "NoReply" error diff -r 50b286866739 -r bbdc5357dc00 src/browser/sat_browser/file_tools.py --- a/src/browser/sat_browser/file_tools.py Sat Jun 14 19:20:27 2014 +0200 +++ b/src/browser/sat_browser/file_tools.py Sun Jun 15 17:52:08 2014 +0200 @@ -19,6 +19,8 @@ from sat.core.log import getLogger log = getLogger(__name__) +from constants import Const as C +from sat.core.i18n import D_ from pyjamas.ui.FileUpload import FileUpload from pyjamas.ui.FormPanel import FormPanel from pyjamas import Window @@ -83,13 +85,13 @@ @param close_cb: the close button callback method """ FormPanel.__init__(self) - self.texts = {'ok_button': 'Upload file', - 'cancel_button': 'Cancel', - 'body': 'Please select a file.', - 'submitting': 'Submitting, please wait...', - 'errback': "Your file has been rejected...", - 'body_errback': 'Please select another file.', - 'callback': "Your file has been accepted!"} + self.texts = {'ok_button': D_('Upload file'), + 'cancel_button': D_('Cancel'), + 'body': D_('Please select a file.'), + 'submitting': D_('Submitting, please wait...'), + 'errback': D_("Your file has been rejected..."), + 'body_errback': D_('Please select another file.'), + 'callback': D_("Your file has been accepted!")} if isinstance(texts, dict): self.texts.update(texts) self.close_cb = close_cb @@ -139,10 +141,13 @@ def onSubmitComplete(self, event): result = event.getResults() - if result != "OK": + if result == C.UPLOAD_KO: Window.alert(self.texts['errback']) self.message.setHTML(self.texts['body_errback']) self.upload_btn.setEnabled(True) - else: + elif result == C.UPLOAD_OK: Window.alert(self.texts['callback']) self.close_cb() + else: + Window.alert(_('Submit error: %s' % result)) + self.upload_btn.setEnabled(True) diff -r 50b286866739 -r bbdc5357dc00 src/browser/sat_browser/radiocol.py --- a/src/browser/sat_browser/radiocol.py Sat Jun 14 19:20:27 2014 +0200 +++ b/src/browser/sat_browser/radiocol.py Sun Jun 15 17:52:08 2014 +0200 @@ -22,6 +22,7 @@ log = getLogger(__name__) from sat_frontends.tools.misc import DEFAULT_MUC from sat.core.i18n import _ +from constants import Const as C from pyjamas.ui.VerticalPanel import VerticalPanel from pyjamas.ui.HorizontalPanel import HorizontalPanel @@ -161,17 +162,17 @@ def onSubmitComplete(self, event): result = event.getResults() - if result == "OK": + if result == C.UPLOAD_OK: # the song can still be rejected (not readable, full queue...) self.setTemporaryStatus('[Your song has been submitted to the radio]', "ok") - elif result == "KO": + elif result == C.UPLOAD_KO: self.setTemporaryStatus('[Something went wrong during your song upload]', "ko") self._parent.radiocolSongRejected(_("The uploaded file has been rejected, only Ogg Vorbis and MP3 songs are accepted.")) # TODO: would be great to re-use the original Exception class and message # but it is lost in the middle of the traceback and encapsulated within # a DBusException instance --> extract the data from the traceback? else: - Window.alert('Submit error: %s' % result) + Window.alert(_('Submit error: %s' % result)) self.status.setText('') diff -r 50b286866739 -r bbdc5357dc00 src/browser/sat_browser/register.py --- a/src/browser/sat_browser/register.py Sat Jun 14 19:20:27 2014 +0200 +++ b/src/browser/sat_browser/register.py Sun Jun 15 17:52:08 2014 +0200 @@ -208,22 +208,24 @@ def onSubmitComplete(self, event): result = event.getResults() - if result == "PROFILE AUTH ERROR": + if result == C.PROFILE_AUTH_ERROR: Window.alert(_('Your login and/or password is incorrect. Please try again')) - elif result == "XMPP AUTH ERROR": + elif result == C.XMPP_AUTH_ERROR: # TODO: call stdui action CHANGE_XMPP_PASSWD_ID as it's done in primitivus Window.alert(_(u'Your SàT profile has been authenticated but the associated XMPP account failed to connect. Please use another SàT frontend to set another XMPP password.')) - elif result == "LOGGED": + elif result == C.PROFILE_LOGGED: self.callback() - elif result == "SESSION_ACTIVE": + elif result == C.SESSION_ACTIVE: Window.alert(_('Session already active, this should not happen, please contact the author to fix it')) - elif result == "ALREADY EXISTS": + elif result == C.NO_REPLY: + Window.alert(_("Did not receive a reply (the timeout expired or the connection is broken)")) + elif result == C.ALREADY_EXISTS: self.register_warning_msg.setHTML(_('This login already exists,
please choose another one')) self.register_warning_msg.setVisible(True) - elif result == "INTERNAL": + elif result == C.INTERNAL_ERROR: self.register_warning_msg.setHTML(_('SERVER ERROR: something went wrong during registration process, please contact the server administrator')) self.register_warning_msg.setVisible(True) - elif result == "REGISTRATION": + elif result == C.REGISTRATION_SUCCEED: self.login_warning_msg.setVisible(False) self.register_warning_msg.setVisible(False) self.login_box.setText(self.register_login_box.getText()) diff -r 50b286866739 -r bbdc5357dc00 src/common/constants.py --- a/src/common/constants.py Sat Jun 14 19:20:27 2014 +0200 +++ b/src/common/constants.py Sun Jun 15 17:52:08 2014 +0200 @@ -29,3 +29,19 @@ # MISC PASSWORD_MIN_LENGTH = 6 # for new account creation + + # HTTP REQUEST RESULT VALUES + PROFILE_AUTH_ERROR = 'PROFILE AUTH ERROR' + XMPP_AUTH_ERROR = 'XMPP AUTH ERROR' + ALREADY_WAITING = 'ALREADY WAITING' + SESSION_ACTIVE = 'SESSION ACTIVE' + PROFILE_LOGGED = 'LOGGED' + ALREADY_EXISTS = 'ALREADY EXISTS' + REGISTRATION_SUCCEED = 'REGISTRATION' + INTERNAL_ERROR = 'INTERNAL ERROR' + BAD_REQUEST = 'BAD REQUEST' + NO_REPLY = 'NO REPLY' + NOT_ALLOWED = 'NOT ALLOWED' + UPLOAD_OK = 'UPLOAD OK' + UPLOAD_KO = 'UPLOAD KO' + UNKNOWN_ERROR = 'UNMANAGED FAULT STRING (%s)' diff -r 50b286866739 -r bbdc5357dc00 src/server/blog.py --- a/src/server/blog.py Sat Jun 14 19:20:27 2014 +0200 +++ b/src/server/blog.py Sun Jun 15 17:52:08 2014 +0200 @@ -59,7 +59,7 @@ prof_requested = request.postpath[0] #TODO: char check: only use alphanumerical chars + some extra(_,-,...) here prof_found = self.host.bridge.getProfileName(prof_requested) - if not prof_found or prof_found == 'libervia': + if not prof_found or prof_found == C.SERVICE_PROFILE: return MicroBlog.ERROR_TEMPLATE % {'root': '../' * len(request.postpath), 'message': "Invalid nickname"} else: @@ -74,7 +74,7 @@ if len(request.postpath) > 1: if request.postpath[1] == 'atom.xml': # return the atom feed d2.addCallbacks(self.render_atom_feed, self.render_error_blog, [request], None, [request, prof_found], None) - self.host.bridge.getLastGroupBlogsAtom(pub_jid.userhost(), max_items, 'libervia', d2.callback, d2.errback) + self.host.bridge.getLastGroupBlogsAtom(pub_jid.userhost(), max_items, C.SERVICE_PROFILE, d2.callback, d2.errback) return try: # check if the given path is a valid UUID uuid.UUID(request.postpath[1]) @@ -83,9 +83,9 @@ pass d2.addCallbacks(self.render_html_blog, self.render_error_blog, [request, prof_found], None, [request, prof_found], None) if item_id: # display one message and its comments - self.host.bridge.getGroupBlogsWithComments(pub_jid.userhost(), [item_id], 'libervia', d2.callback, d2.errback) + self.host.bridge.getGroupBlogsWithComments(pub_jid.userhost(), [item_id], C.SERVICE_PROFILE, d2.callback, d2.errback) else: # display the last messages without comment - self.host.bridge.getLastGroupBlogs(pub_jid.userhost(), max_items, 'libervia', d2.callback, d2.errback) + self.host.bridge.getLastGroupBlogs(pub_jid.userhost(), max_items, C.SERVICE_PROFILE, d2.callback, d2.errback) d1 = defer.Deferred() JID(self.host.bridge.asyncGetParamA('JabberID', 'Connection', 'value', C.SERVER_SECURITY_LIMIT, prof_found, callback=d1.callback, errback=d1.errback)) diff -r 50b286866739 -r bbdc5357dc00 src/server/server.py --- a/src/server/server.py Sat Jun 14 19:20:27 2014 +0200 +++ b/src/server/server.py Sun Jun 15 17:52:08 2014 +0200 @@ -180,7 +180,7 @@ if not profile: #user is not identified, we return a jsonrpc fault parsed = jsonrpclib.loads(request.content.read()) - fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia + fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) return jsonrpc.JSONRPC.render(self, request) @@ -586,7 +586,7 @@ profile = ISATSession(_session).profile if not profile: #user is not identified, we return a jsonrpc fault - fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia + fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) self.request = request return jsonrpc.JSONRPC.render(self, request) @@ -596,13 +596,13 @@ @param request: request of the register form @return: a constant indicating the state: - - BAD REQUEST: something is wrong in the request (bad arguments) + - C.BAD_REQUEST: something is wrong in the request (bad arguments) - a return value from self._loginAccount or self._registerNewAccount """ try: submit_type = request.args['submit_type'][0] except KeyError: - return "BAD REQUEST" + return C.BAD_REQUEST if submit_type == 'register': return self._registerNewAccount(request) @@ -614,10 +614,10 @@ """Try to authenticate the user with the request information. @param request: request of the register form @return: a constant indicating the state: - - BAD REQUEST: something is wrong in the request (bad arguments) - - PROFILE AUTH ERROR: either the profile (login) or the profile password is wrong - - XMPP AUTH ERROR: the profile is authenticated but the XMPP password is wrong - - ALREADY WAITING: a request has already been submitted for this profile + - C.BAD_REQUEST: something is wrong in the request (bad arguments) + - C.PROFILE_AUTH_ERROR: either the profile (login) or the profile password is wrong + - C.XMPP_AUTH_ERROR: the profile is authenticated but the XMPP password is wrong + - C.ALREADY_WAITING: a request has already been submitted for this profile - server.NOT_DONE_YET: the profile is being processed, the return value will be given by self._logged or auth_eb """ @@ -625,7 +625,7 @@ login_ = request.args['login'][0] password_ = request.args['login_password'][0] except KeyError: - return "BAD REQUEST" + return C.BAD_REQUEST if login_.startswith('@'): raise Exception('No profile_key allowed') @@ -633,24 +633,27 @@ profile_check = self.sat_host.bridge.getProfileName(login_) if ((not profile_check or profile_check != login_) or (not password_ and profile_check not in self.sat_host.empty_password_allowed_warning_dangerous_list)): - return "PROFILE AUTH ERROR" + return C.PROFILE_AUTH_ERROR # profiles with empty passwords are restricted to local frontends if login_ in self.profiles_waiting: - return "ALREADY WAITING" + return C.ALREADY_WAITING def auth_eb(failure): fault = failure.value.faultString self.__cleanWaiting(login_) if fault == 'PasswordError': log.info("Profile %s doesn't exist or the submitted password is wrong" % login_) - request.write("PROFILE AUTH ERROR") + request.write(C.PROFILE_AUTH_ERROR) elif fault == 'SASLAuthError': log.info("The XMPP password of profile %s is wrong" % login_) - request.write("XMPP AUTH ERROR") + request.write(C.XMPP_AUTH_ERROR) + elif fault == 'NoReply': + log.info(_("Did not receive a reply (the timeout expired or the connection is broken)")) + request.write(C.NO_REPLY) else: log.error('Unmanaged fault string %s in errback for the connection of profile %s' % (fault, login_)) - request.write('UNMANAGED FAULT STRING: %s' % str(fault)) + request.write(C.UNKNOWN_ERROR % fault) request.finish() self.profiles_waiting[login_] = request @@ -663,10 +666,10 @@ """Create a new account, or return error @param request: request of the register form @return: a constant indicating the state: - - BAD REQUEST: something is wrong in the request (bad arguments) - - REGISTRATION: new account has been successfully registered - - ALREADY EXISTS: the given profile already exists - - INTERNAL or 'Unknown error (...)' + - C.BAD_REQUEST: something is wrong in the request (bad arguments) + - C.REGISTRATION_SUCCEED: new account has been successfully registered + - C.ALREADY_EXISTS: the given profile already exists + - C.INTERNAL_ERROR or C.UNKNOWN_ERROR - server.NOT_DONE_YET: the profile is being processed, the return value will be given later (one of those previously described) """ @@ -675,25 +678,25 @@ password = request.args['register_password'][0] email = request.args['email'][0] except KeyError: - return "BAD REQUEST" + return C.BAD_REQUEST if not re.match(r'^[a-z0-9_-]+$', login, re.IGNORECASE) or \ not re.match(r'^.+@.+\..+', email, re.IGNORECASE) or \ len(password) < C.PASSWORD_MIN_LENGTH: - return "BAD REQUEST" + return C.BAD_REQUEST def registered(result): - request.write('REGISTRATION') + request.write(C.REGISTRATION_SUCCEED) request.finish() def registeringError(failure): reason = failure.value.faultString if reason == "ConflictError": - request.write('ALREADY EXISTS') + request.write(C.ALREADY_EXISTS) elif reason == "InternalError": - request.write('INTERNAL') + request.write(C.INTERNAL_ERROR) else: log.error('Unknown registering error: %s' % (reason,)) - request.write('Unknown error (%s)' % reason) + request.write(C.UNKNOWN_ERROR % reason) request.finish() d = self.asyncBridgeCall("registerSatAccount", email, password, profile) @@ -714,15 +717,15 @@ @param profile @param request @return: a constant indicating the state: - - LOGGED - - SESSION_ACTIVE + - C.PROFILE_LOGGED + - C.SESSION_ACTIVE """ self.__cleanWaiting(profile) _session = request.getSession() sat_session = ISATSession(_session) if sat_session.profile: log.error(('/!\\ Session has already a profile, this should NEVER happen!')) - request.write('SESSION_ACTIVE') + request.write(C.SESSION_ACTIVE) request.finish() return sat_session.profile = profile @@ -740,7 +743,7 @@ _session.notifyOnExpire(onExpire) - request.write('LOGGED') + request.write(C.PROFILE_LOGGED) request.finish() def jsonrpc_isConnected(self): @@ -752,7 +755,7 @@ _session = self.request.getSession() profile = ISATSession(_session).profile if profile in self.profiles_waiting: - raise jsonrpclib.Fault(1, 'Already waiting') # FIXME: define some standard error codes for libervia + raise jsonrpclib.Fault(1, C.ALREADY_WAITING) # FIXME: define some standard error codes for libervia self.profiles_waiting[profile] = self.request self.sat_host.bridge.asyncConnect(profile) return server.NOT_DONE_YET @@ -888,7 +891,7 @@ profile = ISATSession(_session).profile if not profile: #user is not identified, we return a jsonrpc fault - fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, "Not allowed") # FIXME: define some standard error codes for libervia + fault = jsonrpclib.Fault(C.ERRNUM_LIBERVIA, C.NOT_ALLOWED) # FIXME: define some standard error codes for libervia return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) self.request = request return jsonrpc.JSONRPC.render(self, request) @@ -940,7 +943,7 @@ def finish(d): error = isinstance(d, Exception) or isinstance(d, Failure) - request.write('KO' if error else 'OK') + request.write(C.UPLOAD_KO if error else C.UPLOAD_OK) # TODO: would be great to re-use the original Exception class and message # but it is lost in the middle of the backtrace and encapsulated within # a DBusException instance --> extract the data from the backtrace?