comparison libpurple/protocols/yahoo/yahoo.c @ 19360:dbc4bdfb09a9

Fix various things related to authorization on yahoo. Denying authorization requests now works ( Fixes #2692 ). Notification of buddy denying your request is fixed (you only get a notification if you're online at the time the denial - there doesn't appear to be any thing that you recieve when you're offline, the buddy is just removed from your server list). Don't show spurious authorization requests when the buddy authorizes you. Display the First and Last name of the buddy authorizing you (if available).
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 22 Aug 2007 20:09:09 +0000
parents b3901a15147a
children 756dad225d90
comparison
equal deleted inserted replaced
19359:2401b5f0a91d 19360:dbc4bdfb09a9
979 static void 979 static void
980 yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg) { 980 yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg) {
981 struct yahoo_packet *pkt; 981 struct yahoo_packet *pkt;
982 char *encoded_msg = NULL; 982 char *encoded_msg = NULL;
983 struct yahoo_data *yd = add_req->gc->proto_data; 983 struct yahoo_data *yd = add_req->gc->proto_data;
984 984 PurpleAccount *account = purple_connection_get_account(add_req->gc);
985 if (msg) 985
986 if (msg && *msg)
986 encoded_msg = yahoo_string_encode(add_req->gc, msg, NULL); 987 encoded_msg = yahoo_string_encode(add_req->gc, msg, NULL);
987 988
988 pkt = yahoo_packet_new(YAHOO_SERVICE_REJECTCONTACT, 989 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15,
989 YAHOO_STATUS_AVAILABLE, 0); 990 YAHOO_STATUS_AVAILABLE, 0);
990 991
991 yahoo_packet_hash(pkt, "sss", 992 yahoo_packet_hash(pkt, "ssiiis",
992 1, purple_normalize(add_req->gc->account, 993 1, purple_normalize(account, purple_account_get_username(account)),
993 purple_account_get_username( 994 5, add_req->who,
994 purple_connection_get_account( 995 13, 2,
995 add_req->gc))), 996 334, 0,
996 7, add_req->who, 997 97, 1,
997 14, encoded_msg ? encoded_msg : ""); 998 14, encoded_msg ? encoded_msg : "");
998 999
999 yahoo_packet_send_and_free(pkt, yd); 1000 yahoo_packet_send_and_free(pkt, yd);
1000 1001
1001 g_free(encoded_msg); 1002 g_free(encoded_msg);
1021 _("Cancel"), G_CALLBACK(yahoo_buddy_add_deny_noreason_cb), 1022 _("Cancel"), G_CALLBACK(yahoo_buddy_add_deny_noreason_cb),
1022 purple_connection_get_account(add_req->gc), add_req->who, NULL, 1023 purple_connection_get_account(add_req->gc), add_req->who, NULL,
1023 add_req); 1024 add_req);
1024 } 1025 }
1025 1026
1027 static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason)
1028 {
1029 char *notify_msg;
1030 struct yahoo_data *yd = gc->proto_data;
1031
1032 if (who == NULL)
1033 return;
1034
1035 if (reason != NULL) {
1036 char *msg2 = yahoo_string_decode(gc, reason, FALSE);
1037 notify_msg = g_strdup_printf(_("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg2);
1038 g_free(msg2);
1039 } else
1040 notify_msg = g_strdup_printf(_("%s has (retroactively) denied your request to add them to your list."), who);
1041
1042 purple_notify_info(gc, NULL, _("Add buddy rejected"), notify_msg);
1043 g_free(notify_msg);
1044
1045 g_hash_table_remove(yd->friends, who);
1046 purple_prpl_got_user_status(purple_connection_get_account(gc), who, "offline", NULL); /* FIXME: make this set not on list status instead */
1047 /* TODO: Shouldn't we remove the buddy from our local list? */
1048 }
1049
1026 static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *pkt) { 1050 static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *pkt) {
1051 GSList *l = pkt->hash;
1052 const char *msg = NULL;
1053
1054 /* Buddy authorized/declined our addition */
1055 if (pkt->status == 1) {
1056 const char *who = NULL;
1057 int response = 0;
1058
1059 while (l) {
1060 struct yahoo_pair *pair = l->data;
1061
1062 switch (pair->key) {
1063 case 4:
1064 who = pair->value;
1065 break;
1066 case 13:
1067 response = strtol(pair->value, NULL, 10);
1068 break;
1069 case 14:
1070 msg = pair->value;
1071 break;
1072 }
1073 l = l->next;
1074 }
1075
1076 if (response == 1) /* Authorized */
1077 purple_debug_info("yahoo", "Received authorization from buddy '%s'.\n", who ? who : "(Unknown Buddy)");
1078 else if (response == 2) { /* Declined */
1079 purple_debug_info("yahoo", "Received authorization decline from buddy '%s'.\n", who ? who : "(Unknown Buddy)");
1080 yahoo_buddy_denied_our_add(gc, who, msg);
1081 } else
1082 purple_debug_error("yahoo", "Received unknown authorization response of %d from buddy '%s'.\n", response, who ? who : "(Unknown Buddy)");
1083
1084 }
1085 /* Buddy requested authorization to add us. */
1086 else if (pkt->status == 3) {
1087 struct yahoo_add_request *add_req;
1088 const char *firstname = NULL, *lastname = NULL;
1089
1090 add_req = g_new0(struct yahoo_add_request, 1);
1091 add_req->gc = gc;
1092
1093 while (l) {
1094 struct yahoo_pair *pair = l->data;
1095
1096 switch (pair->key) {
1097 case 4:
1098 add_req->who = g_strdup(pair->value);
1099 break;
1100 case 5:
1101 add_req->id = g_strdup(pair->value);
1102 break;
1103 case 14:
1104 msg = pair->value;
1105 break;
1106 case 216:
1107 firstname = pair->value;
1108 break;
1109 case 241:
1110 add_req->protocol = strtol(pair->value, NULL, 10);
1111 break;
1112 case 254:
1113 lastname = pair->value;
1114 break;
1115
1116 }
1117 l = l->next;
1118 }
1119
1120 if (add_req->id) {
1121 char *alias = NULL;
1122 if (msg)
1123 add_req->msg = yahoo_string_decode(gc, msg, FALSE);
1124
1125 if (firstname && lastname)
1126 alias = g_strdup_printf("%s %s", firstname, lastname);
1127 else if (firstname)
1128 alias = g_strdup(firstname);
1129 else if (lastname)
1130 alias = g_strdup(lastname);
1131
1132
1133 /* DONE! this is almost exactly the same as what MSN does,
1134 * this should probably be moved to the core.
1135 */
1136 purple_account_request_authorization(purple_connection_get_account(gc), add_req->who, add_req->id,
1137 alias, add_req->msg, purple_find_buddy(purple_connection_get_account(gc),add_req->who) != NULL,
1138 yahoo_buddy_add_authorize_cb,
1139 yahoo_buddy_add_deny_reason_cb,
1140 add_req);
1141 g_free(alias);
1142 } else {
1143 g_free(add_req->id);
1144 g_free(add_req->who);
1145 /*g_free(add_req->msg);*/
1146 g_free(add_req);
1147 }
1148 } else {
1149 purple_debug_error("yahoo", "Received authorization of unknown status (%d).\n", pkt->status);
1150 }
1151 }
1152
1153 static void yahoo_buddy_added_us(PurpleConnection *gc, struct yahoo_packet *pkt) {
1027 struct yahoo_add_request *add_req; 1154 struct yahoo_add_request *add_req;
1028 char *msg = NULL; 1155 char *msg = NULL;
1029 GSList *l = pkt->hash; 1156 GSList *l = pkt->hash;
1030 1157
1031 add_req = g_new0(struct yahoo_add_request, 1); 1158 add_req = g_new0(struct yahoo_add_request, 1);
1033 1160
1034 while (l) { 1161 while (l) {
1035 struct yahoo_pair *pair = l->data; 1162 struct yahoo_pair *pair = l->data;
1036 1163
1037 switch (pair->key) { 1164 switch (pair->key) {
1038 case 5: 1165 case 1:
1039 add_req->id = g_strdup(pair->value); 1166 add_req->id = g_strdup(pair->value);
1040 break; 1167 break;
1041 case 4: 1168 case 3:
1042 add_req->who = g_strdup(pair->value); 1169 add_req->who = g_strdup(pair->value);
1043 break; 1170 break;
1044 case 241: 1171 case 15: /* time, for when they add us and we're offline */
1045 add_req->protocol = strtol(pair->value, NULL, 10);
1046 break; 1172 break;
1047 case 14: 1173 case 14:
1048 msg = pair->value; 1174 msg = pair->value;
1049 break; 1175 break;
1050 } 1176 }
1069 /*g_free(add_req->msg);*/ 1195 /*g_free(add_req->msg);*/
1070 g_free(add_req); 1196 g_free(add_req);
1071 } 1197 }
1072 } 1198 }
1073 1199
1074 static void yahoo_buddy_added_us(PurpleConnection *gc, struct yahoo_packet *pkt) { 1200 /* I have no idea if this every gets called in version 15 */
1075 struct yahoo_add_request *add_req; 1201 static void yahoo_buddy_denied_our_add_old(PurpleConnection *gc, struct yahoo_packet *pkt)
1076 char *msg = NULL;
1077 GSList *l = pkt->hash;
1078
1079 add_req = g_new0(struct yahoo_add_request, 1);
1080 add_req->gc = gc;
1081
1082 while (l) {
1083 struct yahoo_pair *pair = l->data;
1084
1085 switch (pair->key) {
1086 case 1:
1087 add_req->id = g_strdup(pair->value);
1088 break;
1089 case 3:
1090 add_req->who = g_strdup(pair->value);
1091 break;
1092 case 15: /* time, for when they add us and we're offline */
1093 break;
1094 case 14:
1095 msg = pair->value;
1096 break;
1097 }
1098 l = l->next;
1099 }
1100
1101 if (add_req->id) {
1102 if (msg)
1103 add_req->msg = yahoo_string_decode(gc, msg, FALSE);
1104
1105 /* DONE! this is almost exactly the same as what MSN does,
1106 * this should probably be moved to the core.
1107 */
1108 purple_account_request_authorization(purple_connection_get_account(gc), add_req->who, add_req->id,
1109 NULL, add_req->msg, purple_find_buddy(purple_connection_get_account(gc),add_req->who) != NULL,
1110 yahoo_buddy_add_authorize_cb,
1111 yahoo_buddy_add_deny_reason_cb,
1112 add_req);
1113 } else {
1114 g_free(add_req->id);
1115 g_free(add_req->who);
1116 /*g_free(add_req->msg);*/
1117 g_free(add_req);
1118 }
1119 }
1120
1121 static void yahoo_buddy_denied_our_add(PurpleConnection *gc, struct yahoo_packet *pkt)
1122 { 1202 {
1123 char *who = NULL; 1203 char *who = NULL;
1124 char *msg = NULL; 1204 char *msg = NULL;
1125 GSList *l = pkt->hash; 1205 GSList *l = pkt->hash;
1126 GString *buf = NULL;
1127 struct yahoo_data *yd = gc->proto_data;
1128 1206
1129 while (l) { 1207 while (l) {
1130 struct yahoo_pair *pair = l->data; 1208 struct yahoo_pair *pair = l->data;
1131 1209
1132 switch (pair->key) { 1210 switch (pair->key) {
1138 break; 1216 break;
1139 } 1217 }
1140 l = l->next; 1218 l = l->next;
1141 } 1219 }
1142 1220
1143 if (who) { 1221 yahoo_buddy_denied_our_add(gc, who, msg);
1144 char *msg2;
1145 buf = g_string_sized_new(0);
1146 if (!msg) {
1147 g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list."), who);
1148 } else {
1149 msg2 = yahoo_string_decode(gc, msg, FALSE);
1150 g_string_printf(buf, _("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg2);
1151 g_free(msg2);
1152 }
1153 purple_notify_info(gc, NULL, _("Add buddy rejected"), buf->str);
1154 g_string_free(buf, TRUE);
1155 g_hash_table_remove(yd->friends, who);
1156 purple_prpl_got_user_status(purple_connection_get_account(gc), who, "offline", NULL); /* FIXME: make this set not on list status instead */
1157 /* TODO: Shouldn't we remove the buddy from our local list? */
1158 }
1159 } 1222 }
1160 1223
1161 static void yahoo_process_contact(PurpleConnection *gc, struct yahoo_packet *pkt) 1224 static void yahoo_process_contact(PurpleConnection *gc, struct yahoo_packet *pkt)
1162 { 1225 {
1163 switch (pkt->status) { 1226 switch (pkt->status) {
1166 return; 1229 return;
1167 case 3: 1230 case 3:
1168 yahoo_buddy_added_us(gc, pkt); 1231 yahoo_buddy_added_us(gc, pkt);
1169 break; 1232 break;
1170 case 7: 1233 case 7:
1171 yahoo_buddy_denied_our_add(gc, pkt); 1234 yahoo_buddy_denied_our_add_old(gc, pkt);
1172 break; 1235 break;
1173 default: 1236 default:
1174 break; 1237 break;
1175 } 1238 }
1176 } 1239 }