Mercurial > pidgin.yaz
changeset 25036:06a802d32d71
I incorrectly assumed that the FindMembership and ABFindAll SOAP requests
on MSN would not require token updates. However, these two requests may be
made when it discovers that someone is requesting to be on your buddy list.
Change these SOAP requests so that they will auto-update tokens.
References #7921, only because I saw it in the log there, but probably
doesn't fix it.
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Sun, 01 Feb 2009 08:04:41 +0000 |
parents | 89670ae028bd |
children | 3e89d2c6bf93 |
files | libpurple/protocols/msn/contact.c libpurple/protocols/msn/contact.h |
diffstat | 2 files changed, 152 insertions(+), 151 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/msn/contact.c Sat Jan 31 07:37:11 2009 +0000 +++ b/libpurple/protocols/msn/contact.c Sun Feb 01 08:04:41 2009 +0000 @@ -158,6 +158,113 @@ state->action |= action; } +/*************************************************************** + * General SOAP handling + ***************************************************************/ + +static const char * +msn_contact_operation_str(MsnCallbackAction action) +{ + /* Make sure this is large enough when adding more */ + static char buf[BUF_LEN]; + buf[0] = '\0'; + + if (action & MSN_ADD_BUDDY) + strcat(buf, "Adding Buddy,"); + if (action & MSN_MOVE_BUDDY) + strcat(buf, "Moving Buddy,"); + if (action & MSN_ACCEPTED_BUDDY) + strcat(buf, "Accepted Buddy,"); + if (action & MSN_DENIED_BUDDY) + strcat(buf, "Denied Buddy,"); + if (action & MSN_ADD_GROUP) + strcat(buf, "Adding Group,"); + if (action & MSN_DEL_GROUP) + strcat(buf, "Deleting Group,"); + if (action & MSN_RENAME_GROUP) + strcat(buf, "Renaming Group,"); + if (action & MSN_UPDATE_INFO) + strcat(buf, "Updating Contact Info,"); + + return buf; +} + +static gboolean msn_contact_request(MsnCallbackState *state); + +static void +msn_contact_request_cb(MsnSoapMessage *req, MsnSoapMessage *resp, + gpointer data) +{ + MsnCallbackState *state = data; + xmlnode *fault; + char *faultcode_str; + + if (resp == NULL) { + purple_debug_error("msn", + "Operation {%s} failed. No response received from server.\n", + msn_contact_operation_str(state->action)); + return; + } + + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + + if (fault == NULL) { + /* No errors */ + if (state->cb) + ((MsnSoapCallback)state->cb)(req, resp, data); + msn_callback_state_free(state); + return; + } + + faultcode_str = xmlnode_get_data(xmlnode_get_child(fault, "faultcode")); + + if (faultcode_str && g_str_equal(faultcode_str, "q0:BadContextToken")) { + purple_debug_info("msn", + "Contact Operation {%s} failed because of bad token." + " Updating token now and retrying operation.\n", + msn_contact_operation_str(state->action)); + /* Token has expired, so renew it, and try again later */ + msn_nexus_update_token(state->session->nexus, MSN_AUTH_CONTACTS, + (GSourceFunc)msn_contact_request, data); + } + else + { + if (state->cb) { + ((MsnSoapCallback)state->cb)(req, resp, data); + } else { + /* We don't know how to respond to this faultcode, so log it */ + char *str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), str); + g_free(str); + } + msn_callback_state_free(state); + } + + g_free(faultcode_str); +} + +static gboolean +msn_contact_request(MsnCallbackState *state) +{ + if (state->token == NULL) + state->token = xmlnode_get_child(state->body, + "Header/ABAuthHeader/TicketToken"); + /* delete old & replace with new token */ + xmlnode_free(state->token->child); + xmlnode_insert_data(state->token, + msn_nexus_get_token_str(state->session->nexus, MSN_AUTH_CONTACTS), -1); + msn_soap_message_send(state->session, + msn_soap_message_new(state->post_action, xmlnode_copy(state->body)), + MSN_CONTACT_SERVER, state->post_url, FALSE, + msn_contact_request_cb, state); + return FALSE; +} + +/*************************************************************** + * Address Book and Membership List Operations + ***************************************************************/ + /*get MSN member role utility*/ static MsnListId msn_get_memberrole(const char *role) @@ -180,9 +287,10 @@ static void msn_create_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data) { + MsnCallbackState *state = data; if (resp && xmlnode_get_child(resp->xml, "Body/Fault") == NULL) { purple_debug_info("msn", "Address Book successfully created!\n"); - msn_get_address_book((MsnSession *)data, MSN_PS_INITIAL, NULL, NULL); + msn_get_address_book(state->session, MSN_PS_INITIAL, NULL, NULL); } else { purple_debug_info("msn", "Address Book creation failed!\n"); } @@ -192,7 +300,7 @@ msn_create_address_book(MsnSession *session) { gchar *body; - gchar *token_str; + MsnCallbackState *state; g_return_if_fail(session != NULL); g_return_if_fail(session->user != NULL); @@ -200,17 +308,15 @@ purple_debug_info("msn", "Creating an Address Book.\n"); - token_str = g_markup_escape_text( - msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS), -1); body = g_strdup_printf(MSN_ADD_ADDRESSBOOK_TEMPLATE, - token_str, session->user->passport); - g_free(token_str); + session->user->passport); - msn_soap_message_send(session, - msn_soap_message_new(MSN_ADD_ADDRESSBOOK_SOAP_ACTION, - xmlnode_from_str(body, -1)), - MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL, FALSE, - msn_create_address_cb, session); + state = msn_callback_state_new(session); + state->body = xmlnode_from_str(body, -1); + state->post_action = MSN_ADD_ADDRESSBOOK_SOAP_ACTION; + state->post_url = MSN_ADDRESS_BOOK_POST_URL; + state->cb = msn_create_address_cb; + msn_contact_request(state); g_free(body); } @@ -362,8 +468,8 @@ msn_get_contact_list_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data) { - GetContactListCbData *cb_data = data; - MsnSession *session = cb_data->session; + MsnCallbackState *state = data; + MsnSession *session = state->session; g_return_if_fail(session != NULL); @@ -379,7 +485,7 @@ dynamicItemLastChange = purple_account_get_string(session->account, "dynamicItemLastChange", NULL); - if (cb_data->which == MSN_PS_INITIAL) { + if (state->partner_scenario == MSN_PS_INITIAL) { #ifdef MSN_PARTIAL_LISTS /* XXX: this should be enabled when we can correctly do partial syncs with the server. Currently we need to retrieve the whole @@ -390,8 +496,6 @@ #endif } } - - g_free(cb_data); } /*SOAP get contact list*/ @@ -402,7 +506,7 @@ gchar *body = NULL; gchar *update_str = NULL; gchar *token_str; - GetContactListCbData cb_data = { session, partner_scenario }; + MsnCallbackState *state; const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario]; purple_debug_misc("msn", "Getting Contact List.\n"); @@ -412,17 +516,16 @@ update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML, update_time); } - token_str = g_markup_escape_text( - msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS), -1); body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str, - token_str, update_str ? update_str : ""); - g_free(token_str); + update_str ? update_str : ""); - msn_soap_message_send(session, - msn_soap_message_new(MSN_GET_CONTACT_SOAP_ACTION, - xmlnode_from_str(body, -1)), - MSN_CONTACT_SERVER, MSN_GET_CONTACT_POST_URL, FALSE, - msn_get_contact_list_cb, g_memdup(&cb_data, sizeof(cb_data))); + state = msn_callback_state_new(session); + state->partner_scenario = partner_scenario; + state->body = xmlnode_from_str(body, -1); + state->post_action = MSN_GET_CONTACT_SOAP_ACTION; + state->post_url = MSN_GET_CONTACT_POST_URL; + state->cb = msn_get_contact_list_cb; + msn_contact_request(state); g_free(update_str); g_free(body); @@ -771,10 +874,8 @@ static void msn_get_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data) { - MsnSession *session = data; - - if (resp == NULL) - return; + MsnCallbackState *state = data; + MsnSession *session = state->session; g_return_if_fail(session != NULL); @@ -803,7 +904,7 @@ const char *dynamicItemLastChange) { char *body, *update_str = NULL; - gchar *token_str; + MsnCallbackState *state; purple_debug_misc("msn", "Getting Address Book\n"); @@ -813,19 +914,16 @@ else if (LastChanged != NULL) update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged); - token_str = g_markup_escape_text( - msn_nexus_get_token_str(session->nexus, MSN_AUTH_CONTACTS), -1); body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], - token_str, update_str ? update_str : ""); - g_free(token_str); - msn_soap_message_send(session, - msn_soap_message_new(MSN_GET_ADDRESS_SOAP_ACTION, - xmlnode_from_str(body, -1)), - MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL, FALSE, - msn_get_address_cb, session); + state = msn_callback_state_new(session); + state->body = xmlnode_from_str(body, -1); + state->post_action = MSN_GET_ADDRESS_SOAP_ACTION; + state->post_url = MSN_ADDRESS_BOOK_POST_URL; + state->cb = msn_get_address_cb; + msn_contact_request(state); g_free(update_str); g_free(body); @@ -835,105 +933,6 @@ * Contact Operations ***************************************************************/ -static const char * -msn_contact_operation_str(MsnCallbackAction action) -{ - /* Make sure this is large enough when adding more */ - static char buf[BUF_LEN]; - buf[0] = '\0'; - - if (action & MSN_ADD_BUDDY) - strcat(buf, "Adding Buddy,"); - if (action & MSN_MOVE_BUDDY) - strcat(buf, "Moving Buddy,"); - if (action & MSN_ACCEPTED_BUDDY) - strcat(buf, "Accepted Buddy,"); - if (action & MSN_DENIED_BUDDY) - strcat(buf, "Denied Buddy,"); - if (action & MSN_ADD_GROUP) - strcat(buf, "Adding Group,"); - if (action & MSN_DEL_GROUP) - strcat(buf, "Deleting Group,"); - if (action & MSN_RENAME_GROUP) - strcat(buf, "Renaming Group,"); - if (action & MSN_UPDATE_INFO) - strcat(buf, "Updating Contact Info,"); - - return buf; -} - -static gboolean msn_contact_request(MsnCallbackState *state); - -static void -msn_contact_request_cb(MsnSoapMessage *req, MsnSoapMessage *resp, - gpointer data) -{ - MsnCallbackState *state = data; - xmlnode *fault; - char *faultcode_str; - - if (resp == NULL) { - purple_debug_error("msn", - "Operation {%s} failed. No response received from server.\n", - msn_contact_operation_str(state->action)); - return; - } - - fault = xmlnode_get_child(resp->xml, "Body/Fault"); - - if (fault == NULL) { - /* No errors */ - if (state->cb) - ((MsnSoapCallback)state->cb)(req, resp, data); - msn_callback_state_free(state); - return; - } - - faultcode_str = xmlnode_get_data(xmlnode_get_child(fault, "faultcode")); - - if (faultcode_str && g_str_equal(faultcode_str, "q0:BadContextToken")) { - purple_debug_info("msn", - "Contact Operation {%s} failed because of bad token." - " Updating token now and retrying operation.\n", - msn_contact_operation_str(state->action)); - /* Token has expired, so renew it, and try again later */ - msn_nexus_update_token(state->session->nexus, MSN_AUTH_CONTACTS, - (GSourceFunc)msn_contact_request, data); - } - else - { - if (state->cb) { - ((MsnSoapCallback)state->cb)(req, resp, data); - } else { - /* We don't know how to respond to this faultcode, so log it */ - char *str = xmlnode_to_str(fault, NULL); - purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", - msn_contact_operation_str(state->action), str); - g_free(str); - } - msn_callback_state_free(state); - } - - g_free(faultcode_str); -} - -static gboolean -msn_contact_request(MsnCallbackState *state) -{ - if (state->token == NULL) - state->token = xmlnode_get_child(state->body, - "Header/ABAuthHeader/TicketToken"); - /* delete old & replace with new token */ - xmlnode_free(state->token->child); - xmlnode_insert_data(state->token, - msn_nexus_get_token_str(state->session->nexus, MSN_AUTH_CONTACTS), -1); - msn_soap_message_send(state->session, - msn_soap_message_new(state->post_action, xmlnode_copy(state->body)), - MSN_CONTACT_SERVER, state->post_url, FALSE, - msn_contact_request_cb, state); - return FALSE; -} - static void msn_add_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
--- a/libpurple/protocols/msn/contact.h Sat Jan 31 07:37:11 2009 +0000 +++ b/libpurple/protocols/msn/contact.h Sun Feb 01 08:04:41 2009 +0000 @@ -52,7 +52,7 @@ "</ABApplicationHeader>"\ "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>"\ - "<TicketToken>%s</TicketToken>"\ + "<TicketToken>EMPTY</TicketToken>"\ "</ABAuthHeader>"\ "</soap:Header>"\ "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\ @@ -94,7 +94,7 @@ "</ABApplicationHeader>"\ "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ "<ManagedGroupRequest>false</ManagedGroupRequest>"\ - "<TicketToken>%s</TicketToken>"\ + "<TicketToken>EMPTY</TicketToken>"\ "</ABAuthHeader>"\ "</soap:Header>"\ "<soap:Body>"\ @@ -135,7 +135,7 @@ "</ABApplicationHeader>"\ "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ "<ManagedGroupRequest>false</ManagedGroupRequest>"\ - "<TicketToken>%s</TicketToken>"\ + "<TicketToken>EMPTY</TicketToken>"\ "</ABAuthHeader>"\ "</soap:Header>"\ "<soap:Body>"\ @@ -619,6 +619,15 @@ MSN_UPDATE_INFO = 0x80 } MsnCallbackAction; +typedef enum +{ + MSN_PS_INITIAL, + MSN_PS_SAVE_CONTACT, + MSN_PS_PENDING_LIST, + MSN_PS_CONTACT_API, + MSN_PS_BLOCK_UNBLOCK +} MsnSoapPartnerScenario; + typedef struct _MsnCallbackState MsnCallbackState; struct _MsnCallbackState @@ -636,19 +645,12 @@ const gchar *post_action; const gchar *post_url; MsnSoapCallback cb; + /* For msn_get_contact_list only */ + MsnSoapPartnerScenario partner_scenario; }; typedef enum { - MSN_PS_INITIAL, - MSN_PS_SAVE_CONTACT, - MSN_PS_PENDING_LIST, - MSN_PS_CONTACT_API, - MSN_PS_BLOCK_UNBLOCK -} MsnSoapPartnerScenario; - -typedef enum -{ MSN_UPDATE_DISPLAY, /* Real display name */ MSN_UPDATE_ALIAS, /* Aliased display name */ MSN_UPDATE_COMMENT