/soc/2015/jgeboski/facebook: 7c454f51b56b: facebook: handle auth...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 7c454f51b56b8d71f4f9ba444c8d60c7848d226e Author: James Geboski <[email protected]> Date: 2015-07-27 16:43 -0400 Branch: facebook URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/7c454f51b56b Description: facebook: handle authentication errors Currently, authentication errors are essentially ignored with ambiguous error messages. This is due to errors never being fully parsed for the failure reason. This issue leads to the user being unaware of the cause as it often breaks long after the password has been changed. This extends the error parsing as well as refactors some of the error handling mechanisms. diffstat: libpurple/protocols/facebook/api.c | 103 ++++++++++++++++++++++++------- libpurple/protocols/facebook/api.h | 3 +- libpurple/protocols/facebook/facebook.c | 25 +++---- 3 files changed, 93 insertions(+), 38 deletions(-) diffs (198 lines): diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c --- a/libpurple/protocols/facebook/api.c +++ b/libpurple/protocols/facebook/api.c @@ -306,13 +306,24 @@ fb_api_error_quark(void) static gboolean fb_api_json_chk(FbApi *api, gconstpointer data, gsize size, JsonNode **node) { + FbApiError errc = FB_API_ERROR_GENERAL; FbApiPrivate *priv; - gboolean success = FALSE; + gboolean success = TRUE; gchar *msg = NULL; + gchar *str; GError *err = NULL; gint64 code; + guint i; JsonNode *root; + static const gchar *exprs[] = { + "$.error.message", + "$.error.summary", + "$.error_msg", + "$.errorCode", + "$.failedSend.errorMessage", + }; + g_return_val_if_fail(FB_IS_API(api), FALSE); priv = api->priv; @@ -325,37 +336,71 @@ fb_api_json_chk(FbApi *api, gconstpointe root = fb_json_node_new(data, size, &err); FB_API_ERROR_CHK(api, err, return FALSE); - if (fb_json_node_chk_str(root, "$.error.summary", &msg) || - fb_json_node_chk_str(root, "$.failedSend.errorMessage", &msg)) + if (fb_json_node_chk_int(root, "$.error_code", &code) && + (code == 401)) { - fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg); - } else if (fb_json_node_chk_int(root, "$.error_code", &code)) { - if (!fb_json_node_chk_str(root, "$.error_msg", &msg)) { - msg = g_strdup(_("Generic error")); - } + errc = FB_API_ERROR_AUTH; + success = FALSE; - fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg); - } else if (fb_json_node_chk_str(root, "$.errorCode", &msg)) { - if ((g_ascii_strcasecmp(msg, "ERROR_QUEUE_NOT_FOUND") == 0) || - (g_ascii_strcasecmp(msg, "ERROR_QUEUE_LOST") == 0)) - { - g_free(priv->stoken); - priv->stoken = NULL; - } + g_free(priv->stoken); + priv->stoken = NULL; - fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg); - } else { - success = TRUE; + g_free(priv->token); + priv->token = NULL; } - if (success && (node != NULL)) { + if (fb_json_node_chk_str(root, "$.error.type", &str) && + (g_ascii_strcasecmp(str, "OAuthException") == 0)) + { + errc = FB_API_ERROR_AUTH; + success = FALSE; + g_free(str); + + g_free(priv->stoken); + priv->stoken = NULL; + + g_free(priv->token); + priv->token = NULL; + + } + + if (fb_json_node_chk_str(root, "$.errorCode", &str) && ( + (g_ascii_strcasecmp(str, "ERROR_QUEUE_NOT_FOUND") == 0) || + (g_ascii_strcasecmp(str, "ERROR_QUEUE_LOST") == 0))) + { + errc = FB_API_ERROR_AUTH; + success = FALSE; + g_free(str); + + g_free(priv->stoken); + priv->stoken = NULL; + } + + for (i = 0; i < G_N_ELEMENTS(exprs); i++) { + if (fb_json_node_chk_str(root, exprs[i], &msg)) { + success = FALSE; + break; + } + } + + if (!success && (msg == NULL)) { + msg = g_strdup(_("Unknown error")); + } + + if (msg != NULL) { + fb_api_error(api, errc, "%s", msg); + json_node_free(root); + g_free(msg); + return FALSE; + } + + if (node != NULL) { *node = root; } else { json_node_free(root); } - g_free(msg); - return success; + return TRUE; } static gboolean @@ -388,11 +433,21 @@ fb_api_http_chk(FbApi *api, PurpleHttpCo (gint) size, data); } - if (!fb_http_error_chk(res, &err)) { + if ((root == NULL) && fb_http_error_chk(res, &err)) { + return TRUE; + } + + /* Rudimentary check to prevent wrongful error parsing */ + if ((size < 2) || (data[0] != '{') || (data[size - 1] != '}')) { FB_API_ERROR_CHK(api, err, return FALSE); } - return (root == NULL) || fb_api_json_chk(api, data, size, root); + if (fb_api_json_chk(api, data, size, root)) { + FB_API_ERROR_CHK(api, err, return FALSE); + return TRUE; + } + + return FALSE; } static PurpleHttpConnection * diff --git a/libpurple/protocols/facebook/api.h b/libpurple/protocols/facebook/api.h --- a/libpurple/protocols/facebook/api.h +++ b/libpurple/protocols/facebook/api.h @@ -87,7 +87,8 @@ typedef struct _FbApiHttpInfo FbApiHttpI enum _FbApiError { - FB_API_ERROR_GENERAL + FB_API_ERROR_GENERAL, + FB_API_ERROR_AUTH }; struct _FbApi diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c --- a/libpurple/protocols/facebook/facebook.c +++ b/libpurple/protocols/facebook/facebook.c @@ -170,23 +170,22 @@ static void fb_cb_api_error(FbApi *api, GError *error, gpointer data) { FbData *fata = data; - gboolean nfatal; PurpleConnection *gc; - PurpleConnectionError reason; + PurpleConnectionError errc; - /* Non-fatal errors */ - nfatal = (error->domain == FB_API_ERROR) || - (error->domain == FB_MQTT_ERROR); - - /* Non-fatal HTTP errors */ - nfatal |= (error->domain == FB_HTTP_ERROR) && - ((error->code < 400) || (error->code > 500)); - - reason = (nfatal) ? PURPLE_CONNECTION_ERROR_NETWORK_ERROR - : PURPLE_CONNECTION_ERROR_OTHER_ERROR; + if ((error->domain == FB_HTTP_ERROR) && + (error->code >= 400) && + (error->code <= 500)) + { + errc = PURPLE_CONNECTION_ERROR_OTHER_ERROR; + } else if (g_error_matches(error, FB_API_ERROR, FB_API_ERROR_AUTH)) { + errc = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED; + } else { + errc = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; + } gc = fb_data_get_connection(fata); - purple_connection_error(gc, reason, error->message); + purple_connection_error(gc, errc, error->message); } static void _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits