Changeset 2378406


Ignore:
Timestamp:
2010-04-28T07:44:45Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
a7c6d0e
Parents:
f1b7711 (diff), 3f668e47 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging OAuth branch. It should be stable now and is documented.

Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • doc/user-guide/commands.xml

    rf1b7711 r2378406  
    7979                                                To send tweets yourself, send them to the twitter_(yourusername) contact, or just write in the groupchat channel if you enabled that option.
    8080                                        </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>
    8185                                </description>
    8286                        </bitlbee-command>
     
    703707        </bitlbee-setting>
    704708
     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
    705728        <bitlbee-setting name="ops" type="string" scope="global">
    706729                <default>both</default>
  • lib/Makefile

    rf1b7711 r2378406  
    1010
    1111# [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.o
     12objects = 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
    1313
    1414CFLAGS += -Wall
  • lib/misc.c

    rf1b7711 r2378406  
    306306        for( i = j = 0; t[i]; i ++, j ++ )
    307307        {
    308                 /* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */
    309                 if( !isalnum( t[i] ) )
     308                if( !isalnum( t[i] ) && !strchr( "._-~", t[i] ) )
    310309                {
    311310                        sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
  • lib/url.c

    rf1b7711 r2378406  
    2727
    2828/* Convert an URL to a url_t structure */
    29 int url_set( url_t *url, char *set_url )
     29int url_set( url_t *url, const char *set_url )
    3030{
    3131        char s[MAX_STRING+1];
  • lib/url.h

    rf1b7711 r2378406  
    4242} url_t;
    4343
    44 int url_set( url_t *url, char *set_url );
     44int url_set( url_t *url, const char *set_url );
  • protocols/twitter/twitter.c

    rf1b7711 r2378406  
    2323
    2424#include "nogaim.h"
     25#include "oauth.h"
    2526#include "twitter.h"
    2627#include "twitter_http.h"
     
    4950        // If we are still logged in run this function again after timeout.
    5051        return (ic->flags & OPT_LOGGED_IN) == OPT_LOGGED_IN;
     52}
     53
     54static 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
     68static gboolean twitter_oauth_callback( struct oauth_info *info );
     69
     70static 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
     80static 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;
    51127}
    52128
     
    67143        s = set_add( &acc->set, "mode", "one", set_eval_mode, acc );
    68144        s->flags |= ACC_SET_OFFLINE_ONLY;
     145       
     146        s = set_add( &acc->set, "oauth", "true", set_eval_bool, acc );
    69147}
    70148
     
    80158
    81159        twitter_connections = g_slist_append( twitter_connections, ic );
    82 
     160        ic->proto_data = td;
     161       
    83162        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 );
    85167        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_loop
    95         // 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);
    97168       
    98169        sprintf( name, "twitter_%s", acc->user );
    99170        imcb_add_buddy( ic, name, NULL );
    100171        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 );
    101177}
    102178
     
    119195        if( td )
    120196        {
     197                oauth_info_free( td->oauth_info );
     198               
     199                g_free( td->pass );
     200                g_free( td->oauth );
    121201                g_free( td );
    122202        }
     
    130210static int twitter_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
    131211{
     212        struct twitter_data *td = ic->proto_data;
     213       
    132214        if (g_strncasecmp(who, "twitter_", 8) == 0 &&
    133215            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        }
    135225        else
     226        {
    136227                twitter_direct_messages_new(ic, who, message);
    137        
     228        }
    138229        return( 0 );
    139230}
  • protocols/twitter/twitter.h

    rf1b7711 r2378406  
    3737        char* user;
    3838        char* pass;
     39        char* oauth;
     40        struct oauth_info *oauth_info;
    3941        guint64 home_timeline_id;
    4042        gint main_loop_id;
     
    5052GSList *twitter_connections;
    5153
     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
    5258#endif //_TWITTER_H
  • protocols/twitter/twitter_http.c

    rf1b7711 r2378406  
    3535#include "misc.h"
    3636#include "base64.h"
     37#include "oauth.h"
    3738#include <ctype.h>
    3839#include <errno.h>
     
    4546 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
    4647 */
    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)
     48void *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)
    4849{
    4950        url_t *url = g_new0( url_t, 1 );
     
    110111
    111112        // 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)
    113127        {
    114128                tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64);
  • protocols/twitter/twitter_http.h

    rf1b7711 r2378406  
    2929
    3030void *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);
    3232
    3333#endif //_TWITTER_HTTP_H
  • protocols/twitter/twitter_lib.c

    rf1b7711 r2378406  
    130130        args[0] = "cursor";
    131131        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);
    133133
    134134        g_free(args[1]);
     
    396396        }
    397397
    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);
    399399
    400400        g_free(args[1]);
     
    620620        args[1] = g_strdup_printf ("%d", next_cursor);
    621621
    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);
    623623
    624624        g_free(args[1]);
     
    654654        args[0] = "status";
    655655        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);
    657657//      g_free(args[1]);
    658658}
     
    672672        args[3] = msg;
    673673        // 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);
    675675//      g_free(args[1]);
    676676//      g_free(args[3]);
Note: See TracChangeset for help on using the changeset viewer.