GData plugin: Support cold-start
Store refresh token, and try to authorize Google access with it on startup. Interactive authorization is now only the fallback if refreshing cannot be done or was not successful. Fixes bug #3432 but requires yet unreleased libgdata, see https://bugzilla.gnome.org/show_bug.cgi?id=750746
This commit is contained in:
parent
bee73785e5
commit
aadb7d5405
|
@ -1114,7 +1114,7 @@ AC_CHECK_LIB([archive], [archive_read_new],
|
|||
)
|
||||
|
||||
dnl libgdata *******************************************************************
|
||||
PKG_CHECK_MODULES(GDATA, libgdata >= 0.17.1, HAVE_GDATA=yes, HAVE_GDATA=no)
|
||||
PKG_CHECK_MODULES(GDATA, libgdata >= 0.17.2, HAVE_GDATA=yes, HAVE_GDATA=no)
|
||||
AC_SUBST(GDATA_CFLAGS)
|
||||
AC_SUBST(GDATA_LIBS)
|
||||
|
||||
|
|
|
@ -430,11 +430,11 @@ static void query_after_auth()
|
|||
}
|
||||
|
||||
|
||||
static void cm_gdata_auth_ready(GDataOAuth2Authorizer *authorizer, GAsyncResult *res, gpointer data)
|
||||
static void cm_gdata_auth_ready(GDataOAuth2Authorizer *auth, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if(gdata_oauth2_authorizer_request_authorization_finish(authorizer, res, &error) == FALSE)
|
||||
if(gdata_oauth2_authorizer_request_authorization_finish(auth, res, &error) == FALSE)
|
||||
{
|
||||
/* Notify the user of all errors except cancellation errors */
|
||||
if(!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
|
@ -451,6 +451,58 @@ static void cm_gdata_auth_ready(GDataOAuth2Authorizer *authorizer, GAsyncResult
|
|||
query_after_auth();
|
||||
}
|
||||
|
||||
static void cm_gdata_interactive_auth()
|
||||
{
|
||||
gchar *auth_uri;
|
||||
gchar *auth_code;
|
||||
|
||||
log_message(LOG_PROTOCOL, _("GData plugin: Starting interactive authorization\n"));
|
||||
|
||||
auth_uri = gdata_oauth2_authorizer_build_authentication_uri(authorizer, cm_gdata_config.username, FALSE);
|
||||
g_return_if_fail(auth_uri);
|
||||
|
||||
auth_code = ask_user_for_auth_code(auth_uri);
|
||||
|
||||
if(auth_code)
|
||||
{
|
||||
cm_gdata_contacts_query_running = TRUE;
|
||||
log_message(LOG_PROTOCOL, _("GData plugin: Got authorization code, requesting authorization\n"));
|
||||
gdata_oauth2_authorizer_request_authorization_async(authorizer, auth_code, NULL, (GAsyncReadyCallback)cm_gdata_auth_ready, NULL);
|
||||
memset(auth_code, 0, strlen(auth_code));
|
||||
g_free(auth_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_warning(LOG_PROTOCOL, _("GData plugin: No authorization code received, authorization request cancelled\n"));
|
||||
}
|
||||
|
||||
g_free(auth_uri);
|
||||
}
|
||||
|
||||
|
||||
static void cm_gdata_refresh_ready(GDataOAuth2Authorizer *auth, GAsyncResult *res, gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if(gdata_authorizer_refresh_authorization_finish(GDATA_AUTHORIZER(auth), res, &error) == FALSE)
|
||||
{
|
||||
/* Notify the user of all errors except cancellation errors */
|
||||
if(!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
log_error(LOG_PROTOCOL, _("GData plugin: Authorization refresh error: %s\n"), error->message);
|
||||
}
|
||||
g_error_free(error);
|
||||
|
||||
cm_gdata_interactive_auth();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
log_message(LOG_PROTOCOL, _("GData plugin: Authorization refresh successful\n"));
|
||||
|
||||
query_after_auth();
|
||||
}
|
||||
|
||||
/* returns allocated string which must be freed */
|
||||
static guchar* decode(const gchar *in)
|
||||
{
|
||||
|
@ -464,9 +516,6 @@ static guchar* decode(const gchar *in)
|
|||
|
||||
static void query()
|
||||
{
|
||||
gchar *auth_uri;
|
||||
gchar *auth_code;
|
||||
|
||||
if(cm_gdata_contacts_query_running)
|
||||
{
|
||||
debug_print("GData plugin: Network query already in progress");
|
||||
|
@ -475,6 +524,8 @@ static void query()
|
|||
|
||||
if(!authorizer)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
gchar *c1 = decode(GDATA_C1);
|
||||
gchar *c2 = decode(GDATA_C2);
|
||||
gchar *c3 = decode(GDATA_C3);
|
||||
|
@ -495,27 +546,17 @@ static void query()
|
|||
|
||||
if(!gdata_service_is_authorized(GDATA_SERVICE(service)))
|
||||
{
|
||||
log_message(LOG_PROTOCOL, _("GData plugin: Starting async authorization\n"));
|
||||
|
||||
auth_uri = gdata_oauth2_authorizer_build_authentication_uri(authorizer, cm_gdata_config.username, FALSE);
|
||||
g_return_if_fail(auth_uri);
|
||||
|
||||
auth_code = ask_user_for_auth_code(auth_uri);
|
||||
|
||||
if(auth_code)
|
||||
/* Try to restore from saved refresh token.*/
|
||||
if(cm_gdata_config.oauth2_refresh_token)
|
||||
{
|
||||
cm_gdata_contacts_query_running = TRUE;
|
||||
log_message(LOG_PROTOCOL, _("GData plugin: Got authorization code, requesting authorization\n"));
|
||||
gdata_oauth2_authorizer_request_authorization_async(authorizer, auth_code, NULL, (GAsyncReadyCallback)cm_gdata_auth_ready, NULL);
|
||||
memset(auth_code, 0, strlen(auth_code));
|
||||
g_free(auth_code);
|
||||
log_message(LOG_PROTOCOL, _("GData plugin: Trying to refresh authorization\n"));
|
||||
gdata_oauth2_authorizer_set_refresh_token(authorizer, cm_gdata_config.oauth2_refresh_token);
|
||||
gdata_authorizer_refresh_authorization_async(GDATA_AUTHORIZER(authorizer), NULL, (GAsyncReadyCallback)cm_gdata_refresh_ready, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_warning(LOG_PROTOCOL, _("GData plugin: No authorization code received, authorization request cancelled\n"));
|
||||
cm_gdata_interactive_auth();
|
||||
}
|
||||
|
||||
g_free(auth_uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -579,6 +620,9 @@ void cm_gdata_contacts_done(void)
|
|||
|
||||
if(authorizer)
|
||||
{
|
||||
/* store refresh token */
|
||||
cm_gdata_config.oauth2_refresh_token = gdata_oauth2_authorizer_dup_refresh_token(authorizer);
|
||||
|
||||
g_object_unref(G_OBJECT(authorizer));
|
||||
authorizer = NULL;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,9 @@ PrefParam cm_gdata_param[] =
|
|||
{ "max_cache_age", "300", &cm_gdata_config.max_cache_age, P_INT,
|
||||
&gdata_page.spin_max_cache_age, prefs_set_data_from_spinbtn, prefs_set_spinbtn},
|
||||
|
||||
{"oauth2_refresh_token", NULL, &cm_gdata_config.oauth2_refresh_token, P_PASSWORD,
|
||||
NULL, NULL, NULL},
|
||||
|
||||
{NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ typedef struct {
|
|||
char *password;
|
||||
int max_num_results;
|
||||
int max_cache_age;
|
||||
char *oauth2_refresh_token;
|
||||
} CmGDataPrefs;
|
||||
|
||||
extern CmGDataPrefs cm_gdata_config;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
<dependencies>
|
||||
<dep package="glib"/>
|
||||
<dep package="liboauth"/>
|
||||
<dep package="m4-common"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
|
@ -50,6 +51,10 @@
|
|||
md5sum="973ded7a1af348c5bfe4e3b6b7e47bd3"
|
||||
size="459597"/>
|
||||
</tarball>
|
||||
|
||||
<autotools id="m4-common">
|
||||
<branch repo="github.com" module="desrt/m4-common.git"/>
|
||||
</autotools>
|
||||
|
||||
<tarball id="libchamplain" version="0.8.3" makeargs="LDFLAGS='-lgthread-2.0'">
|
||||
<source href="ftp://ftp.gnome.org/pub/GNOME/sources/libchamplain/0.8/libchamplain-0.8.3.tar.gz"
|
||||
|
|
|
@ -26,7 +26,7 @@ prefix = '/opt/claws-mail'
|
|||
|
||||
# module-specific autofoo args
|
||||
#module_autogenargs['claws-mail'] = " ".join([autogenargs, "--disable-manual"])
|
||||
#module_autogenargs['libgdata'] = " ".join([autogenargs, "--disable-tests"])
|
||||
#module_autogenargs['libgdata'] = " ".join([autogenargs, "--disable-always-build-tests"])
|
||||
|
||||
# path for building (if None, build in-tree)
|
||||
#buildroot = None
|
||||
|
|
Loading…
Reference in New Issue