Changes in / [f1b7711:23784065]
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user-guide/commands.xml
rf1b7711 r23784065 79 79 To send tweets yourself, send them to the twitter_(yourusername) contact, or just write in the groupchat channel if you enabled that option. 80 80 </para> 81 82 <para> 83 Since Twitter now requires OAuth authentication, you should not enter your Twitter password into BitlBee. Just type a bogus password. The first time you log in, BitlBee will start OAuth authentication. (See <emphasis>help set oauth</emphasis>.) 84 </para> 81 85 </description> 82 86 </bitlbee-command> … … 703 707 </bitlbee-setting> 704 708 709 <bitlbee-setting name="oauth" type="boolean" scope="account"> 710 <default>true</default> 711 712 <description> 713 <para> 714 This enables OAuth authentication for Twitter accounts. From June 2010 this will be mandatory. 715 </para> 716 717 <para> 718 With OAuth enabled, you shouldn't tell BitlBee your Twitter password. Just add your account with a bogus password and type <emphasis>account on</emphasis>. BitlBee will then give you a URL to authenticate with Twitter. If this succeeds, Twitter will return a PIN code which you can give back to BitlBee to finish the process. 719 </para> 720 721 <para> 722 The resulting access token will be saved permanently, so you have to do this only once. 723 </para> 724 </description> 725 726 </bitlbee-setting> 727 705 728 <bitlbee-setting name="ops" type="string" scope="global"> 706 729 <default>both</default> -
lib/Makefile
rf1b7711 r23784065 10 10 11 11 # [SH] Program variables 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 13 13 14 14 CFLAGS += -Wall -
lib/misc.c
rf1b7711 r23784065 306 306 for( i = j = 0; t[i]; i ++, j ++ ) 307 307 { 308 /* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */ 309 if( !isalnum( t[i] ) ) 308 if( !isalnum( t[i] ) && !strchr( "._-~", t[i] ) ) 310 309 { 311 310 sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] ); -
lib/url.c
rf1b7711 r23784065 27 27 28 28 /* Convert an URL to a url_t structure */ 29 int url_set( url_t *url, c har *set_url )29 int url_set( url_t *url, const char *set_url ) 30 30 { 31 31 char s[MAX_STRING+1]; -
lib/url.h
rf1b7711 r23784065 42 42 } url_t; 43 43 44 int url_set( url_t *url, c har *set_url );44 int url_set( url_t *url, const char *set_url ); -
protocols/twitter/twitter.c
rf1b7711 r23784065 23 23 24 24 #include "nogaim.h" 25 #include "oauth.h" 25 26 #include "twitter.h" 26 27 #include "twitter_http.h" … … 49 50 // If we are still logged in run this function again after timeout. 50 51 return (ic->flags & OPT_LOGGED_IN) == OPT_LOGGED_IN; 52 } 53 54 static void twitter_main_loop_start( struct im_connection *ic ) 55 { 56 struct twitter_data *td = ic->proto_data; 57 58 imcb_log( ic, "Connecting to Twitter" ); 59 60 // Run this once. After this queue the main loop function. 61 twitter_main_loop(ic, -1, 0); 62 63 // Queue the main_loop 64 // Save the return value, so we can remove the timeout on logout. 65 td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic); 66 } 67 68 static gboolean twitter_oauth_callback( struct oauth_info *info ); 69 70 static void twitter_oauth_start( struct im_connection *ic ) 71 { 72 struct twitter_data *td = ic->proto_data; 73 74 imcb_log( ic, "Requesting OAuth request token" ); 75 76 td->oauth_info = oauth_request_token( 77 TWITTER_OAUTH_REQUEST_TOKEN, twitter_oauth_callback, ic ); 78 } 79 80 static gboolean twitter_oauth_callback( struct oauth_info *info ) 81 { 82 struct im_connection *ic = info->data; 83 struct twitter_data *td; 84 85 if( !g_slist_find( twitter_connections, ic ) ) 86 return FALSE; 87 88 td = ic->proto_data; 89 if( info->stage == OAUTH_REQUEST_TOKEN ) 90 { 91 char name[strlen(ic->acc->user)+9], *msg; 92 93 if( info->request_token == NULL ) 94 { 95 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 96 imc_logout( ic, TRUE ); 97 return FALSE; 98 } 99 100 sprintf( name, "twitter_%s", ic->acc->user ); 101 msg = g_strdup_printf( "To finish OAuth authentication, please visit " 102 "%s?%s and respond with the resulting PIN code.", 103 TWITTER_OAUTH_AUTHORIZE, info->auth_params ); 104 imcb_buddy_msg( ic, name, msg, 0, 0 ); 105 g_free( msg ); 106 } 107 else if( info->stage == OAUTH_ACCESS_TOKEN ) 108 { 109 if( info->access_token == NULL ) 110 { 111 imcb_error( ic, "OAuth error: %s", info->http->status_string ); 112 imc_logout( ic, TRUE ); 113 return FALSE; 114 } 115 116 td->oauth = g_strdup( info->access_token ); 117 118 /* IM mods didn't do this so far and it's ugly but I should 119 be able to get away with it... */ 120 g_free( ic->acc->pass ); 121 ic->acc->pass = g_strdup( info->access_token ); 122 123 twitter_main_loop_start( ic ); 124 } 125 126 return TRUE; 51 127 } 52 128 … … 67 143 s = set_add( &acc->set, "mode", "one", set_eval_mode, acc ); 68 144 s->flags |= ACC_SET_OFFLINE_ONLY; 145 146 s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc ); 69 147 } 70 148 … … 80 158 81 159 twitter_connections = g_slist_append( twitter_connections, ic ); 82 160 ic->proto_data = td; 161 83 162 td->user = acc->user; 84 td->pass = acc->pass; 163 if( !set_getbool( &acc->set, "oauth" ) ) 164 td->pass = g_strdup( acc->pass ); 165 else if( strstr( acc->pass, "oauth_token=" ) ) 166 td->oauth = g_strdup( acc->pass ); 85 167 td->home_timeline_id = 0; 86 87 ic->proto_data = td;88 89 imcb_log( ic, "Connecting to Twitter" );90 91 // Run this once. After this queue the main loop function.92 twitter_main_loop(ic, -1, 0);93 94 // Queue the main_loop95 // Save the return value, so we can remove the timeout on logout.96 td->main_loop_id = b_timeout_add(60000, twitter_main_loop, ic);97 168 98 169 sprintf( name, "twitter_%s", acc->user ); 99 170 imcb_add_buddy( ic, name, NULL ); 100 171 imcb_buddy_status( ic, name, OPT_LOGGED_IN, NULL, NULL ); 172 173 if( td->pass || td->oauth ) 174 twitter_main_loop_start( ic ); 175 else 176 twitter_oauth_start( ic ); 101 177 } 102 178 … … 119 195 if( td ) 120 196 { 197 oauth_info_free( td->oauth_info ); 198 199 g_free( td->pass ); 200 g_free( td->oauth ); 121 201 g_free( td ); 122 202 } … … 130 210 static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) 131 211 { 212 struct twitter_data *td = ic->proto_data; 213 132 214 if (g_strncasecmp(who, "twitter_", 8) == 0 && 133 215 g_strcasecmp(who + 8, ic->acc->user) == 0) 134 twitter_post_status(ic, message); 216 { 217 if( set_getbool( &ic->acc->set, "oauth" ) && td->oauth_info ) 218 { 219 oauth_access_token( TWITTER_OAUTH_ACCESS_TOKEN, message, td->oauth_info ); 220 td->oauth_info = NULL; 221 } 222 else 223 twitter_post_status(ic, message); 224 } 135 225 else 226 { 136 227 twitter_direct_messages_new(ic, who, message); 137 228 } 138 229 return( 0 ); 139 230 } -
protocols/twitter/twitter.h
rf1b7711 r23784065 37 37 char* user; 38 38 char* pass; 39 char* oauth; 40 struct oauth_info *oauth_info; 39 41 guint64 home_timeline_id; 40 42 gint main_loop_id; … … 50 52 GSList *twitter_connections; 51 53 54 #define TWITTER_OAUTH_REQUEST_TOKEN "http://api.twitter.com/oauth/request_token" 55 #define TWITTER_OAUTH_ACCESS_TOKEN "http://api.twitter.com/oauth/access_token" 56 #define TWITTER_OAUTH_AUTHORIZE "http://api.twitter.com/oauth/authorize" 57 52 58 #endif //_TWITTER_H -
protocols/twitter/twitter_http.c
rf1b7711 r23784065 35 35 #include "misc.h" 36 36 #include "base64.h" 37 #include "oauth.h" 37 38 #include <ctype.h> 38 39 #include <errno.h> … … 45 46 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c 46 47 */ 47 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char* * arguments, int arguments_len)48 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char* oauth_token, char** arguments, int arguments_len) 48 49 { 49 50 url_t *url = g_new0( url_t, 1 ); … … 110 111 111 112 // If a pass and user are given we append them to the request. 112 if (userpass_base64) 113 if (oauth_token) 114 { 115 char *full_header; 116 117 full_header = oauth_http_header(oauth_token, 118 is_post ? "POST" : "GET", 119 url_string, url_arguments); 120 121 tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header); 122 g_free(request); 123 g_free(full_header); 124 request = tmp; 125 } 126 else if (userpass_base64) 113 127 { 114 128 tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64); -
protocols/twitter/twitter_http.h
rf1b7711 r23784065 29 29 30 30 void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, 31 char* user, char* pass, char** arguments, int arguments_len);31 char* user, char* pass, char *oauth_token, char** arguments, int arguments_len); 32 32 33 33 #endif //_TWITTER_HTTP_H -
protocols/twitter/twitter_lib.c
rf1b7711 r23784065 130 130 args[0] = "cursor"; 131 131 args[1] = g_strdup_printf ("%d", next_cursor); 132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, args, 2);132 twitter_http(TWITTER_FRIENDS_IDS_URL, twitter_http_get_friends_ids, ic, 0, td->user, td->pass, td->oauth, args, 2); 133 133 134 134 g_free(args[1]); … … 396 396 } 397 397 398 twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, args, td->home_timeline_id ? 4 : 2);398 twitter_http(TWITTER_HOME_TIMELINE_URL, twitter_http_get_home_timeline, ic, 0, td->user, td->pass, td->oauth, args, td->home_timeline_id ? 4 : 2); 399 399 400 400 g_free(args[1]); … … 620 620 args[1] = g_strdup_printf ("%d", next_cursor); 621 621 622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, args, 2);622 twitter_http(TWITTER_SHOW_FRIENDS_URL, twitter_http_get_statuses_friends, ic, 0, td->user, td->pass, td->oauth, args, 2); 623 623 624 624 g_free(args[1]); … … 654 654 args[0] = "status"; 655 655 args[1] = msg; 656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 2);656 twitter_http(TWITTER_STATUS_UPDATE_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth, args, 2); 657 657 // g_free(args[1]); 658 658 } … … 672 672 args[3] = msg; 673 673 // Use the same callback as for twitter_post_status, since it does basically the same. 674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, args, 4);674 twitter_http(TWITTER_DIRECT_MESSAGES_NEW_URL, twitter_http_post_status, ic, 1, td->user, td->pass, td->oauth, args, 4); 675 675 // g_free(args[1]); 676 676 // g_free(args[3]);
Note: See TracChangeset
for help on using the changeset viewer.