From 21f9cc657cf49911f9c86982fe21607fc36b6e54 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 20 Nov 2024 13:15:26 +0000 Subject: [PATCH] import RHEL 10 Beta gnome-online-accounts-3.51.0-1.el10 --- .gitignore | 2 +- 0001-remove-google-files-backend.patch | 77 + SOURCES/0001-mute-debug-prints.patch | 229 - ...002-Drop-dependency-on-WebKitGTK-139.patch | 4922 ----------------- ...ccounts.spec => gnome-online-accounts.spec | 359 +- sources | 1 + 6 files changed, 337 insertions(+), 5253 deletions(-) create mode 100644 0001-remove-google-files-backend.patch delete mode 100644 SOURCES/0001-mute-debug-prints.patch delete mode 100644 SOURCES/0002-Drop-dependency-on-WebKitGTK-139.patch rename SPECS/gnome-online-accounts.spec => gnome-online-accounts.spec (63%) create mode 100644 sources diff --git a/.gitignore b/.gitignore index 2f17db8..a0a5d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gnome-online-accounts-3.28.2.tar.xz +gnome-online-accounts-3.51.0.tar.xz diff --git a/0001-remove-google-files-backend.patch b/0001-remove-google-files-backend.patch new file mode 100644 index 0000000..b535897 --- /dev/null +++ b/0001-remove-google-files-backend.patch @@ -0,0 +1,77 @@ +diff -up gnome-online-accounts-3.51.0/src/goabackend/goagoogleprovider.c.1 gnome-online-accounts-3.51.0/src/goabackend/goagoogleprovider.c +--- gnome-online-accounts-3.51.0/src/goabackend/goagoogleprovider.c.1 2024-06-29 03:16:48.000000000 +0200 ++++ gnome-online-accounts-3.51.0/src/goabackend/goagoogleprovider.c 2024-07-16 15:19:45.450083253 +0200 +@@ -69,8 +69,7 @@ get_provider_features (GoaProvider *prov + return GOA_PROVIDER_FEATURE_BRANDED | + GOA_PROVIDER_FEATURE_MAIL | + GOA_PROVIDER_FEATURE_CALENDAR | +- GOA_PROVIDER_FEATURE_CONTACTS | +- GOA_PROVIDER_FEATURE_FILES; ++ GOA_PROVIDER_FEATURE_CONTACTS; + } + + static const gchar * +@@ -140,9 +139,6 @@ get_scope (GoaOAuth2Provider *oauth2_pro + /* Google Contacts API (CardDAV) - undocumented */ + "https://www.googleapis.com/auth/carddav " + +- /* Google Drive API */ +- "https://www.googleapis.com/auth/drive " +- + /* Google Documents List Data API */ + "https://docs.googleusercontent.com/ " + "https://spreadsheets.google.com/feeds/ " +@@ -276,12 +272,10 @@ build_object (GoaProvider *provi + GKeyFile *goa_conf; + const gchar *provider_type; + gchar *uri_caldav; +- gchar *uri_drive; + gboolean ret = FALSE; + gboolean mail_enabled; + gboolean calendar_enabled; + gboolean contacts_enabled; +- gboolean files_enabled; + const gchar *email_address; + + /* Chain up */ +@@ -346,13 +340,6 @@ build_object (GoaProvider *provi + contacts_enabled, + FALSE); + +- /* Files */ +- files_enabled = goa_util_provider_feature_is_enabled (goa_conf, provider_type, GOA_PROVIDER_FEATURE_FILES) && +- g_key_file_get_boolean (key_file, group, "FilesEnabled", NULL); +- uri_drive = g_strconcat ("google-drive://", email_address, "/", NULL); +- goa_object_skeleton_attach_files (object, uri_drive, files_enabled, FALSE); +- g_free (uri_drive); +- + g_clear_pointer (&goa_conf, g_key_file_free); + + if (just_added) +@@ -360,7 +347,6 @@ build_object (GoaProvider *provi + goa_account_set_mail_disabled (account, !mail_enabled); + goa_account_set_calendar_disabled (account, !calendar_enabled); + goa_account_set_contacts_disabled (account, !contacts_enabled); +- goa_account_set_files_disabled (account, !files_enabled); + + g_signal_connect (account, + "notify::mail-disabled", +@@ -374,10 +360,6 @@ build_object (GoaProvider *provi + "notify::contacts-disabled", + G_CALLBACK (goa_util_account_notify_property_cb), + (gpointer) "ContactsEnabled"); +- g_signal_connect (account, +- "notify::files-disabled", +- G_CALLBACK (goa_util_account_notify_property_cb), +- (gpointer) "FilesEnabled"); + } + + ret = TRUE; +@@ -397,7 +379,6 @@ add_account_key_values (GoaOAuth2Provide + g_variant_builder_add (builder, "{ss}", "MailEnabled", "true"); + g_variant_builder_add (builder, "{ss}", "CalendarEnabled", "true"); + g_variant_builder_add (builder, "{ss}", "ContactsEnabled", "true"); +- g_variant_builder_add (builder, "{ss}", "FilesEnabled", "true"); + } + + /* ---------------------------------------------------------------------------------------------------- */ diff --git a/SOURCES/0001-mute-debug-prints.patch b/SOURCES/0001-mute-debug-prints.patch deleted file mode 100644 index 5e5957f..0000000 --- a/SOURCES/0001-mute-debug-prints.patch +++ /dev/null @@ -1,229 +0,0 @@ -diff -up gnome-online-accounts-3.28.2/src/goabackend/goautils.c.mute-debug-prints gnome-online-accounts-3.28.2/src/goabackend/goautils.c ---- gnome-online-accounts-3.28.2/src/goabackend/goautils.c.mute-debug-prints 2019-02-10 20:18:08.000000000 +0100 -+++ gnome-online-accounts-3.28.2/src/goabackend/goautils.c 2022-09-02 12:02:45.020910337 +0200 -@@ -380,7 +380,7 @@ goa_utils_delete_credentials_for_id_sync - NULL); - if (sec_error != NULL) - { -- g_warning ("secret_password_clear_sync() failed: %s", sec_error->message); -+ g_debug ("secret_password_clear_sync() failed: %s", sec_error->message); - g_set_error_literal (error, - GOA_ERROR, - GOA_ERROR_FAILED, /* TODO: more specific */ -@@ -428,7 +428,7 @@ goa_utils_lookup_credentials_sync (GoaPr - NULL); - if (sec_error != NULL) - { -- g_warning ("secret_password_lookup_sync() failed: %s", sec_error->message); -+ g_debug ("secret_password_lookup_sync() failed: %s", sec_error->message); - g_set_error_literal (error, - GOA_ERROR, - GOA_ERROR_FAILED, /* TODO: more specific */ -@@ -438,7 +438,7 @@ goa_utils_lookup_credentials_sync (GoaPr - } - else if (password == NULL) - { -- g_warning ("secret_password_lookup_sync() returned NULL"); -+ g_debug ("secret_password_lookup_sync() returned NULL"); - g_set_error_literal (error, - GOA_ERROR, - GOA_ERROR_FAILED, /* TODO: more specific */ -@@ -509,7 +509,7 @@ goa_utils_store_credentials_for_id_sync - "goa-identity", password_key, - NULL)) - { -- g_warning ("secret_password_store_sync() failed: %s", sec_error->message); -+ g_debug ("secret_password_store_sync() failed: %s", sec_error->message); - g_set_error_literal (error, - GOA_ERROR, - GOA_ERROR_FAILED, /* TODO: more specific */ -@@ -562,11 +562,11 @@ goa_utils_keyfile_copy_group (GKeyFile - keys = g_key_file_get_keys (src_key_file, src_group_name, NULL, &error); - if (error != NULL) - { -- g_warning ("Error getting keys from group %s: %s (%s, %d)", -- src_group_name, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error getting keys from group %s: %s (%s, %d)", -+ src_group_name, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - g_error_free (error); - goto out; - } -@@ -580,12 +580,12 @@ goa_utils_keyfile_copy_group (GKeyFile - src_value = g_key_file_get_value (src_key_file, src_group_name, keys[i], &error); - if (error != NULL) - { -- g_warning ("Error reading key %s from group %s: %s (%s, %d)", -- keys[i], -- src_group_name, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error reading key %s from group %s: %s (%s, %d)", -+ keys[i], -+ src_group_name, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - g_error_free (error); - continue; - } -@@ -597,12 +597,12 @@ goa_utils_keyfile_copy_group (GKeyFile - if (!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND) - && !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) - { -- g_warning ("Error reading key %s from group %s: %s (%s, %d)", -- keys[i], -- src_group_name, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error reading key %s from group %s: %s (%s, %d)", -+ keys[i], -+ src_group_name, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - } - - g_error_free (error); -@@ -635,12 +635,12 @@ goa_utils_keyfile_get_boolean (GKeyFile - { - if (!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) - { -- g_warning ("Error reading key %s from group %s in keyfile: %s (%s, %d)", -- key, -- group_name, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error reading key %s from group %s in keyfile: %s (%s, %d)", -+ key, -+ group_name, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - } - - g_error_free (error); -@@ -667,11 +667,11 @@ goa_utils_keyfile_remove_key (GoaAccount - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, - &error)) - { -- g_warning ("Error loading keyfile %s: %s (%s, %d)", -- path, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error loading keyfile %s: %s (%s, %d)", -+ path, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - g_error_free (error); - goto out; - } -@@ -683,7 +683,7 @@ goa_utils_keyfile_remove_key (GoaAccount - if (!g_key_file_save_to_file (key_file, path, &error)) - { - g_prefix_error (&error, "Error writing key-value-file %s: ", path); -- g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); -+ g_debug ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } -@@ -714,11 +714,11 @@ goa_utils_keyfile_set_boolean (GoaAccoun - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, - &error)) - { -- g_warning ("Error loading keyfile %s: %s (%s, %d)", -- path, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error loading keyfile %s: %s (%s, %d)", -+ path, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - g_error_free (error); - goto out; - } -@@ -727,12 +727,12 @@ goa_utils_keyfile_set_boolean (GoaAccoun - old_value = g_key_file_get_boolean (key_file, group, key, &error); - if (error != NULL) - { -- g_warning ("Error reading key %s from keyfile %s: %s (%s, %d)", -- key, -- path, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error reading key %s from keyfile %s: %s (%s, %d)", -+ key, -+ path, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - needs_update = TRUE; - g_error_free (error); - } -@@ -750,7 +750,7 @@ goa_utils_keyfile_set_boolean (GoaAccoun - if (!g_key_file_save_to_file (key_file, path, &error)) - { - g_prefix_error (&error, "Error writing key-value-file %s: ", path); -- g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); -+ g_debug ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } -@@ -781,11 +781,11 @@ goa_utils_keyfile_set_string (GoaAccount - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, - &error)) - { -- g_warning ("Error loading keyfile %s: %s (%s, %d)", -- path, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error loading keyfile %s: %s (%s, %d)", -+ path, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - g_error_free (error); - goto out; - } -@@ -794,12 +794,12 @@ goa_utils_keyfile_set_string (GoaAccount - old_value = g_key_file_get_string (key_file, group, key, &error); - if (error != NULL) - { -- g_warning ("Error reading key %s from keyfile %s: %s (%s, %d)", -- key, -- path, -- error->message, -- g_quark_to_string (error->domain), -- error->code); -+ g_debug ("Error reading key %s from keyfile %s: %s (%s, %d)", -+ key, -+ path, -+ error->message, -+ g_quark_to_string (error->domain), -+ error->code); - needs_update = TRUE; - g_error_free (error); - } -@@ -817,7 +817,7 @@ goa_utils_keyfile_set_string (GoaAccount - if (!g_key_file_save_to_file (key_file, path, &error)) - { - g_prefix_error (&error, "Error writing key-value-file %s: ", path); -- g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); -+ g_debug ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } diff --git a/SOURCES/0002-Drop-dependency-on-WebKitGTK-139.patch b/SOURCES/0002-Drop-dependency-on-WebKitGTK-139.patch deleted file mode 100644 index 09be406..0000000 --- a/SOURCES/0002-Drop-dependency-on-WebKitGTK-139.patch +++ /dev/null @@ -1,4922 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index ddf98f1..f997d36 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -124,10 +124,6 @@ if test "$enable_backend" != "no"; then - AC_SUBST(GTK_CFLAGS) - AC_SUBST(GTK_LIBS) - -- PKG_CHECK_MODULES(WEBKIT_GTK, [webkit2gtk-4.0 >= 2.12.0]) -- AC_SUBST(WEBKIT_GTK_CFLAGS) -- AC_SUBST(WEBKIT_GTK_LIBS) -- - PKG_CHECK_MODULES(LIBSOUP, [libsoup-2.4 >= 2.42]) - AC_SUBST(LIBSOUP_CFLAGS) - AC_SUBST(LIBSOUP_LIBS) -@@ -176,14 +172,6 @@ if test "$enable_backend" != "no"; then - fi - fi - --AC_ARG_ENABLE([inspector], -- [AS_HELP_STRING([--enable-inspector], [Enable a WebKitWebInspector for the embedded web view])], -- [], -- [enable_inspector=no]) --if test "$enable_inspector" != "no"; then -- AC_DEFINE(GOA_INSPECTOR_ENABLED, 1, [Enable a WebKitWebInspector for the embedded web view]) --fi -- - AC_ARG_WITH(template-file, - [AS_HELP_STRING([--with-template-file], [Path to the template file])], - [], -@@ -271,7 +259,11 @@ AC_DEFINE_UNQUOTED(GOA_GOOGLE_CLIENT_ID, ["$with_google_client_id"], [Google OAu - AC_DEFINE_UNQUOTED(GOA_GOOGLE_CLIENT_SECRET, ["$with_google_client_secret"], [Google OAuth 2.0 client secret]) - if test "$enable_google" != "no"; then - AC_DEFINE(GOA_GOOGLE_ENABLED, 1, [Enable Google data provider]) -+ if test "$with_google_client_id" != "44438659992-7kgjeitenc16ssihbtdjbgguch7ju55s.apps.googleusercontent.com"; then -+ AC_MSG_ERROR([Unexpected Google OAuth2 Client ID, correct it here and in data/Makefile.am in oauth2_schemes, to be reverse-DNS of the new Client ID]) -+ fi - fi -+AM_CONDITIONAL(GOOGLE_ENABLED, [test x$enable_google != xno]) - - # IMAP/SMTP - AC_DEFINE(GOA_IMAP_SMTP_NAME, ["imap_smtp"], [ProviderType and extension point name]) -diff --git a/data/Makefile.am b/data/Makefile.am -index 286dcd0..61b69e1 100644 ---- a/data/Makefile.am -+++ b/data/Makefile.am -@@ -20,16 +20,30 @@ service_DATA = $(service_in_files:.service.in=.service) - @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ - endif - -+desktopdir = $(datadir)/applications -+desktop_in_files = org.gnome.OnlineAccounts.OAuth2.desktop.in -+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) -+if GOOGLE_ENABLED -+ oauth2_schemes=x-scheme-handler/com.googleusercontent.apps.44438659992-7kgjeitenc16ssihbtdjbgguch7ju55s; -+else -+ oauth2_schemes= -+endif -+ -+%.desktop: %.desktop.in Makefile -+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" -e "s|\@oauth2_schemes\@|$(oauth2_schemes)|" $< > $@ -+ - EXTRA_DIST = \ - $(gsettings_SCHEMAS) \ - dbus-interfaces.xml \ - org.gnome.Identity.service.in \ - org.gnome.OnlineAccounts.service.in \ -+ org.gnome.OnlineAccounts.OAuth2.desktop.in \ - $(NULL) - - CLEANFILES = \ - org.gnome.OnlineAccounts.service \ - org.gnome.Identity.service \ -+ org.gnome.OnlineAccounts.OAuth2.desktop \ - $(NULL) - - clean-local : -diff --git a/data/org.gnome.OnlineAccounts.OAuth2.desktop.in b/data/org.gnome.OnlineAccounts.OAuth2.desktop.in -new file mode 100644 -index 0000000..d0478aa ---- /dev/null -+++ b/data/org.gnome.OnlineAccounts.OAuth2.desktop.in -@@ -0,0 +1,6 @@ -+[Desktop Entry] -+Name=GNOME OAuth2 Handler -+Exec=@libexecdir@/goa-oauth2-handler %u -+Type=Application -+MimeType=x-scheme-handler/goa-oauth2;@oauth2_schemes@ -+NoDisplay=true -diff --git a/doc/goa-docs.xml b/doc/goa-docs.xml -index 0abb53a..a9d45e1 100644 ---- a/doc/goa-docs.xml -+++ b/doc/goa-docs.xml -@@ -171,7 +171,6 @@ - Core - - -- - - - -diff --git a/doc/goa-sections.txt b/doc/goa-sections.txt -index 306846e..a27d942 100644 ---- a/doc/goa-sections.txt -+++ b/doc/goa-sections.txt -@@ -498,36 +498,6 @@ GoaOAuth2ProviderPrivate - goa_oauth2_provider_get_type - - --
--goaoauthprovider --GoaOAuthProvider --GoaOAuthProviderClass --goa_oauth_provider_get_request_uri --goa_oauth_provider_get_request_uri_params --goa_oauth_provider_get_authorization_uri --goa_oauth_provider_get_token_uri --goa_oauth_provider_get_callback_uri --goa_oauth_provider_get_consumer_key --goa_oauth_provider_get_consumer_secret --goa_oauth_provider_build_authorization_uri --goa_oauth_provider_get_use_mobile_browser --goa_oauth_provider_is_deny_node --goa_oauth_provider_is_identity_node --goa_oauth_provider_is_password_node --goa_oauth_provider_add_account_key_values --goa_oauth_provider_get_identity_sync --goa_oauth_provider_get_access_token_sync --goa_oauth_provider_parse_request_token_error -- --GOA_OAUTH_PROVIDER --GOA_OAUTH_PROVIDER_CLASS --GOA_OAUTH_PROVIDER_GET_CLASS --GOA_IS_OAUTH_PROVIDER --GOA_IS_OAUTH_PROVIDER_CLASS --GOA_TYPE_OAUTH_PROVIDER --goa_oauth_provider_get_type --
-- -
- GoaMail - GoaMail -diff --git a/doc/goa.types b/doc/goa.types -index 56ba3c4..d8d7325 100644 ---- a/doc/goa.types -+++ b/doc/goa.types -@@ -62,5 +62,4 @@ goa_printers_proxy_get_type - goa_printers_skeleton_get_type - - goa_provider_get_type --goa_oauth_provider_get_type - goa_oauth2_provider_get_type -diff --git a/po/POTFILES.in b/po/POTFILES.in -index b65650c..8ee89ae 100644 ---- a/po/POTFILES.in -+++ b/po/POTFILES.in -@@ -22,7 +22,6 @@ src/goabackend/goasmtpauth.c - src/goabackend/goatelepathyprovider.c - src/goabackend/goatodoistprovider.c - src/goabackend/goautils.c --src/goabackend/goawebview.c - src/goabackend/goawindowsliveprovider.c - src/goaidentity/goaidentityservice.c - src/goaidentity/goakerberosidentity.c -diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am -index c254594..7f15518 100644 ---- a/src/goabackend/Makefile.am -+++ b/src/goabackend/Makefile.am -@@ -19,7 +19,6 @@ AM_CPPFLAGS = \ - -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \ - -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \ - -DPACKAGE_LIB_DIR=\""$(libdir)"\" \ -- -DPACKAGE_WEB_EXTENSIONS_DIR=\""$(libdir)/goa-1.0/web-extensions"\" \ - -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \ - $(WARN_CFLAGS) \ - $(NULL) -@@ -81,17 +80,13 @@ libgoa_backend_1_0_la_SOURCES = \ - goasouplogger.h goasouplogger.c \ - goamailclient.h goamailclient.c \ - goaexchangeprovider.h goaexchangeprovider.c \ -- goaoauthprovider.h goaoauthprovider.c \ - goaoauth2provider.h goaoauth2provider-priv.h \ -- goaoauth2provider-web-extension.h \ -- goaoauth2provider-web-view.h \ - goaoauth2provider.c \ - goagoogleprovider.h goagoogleprovider.c \ - goafacebookprovider.h goafacebookprovider.c \ - goaimapsmtpprovider.h goaimapsmtpprovider.c \ - goamediaserverprovider.h goamediaserverprovider.c \ - goaowncloudprovider.h goaowncloudprovider.c \ -- goaflickrprovider.h goaflickrprovider.c \ - goafoursquareprovider.h goafoursquareprovider.c \ - goawindowsliveprovider.h goawindowsliveprovider.c \ - goapocketprovider.h goapocketprovider.c \ -@@ -99,7 +94,6 @@ libgoa_backend_1_0_la_SOURCES = \ - goatodoistprovider.h goatodoistprovider.c \ - goaobjectskeletonutils.h goaobjectskeletonutils.c \ - goautils.h goautils.c \ -- goawebview.h goawebview.c \ - nautilus-floating-bar.h nautilus-floating-bar.c \ - $(top_builddir)/src/goaidentity/org.gnome.Identity.c \ - $(top_srcdir)/src/goaidentity/goaidentitymanagererror.c \ -@@ -119,7 +113,6 @@ libgoa_backend_1_0_la_SOURCES += \ - endif - - libgoa_backend_1_0_la_CFLAGS = \ -- $(WEBKIT_GTK_CFLAGS) \ - $(JSON_GLIB_CFLAGS) \ - $(GCR_CFLAGS) \ - $(GLIB_CFLAGS) \ -@@ -134,7 +127,6 @@ libgoa_backend_1_0_la_CFLAGS = \ - - libgoa_backend_1_0_la_LIBADD = \ - $(top_builddir)/src/goa/libgoa-1.0.la \ -- $(WEBKIT_GTK_LIBS) \ - $(JSON_GLIB_LIBS) \ - $(GCR_LIBS) \ - $(GLIB_LIBS) \ -@@ -154,39 +146,29 @@ libgoa_backend_1_0_la_LDFLAGS = \ - - # ---------------------------------------------------------------------------------------------------- - --webextension_LTLIBRARIES = libgoawebextension.la -+libexec_PROGRAMS = goa-oauth2-handler - --webextensiondir = $(libdir)/goa-1.0/web-extensions -- --libgoawebextension_la_SOURCES = \ -- goawebextension.h goawebextension.c \ -- goawebextensionmain.c \ -+goa_oauth2_handler_SOURCES = \ -+ goaoauth2handler.c \ - $(NULL) - --libgoawebextension_la_CFLAGS = \ -- $(REST_CFLAGS) \ -- $(WEBKIT_GTK_CFLAGS) \ -+goa_oauth2_handler_CFLAGS = \ -+ $(GLIB_CFLAGS) \ -+ $(LIBSOUP_CFLAGS) \ -+ $(SECRET_CFLAGS) \ -+ -DG_LOG_DOMAIN=\"goa-oauth2-handler\" \ - $(NULL) - --libgoawebextension_la_LIBADD = \ -- libgoa-backend-1.0.la \ -- $(REST_LIBS) \ -- $(WEBKIT_GTK_LIBS) \ -+goa_oauth2_handler_LDADD = \ -+ $(GLIB_LIBS) \ -+ $(LIBSOUP_LIBS) \ -+ $(SECRET_LIBS) \ - $(NULL) - --libgoawebextension_la_LDFLAGS = \ -- -avoid-version \ -- -module \ -- -no-undefined \ -+goa_oauth2_handler_LDFLAGS = \ -+ $(WARN_LDFLAGS) \ - $(NULL) - --# Force installation order: libgoa-backend-1.0 must be installed first, othwerwise --# libtool will incorrectly relink libgoawebextension.la under parallel make install. --# Requires ugly automake syntax - see http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7328 -- --installwebextensionLTLIBRARIES = install-webextensionLTLIBRARIES --$(installwebextensionLTLIBRARIES): install-libLTLIBRARIES -- - # ---------------------------------------------------------------------------------------------------- - - BUILT_SOURCES = \ -diff --git a/src/goabackend/goafacebookprovider.c b/src/goabackend/goafacebookprovider.c -index c6033fb..c1d35d0 100644 ---- a/src/goabackend/goafacebookprovider.c -+++ b/src/goabackend/goafacebookprovider.c -@@ -243,31 +243,6 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --is_identity_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMHTMLInputElement *element) --{ -- gboolean ret = FALSE; -- gchar *element_type = NULL; -- gchar *name = NULL; -- -- g_object_get (element, "type", &element_type, NULL); -- if (g_strcmp0 (element_type, "text") != 0) -- goto out; -- -- name = webkit_dom_html_input_element_get_name (element); -- if (g_strcmp0 (name, "email") != 0) -- goto out; -- -- ret = TRUE; -- -- out: -- g_free (element_type); -- g_free (name); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static gboolean - build_object (GoaProvider *provider, - GoaObjectSkeleton *object, -@@ -367,6 +342,5 @@ goa_facebook_provider_class_init (GoaFacebookProviderClass *klass) - oauth2_class->get_client_id = get_client_id; - oauth2_class->get_client_secret = get_client_secret; - oauth2_class->get_identity_sync = get_identity_sync; -- oauth2_class->is_identity_node = is_identity_node; - oauth2_class->add_account_key_values = add_account_key_values; - } -diff --git a/src/goabackend/goaflickrprovider.c b/src/goabackend/goaflickrprovider.c -deleted file mode 100644 -index 702ed1e..0000000 ---- a/src/goabackend/goaflickrprovider.c -+++ /dev/null -@@ -1,364 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright (C) 2011 Willem van Engen -- * Copyright © 2012 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#include "config.h" --#include -- --#include --#include -- --#include "goaprovider.h" --#include "goaprovider-priv.h" --#include "goaflickrprovider.h" --#include "goaobjectskeletonutils.h" --#include "goasouplogger.h" -- --struct _GoaFlickrProvider --{ -- GoaOAuthProvider parent_instance; --}; -- --G_DEFINE_TYPE_WITH_CODE (GoaFlickrProvider, goa_flickr_provider, GOA_TYPE_OAUTH_PROVIDER, -- goa_provider_ensure_extension_points_registered (); -- g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME, -- g_define_type_id, -- GOA_FLICKR_NAME, -- 0)); -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static const gchar * --get_provider_type (GoaProvider *provider) --{ -- return GOA_FLICKR_NAME; --} -- --static gchar * --get_provider_name (GoaProvider *provider, -- GoaObject *object) --{ -- return g_strdup (_("Flickr")); --} -- --static GoaProviderGroup --get_provider_group (GoaProvider *provider) --{ -- return GOA_PROVIDER_GROUP_BRANDED; --} -- --static GoaProviderFeatures --get_provider_features (GoaProvider *provider) --{ -- return GOA_PROVIDER_FEATURE_BRANDED | GOA_PROVIDER_FEATURE_PHOTOS; --} -- --static const gchar * --get_consumer_key (GoaOAuthProvider *oauth_provider) --{ -- return GOA_FLICKR_CONSUMER_KEY; --} -- --static const gchar * --get_consumer_secret (GoaOAuthProvider *oauth_provider) --{ -- return GOA_FLICKR_CONSUMER_SECRET; --} -- --static const gchar * --get_request_uri (GoaOAuthProvider *oauth_provider) --{ -- return "https://www.flickr.com/services/oauth/request_token"; --} -- --static const gchar * --get_authorization_uri (GoaOAuthProvider *oauth_provider) --{ -- return "https://www.flickr.com/services/oauth/authorize"; --} -- --static const gchar * --get_token_uri (GoaOAuthProvider *oauth_provider) --{ -- return "https://www.flickr.com/services/oauth/access_token"; --} -- --static const gchar * --get_callback_uri (GoaOAuthProvider *oauth_provider) --{ -- /* Should match the URI specified in the Flickr App -- * Garden in order to detect when the user denied access via -- * the OAuth1 web page. -- */ -- return "https://www.gnome.org/"; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gchar * --get_identity_sync (GoaOAuthProvider *oauth_provider, -- const gchar *access_token, -- const gchar *access_token_secret, -- gchar **out_presentation_identity, -- GCancellable *cancellable, -- GError **error) --{ -- GError *identity_error = NULL; -- RestProxy *proxy = NULL; -- RestProxyCall *call = NULL; -- JsonParser *parser = NULL; -- JsonObject *json_object; -- SoupLogger *logger = NULL; -- gchar *ret = NULL; -- gchar *id = NULL; -- gchar *presentation_identity = NULL; -- -- /* TODO: cancellable */ -- -- proxy = oauth_proxy_new_with_token (goa_oauth_provider_get_consumer_key (oauth_provider), -- goa_oauth_provider_get_consumer_secret (oauth_provider), -- access_token, -- access_token_secret, -- "https://api.flickr.com/services/rest", -- FALSE); -- logger = goa_soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); -- rest_proxy_add_soup_feature (proxy, SOUP_SESSION_FEATURE (logger)); -- -- call = rest_proxy_new_call (proxy); -- rest_proxy_call_add_param (call, "method", "flickr.test.login"); -- rest_proxy_call_add_param (call, "format", "json"); -- rest_proxy_call_add_param (call, "nojsoncallback", "1"); -- rest_proxy_call_set_method (call, "GET"); -- -- if (!rest_proxy_call_sync (call, error)) -- goto out; -- if (rest_proxy_call_get_status_code (call) != 200) -- { -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Expected status 200 when requesting your identity, instead got status %d (%s)"), -- rest_proxy_call_get_status_code (call), -- rest_proxy_call_get_status_message (call)); -- goto out; -- } -- -- parser = json_parser_new (); -- if (!json_parser_load_from_data (parser, -- rest_proxy_call_get_payload (call), -- rest_proxy_call_get_payload_length (call), -- &identity_error)) -- { -- g_warning ("json_parser_load_from_data() failed: %s (%s, %d)", -- identity_error->message, -- g_quark_to_string (identity_error->domain), -- identity_error->code); -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Could not parse response")); -- goto out; -- } -- -- json_object = json_node_get_object (json_parser_get_root (parser)); -- if (!json_object_has_member (json_object, "user")) -- { -- g_warning ("Did not find user in JSON data"); -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Could not parse response")); -- goto out; -- } -- -- json_object = json_object_get_object_member (json_object, "user"); -- if (!json_object_has_member (json_object, "id")) -- { -- g_warning ("Did not find user.id in JSON data"); -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Could not parse response")); -- goto out; -- } -- if (!json_object_has_member (json_object, "username")) -- { -- g_warning ("Did not find user.username in JSON data"); -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Could not parse response")); -- goto out; -- } -- -- id = g_strdup (json_object_get_string_member (json_object, "id")); -- -- json_object = json_object_get_object_member (json_object, "username"); -- if (!json_object_has_member (json_object, "_content")) -- { -- g_warning ("Did not find user.username._content in JSON data"); -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Could not parse response")); -- goto out; -- } -- -- presentation_identity = g_strdup (json_object_get_string_member (json_object, "_content")); -- -- ret = id; -- id = NULL; -- if (out_presentation_identity != NULL) -- { -- *out_presentation_identity = presentation_identity; -- presentation_identity = NULL; -- } -- -- out: -- g_clear_object (&parser); -- g_clear_error (&identity_error); -- g_clear_object (&call); -- g_clear_object (&proxy); -- g_clear_object (&logger); -- g_free (id); -- g_free (presentation_identity); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --is_identity_node (GoaOAuthProvider *oauth_provider, WebKitDOMHTMLInputElement *element) --{ -- /* Flickr does not provide a way to query the string used by the -- * user to log in via the web interface. The user id and username -- * returned by flickr.test.login [1] are not what we are looking -- * for. -- * -- * [1] http://www.flickr.com/services/api/flickr.test.login.html -- */ -- return FALSE; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gchar * --parse_request_token_error (GoaOAuthProvider *oauth_provider, RestProxyCall *call) --{ -- const gchar *payload; -- gchar *msg = NULL; -- guint status; -- -- payload = rest_proxy_call_get_payload (call); -- status = rest_proxy_call_get_status_code (call); -- -- if (status == 401 && g_strcmp0 (payload, "oauth_problem=timestamp_refused") == 0) -- msg = g_strdup (_("Your system time is invalid. Check your date and time settings.")); -- -- return msg; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --build_object (GoaProvider *provider, -- GoaObjectSkeleton *object, -- GKeyFile *key_file, -- const gchar *group, -- GDBusConnection *connection, -- gboolean just_added, -- GError **error) --{ -- GoaAccount *account = NULL; -- gboolean photos_enabled; -- gboolean ret = FALSE; -- -- /* Chain up */ -- if (!GOA_PROVIDER_CLASS (goa_flickr_provider_parent_class)->build_object (provider, -- object, -- key_file, -- group, -- connection, -- just_added, -- error)) -- goto out; -- -- account = goa_object_get_account (GOA_OBJECT (object)); -- -- /* Photos */ -- photos_enabled = g_key_file_get_boolean (key_file, group, "PhotosEnabled", NULL); -- goa_object_skeleton_attach_photos (object, photos_enabled); -- -- if (just_added) -- { -- goa_account_set_photos_disabled (account, !photos_enabled); -- -- g_signal_connect (account, -- "notify::photos-disabled", -- G_CALLBACK (goa_util_account_notify_property_cb), -- (gpointer) "PhotosEnabled"); -- } -- -- ret = TRUE; -- -- out: -- g_clear_object (&account); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static void --add_account_key_values (GoaOAuthProvider *oauth_provider, -- GVariantBuilder *builder) --{ -- g_variant_builder_add (builder, "{ss}", "PhotosEnabled", "true"); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static void --goa_flickr_provider_init (GoaFlickrProvider *self) --{ --} -- --static void --goa_flickr_provider_class_init (GoaFlickrProviderClass *klass) --{ -- GoaProviderClass *provider_class; -- GoaOAuthProviderClass *oauth_class; -- -- provider_class = GOA_PROVIDER_CLASS (klass); -- provider_class->get_provider_type = get_provider_type; -- provider_class->get_provider_name = get_provider_name; -- provider_class->get_provider_group = get_provider_group; -- provider_class->get_provider_features = get_provider_features; -- provider_class->build_object = build_object; -- -- oauth_class = GOA_OAUTH_PROVIDER_CLASS (klass); -- oauth_class->get_identity_sync = get_identity_sync; -- oauth_class->is_identity_node = is_identity_node; -- oauth_class->get_consumer_key = get_consumer_key; -- oauth_class->get_consumer_secret = get_consumer_secret; -- oauth_class->get_request_uri = get_request_uri; -- oauth_class->get_authorization_uri = get_authorization_uri; -- oauth_class->get_token_uri = get_token_uri; -- oauth_class->get_callback_uri = get_callback_uri; -- oauth_class->parse_request_token_error = parse_request_token_error; -- oauth_class->add_account_key_values = add_account_key_values; --} -diff --git a/src/goabackend/goaflickrprovider.h b/src/goabackend/goaflickrprovider.h -deleted file mode 100644 -index f08a8a6..0000000 ---- a/src/goabackend/goaflickrprovider.h -+++ /dev/null -@@ -1,37 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2012 Willem van Engen -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) --#error "Only can be included directly." --#endif -- --#ifndef __GOA_FLICKR_PROVIDER_H__ --#define __GOA_FLICKR_PROVIDER_H__ -- --#include -- --#include "goaoauthprovider.h" -- --G_BEGIN_DECLS -- --#define GOA_TYPE_FLICKR_PROVIDER (goa_flickr_provider_get_type ()) --G_DECLARE_FINAL_TYPE (GoaFlickrProvider, goa_flickr_provider, GOA, FLICKR_PROVIDER, GoaOAuthProvider); -- --G_END_DECLS -- --#endif /* __GOA_FLICKR_PROVIDER_H__ */ -diff --git a/src/goabackend/goafoursquareprovider.c b/src/goabackend/goafoursquareprovider.c -index c1e4146..def21cb 100644 ---- a/src/goabackend/goafoursquareprovider.c -+++ b/src/goabackend/goafoursquareprovider.c -@@ -251,31 +251,6 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --is_identity_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMHTMLInputElement *element) --{ -- gboolean ret = FALSE; -- gchar *element_type = NULL; -- gchar *name = NULL; -- -- g_object_get (element, "type", &element_type, NULL); -- if (g_strcmp0 (element_type, "email") != 0) -- goto out; -- -- name = webkit_dom_html_input_element_get_name (element); -- if (g_strcmp0 (name, "emailOrPhone") != 0) -- goto out; -- -- ret = TRUE; -- -- out: -- g_free (element_type); -- g_free (name); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static gboolean - build_object (GoaProvider *provider, - GoaObjectSkeleton *object, -@@ -366,6 +341,5 @@ goa_foursquare_provider_class_init (GoaFoursquareProviderClass *klass) - oauth2_class->get_client_secret = get_client_secret; - oauth2_class->get_use_mobile_browser = get_use_mobile_browser; - oauth2_class->get_identity_sync = get_identity_sync; -- oauth2_class->is_identity_node = is_identity_node; - oauth2_class->add_account_key_values = add_account_key_values; - } -diff --git a/src/goabackend/goagoogleprovider.c b/src/goabackend/goagoogleprovider.c -index 6e4ace2..6f951e5 100644 ---- a/src/goabackend/goagoogleprovider.c -+++ b/src/goabackend/goagoogleprovider.c -@@ -32,6 +32,7 @@ - struct _GoaGoogleProvider - { - GoaOAuth2Provider parent_instance; -+ gchar *redirect_uri; - }; - - G_DEFINE_TYPE_WITH_CODE (GoaGoogleProvider, goa_google_provider, GOA_TYPE_OAUTH2_PROVIDER, -@@ -81,19 +82,50 @@ get_provider_features (GoaProvider *provider) - static const gchar * - get_authorization_uri (GoaOAuth2Provider *oauth2_provider) - { -- return "https://accounts.google.com/o/oauth2/auth"; -+ return "https://accounts.google.com/o/oauth2/v2/auth"; - } - - static const gchar * - get_token_uri (GoaOAuth2Provider *oauth2_provider) - { -- return "https://accounts.google.com/o/oauth2/token"; -+ return "https://oauth2.googleapis.com/token"; - } - - static const gchar * - get_redirect_uri (GoaOAuth2Provider *oauth2_provider) - { -- return "http://localhost"; -+ G_LOCK_DEFINE_STATIC (redirect_uri); -+ GoaGoogleProvider *self = GOA_GOOGLE_PROVIDER (oauth2_provider); -+ -+ G_LOCK (redirect_uri); -+ -+ if (!self->redirect_uri) { -+ GPtrArray *array; -+ gchar **strv; -+ gchar *joinstr; -+ guint ii; -+ -+ strv = g_strsplit (GOA_GOOGLE_CLIENT_ID, ".", -1); -+ array = g_ptr_array_new (); -+ -+ for (ii = 0; strv[ii]; ii++) { -+ g_ptr_array_insert (array, 0, strv[ii]); -+ } -+ -+ g_ptr_array_add (array, NULL); -+ -+ joinstr = g_strjoinv (".", (gchar **) array->pdata); -+ /* Use reverse-DNS of the client ID with the below path */ -+ self->redirect_uri = g_strconcat (joinstr, ":/oauth2redirect", NULL); -+ -+ g_ptr_array_free (array, TRUE); -+ g_strfreev (strv); -+ g_free (joinstr); -+ } -+ -+ G_UNLOCK (redirect_uri); -+ -+ return self->redirect_uri; - } - - static const gchar * -@@ -241,37 +273,6 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --is_identity_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMHTMLInputElement *element) --{ -- gboolean ret = FALSE; -- gchar *element_type = NULL; -- gchar *id = NULL; -- gchar *name = NULL; -- -- g_object_get (element, "type", &element_type, NULL); -- if (g_strcmp0 (element_type, "email") != 0) -- goto out; -- -- id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (element)); -- if (g_strcmp0 (id, "identifierId") != 0) -- goto out; -- -- name = webkit_dom_html_input_element_get_name (element); -- if (g_strcmp0 (name, "identifier") != 0) -- goto out; -- -- ret = TRUE; -- -- out: -- g_free (element_type); -- g_free (id); -- g_free (name); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static gboolean - build_object (GoaProvider *provider, - GoaObjectSkeleton *object, -@@ -446,6 +447,16 @@ add_account_key_values (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - -+static void -+goa_google_finalize (GObject *object) -+{ -+ GoaGoogleProvider *self = GOA_GOOGLE_PROVIDER (object); -+ -+ g_free (self->redirect_uri); -+ -+ G_OBJECT_CLASS (goa_google_provider_parent_class)->finalize (object); -+} -+ - static void - goa_google_provider_init (GoaGoogleProvider *self) - { -@@ -456,6 +467,10 @@ goa_google_provider_class_init (GoaGoogleProviderClass *klass) - { - GoaProviderClass *provider_class; - GoaOAuth2ProviderClass *oauth2_class; -+ GObjectClass *object_class; -+ -+ object_class = G_OBJECT_CLASS (klass); -+ object_class->finalize = goa_google_finalize; - - provider_class = GOA_PROVIDER_CLASS (klass); - provider_class->get_provider_type = get_provider_type; -@@ -472,7 +487,6 @@ goa_google_provider_class_init (GoaGoogleProviderClass *klass) - oauth2_class->get_identity_sync = get_identity_sync; - oauth2_class->get_redirect_uri = get_redirect_uri; - oauth2_class->get_scope = get_scope; -- oauth2_class->is_identity_node = is_identity_node; - oauth2_class->get_token_uri = get_token_uri; - oauth2_class->add_account_key_values = add_account_key_values; - } -diff --git a/src/goabackend/goaoauth2handler.c b/src/goabackend/goaoauth2handler.c -new file mode 100644 -index 0000000..c5a86cb ---- /dev/null -+++ b/src/goabackend/goaoauth2handler.c -@@ -0,0 +1,173 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* -+ * Copyright © 2023 GNOME Foundation Inc. -+ * Contributor: Andy Holmes -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General -+ * Public License along with this library; if not, see . -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+ -+static const SecretSchema oauth2_schema = -+{ -+ .name = "org.gnome.OnlineAccounts.OAuth2", -+ .flags = SECRET_SCHEMA_NONE, -+ .attributes = { -+ { -+ .name = "goa-oauth2-client", -+ .type = SECRET_SCHEMA_ATTRIBUTE_STRING, -+ }, -+ { -+ .name = "goa-oauth2-provider", -+ .type = SECRET_SCHEMA_ATTRIBUTE_STRING, -+ }, -+ { "NULL", 0 } -+ } -+}; -+ -+static struct -+{ -+ const char *client_id; -+ const char *provider; -+} -+oauth2_providers[] = -+{ -+#ifdef GOA_GOOGLE_ENABLED -+ { -+ .client_id = GOA_GOOGLE_CLIENT_ID, -+ .provider = GOA_GOOGLE_NAME, -+ }, -+#endif -+#ifdef GOA_WINDOWS_LIVE_ENABLED -+ { -+ .client_id = GOA_WINDOWS_LIVE_CLIENT_ID, -+ .provider = GOA_WINDOWS_LIVE_NAME, -+ }, -+#endif -+ { NULL, NULL }, -+}; -+ -+static gboolean -+get_oauth2_provider (const char *needle, -+ const char **client_out, -+ const char **provider_out) -+{ -+ g_return_val_if_fail (needle != NULL, FALSE); -+ -+ for (unsigned int i = 0; oauth2_providers[i].client_id != NULL; i++) -+ { -+ if (g_str_equal (needle, oauth2_providers[i].client_id)) -+ { -+ if (client_out) -+ *client_out = oauth2_providers[i].client_id; -+ -+ if (provider_out) -+ *provider_out = oauth2_providers[i].provider; -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+int -+main (int argc, -+ char **argv) -+{ -+ SoupURI *uri = NULL; -+ const char *scheme = NULL; -+ const char *path = NULL; -+ const char *client_id = NULL; -+ const char *provider_type = NULL; -+ GError *error = NULL; -+ -+ if (argc < 2) -+ { -+ g_printerr ("%s: Missing URI\n", argv[0]); -+ return EXIT_FAILURE; -+ } -+ -+ uri = soup_uri_new (argv[1]); -+ if (uri == NULL) -+ { -+ g_printerr ("%s: Invalid URI: %s\n", argv[0], argv[1]); -+ return EXIT_FAILURE; -+ } -+ -+ /* Google apps may use a reverse-DNS form of the client ID as the URI scheme -+ * See: https://developers.google.com/identity/protocols/oauth2/native-app -+ */ -+ scheme = soup_uri_get_scheme (uri); -+ if (scheme != NULL) -+ { -+ g_auto (GStrv) strv = g_strsplit (scheme, ".", -1); -+ g_autoptr (GString) tmp = g_string_new (""); -+ -+ for (unsigned int i = 0; strv[i] != NULL; i++) -+ { -+ if (i > 0) -+ g_string_prepend_c (tmp, '.'); -+ g_string_prepend (tmp, strv[i]); -+ } -+ -+ get_oauth2_provider (tmp->str, &client_id, &provider_type); -+ } -+ -+ /* Windows Live uses goa-oauth2:// with the client ID as the first path segment -+ */ -+ if (client_id == NULL) -+ { -+ path = soup_uri_get_path (uri); -+ if (path != NULL && *path != '\0') -+ { -+ g_auto (GStrv) strv = NULL; -+ -+ strv = g_strsplit (*path == '/' ? path +1 : path, "/", 1); -+ get_oauth2_provider (strv[0], &client_id, &provider_type); -+ } -+ } -+ -+ if (client_id == NULL) -+ { -+ g_printerr ("%s: Unknown provider\n", argv[0]); -+ soup_uri_free (uri); -+ return EXIT_FAILURE; -+ } -+ -+ if (!secret_password_store_sync (&oauth2_schema, -+ SECRET_COLLECTION_SESSION, -+ "GNOME Online Accounts OAuth2 URI", -+ argv[1], /* Secret */ -+ NULL, -+ &error, -+ "goa-oauth2-client", client_id, -+ "goa-oauth2-provider", provider_type, -+ NULL)) -+ { -+ if (error != NULL) -+ g_printerr ("%s: Failed to store OAuth2 URI: %s\n", argv[0], error->message); -+ -+ soup_uri_free (uri); -+ g_clear_error (&error); -+ return EXIT_FAILURE; -+ } -+ -+ return EXIT_SUCCESS; -+} -diff --git a/src/goabackend/goaoauth2provider-priv.h b/src/goabackend/goaoauth2provider-priv.h -index de1b808..4b00a24 100644 ---- a/src/goabackend/goaoauth2provider-priv.h -+++ b/src/goabackend/goaoauth2provider-priv.h -@@ -26,8 +26,6 @@ - #include - #include - #include --#include --#include - - G_BEGIN_DECLS - -@@ -51,11 +49,7 @@ G_BEGIN_DECLS - * @build_authorization_uri: Virtual function for goa_oauth2_provider_build_authorization_uri(). - * @get_use_mobile_browser: Virtual function for goa_oauth2_provider_get_use_mobile_browser(). - * @add_account_key_values: Virtual function for goa_oauth2_provider_add_account_key_values(). -- * @decide_navigation_policy: Virtual function for goa_oauth2_provider_decide_navigation_policy(). - * @process_redirect_url: Virtual function for goa_oauth2_provider_process_redirect_url(). -- * @is_deny_node: Virtual function for goa_oauth2_provider_is_deny_node(). -- * @is_identity_node: Virtual function for goa_oauth2_provider_is_identity_node(). -- * @is_password_node: Virtual function for goa_oauth2_provider_is_password_node(). - * - * Class structure for #GoaOAuth2Provider. - */ -@@ -86,18 +80,7 @@ struct _GoaOAuth2ProviderClass - void (*add_account_key_values) (GoaOAuth2Provider *provider, - GVariantBuilder *builder); - -- /* pure virtual */ -- gboolean (*is_identity_node) (GoaOAuth2Provider *provider, -- WebKitDOMHTMLInputElement *element); -- - /* virtual but with default implementation */ -- gboolean (*is_deny_node) (GoaOAuth2Provider *provider, -- WebKitDOMNode *node); -- gboolean (*is_password_node) (GoaOAuth2Provider *provider, -- WebKitDOMHTMLInputElement *element); -- gboolean (*decide_navigation_policy) (GoaOAuth2Provider *provider, -- WebKitWebView *web_view, -- WebKitNavigationPolicyDecision *decision); - gboolean (*process_redirect_url) (GoaOAuth2Provider *provider, - const gchar *redirect_url, - gchar **access_token, -diff --git a/src/goabackend/goaoauth2provider-web-extension.h b/src/goabackend/goaoauth2provider-web-extension.h -deleted file mode 100644 -index baac005..0000000 ---- a/src/goabackend/goaoauth2provider-web-extension.h -+++ /dev/null -@@ -1,40 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2016 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) --#error "Only can be included directly." --#endif -- --#ifndef __GOA_OAUTH2_PROVIDER_WEB_EXTENSION_H__ --#define __GOA_OAUTH2_PROVIDER_WEB_EXTENSION_H__ -- --#include --#include -- --G_BEGIN_DECLS -- --gboolean goa_oauth2_provider_is_deny_node (GoaOAuth2Provider *provider, -- WebKitDOMNode *node); --gboolean goa_oauth2_provider_is_identity_node (GoaOAuth2Provider *provider, -- WebKitDOMHTMLInputElement *element); --gboolean goa_oauth2_provider_is_password_node (GoaOAuth2Provider *provider, -- WebKitDOMHTMLInputElement *element); -- --G_END_DECLS -- --#endif /* __GOA_OAUTH2_PROVIDER_WEB_EXTENSION_H__ */ -diff --git a/src/goabackend/goaoauth2provider-web-view.h b/src/goabackend/goaoauth2provider-web-view.h -deleted file mode 100644 -index f2dae5e..0000000 ---- a/src/goabackend/goaoauth2provider-web-view.h -+++ /dev/null -@@ -1,37 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2016 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) --#error "Only can be included directly." --#endif -- --#ifndef __GOA_OAUTH2_PROVIDER_WEB_VIEW_H__ --#define __GOA_OAUTH2_PROVIDER_WEB_VIEW_H__ -- --#include --#include -- --G_BEGIN_DECLS -- --gboolean goa_oauth2_provider_decide_navigation_policy (GoaOAuth2Provider *provider, -- WebKitWebView *web_view, -- WebKitNavigationPolicyDecision *decision); -- --G_END_DECLS -- --#endif /* __GOA_OAUTH2_PROVIDER_WEB_VIEW_H__ */ -diff --git a/src/goabackend/goaoauth2provider.c b/src/goabackend/goaoauth2provider.c -index 9092605..1ceacb5 100644 ---- a/src/goabackend/goaoauth2provider.c -+++ b/src/goabackend/goaoauth2provider.c -@@ -22,16 +22,13 @@ - - #include - #include -+#include - #include --#include - - #include "goaprovider.h" - #include "goautils.h" --#include "goawebview.h" - #include "goaoauth2provider.h" - #include "goaoauth2provider-priv.h" --#include "goaoauth2provider-web-extension.h" --#include "goaoauth2provider-web-view.h" - #include "goarestproxy.h" - - /** -@@ -81,6 +78,8 @@ struct _GoaOAuth2ProviderPrivate - gchar *identity; - gchar *presentation_identity; - gchar *password; -+ gchar *request_uri; -+ SecretCollection *session; - }; - - G_LOCK_DEFINE_STATIC (provider_lock); -@@ -134,70 +133,6 @@ goa_oauth2_provider_get_use_mobile_browser (GoaOAuth2Provider *self) - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --goa_oauth2_provider_is_deny_node_default (GoaOAuth2Provider *self, WebKitDOMNode *node) --{ -- return FALSE; --} -- --/** -- * goa_oauth2_provider_is_deny_node: -- * @self: A #GoaOAuth2Provider. -- * @node: A WebKitDOMNode. -- * -- * Checks whether @node is the HTML UI element that the user can use -- * to deny permission to access his account. Usually they are either a -- * WebKitDOMHTMLButtonElement or a WebKitDOMHTMLInputElement. -- * -- * Please note that providers may have multiple such elements in their -- * UI and this method should catch all of them. -- * -- * This is a virtual method where the default implementation returns -- * %FALSE. -- * -- * Returns: %TRUE if the @node can be used to deny permission. -- */ --gboolean --goa_oauth2_provider_is_deny_node (GoaOAuth2Provider *self, WebKitDOMNode *node) --{ -- g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (self), FALSE); -- return GOA_OAUTH2_PROVIDER_GET_CLASS (self)->is_deny_node (self, node); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --goa_oauth2_provider_is_password_node_default (GoaOAuth2Provider *self, WebKitDOMHTMLInputElement *element) --{ -- return FALSE; --} -- --/** -- * goa_oauth2_provider_is_password_node: -- * @self: A #GoaOAuth2Provider. -- * @element: A WebKitDOMHTMLInputElement -- * -- * Checks whether @element is the HTML UI element that the user can -- * use to enter her password. This can be used to offer a -- * #GoaPasswordBased interface by saving the user's -- * password. Providers usually frown upon doing this, so this is not -- * recommended. -- * -- * This is a virtual method where the default implementation returns -- * %FALSE. -- * -- * Returns: %TRUE if @element can be used to enter the password. -- */ --gboolean --goa_oauth2_provider_is_password_node (GoaOAuth2Provider *self, WebKitDOMHTMLInputElement *element) --{ -- g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (self), FALSE); -- g_return_val_if_fail (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element), FALSE); -- return GOA_OAUTH2_PROVIDER_GET_CLASS (self)->is_password_node (self, element); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static void - goa_oauth2_provider_add_account_key_values_default (GoaOAuth2Provider *self, - GVariantBuilder *builder) -@@ -287,45 +222,6 @@ goa_oauth2_provider_build_authorization_uri (GoaOAuth2Provider *self, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --goa_oauth2_provider_decide_navigation_policy_default (GoaOAuth2Provider *self, -- WebKitWebView *web_view, -- WebKitNavigationPolicyDecision *decision) --{ -- return FALSE; --} -- --/* -- * goa_oauth2_provider_decide_navigation_policy_default: -- * @self: A #GoaOAuth2Provider. -- * @decision: A #WebKitNavigationPolicyDecision -- * -- * Certain OAuth2-like, but not exactly OAuth2, -- * providers may not send us to the redirect URI, as expected. They -- * might need some special handling for that. This is a provider -- * specific hook to accommodate them. -- * -- * This is a virtual method where the default implementation returns -- * %FALSE. -- * -- * Returns: %TRUE if @provider decided what to do with @decision, -- * %FALSE otherwise. -- */ --gboolean --goa_oauth2_provider_decide_navigation_policy (GoaOAuth2Provider *self, -- WebKitWebView *web_view, -- WebKitNavigationPolicyDecision *decision) --{ -- g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (self), FALSE); -- g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (web_view), FALSE); -- g_return_val_if_fail (WEBKIT_IS_NAVIGATION_POLICY_DECISION (decision), FALSE); -- -- return GOA_OAUTH2_PROVIDER_GET_CLASS (self)->decide_navigation_policy (self, web_view, decision); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - /** - * goa_oauth2_provider_process_redirect_url: - * @self: A #GoaOAuth2Provider. -@@ -551,26 +447,6 @@ goa_oauth2_provider_get_identity_sync (GoaOAuth2Provider *self, - error); - } - --/** -- * goa_oauth2_provider_is_identity_node: -- * @self: A #GoaOAuth2Provider. -- * @element: A WebKitDOMHTMLInputElement. -- * -- * Checks whether @element is the HTML UI element that the user can -- * use to identify herself at the provider. -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: %TRUE if the @element can be used to deny permission. -- */ --gboolean --goa_oauth2_provider_is_identity_node (GoaOAuth2Provider *self, WebKitDOMHTMLInputElement *element) --{ -- g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (self), FALSE); -- return GOA_OAUTH2_PROVIDER_GET_CLASS (self)->is_identity_node (self, element); --} -- - /* ---------------------------------------------------------------------------------------------------- */ - - static gchar * -@@ -730,72 +606,42 @@ get_tokens_sync (GoaOAuth2Provider *self, - - /* ---------------------------------------------------------------------------------------------------- */ - --static void --on_web_view_deny_click (GoaWebView *web_view, gpointer user_data) --{ -- GoaOAuth2Provider *self = GOA_OAUTH2_PROVIDER (user_data); -- GoaOAuth2ProviderPrivate *priv; -- -- priv = goa_oauth2_provider_get_instance_private (self); -- gtk_dialog_response (priv->dialog, GTK_RESPONSE_CANCEL); --} -- --static void --on_web_view_password_submit (GoaWebView *web_view, const gchar *password, gpointer user_data) --{ -- GoaOAuth2Provider *self = GOA_OAUTH2_PROVIDER (user_data); -- GoaOAuth2ProviderPrivate *priv; -- -- priv = goa_oauth2_provider_get_instance_private (self); -- -- g_free (priv->password); -- priv->password = g_strdup (password); --} -- - static gboolean --on_web_view_decide_policy (WebKitWebView *web_view, -- WebKitPolicyDecision *decision, -- WebKitPolicyDecisionType decision_type, -- gpointer user_data) -+parse_requested_uri (GoaOAuth2Provider *self, -+ const char *requested_uri) - { -- GoaOAuth2Provider *self = GOA_OAUTH2_PROVIDER (user_data); -- GoaOAuth2ProviderPrivate *priv; -+ GoaOAuth2ProviderPrivate *priv = goa_oauth2_provider_get_instance_private (self); - GHashTable *key_value_pairs; -- WebKitNavigationAction *action; -- WebKitURIRequest *request; - SoupURI *uri; - const gchar *fragment; - const gchar *oauth2_error; - const gchar *query; - const gchar *redirect_uri; -- const gchar *requested_uri; -- gint response_id = GTK_RESPONSE_NONE; -- -- priv = goa_oauth2_provider_get_instance_private (self); -- -- if (decision_type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION) -- goto default_behaviour; -- -- if (goa_oauth2_provider_decide_navigation_policy (self, -- web_view, -- WEBKIT_NAVIGATION_POLICY_DECISION (decision))) -- { -- response_id = 0; -- goto ignore_request; -- } - - /* TODO: use oauth2_proxy_extract_access_token() */ -+ g_assert (priv->error == NULL); - -- action = webkit_navigation_policy_decision_get_navigation_action (WEBKIT_NAVIGATION_POLICY_DECISION (decision)); -- request = webkit_navigation_action_get_request (action); -- requested_uri = webkit_uri_request_get_uri (request); - redirect_uri = goa_oauth2_provider_get_redirect_uri (self); - if (!g_str_has_prefix (requested_uri, redirect_uri)) -- goto default_behaviour; -+ { -+ g_set_error (&priv->error, -+ GOA_ERROR, -+ GOA_ERROR_FAILED, -+ "Invalid URI: %s", -+ requested_uri); -+ return FALSE; -+ } - - uri = soup_uri_new (requested_uri); -- fragment = soup_uri_get_fragment (uri); -- query = soup_uri_get_query (uri); -+ if (uri == NULL) -+ { -+ g_set_error (&priv->error, -+ GOA_ERROR, -+ GOA_ERROR_FAILED, -+ "Invalid URI: %s", -+ requested_uri); -+ return FALSE; -+ } - - /* Three cases: - * 1) we can either have the backend handle the URI for us, or -@@ -806,23 +652,23 @@ on_web_view_decide_policy (WebKitWebView *web_view, - */ - if (GOA_OAUTH2_PROVIDER_GET_CLASS (self)->process_redirect_url) - { -- gchar *url; -+ g_autofree char *url = NULL; - - url = soup_uri_to_string (uri, FALSE); -+ soup_uri_free (uri); - if (!goa_oauth2_provider_process_redirect_url (self, url, &priv->access_token, &priv->error)) - { - g_prefix_error (&priv->error, _("Authorization response: ")); - priv->error->domain = GOA_ERROR; - priv->error->code = GOA_ERROR_NOT_AUTHORIZED; -- response_id = GTK_RESPONSE_CLOSE; -+ -+ return FALSE; - } -- else -- response_id = GTK_RESPONSE_OK; - -- g_free (url); -- goto ignore_request; -+ return TRUE; - } - -+ fragment = soup_uri_get_fragment (uri); - if (fragment != NULL) - { - /* fragment is encoded into a key/value pairs for the token and -@@ -846,57 +692,175 @@ on_web_view_decide_policy (WebKitWebView *web_view, - priv->access_token_expires_in = atoi (expires_in_str); - - priv->refresh_token = g_strdup (g_hash_table_lookup (key_value_pairs, "refresh_token")); -- -- response_id = GTK_RESPONSE_OK; - } - g_hash_table_unref (key_value_pairs); -- } - -- if (priv->access_token != NULL) -- goto ignore_request; -+ if (priv->access_token != NULL) -+ { -+ soup_uri_free (uri); -+ return TRUE; -+ } -+ } - -+ query = soup_uri_get_query (uri); - if (query != NULL) - { - key_value_pairs = soup_form_decode (query); - - priv->authorization_code = g_strdup (g_hash_table_lookup (key_value_pairs, "code")); -- if (priv->authorization_code != NULL) -- response_id = GTK_RESPONSE_OK; -- - g_hash_table_unref (key_value_pairs); -+ if (priv->authorization_code != NULL) -+ { -+ soup_uri_free (uri); -+ return TRUE; -+ } - } - -- if (priv->authorization_code != NULL) -- goto ignore_request; -- - /* In case we don't find the access_token or auth code, then look - * for the error in the query part of the URI. - */ - key_value_pairs = soup_form_decode (query); - oauth2_error = (const gchar *) g_hash_table_lookup (key_value_pairs, "error"); - if (g_strcmp0 (oauth2_error, GOA_OAUTH2_ACCESS_DENIED) == 0) -- response_id = GTK_RESPONSE_CANCEL; -- else - { - g_set_error (&priv->error, - GOA_ERROR, - GOA_ERROR_NOT_AUTHORIZED, - _("Authorization response: %s"), - oauth2_error); -- response_id = GTK_RESPONSE_CLOSE; -+ } -+ else -+ { -+ g_set_error_literal (&priv->error, -+ GOA_ERROR, -+ GOA_ERROR_FAILED, -+ _("Failed to authenticate")); - } - g_hash_table_unref (key_value_pairs); -- goto ignore_request; -+ soup_uri_free (uri); -+ return FALSE; -+} - -- ignore_request: -- g_assert (response_id != GTK_RESPONSE_NONE); -- if (response_id < 0) -- gtk_dialog_response (priv->dialog, response_id); -- webkit_policy_decision_ignore (decision); -- return TRUE; -+/* ---------------------------------------------------------------------------------------------------- */ - -- default_behaviour: -- return FALSE; -+static const SecretSchema oauth2_schema = -+{ -+ .name = "org.gnome.OnlineAccounts.OAuth2", -+ .flags = SECRET_SCHEMA_NONE, -+ .attributes = { -+ { -+ .name = "goa-oauth2-client", -+ .type = SECRET_SCHEMA_ATTRIBUTE_STRING, -+ }, -+ { -+ .name = "goa-oauth2-provider", -+ .type = SECRET_SCHEMA_ATTRIBUTE_STRING, -+ }, -+ { "NULL", 0 } -+ } -+}; -+ -+static void -+on_secrets_changed (SecretCollection *collection, -+ GParamSpec *pspec, -+ GoaOAuth2Provider *self) -+{ -+ GoaOAuth2ProviderPrivate *priv = goa_oauth2_provider_get_instance_private (self); -+ const char *client_id = NULL; -+ const char *provider_type = NULL; -+ g_autofree char *requested_uri = NULL; -+ GtkResponseType response_id = GTK_RESPONSE_NONE; -+ -+ client_id = goa_oauth2_provider_get_client_id (self); -+ provider_type = goa_provider_get_provider_type (GOA_PROVIDER (self)); -+ requested_uri = secret_password_lookup_sync (&oauth2_schema, NULL, NULL, -+ "goa-oauth2-client", client_id, -+ "goa-oauth2-provider", provider_type, -+ NULL); -+ -+ if (requested_uri != NULL) -+ { -+ if (parse_requested_uri (self, requested_uri)) -+ response_id = GTK_RESPONSE_OK; -+ else -+ response_id = GTK_RESPONSE_CANCEL; -+ } -+ -+ if (response_id != GTK_RESPONSE_NONE) -+ { -+ g_signal_handlers_disconnect_by_func (collection, on_secrets_changed, self); -+ gtk_dialog_response (priv->dialog, response_id); -+ } -+} -+ -+static void -+secret_service_get_cb (GObject *object, -+ GAsyncResult *result, -+ GoaOAuth2Provider *self) -+{ -+ GoaOAuth2ProviderPrivate *priv = goa_oauth2_provider_get_instance_private (self); -+ SecretService *service = NULL; -+ GList *collections = NULL; -+ -+ service = secret_service_get_finish (result, &priv->error); -+ if (service == NULL) -+ goto out; -+ -+ collections = secret_service_get_collections (service); -+ for (const GList *iter = collections; iter != NULL; iter = iter->next) -+ { -+ g_autofree char *label = secret_collection_get_label (iter->data); -+ -+ /* The session collection is an empty string (?) */ -+ if (g_strcmp0 (label, "") == 0) -+ { -+ const char *client_id = NULL; -+ const char *provider_type = NULL; -+ -+ /* Ensure there's no dangling entry */ -+ client_id = goa_oauth2_provider_get_client_id (self); -+ provider_type = goa_provider_get_provider_type (GOA_PROVIDER (self)); -+ secret_password_clear_sync (&oauth2_schema, NULL, NULL, -+ "goa-oauth2-client", client_id, -+ "goa-oauth2-provider", provider_type, -+ NULL); -+ -+ /* Watch the session collection for the requested URI */ -+ priv->session = g_object_ref (iter->data); -+ g_signal_connect_object (priv->session, -+ "notify::items", -+ G_CALLBACK (on_secrets_changed), -+ self, -+ 0); -+ goto out; -+ } -+ } -+ -+ if (priv->session == NULL && priv->error == NULL) -+ { -+ g_set_error (&priv->error, -+ GOA_ERROR, -+ GOA_ERROR_FAILED, -+ "Failed to connect to session keyring"); -+ goto out; -+ } -+ -+out: -+ g_clear_object (&service); -+ g_list_free_full (collections, g_object_unref); -+ g_main_loop_quit (priv->loop); -+} -+ -+static void -+on_continue_in_browser (GtkButton *button, -+ GoaOAuth2Provider *self) -+{ -+ GoaOAuth2ProviderPrivate *priv = goa_oauth2_provider_get_instance_private (self); -+ -+ if (!g_app_info_launch_default_for_uri (priv->request_uri, NULL, &priv->error)) -+ gtk_dialog_response (priv->dialog, GTK_RESPONSE_CANCEL); -+ else -+ gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE); - } - - static gboolean -@@ -906,12 +870,13 @@ get_tokens_and_identity (GoaOAuth2Provider *self, - GtkDialog *dialog, - GtkBox *vbox) - { -- GoaOAuth2ProviderPrivate *priv; -+ GoaOAuth2ProviderPrivate *priv = goa_oauth2_provider_get_instance_private (self); - gboolean ret = FALSE; -- gchar *url; -- GtkWidget *embed; -+ int response_id = GTK_RESPONSE_NONE; - GtkWidget *grid; -- GtkWidget *web_view; -+ GtkWidget *image; -+ GtkWidget *label; -+ GtkWidget *button; - const gchar *scope; - gchar *escaped_redirect_uri = NULL; - gchar *escaped_client_id = NULL; -@@ -923,7 +888,6 @@ get_tokens_and_identity (GoaOAuth2Provider *self, - g_return_val_if_fail (GTK_IS_DIALOG (dialog), FALSE); - g_return_val_if_fail (GTK_IS_BOX (vbox), FALSE); - -- priv = goa_oauth2_provider_get_instance_private (self); - g_return_val_if_fail (priv->error == NULL, FALSE); - - /* TODO: check with NM whether we're online, if not - return error */ -@@ -937,6 +901,8 @@ get_tokens_and_identity (GoaOAuth2Provider *self, - g_clear_pointer (&priv->authorization_code, g_free); - g_clear_pointer (&priv->access_token, g_free); - g_clear_pointer (&priv->refresh_token, g_free); -+ g_clear_pointer (&priv->request_uri, g_free); -+ g_clear_object (&priv->session); - - /* TODO: use oauth2_proxy_build_login_url_full() */ - escaped_redirect_uri = g_uri_escape_string (goa_oauth2_provider_get_redirect_uri (self), NULL, TRUE); -@@ -946,40 +912,71 @@ get_tokens_and_identity (GoaOAuth2Provider *self, - escaped_scope = g_uri_escape_string (goa_oauth2_provider_get_scope (self), NULL, TRUE); - else - escaped_scope = NULL; -- url = goa_oauth2_provider_build_authorization_uri (self, -- goa_oauth2_provider_get_authorization_uri (self), -- escaped_redirect_uri, -- escaped_client_id, -- escaped_scope); -+ priv->request_uri = goa_oauth2_provider_build_authorization_uri (self, -+ goa_oauth2_provider_get_authorization_uri (self), -+ escaped_redirect_uri, -+ escaped_client_id, -+ escaped_scope); - - goa_utils_set_dialog_title (GOA_PROVIDER (self), dialog, add_account); - -- grid = gtk_grid_new (); -- gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL); -- gtk_grid_set_row_spacing (GTK_GRID (grid), 12); -+ grid = g_object_new (GTK_TYPE_BOX, -+ "orientation", GTK_ORIENTATION_VERTICAL, -+ "spacing", 18, -+ "halign", GTK_ALIGN_CENTER, -+ "hexpand", TRUE, -+ "valign", GTK_ALIGN_CENTER, -+ "vexpand", TRUE, -+ "margin", 12, -+ NULL); - gtk_container_add (GTK_CONTAINER (vbox), grid); - -- web_view = goa_web_view_new (GOA_PROVIDER (self), existing_identity); -- gtk_widget_set_hexpand (web_view, TRUE); -- gtk_widget_set_vexpand (web_view, TRUE); -- embed = goa_web_view_get_view (GOA_WEB_VIEW (web_view)); -- -- if (goa_oauth2_provider_get_use_mobile_browser (self)) -- goa_web_view_fake_mobile (GOA_WEB_VIEW (web_view)); -- -- webkit_web_view_load_uri (WEBKIT_WEB_VIEW (embed), url); -- g_signal_connect (embed, -- "decide-policy", -- G_CALLBACK (on_web_view_decide_policy), -- self); -- g_signal_connect (web_view, "deny-click", G_CALLBACK (on_web_view_deny_click), self); -- g_signal_connect (web_view, "password-submit", G_CALLBACK (on_web_view_password_submit), self); -+ image = g_object_new (GTK_TYPE_IMAGE, -+ "icon-name", "web-browser-symbolic", -+ "pixel-size", 128, -+ NULL); -+ gtk_style_context_add_class (gtk_widget_get_style_context (image), "dim-label"); -+ gtk_container_add (GTK_CONTAINER (grid), image); -+ -+ label = gtk_label_new (_("Sign in with your browser to setup an account.")); -+ gtk_style_context_add_class (gtk_widget_get_style_context (label), "heading"); -+ gtk_container_add (GTK_CONTAINER (grid), label); -+ -+ button = gtk_button_new_with_label (_("Continue")); -+ gtk_widget_set_halign (button, GTK_ALIGN_CENTER); -+ gtk_style_context_add_class (gtk_widget_get_style_context (button), "suggested-action"); -+ g_signal_connect_object (button, -+ "clicked", -+ G_CALLBACK (on_continue_in_browser), -+ self, 0); -+ gtk_container_add (GTK_CONTAINER (grid), button); -+ gtk_dialog_add_button (priv->dialog, _("_Cancel"), GTK_RESPONSE_CANCEL); - -- gtk_container_add (GTK_CONTAINER (grid), web_view); -+ gtk_widget_show_all (GTK_WIDGET (vbox)); - gtk_window_set_default_size (GTK_WINDOW (dialog), -1, -1); - -- gtk_widget_show_all (GTK_WIDGET (vbox)); -- gtk_dialog_run (GTK_DIALOG (dialog)); -+ /* Watch the session secret collection for the OAuth2 URI */ -+ secret_service_get (SECRET_SERVICE_LOAD_COLLECTIONS | SECRET_SERVICE_OPEN_SESSION, -+ NULL, -+ (GAsyncReadyCallback) secret_service_get_cb, -+ self); -+ g_main_loop_run (priv->loop); -+ if (priv->error != NULL) -+ goto out; -+ -+ /* Inform the user authentication should be completed in the browser */ -+ response_id = gtk_dialog_run (GTK_DIALOG (dialog)); -+ if (response_id != GTK_RESPONSE_OK) -+ { -+ if (priv->error == NULL) -+ { -+ g_set_error (&priv->error, -+ GOA_ERROR, -+ GOA_ERROR_DIALOG_DISMISSED, -+ _("Dialog was dismissed")); -+ } -+ goto out; -+ } - - /* We can have either the auth code, with which we'll obtain the token, or - * the token directly if we are using a client side flow, since we don't -@@ -1038,12 +1035,14 @@ get_tokens_and_identity (GoaOAuth2Provider *self, - } - - ret = TRUE; -+ gtk_dialog_response (dialog, GTK_RESPONSE_OK); - - out: -- g_free (url); - g_free (escaped_redirect_uri); - g_free (escaped_client_id); - g_free (escaped_scope); -+ g_clear_pointer (&priv->request_uri, g_free); -+ g_clear_object (&priv->session); - return ret; - } - -@@ -1131,6 +1130,7 @@ goa_oauth2_provider_add_account (GoaProvider *provider, - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - priv = goa_oauth2_provider_get_instance_private (self); -+ priv->loop = g_main_loop_new (NULL, FALSE); - - if (!get_tokens_and_identity (self, TRUE, NULL, dialog, vbox)) - goto out; -@@ -1165,7 +1165,6 @@ goa_oauth2_provider_add_account (GoaProvider *provider, - NULL, /* GCancellable* */ - (GAsyncReadyCallback) add_account_cb, - self); -- priv->loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (priv->loop); - if (priv->error != NULL) - goto out; -@@ -1215,6 +1214,7 @@ goa_oauth2_provider_refresh_account (GoaProvider *provider, - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - priv = goa_oauth2_provider_get_instance_private (self); -+ priv->loop = g_main_loop_new (NULL, FALSE); - - dialog = gtk_dialog_new_with_buttons (NULL, - parent, -@@ -1625,6 +1625,8 @@ goa_oauth2_provider_finalize (GObject *object) - g_free (priv->authorization_code); - g_free (priv->access_token); - g_free (priv->refresh_token); -+ g_clear_pointer (&priv->request_uri, g_free); -+ g_clear_object (&priv->session); - - G_OBJECT_CLASS (goa_oauth2_provider_parent_class)->finalize (object); - } -@@ -1650,12 +1652,9 @@ goa_oauth2_provider_class_init (GoaOAuth2ProviderClass *klass) - provider_class->ensure_credentials_sync = goa_oauth2_provider_ensure_credentials_sync; - - klass->build_authorization_uri = goa_oauth2_provider_build_authorization_uri_default; -- klass->decide_navigation_policy = goa_oauth2_provider_decide_navigation_policy_default; - klass->get_token_uri = goa_oauth2_provider_get_token_uri_default; - klass->get_scope = goa_oauth2_provider_get_scope_default; - klass->get_use_mobile_browser = goa_oauth2_provider_get_use_mobile_browser_default; -- klass->is_deny_node = goa_oauth2_provider_is_deny_node_default; -- klass->is_password_node = goa_oauth2_provider_is_password_node_default; - klass->add_account_key_values = goa_oauth2_provider_add_account_key_values_default; - } - -diff --git a/src/goabackend/goaoauthprovider.c b/src/goabackend/goaoauthprovider.c -deleted file mode 100644 -index 71bcad6..0000000 ---- a/src/goabackend/goaoauthprovider.c -+++ /dev/null -@@ -1,1662 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2011 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#include "config.h" --#include --#include -- --#include --#include --#include --#include -- --#include "goaprovider.h" --#include "goautils.h" --#include "goawebview.h" --#include "goaoauthprovider.h" --#include "goasouplogger.h" -- --/** -- * SECTION:goaoauthprovider -- * @title: GoaOAuthProvider -- * @short_description: Abstract base class for OAuth 1.0a providers -- * -- * #GoaOAuthProvider is an abstract base class for OAuth 1.0a -- * compliant implementations as defined by RFC -- * 5849. Additionally, the code works with providers -- * implementing OAuth -- * Session 1.0 Draft 1 for refreshing access tokens. -- * -- * Subclasses must implement -- * #GoaOAuthProviderClass.get_consumer_key, -- * #GoaOAuthProviderClass.get_consumer_secret, -- * #GoaOAuthProviderClass.get_request_uri, -- * #GoaOAuthProviderClass.get_authorization_uri, -- * #GoaOAuthProviderClass.get_token_uri, -- * #GoaOAuthProviderClass.get_callback_uri and -- * #GoaOAuthProviderClass.get_identity_sync methods. -- * -- * Additionally, the -- * #GoaProviderClass.get_provider_type, -- * #GoaProviderClass.get_provider_name, -- * #GoaProviderClass.build_object (this should chain up to its -- * parent class) methods must be implemented. -- * -- * Note that the #GoaProviderClass.add_account, -- * #GoaProviderClass.refresh_account and -- * #GoaProviderClass.ensure_credentials_sync methods do not -- * need to be implemented - this type implements these methods. -- */ -- --G_LOCK_DEFINE_STATIC (provider_lock); -- --G_DEFINE_ABSTRACT_TYPE (GoaOAuthProvider, goa_oauth_provider, GOA_TYPE_PROVIDER); -- --static gboolean --is_authorization_error (GError *error) --{ -- gboolean ret; -- -- g_return_val_if_fail (error != NULL, FALSE); -- -- ret = FALSE; -- if (error->domain == REST_PROXY_ERROR || error->domain == SOUP_HTTP_ERROR) -- { -- if (SOUP_STATUS_IS_CLIENT_ERROR (error->code)) -- ret = TRUE; -- } -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --goa_oauth_provider_get_use_mobile_browser_default (GoaOAuthProvider *provider) --{ -- return FALSE; --} -- --/** -- * goa_oauth_provider_get_use_mobile_browser: -- * @provider: A #GoaOAuthProvider. -- * -- * Returns whether there is a need for the embedded browser to identify -- * itself as running on a mobile phone in order to get a more compact -- * version of the approval page. -- * -- * This is a virtual method where the default implementation returns -- * %FALSE. -- * -- * Returns: %TRUE if the embedded browser should identify itself as -- * running on a mobile platform, %FALSE otherwise. -- */ --gboolean --goa_oauth_provider_get_use_mobile_browser (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_use_mobile_browser (provider); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --goa_oauth_provider_is_deny_node_default (GoaOAuthProvider *provider, WebKitDOMNode *node) --{ -- return FALSE; --} -- --/** -- * goa_oauth_provider_is_deny_node: -- * @provider: A #GoaOAuthProvider. -- * @node: A WebKitDOMNode. -- * -- * Checks whether @node is the HTML UI element that the user can use -- * to deny permission to access his account. Usually they are either a -- * WebKitDOMHTMLButtonElement or a WebKitDOMHTMLInputElement. -- * -- * Please note that providers may have multiple such elements in their -- * UI and this method should catch all of them. -- * -- * This is a virtual method where the default implementation returns -- * %FALSE. -- * -- * Returns: %TRUE if the @node can be used to deny permission. -- */ --gboolean --goa_oauth_provider_is_deny_node (GoaOAuthProvider *provider, WebKitDOMNode *node) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->is_deny_node (provider, node); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --goa_oauth_provider_is_password_node_default (GoaOAuthProvider *provider, WebKitDOMHTMLInputElement *element) --{ -- return FALSE; --} -- --/** -- * goa_oauth_provider_is_password_node: -- * @provider: A #GoaOAuthProvider. -- * @element: A WebKitDOMHTMLInputElement -- * -- * Checks whether @element is the HTML UI element that the user can -- * use to enter her password. This can be used to offer a -- * #GoaPasswordBased interface by saving the user's -- * password. Providers usually frown upon doing this, so this is not -- * recommended. -- * -- * This is a virtual method where the default implementation returns -- * %FALSE. -- * -- * Returns: %TRUE if @element can be used to enter the password. -- */ --gboolean --goa_oauth_provider_is_password_node (GoaOAuthProvider *provider, WebKitDOMHTMLInputElement *element) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE); -- g_return_val_if_fail (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element), FALSE); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->is_password_node (provider, element); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static void --goa_oauth_provider_add_account_key_values_default (GoaOAuthProvider *provider, -- GVariantBuilder *builder) --{ -- /* do nothing */ --} -- --/** -- * goa_oauth_provider_add_account_key_values: -- * @provider: A #GoaProvider. -- * @builder: A #GVariantBuilder for a a{ss} variant. -- * -- * Hook for implementations to add key/value pairs to the key-file -- * when creating an account. -- * -- * This is a virtual method where the default implementation does nothing. -- */ --void --goa_oauth_provider_add_account_key_values (GoaOAuthProvider *provider, -- GVariantBuilder *builder) --{ -- g_return_if_fail (GOA_IS_OAUTH_PROVIDER (provider)); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->add_account_key_values (provider, builder); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gchar * --goa_oauth_provider_build_authorization_uri_default (GoaOAuthProvider *provider, -- const gchar *authorization_uri, -- const gchar *escaped_oauth_token) --{ -- return g_strdup_printf ("%s" -- "?oauth_token=%s", -- authorization_uri, -- escaped_oauth_token); --} -- --/** -- * goa_oauth_provider_build_authorization_uri: -- * @provider: A #GoaOAuthProvider. -- * @authorization_uri: An authorization URI. -- * @escaped_oauth_token: An escaped oauth token. -- * -- * Builds the URI that can be opened in a web browser (or embedded web -- * browser widget) to start authenticating an user. -- * -- * The default implementation just returns the expected URI -- * (e.g. http://example.com/dialog/oauth?auth_token=1234567890) -- * - override (and chain up) if you e.g. need to to pass additional -- * parameters. -- * -- * The @authorization_uri parameter originate from the result of the -- * the goa_oauth_provider_get_authorization_uri() method. The -- * @escaped_oauth_token parameter is the temporary credentials identifier -- * escaped using g_uri_escape_string(). -- * -- * Returns: (transfer full): An authorization URI that must be freed with g_free(). -- */ --gchar * --goa_oauth_provider_build_authorization_uri (GoaOAuthProvider *provider, -- const gchar *authorization_uri, -- const gchar *escaped_oauth_token) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- g_return_val_if_fail (authorization_uri != NULL, NULL); -- g_return_val_if_fail (escaped_oauth_token != NULL, NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->build_authorization_uri (provider, -- authorization_uri, -- escaped_oauth_token); --} -- --/** -- * goa_oauth_provider_get_consumer_key: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets the consumer key identifying the client. -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: (transfer none): A string owned by @provider - do not free. -- */ --const gchar * --goa_oauth_provider_get_consumer_key (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_consumer_key (provider); --} -- --/** -- * goa_oauth_provider_get_consumer_secret: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets the consumer secret identifying the client. -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: (transfer none): A string owned by @provider - do not free. -- */ --const gchar * --goa_oauth_provider_get_consumer_secret (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_consumer_secret (provider); --} -- --/** -- * goa_oauth_provider_get_request_uri: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets the request uri. -- * -- * http://tools.ietf.org/html/rfc5849#section-2.1 -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: (transfer none): A string owned by @provider - do not free. -- */ --const gchar * --goa_oauth_provider_get_request_uri (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_request_uri (provider); --} -- --/** -- * goa_oauth_provider_get_request_uri_params: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets additional parameters for the request URI. -- * -- * http://tools.ietf.org/html/rfc5849#section-2.1 -- * -- * This is a virtual method where the default implementation returns -- * %NULL. -- * -- * Returns: (transfer full): %NULL (for no parameters) or a -- * %NULL-terminated array of (key, value) pairs that will be added to -- * the URI. The caller will free the returned value with g_strfreev(). -- */ --gchar ** --goa_oauth_provider_get_request_uri_params (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_request_uri_params (provider); --} -- --static gchar ** --goa_oauth_provider_get_request_uri_params_default (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return NULL; --} -- --/** -- * goa_oauth_provider_get_authorization_uri: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets the authorization uri. -- * -- * http://tools.ietf.org/html/rfc5849#section-2.2 -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: (transfer none): A string owned by @provider - do not free. -- */ --const gchar * --goa_oauth_provider_get_authorization_uri (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_authorization_uri (provider); --} -- --/** -- * goa_oauth_provider_get_token_uri: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets the token uri. -- * -- * http://tools.ietf.org/html/rfc5849#section-2.3 -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: (transfer none): A string owned by @provider - do not free. -- */ --const gchar * --goa_oauth_provider_get_token_uri (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_token_uri (provider); --} -- --/** -- * goa_oauth_provider_get_callback_uri: -- * @provider: A #GoaOAuthProvider. -- * -- * Gets the callback uri. -- * -- * http://tools.ietf.org/html/rfc5849#section-2.1 -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: (transfer none): A string owned by @provider - do not free. -- */ --const gchar * --goa_oauth_provider_get_callback_uri (GoaOAuthProvider *provider) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_callback_uri (provider); --} -- --/** -- * goa_oauth_provider_get_identity_sync: -- * @provider: A #GoaOAuthProvider. -- * @access_token: A valid OAuth 1.0 access token. -- * @access_token_secret: The valid secret for @access_token. -- * @out_presentation_identity: (out): Return location for presentation identity or %NULL. -- * @cancellable: (allow-none): A #GCancellable or %NULL. -- * @error: Return location for error or %NULL. -- * -- * Method that returns the identity corresponding to @access_token and -- * @access_token_secret. -- * -- * The identity is needed because all authentication happens out of -- * band. In addition to the identity, an implementation also returns a -- * presentation identity that is more suitable -- * for presentation (the identity could be a GUID for example). -- * -- * The calling thread is blocked while the identity is obtained. -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: The identity or %NULL if error is set. The returned string -- * must be freed with g_free(). -- */ --gchar * --goa_oauth_provider_get_identity_sync (GoaOAuthProvider *provider, -- const gchar *access_token, -- const gchar *access_token_secret, -- gchar **out_presentation_identity, -- GCancellable *cancellable, -- GError **error) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- g_return_val_if_fail (access_token != NULL, NULL); -- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); -- g_return_val_if_fail (error == NULL || *error == NULL, NULL); -- -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->get_identity_sync (provider, -- access_token, -- access_token_secret, -- out_presentation_identity, -- cancellable, -- error); --} -- --/** -- * goa_oauth_provider_is_identity_node: -- * @provider: A #GoaOAuthProvider. -- * @element: A WebKitDOMHTMLInputElement. -- * -- * Checks whether @element is the HTML UI element that the user can -- * use to identify herself at the provider. -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: %TRUE if the @element can be used to deny permission. -- */ --gboolean --goa_oauth_provider_is_identity_node (GoaOAuthProvider *provider, WebKitDOMHTMLInputElement *element) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->is_identity_node (provider, element); --} -- --/** -- * goa_oauth_provider_parse_request_token_error: -- * @provider: A #GoaOAuthProvider. -- * @call: The #RestProxyCall that was used to fetch the request token. -- * -- * Tries to parse the headers and payload within @call to provide a -- * human readable error message in case the request token could not -- * be fetched. -- * -- * This is a pure virtual method - a subclass must provide an -- * implementation. -- * -- * Returns: A human readable error message or %NULL if the cause of the -- * error could not be determined. The returned string must be freed with -- * g_free(). -- */ --gchar * --goa_oauth_provider_parse_request_token_error (GoaOAuthProvider *provider, RestProxyCall *call) --{ -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->parse_request_token_error (provider, call); --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gchar * --get_tokens_sync (GoaOAuthProvider *provider, -- const gchar *token, -- const gchar *token_secret, -- const gchar *session_handle, /* may be NULL */ -- const gchar *verifier, /* may be NULL */ -- gchar **out_access_token_secret, -- gint *out_access_token_expires_in, -- gchar **out_session_handle, -- gint *out_session_handle_expires_in, -- GCancellable *cancellable, -- GError **error) --{ -- RestProxy *proxy; -- RestProxyCall *call; -- SoupLogger *logger = NULL; -- gchar *ret = NULL; -- guint status_code; -- GHashTable *f; -- const gchar *expires_in_str; -- gchar *ret_access_token = NULL; -- gchar *ret_access_token_secret = NULL; -- gint ret_access_token_expires_in = 0; -- gchar *ret_session_handle = NULL; -- gint ret_session_handle_expires_in = 0; -- -- proxy = oauth_proxy_new (goa_oauth_provider_get_consumer_key (provider), -- goa_oauth_provider_get_consumer_secret (provider), -- goa_oauth_provider_get_token_uri (provider), -- FALSE); -- logger = goa_soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); -- rest_proxy_add_soup_feature (proxy, SOUP_SESSION_FEATURE (logger)); -- oauth_proxy_set_token (OAUTH_PROXY (proxy), token); -- oauth_proxy_set_token_secret (OAUTH_PROXY (proxy), token_secret); -- call = rest_proxy_new_call (proxy); -- rest_proxy_call_set_method (call, "POST"); -- if (verifier != NULL) -- rest_proxy_call_add_param (call, "oauth_verifier", verifier); -- if (session_handle != NULL) -- rest_proxy_call_add_param (call, "oauth_session_handle", session_handle); -- /* TODO: cancellable support? */ -- if (!rest_proxy_call_sync (call, error)) -- goto out; -- -- status_code = rest_proxy_call_get_status_code (call); -- if (status_code != 200) -- { -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- /* Translators: the %d is a HTTP status code and the %s is a textual description of it */ -- _("Expected status 200 when requesting access token, instead got status %d (%s)"), -- status_code, -- rest_proxy_call_get_status_message (call)); -- goto out; -- } -- -- f = soup_form_decode (rest_proxy_call_get_payload (call)); -- ret_access_token = g_strdup (g_hash_table_lookup (f, "oauth_token")); -- ret_access_token_secret = g_strdup (g_hash_table_lookup (f, "oauth_token_secret")); -- ret_session_handle = g_strdup (g_hash_table_lookup (f, "oauth_session_handle")); -- expires_in_str = g_hash_table_lookup (f, "oauth_expires_in"); -- if (expires_in_str != NULL) -- ret_access_token_expires_in = atoi (expires_in_str); -- expires_in_str = g_hash_table_lookup (f, "oauth_authorization_expires_in"); -- if (expires_in_str != NULL) -- ret_session_handle_expires_in = atoi (expires_in_str); -- g_hash_table_unref (f); -- -- if (ret_access_token == NULL || ret_access_token_secret == NULL) -- { -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Missing access_token or access_token_secret headers in response")); -- goto out; -- } -- -- ret = ret_access_token; ret_access_token = NULL; -- if (out_access_token_secret != NULL) -- { -- *out_access_token_secret = ret_access_token_secret; -- ret_access_token_secret = NULL; -- } -- if (out_access_token_expires_in != NULL) -- *out_access_token_expires_in = ret_access_token_expires_in; -- if (out_session_handle != NULL) -- { -- *out_session_handle = ret_session_handle; -- ret_session_handle = NULL; -- } -- if (out_session_handle_expires_in != NULL) -- *out_session_handle_expires_in = ret_session_handle_expires_in; -- -- out: -- g_free (ret_access_token); -- g_free (ret_access_token_secret); -- g_free (ret_session_handle); -- g_clear_object (&call); -- g_clear_object (&proxy); -- g_clear_object (&logger); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --typedef struct --{ -- GoaOAuthProvider *provider; -- GtkDialog *dialog; -- GError *error; -- GMainLoop *loop; -- -- gchar *password; -- -- gchar *oauth_verifier; -- -- const gchar *existing_identity; -- -- gchar *identity; -- gchar *presentation_identity; -- -- gchar *request_token; -- gchar *request_token_secret; -- gchar *access_token; -- gchar *access_token_secret; -- gint access_token_expires_in; -- gchar *session_handle; -- gint session_handle_expires_in; --} IdentifyData; -- --static void --on_web_view_deny_click (GoaWebView *web_view, gpointer user_data) --{ -- IdentifyData *data = user_data; -- gtk_dialog_response (data->dialog, GTK_RESPONSE_CANCEL); --} -- --static void --on_web_view_password_submit (GoaWebView *web_view, const gchar *password, gpointer user_data) --{ -- IdentifyData *data = user_data; -- -- g_free (data->password); -- data->password = g_strdup (password); --} -- --static gboolean --on_web_view_decide_policy (WebKitWebView *web_view, -- WebKitPolicyDecision *decision, -- WebKitPolicyDecisionType decision_type, -- gpointer user_data) --{ -- GHashTable *key_value_pairs; -- IdentifyData *data = user_data; -- SoupURI *uri; -- WebKitNavigationAction *action; -- WebKitURIRequest *request; -- const gchar *query; -- const gchar *redirect_uri; -- const gchar *requested_uri; -- gint response_id = GTK_RESPONSE_NONE; -- -- if (decision_type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION) -- return FALSE; -- -- /* TODO: use oauth_proxy_extract_access_token() */ -- -- action = webkit_navigation_policy_decision_get_navigation_action (WEBKIT_NAVIGATION_POLICY_DECISION (decision)); -- request = webkit_navigation_action_get_request (action); -- requested_uri = webkit_uri_request_get_uri (request); -- redirect_uri = goa_oauth_provider_get_callback_uri (data->provider); -- -- if (!g_str_has_prefix (requested_uri, redirect_uri)) -- goto default_behaviour; -- -- uri = soup_uri_new (requested_uri); -- query = soup_uri_get_query (uri); -- -- if (query != NULL) -- { -- key_value_pairs = soup_form_decode (query); -- -- data->oauth_verifier = g_strdup (g_hash_table_lookup (key_value_pairs, "oauth_verifier")); -- if (data->oauth_verifier != NULL) -- response_id = GTK_RESPONSE_OK; -- -- g_hash_table_unref (key_value_pairs); -- } -- -- if (data->oauth_verifier != NULL) -- goto ignore_request; -- -- /* TODO: The only OAuth1 provider is Flickr. It doesn't send any -- * error code and only redirects to the URI specified in the Flickr -- * App Garden. Re-evaluate when the situation changes. -- */ -- response_id = GTK_RESPONSE_CANCEL; -- goto ignore_request; -- -- ignore_request: -- g_assert (response_id != GTK_RESPONSE_NONE); -- gtk_dialog_response (data->dialog, response_id); -- webkit_policy_decision_ignore (decision); -- return TRUE; -- -- default_behaviour: -- return FALSE; --} -- --static void --rest_proxy_call_cb (RestProxyCall *call, const GError *error, GObject *weak_object, gpointer user_data) --{ -- IdentifyData *data = user_data; -- g_main_loop_quit (data->loop); --} -- --static gboolean --get_tokens_and_identity (GoaOAuthProvider *provider, -- gboolean add_account, -- const gchar *existing_identity, -- GtkDialog *dialog, -- GtkBox *vbox, -- gchar **out_access_token, -- gchar **out_access_token_secret, -- gint *out_access_token_expires_in, -- gchar **out_session_handle, -- gint *out_session_handle_expires_in, -- gchar **out_identity, -- gchar **out_presentation_identity, -- gchar **out_password, -- GError **error) --{ -- gboolean ret = FALSE; -- gchar *url = NULL; -- IdentifyData data; -- gchar *escaped_request_token = NULL; -- RestProxy *proxy = NULL; -- RestProxyCall *call = NULL; -- SoupLogger *logger = NULL; -- GHashTable *f; -- GtkWidget *embed; -- GtkWidget *grid; -- GtkWidget *spinner; -- GtkWidget *web_view; -- gchar **request_params = NULL; -- guint n; -- -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE); -- g_return_val_if_fail ((!add_account && existing_identity != NULL && existing_identity[0] != '\0') -- || (add_account && existing_identity == NULL), FALSE); -- g_return_val_if_fail (GTK_IS_DIALOG (dialog), FALSE); -- g_return_val_if_fail (GTK_IS_BOX (vbox), FALSE); -- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); -- -- /* TODO: check with NM whether we're online, if not - return error */ -- -- memset (&data, '\0', sizeof (IdentifyData)); -- data.provider = provider; -- data.dialog = dialog; -- data.loop = g_main_loop_new (NULL, FALSE); -- data.existing_identity = existing_identity; -- -- proxy = oauth_proxy_new (goa_oauth_provider_get_consumer_key (provider), -- goa_oauth_provider_get_consumer_secret (provider), -- goa_oauth_provider_get_request_uri (provider), FALSE); -- logger = goa_soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); -- rest_proxy_add_soup_feature (proxy, SOUP_SESSION_FEATURE (logger)); -- -- call = rest_proxy_new_call (proxy); -- rest_proxy_call_set_method (call, "POST"); -- rest_proxy_call_add_param (call, "oauth_callback", goa_oauth_provider_get_callback_uri (provider)); -- -- request_params = goa_oauth_provider_get_request_uri_params (provider); -- if (request_params != NULL) -- { -- g_assert (g_strv_length (request_params) % 2 == 0); -- for (n = 0; request_params[n] != NULL; n += 2) -- rest_proxy_call_add_param (call, request_params[n], request_params[n+1]); -- } -- if (!rest_proxy_call_async (call, rest_proxy_call_cb, NULL, &data, &data.error)) -- { -- g_prefix_error (&data.error, _("Error getting a Request Token: ")); -- goto out; -- } -- -- goa_utils_set_dialog_title (GOA_PROVIDER (provider), dialog, add_account); -- -- grid = gtk_grid_new (); -- gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL); -- gtk_grid_set_row_spacing (GTK_GRID (grid), 12); -- gtk_container_add (GTK_CONTAINER (vbox), grid); -- -- spinner = gtk_spinner_new (); -- gtk_widget_set_hexpand (spinner, TRUE); -- gtk_widget_set_halign (spinner, GTK_ALIGN_CENTER); -- gtk_widget_set_vexpand (spinner, TRUE); -- gtk_widget_set_valign (spinner, GTK_ALIGN_CENTER); -- gtk_widget_set_size_request (GTK_WIDGET (spinner), 24, 24); -- gtk_spinner_start (GTK_SPINNER (spinner)); -- gtk_container_add (GTK_CONTAINER (grid), spinner); -- gtk_widget_show_all (GTK_WIDGET (vbox)); -- -- g_main_loop_run (data.loop); -- gtk_container_remove (GTK_CONTAINER (grid), spinner); -- -- if (rest_proxy_call_get_status_code (call) != 200) -- { -- gchar *msg; -- -- msg = goa_oauth_provider_parse_request_token_error (provider, call); -- if (msg == NULL) -- /* Translators: the %d is a HTTP status code and the %s is a textual description of it */ -- msg = g_strdup_printf (_("Expected status 200 for getting a Request Token, instead got status %d (%s)"), -- rest_proxy_call_get_status_code (call), -- rest_proxy_call_get_status_message (call)); -- -- g_set_error_literal (&data.error, GOA_ERROR, GOA_ERROR_FAILED, msg); -- g_free (msg); -- goto out; -- } -- f = soup_form_decode (rest_proxy_call_get_payload (call)); -- data.request_token = g_strdup (g_hash_table_lookup (f, "oauth_token")); -- data.request_token_secret = g_strdup (g_hash_table_lookup (f, "oauth_token_secret")); -- g_hash_table_unref (f); -- if (data.request_token == NULL || data.request_token_secret == NULL) -- { -- g_set_error (&data.error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Missing request_token or request_token_secret headers in response")); -- goto out; -- } -- -- escaped_request_token = g_uri_escape_string (data.request_token, NULL, TRUE); -- url = goa_oauth_provider_build_authorization_uri (provider, -- goa_oauth_provider_get_authorization_uri (provider), -- escaped_request_token); -- -- web_view = goa_web_view_new (GOA_PROVIDER (provider), existing_identity); -- gtk_widget_set_hexpand (web_view, TRUE); -- gtk_widget_set_vexpand (web_view, TRUE); -- embed = goa_web_view_get_view (GOA_WEB_VIEW (web_view)); -- -- if (goa_oauth_provider_get_use_mobile_browser (provider)) -- goa_web_view_fake_mobile (GOA_WEB_VIEW (web_view)); -- -- webkit_web_view_load_uri (WEBKIT_WEB_VIEW (embed), url); -- g_signal_connect (embed, -- "decide-policy", -- G_CALLBACK (on_web_view_decide_policy), -- &data); -- g_signal_connect (web_view, "deny-click", G_CALLBACK (on_web_view_deny_click), &data); -- g_signal_connect (web_view, "password-submit", G_CALLBACK (on_web_view_password_submit), &data); -- -- gtk_container_add (GTK_CONTAINER (grid), web_view); -- gtk_window_set_default_size (GTK_WINDOW (dialog), -1, -1); -- -- gtk_widget_show_all (GTK_WIDGET (vbox)); -- gtk_dialog_run (GTK_DIALOG (dialog)); -- -- if (data.oauth_verifier == NULL) -- { -- if (data.error == NULL) -- { -- g_set_error (&data.error, -- GOA_ERROR, -- GOA_ERROR_DIALOG_DISMISSED, -- _("Dialog was dismissed")); -- } -- goto out; -- } -- g_assert (data.error == NULL); -- -- /* OK, we are done interacting with the user ... but before we can -- * make up our mind, there are two more RPC calls to make and these -- * call may take some time. So hide the dialog immediately. -- */ -- gtk_widget_hide (GTK_WIDGET (dialog)); -- -- /* OK, we now have the request token... we can exchange that for a -- * (short-lived) access token and session_handle (used to refresh the -- * access token).. -- */ -- -- /* TODO: run in worker thread */ -- data.access_token = get_tokens_sync (provider, -- data.request_token, -- data.request_token_secret, -- NULL, /* session_handle */ -- data.oauth_verifier, -- &data.access_token_secret, -- &data.access_token_expires_in, -- &data.session_handle, -- &data.session_handle_expires_in, -- NULL, /* GCancellable */ -- &data.error); -- if (data.access_token == NULL) -- { -- g_prefix_error (&data.error, _("Error getting an Access Token: ")); -- goto out; -- } -- -- /* TODO: run in worker thread */ -- data.identity = goa_oauth_provider_get_identity_sync (provider, -- data.access_token, -- data.access_token_secret, -- &data.presentation_identity, -- NULL, /* TODO: GCancellable */ -- &data.error); -- if (data.identity == NULL) -- { -- g_prefix_error (&data.error, _("Error getting identity: ")); -- goto out; -- } -- -- ret = TRUE; -- -- out: -- g_clear_object (&call); -- -- if (ret) -- { -- g_warn_if_fail (data.error == NULL); -- if (out_access_token != NULL) -- *out_access_token = g_strdup (data.access_token); -- if (out_access_token_secret != NULL) -- *out_access_token_secret = g_strdup (data.access_token_secret); -- if (out_access_token_expires_in != NULL) -- *out_access_token_expires_in = data.access_token_expires_in; -- if (out_session_handle != NULL) -- *out_session_handle = g_strdup (data.session_handle); -- if (out_session_handle_expires_in != NULL) -- *out_session_handle_expires_in = data.session_handle_expires_in; -- if (out_identity != NULL) -- *out_identity = g_strdup (data.identity); -- if (out_presentation_identity != NULL) -- *out_presentation_identity = g_strdup (data.presentation_identity); -- if (out_password != NULL) -- *out_password = g_strdup (data.password); -- } -- else -- { -- g_warn_if_fail (data.error != NULL); -- g_propagate_error (error, data.error); -- } -- -- g_free (data.password); -- g_free (data.presentation_identity); -- g_free (data.identity); -- g_free (url); -- -- g_free (data.oauth_verifier); -- g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); -- g_free (data.access_token); -- g_free (data.access_token_secret); -- g_free (escaped_request_token); -- -- g_free (data.request_token); -- g_free (data.request_token_secret); -- -- g_strfreev (request_params); -- g_clear_object (&proxy); -- g_clear_object (&logger); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --typedef struct --{ -- GError *error; -- GMainLoop *loop; -- gchar *account_object_path; --} AddData; -- --static void --add_account_cb (GoaManager *manager, -- GAsyncResult *res, -- gpointer user_data) --{ -- AddData *data = user_data; -- goa_manager_call_add_account_finish (manager, -- &data->account_object_path, -- res, -- &data->error); -- g_main_loop_quit (data->loop); --} -- --static gint64 --duration_to_abs_usec (gint duration_sec) --{ -- gint64 ret; -- GTimeVal now; -- -- g_get_current_time (&now); -- ret = ((gint64) now.tv_sec) * 1000L * 1000L + ((gint64) now.tv_usec); -- ret += ((gint64) duration_sec) * 1000L * 1000L; -- return ret; --} -- --static gint --abs_usec_to_duration (gint64 abs_usec) --{ -- gint64 ret; -- GTimeVal now; -- -- g_get_current_time (&now); -- ret = abs_usec - (((gint64) now.tv_sec) * 1000L * 1000L + ((gint64) now.tv_usec)); -- ret /= 1000L * 1000L; -- return ret; --} -- --static GoaObject * --goa_oauth_provider_add_account (GoaProvider *_provider, -- GoaClient *client, -- GtkDialog *dialog, -- GtkBox *vbox, -- GError **error) --{ -- GoaOAuthProvider *provider = GOA_OAUTH_PROVIDER (_provider); -- GoaObject *ret = NULL; -- gchar *access_token = NULL; -- gchar *access_token_secret = NULL; -- gint access_token_expires_in; -- gchar *session_handle = NULL; -- gint session_handle_expires_in; -- gchar *identity = NULL; -- gchar *presentation_identity = NULL; -- gchar *password = NULL; -- AddData data; -- GVariantBuilder credentials; -- GVariantBuilder details; -- -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- g_return_val_if_fail (GOA_IS_CLIENT (client), NULL); -- g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL); -- g_return_val_if_fail (GTK_IS_BOX (vbox), NULL); -- g_return_val_if_fail (error == NULL || *error == NULL, NULL); -- -- memset (&data, '\0', sizeof (AddData)); -- data.loop = g_main_loop_new (NULL, FALSE); -- -- if (!get_tokens_and_identity (provider, -- TRUE, -- NULL, -- dialog, -- vbox, -- &access_token, -- &access_token_secret, -- &access_token_expires_in, -- &session_handle, -- &session_handle_expires_in, -- &identity, -- &presentation_identity, -- &password, -- &data.error)) -- goto out; -- -- /* OK, got the identity... see if there's already an account -- * of this type with the given identity -- */ -- if (!goa_utils_check_duplicate (client, -- identity, -- presentation_identity, -- goa_provider_get_provider_type (GOA_PROVIDER (provider)), -- (GoaPeekInterfaceFunc) goa_object_peek_oauth_based, -- &data.error)) -- goto out; -- -- g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT); -- g_variant_builder_add (&credentials, "{sv}", "access_token", g_variant_new_string (access_token)); -- g_variant_builder_add (&credentials, "{sv}", "access_token_secret", g_variant_new_string (access_token_secret)); -- if (access_token_expires_in > 0) -- g_variant_builder_add (&credentials, "{sv}", "access_token_expires_at", -- g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in))); -- if (session_handle != NULL) -- g_variant_builder_add (&credentials, "{sv}", "session_handle", g_variant_new_string (session_handle)); -- if (session_handle_expires_in > 0) -- g_variant_builder_add (&credentials, "{sv}", "session_handle_expires_at", -- g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in))); -- if (password != NULL) -- g_variant_builder_add (&credentials, "{sv}", "password", g_variant_new_string (password)); -- -- g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); -- goa_oauth_provider_add_account_key_values (provider, &details); -- -- /* we want the GoaClient to update before this method returns (so it -- * can create a proxy for the new object) so run the mainloop while -- * waiting for this to complete -- */ -- goa_manager_call_add_account (goa_client_get_manager (client), -- goa_provider_get_provider_type (GOA_PROVIDER (provider)), -- identity, -- presentation_identity, -- g_variant_builder_end (&credentials), -- g_variant_builder_end (&details), -- NULL, /* GCancellable* */ -- (GAsyncReadyCallback) add_account_cb, -- &data); -- g_main_loop_run (data.loop); -- if (data.error != NULL) -- goto out; -- -- ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client), -- data.account_object_path)); -- -- out: -- /* We might have an object even when data.error is set. -- * eg., if we failed to store the credentials in the keyring. -- */ -- if (data.error != NULL) -- g_propagate_error (error, data.error); -- else -- g_assert (ret != NULL); -- -- g_free (identity); -- g_free (presentation_identity); -- g_free (password); -- g_free (access_token); -- g_free (access_token_secret); -- g_free (session_handle); -- g_free (data.account_object_path); -- g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --goa_oauth_provider_refresh_account (GoaProvider *_provider, -- GoaClient *client, -- GoaObject *object, -- GtkWindow *parent, -- GError **error) --{ -- GoaOAuthProvider *provider = GOA_OAUTH_PROVIDER (_provider); -- GoaAccount *account; -- GtkWidget *dialog; -- gchar *access_token = NULL; -- gchar *access_token_secret = NULL; -- gchar *password = NULL; -- gint access_token_expires_in; -- gchar *session_handle = NULL; -- gint session_handle_expires_in; -- gchar *identity = NULL; -- const gchar *existing_identity; -- const gchar *existing_presentation_identity; -- GVariantBuilder builder; -- gboolean ret = FALSE; -- -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE); -- g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE); -- g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE); -- g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE); -- g_return_val_if_fail (error == NULL || *error == NULL, FALSE); -- -- dialog = gtk_dialog_new_with_buttons (NULL, -- parent, -- GTK_DIALOG_MODAL -- | GTK_DIALOG_DESTROY_WITH_PARENT -- | GTK_DIALOG_USE_HEADER_BAR, -- NULL, -- NULL); -- gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); -- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); -- gtk_widget_show_all (dialog); -- -- account = goa_object_peek_account (object); -- -- /* We abuse presentation identity here because for some providers -- * identity can be a machine readable ID, which can not be used to -- * log in via the provider's web interface. -- */ -- existing_presentation_identity = goa_account_get_presentation_identity (account); -- if (!get_tokens_and_identity (provider, -- FALSE, -- existing_presentation_identity, -- GTK_DIALOG (dialog), -- GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), -- &access_token, -- &access_token_secret, -- &access_token_expires_in, -- &session_handle, -- &session_handle_expires_in, -- &identity, -- NULL, /* out_presentation_identity */ -- &password, -- error)) -- goto out; -- -- /* Changes made to the web interface by the providers can break our -- * DOM parsing. So we should still query and check the identity -- * afterwards. -- */ -- existing_identity = goa_account_get_identity (account); -- if (g_strcmp0 (identity, existing_identity) != 0) -- { -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_FAILED, -- _("Was asked to log in as %s, but logged in as %s"), -- existing_identity, -- identity); -- goto out; -- } -- -- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); -- g_variant_builder_add (&builder, "{sv}", "access_token", g_variant_new_string (access_token)); -- g_variant_builder_add (&builder, "{sv}", "access_token_secret", g_variant_new_string (access_token_secret)); -- if (access_token_expires_in > 0) -- g_variant_builder_add (&builder, "{sv}", "access_token_expires_at", -- g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in))); -- if (session_handle != NULL) -- g_variant_builder_add (&builder, "{sv}", "session_handle", g_variant_new_string (session_handle)); -- if (session_handle_expires_in > 0) -- g_variant_builder_add (&builder, "{sv}", "session_handle_expires_at", -- g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in))); -- if (password != NULL) -- g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password)); -- /* TODO: run in worker thread */ -- if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider), -- object, -- g_variant_builder_end (&builder), -- NULL, /* GCancellable */ -- error)) -- goto out; -- -- goa_account_call_ensure_credentials (goa_object_peek_account (object), -- NULL, /* GCancellable */ -- NULL, NULL); /* callback, user_data */ -- -- ret = TRUE; -- -- out: -- gtk_widget_destroy (dialog); -- -- g_free (identity); -- g_free (access_token); -- g_free (access_token_secret); -- g_free (password); -- g_free (session_handle); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static void --free_mutex (GMutex *mutex) --{ -- g_mutex_clear (mutex); -- g_slice_free (GMutex, mutex); --} -- --/** -- * goa_oauth_provider_get_access_token_sync: -- * @provider: A #GoaOAuthProvider. -- * @object: A #GoaObject. -- * @force_refresh: If set to %TRUE, forces a refresh of the access token, if possible. -- * @out_access_token_secret: (out): The secret for the return access token. -- * @out_access_token_expires_in: (out): Return location for how many seconds the returned token is valid for (0 if unknown) or %NULL. -- * @cancellable: (allow-none): A #GCancellable or %NULL. -- * @error: Return location for error or %NULL. -- * -- * Synchronously gets an access token for @object. The calling thread -- * is blocked while the operation is pending. -- * -- * The resulting token is typically read from the local cache so most -- * of the time only a local roundtrip to the storage for the token -- * cache (e.g. gnome-keyring-daemon) is -- * needed. However, the operation may involve refreshing the token -- * with the service provider so a full network round-trip may be -- * needed. -- * -- * Note that multiple calls are serialized to avoid multiple -- * outstanding requests to the service provider. -- * -- * This operation may fail if e.g. unable to refresh the credentials -- * or if network connectivity is not available. Note that even if a -- * token is returned, the returned token isn't guaranteed to work - -- * use goa_provider_ensure_credentials_sync() if you need -- * stronger guarantees. -- * -- * Returns: The access token or %NULL if error is set. The returned -- * string must be freed with g_free(). -- */ --gchar * --goa_oauth_provider_get_access_token_sync (GoaOAuthProvider *provider, -- GoaObject *object, -- gboolean force_refresh, -- gchar **out_access_token_secret, -- gint *out_access_token_expires_in, -- GCancellable *cancellable, -- GError **error) --{ -- GVariant *credentials = NULL; -- GVariantIter iter; -- const gchar *key; -- GVariant *value; -- gchar *access_token = NULL; -- gchar *access_token_secret = NULL; -- gchar *session_handle = NULL; -- gchar *access_token_for_refresh = NULL; -- gchar *access_token_secret_for_refresh = NULL; -- gchar *session_handle_for_refresh = NULL; -- gchar *password = NULL; -- gint access_token_expires_in = 0; -- gint session_handle_expires_in = 0; -- gboolean success = FALSE; -- GVariantBuilder builder; -- gchar *ret = NULL; -- GMutex *lock; -- -- g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); -- g_return_val_if_fail (GOA_IS_OBJECT (object), NULL); -- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); -- g_return_val_if_fail (error == NULL || *error == NULL, NULL); -- -- /* provider_lock is too coarse, use a per-object lock instead */ -- G_LOCK (provider_lock); -- lock = g_object_get_data (G_OBJECT (object), "-goa-oauth-provider-get-access-token-lock"); -- if (lock == NULL) -- { -- lock = g_slice_new0 (GMutex); -- g_mutex_init (lock); -- g_object_set_data_full (G_OBJECT (object), -- "-goa-oauth-provider-get-access-token-lock", -- lock, -- (GDestroyNotify) free_mutex); -- } -- G_UNLOCK (provider_lock); -- -- g_mutex_lock (lock); -- -- /* First, get the credentials from the keyring */ -- credentials = goa_utils_lookup_credentials_sync (GOA_PROVIDER (provider), -- object, -- cancellable, -- error); -- if (credentials == NULL) -- { -- if (error != NULL) -- { -- (*error)->domain = GOA_ERROR; -- (*error)->code = GOA_ERROR_NOT_AUTHORIZED; -- } -- goto out; -- } -- -- g_variant_iter_init (&iter, credentials); -- while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) -- { -- if (g_strcmp0 (key, "access_token") == 0) -- access_token = g_variant_dup_string (value, NULL); -- else if (g_strcmp0 (key, "access_token_secret") == 0) -- access_token_secret = g_variant_dup_string (value, NULL); -- else if (g_strcmp0 (key, "access_token_expires_at") == 0) -- access_token_expires_in = abs_usec_to_duration (g_variant_get_int64 (value)); -- else if (g_strcmp0 (key, "session_handle") == 0) -- session_handle = g_variant_dup_string (value, NULL); -- else if (g_strcmp0 (key, "session_handle_expires_at") == 0) -- session_handle_expires_in = abs_usec_to_duration (g_variant_get_int64 (value)); -- else if (g_strcmp0 (key, "password") == 0) -- password = g_variant_dup_string (value, NULL); -- g_variant_unref (value); -- } -- -- if (access_token == NULL || access_token_secret == NULL) -- { -- g_set_error (error, -- GOA_ERROR, -- GOA_ERROR_NOT_AUTHORIZED, -- _("Credentials do not contain access_token or access_token_secret")); -- goto out; -- } -- -- /* if we can't refresh the token, just return it no matter what */ -- if (session_handle == NULL) -- { -- g_debug ("Returning locally cached credentials that cannot be refreshed"); -- success = TRUE; -- goto out; -- } -- -- /* If access_token is still "fresh enough" (e.g. more than ten -- * minutes of life left in it), just return it unless we've been -- * asked to forcibly refresh it -- */ -- if (!force_refresh && access_token_expires_in > 10*60) -- { -- g_debug ("Returning locally cached credentials (expires in %d seconds)", access_token_expires_in); -- success = TRUE; -- goto out; -- } -- -- g_debug ("Refreshing locally cached credentials (expires in %d seconds, force_refresh=%d)", access_token_expires_in, force_refresh); -- -- /* Otherwise, refresh it */ -- access_token_for_refresh = access_token; access_token = NULL; -- access_token_secret_for_refresh = access_token_secret; access_token_secret = NULL; -- session_handle_for_refresh = session_handle; session_handle = NULL; -- access_token = get_tokens_sync (provider, -- access_token_for_refresh, -- access_token_secret_for_refresh, -- session_handle_for_refresh, -- NULL, /* verifier */ -- &access_token_secret, -- &access_token_expires_in, -- &session_handle, -- &session_handle_expires_in, -- cancellable, -- error); -- if (access_token == NULL) -- { -- if (error != NULL) -- { -- g_prefix_error (error, _("Failed to refresh access token (%s, %d): "), -- g_quark_to_string ((*error)->domain), (*error)->code); -- (*error)->code = is_authorization_error (*error) ? GOA_ERROR_NOT_AUTHORIZED : GOA_ERROR_FAILED; -- (*error)->domain = GOA_ERROR; -- } -- goto out; -- } -- -- /* Good. Now update the keyring with the refreshed credentials */ -- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); -- g_variant_builder_add (&builder, "{sv}", "access_token", g_variant_new_string (access_token)); -- g_variant_builder_add (&builder, "{sv}", "access_token_secret", g_variant_new_string (access_token_secret)); -- if (access_token_expires_in > 0) -- g_variant_builder_add (&builder, "{sv}", "access_token_expires_at", -- g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in))); -- if (session_handle != NULL) -- g_variant_builder_add (&builder, "{sv}", "session_handle", g_variant_new_string (session_handle)); -- if (session_handle_expires_in > 0) -- g_variant_builder_add (&builder, "{sv}", "session_handle_expires_at", -- g_variant_new_int64 (duration_to_abs_usec (session_handle_expires_in))); -- if (password != NULL) -- g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password)); -- -- /* TODO: run in worker thread */ -- if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider), -- object, -- g_variant_builder_end (&builder), -- cancellable, -- error)) -- { -- if (error != NULL) -- { -- (*error)->domain = GOA_ERROR; -- (*error)->code = GOA_ERROR_NOT_AUTHORIZED; -- } -- goto out; -- } -- -- success = TRUE; -- -- out: -- if (success) -- { -- ret = access_token; access_token = NULL; -- g_assert (ret != NULL); -- if (out_access_token_secret != NULL) -- { -- *out_access_token_secret = access_token_secret; access_token_secret = NULL; -- } -- if (out_access_token_expires_in != NULL) -- *out_access_token_expires_in = access_token_expires_in; -- } -- g_free (access_token); -- g_free (access_token_secret); -- g_free (session_handle); -- g_free (access_token_for_refresh); -- g_free (access_token_secret_for_refresh); -- g_free (session_handle_for_refresh); -- g_free (password); -- g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); -- -- g_mutex_unlock (lock); -- -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean on_handle_get_access_token (GoaOAuthBased *object, -- GDBusMethodInvocation *invocation, -- gpointer user_data); -- --static gboolean --goa_oauth_provider_build_object (GoaProvider *provider, -- GoaObjectSkeleton *object, -- GKeyFile *key_file, -- const gchar *group, -- GDBusConnection *connection, -- gboolean just_added, -- GError **error) --{ -- GoaOAuthBased *oauth_based; -- gchar *identity; -- -- identity = NULL; -- -- oauth_based = goa_object_get_oauth_based (GOA_OBJECT (object)); -- if (oauth_based != NULL) -- goto out; -- -- oauth_based = goa_oauth_based_skeleton_new (); -- goa_oauth_based_set_consumer_key (oauth_based, -- goa_oauth_provider_get_consumer_key (GOA_OAUTH_PROVIDER (provider))); -- goa_oauth_based_set_consumer_secret (oauth_based, -- goa_oauth_provider_get_consumer_secret (GOA_OAUTH_PROVIDER (provider))); -- /* Ensure D-Bus method invocations run in their own thread */ -- g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (oauth_based), -- G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); -- goa_object_skeleton_set_oauth_based (object, oauth_based); -- g_signal_connect (oauth_based, -- "handle-get-access-token", -- G_CALLBACK (on_handle_get_access_token), -- NULL); -- -- out: -- g_object_unref (oauth_based); -- g_free (identity); -- return TRUE; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static gboolean --goa_oauth_provider_ensure_credentials_sync (GoaProvider *_provider, -- GoaObject *object, -- gint *out_expires_in, -- GCancellable *cancellable, -- GError **error) --{ -- GoaOAuthProvider *provider = GOA_OAUTH_PROVIDER (_provider); -- gboolean ret = FALSE; -- gchar *access_token = NULL; -- gchar *access_token_secret = NULL; -- gint access_token_expires_in; -- gchar *identity = NULL; -- gboolean force_refresh = FALSE; -- -- again: -- access_token = goa_oauth_provider_get_access_token_sync (provider, -- object, -- force_refresh, -- &access_token_secret, -- &access_token_expires_in, -- cancellable, -- error); -- if (access_token == NULL) -- goto out; -- -- identity = goa_oauth_provider_get_identity_sync (provider, -- access_token, -- access_token_secret, -- NULL, /* out_presentation_identity */ -- cancellable, -- error); -- if (identity == NULL) -- { -- /* OK, try again, with forcing the locally cached credentials to be refreshed */ -- if (!force_refresh) -- { -- force_refresh = TRUE; -- g_free (access_token); access_token = NULL; -- g_free (access_token_secret); access_token_secret = NULL; -- g_clear_error (error); -- goto again; -- } -- else -- { -- goto out; -- } -- } -- -- /* TODO: maybe check with the identity we have */ -- ret = TRUE; -- if (out_expires_in != NULL) -- *out_expires_in = access_token_expires_in; -- -- out: -- g_free (identity); -- g_free (access_token); -- g_free (access_token_secret); -- return ret; --} -- -- --/* ---------------------------------------------------------------------------------------------------- */ -- --static void --goa_oauth_provider_init (GoaOAuthProvider *client) --{ --} -- --static void --goa_oauth_provider_class_init (GoaOAuthProviderClass *klass) --{ -- GoaProviderClass *provider_class; -- -- provider_class = GOA_PROVIDER_CLASS (klass); -- provider_class->add_account = goa_oauth_provider_add_account; -- provider_class->refresh_account = goa_oauth_provider_refresh_account; -- provider_class->build_object = goa_oauth_provider_build_object; -- provider_class->ensure_credentials_sync = goa_oauth_provider_ensure_credentials_sync; -- -- klass->build_authorization_uri = goa_oauth_provider_build_authorization_uri_default; -- klass->get_use_mobile_browser = goa_oauth_provider_get_use_mobile_browser_default; -- klass->is_deny_node = goa_oauth_provider_is_deny_node_default; -- klass->is_password_node = goa_oauth_provider_is_password_node_default; -- klass->get_request_uri_params = goa_oauth_provider_get_request_uri_params_default; -- klass->add_account_key_values = goa_oauth_provider_add_account_key_values_default; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- --/* runs in a thread dedicated to handling @invocation */ --static gboolean --on_handle_get_access_token (GoaOAuthBased *interface, -- GDBusMethodInvocation *invocation, -- gpointer user_data) --{ -- GoaObject *object; -- GoaAccount *account; -- GoaProvider *provider; -- GError *error; -- const gchar *id; -- const gchar *method_name; -- const gchar *provider_type; -- gchar *access_token = NULL; -- gchar *access_token_secret = NULL; -- gint access_token_expires_in; -- -- /* TODO: maybe log what app is requesting access */ -- -- object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface))); -- account = goa_object_peek_account (object); -- -- id = goa_account_get_id (account); -- provider_type = goa_account_get_provider_type (account); -- method_name = g_dbus_method_invocation_get_method_name (invocation); -- g_debug ("Handling %s for account (%s, %s)", method_name, provider_type, id); -- -- provider = goa_provider_get_for_provider_type (provider_type); -- -- error = NULL; -- access_token = goa_oauth_provider_get_access_token_sync (GOA_OAUTH_PROVIDER (provider), -- object, -- FALSE, /* force_refresh */ -- &access_token_secret, -- &access_token_expires_in, -- NULL, /* GCancellable* */ -- &error); -- if (access_token == NULL) -- { -- g_dbus_method_invocation_take_error (invocation, error); -- } -- else -- { -- goa_oauth_based_complete_get_access_token (interface, -- invocation, -- access_token, -- access_token_secret, -- access_token_expires_in); -- } -- g_free (access_token); -- g_free (access_token_secret); -- g_object_unref (provider); -- return TRUE; /* invocation was handled */ --} -diff --git a/src/goabackend/goaoauthprovider.h b/src/goabackend/goaoauthprovider.h -deleted file mode 100644 -index d4ffa3c..0000000 ---- a/src/goabackend/goaoauthprovider.h -+++ /dev/null -@@ -1,143 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2011 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) --#error "Only can be included directly." --#endif -- --#ifndef __GOA_OAUTH_PROVIDER_H__ --#define __GOA_OAUTH_PROVIDER_H__ -- --#include --#include --#include --#include -- --G_BEGIN_DECLS -- --#define GOA_TYPE_OAUTH_PROVIDER (goa_oauth_provider_get_type ()) --G_DECLARE_DERIVABLE_TYPE (GoaOAuthProvider, goa_oauth_provider, GOA, OAUTH_PROVIDER, GoaProvider); -- --/** -- * GoaOAuthProvider: -- * -- * The #GoaOAuthProvider structure contains only private data and should -- * only be accessed using the provided API. -- */ -- --/** -- * GoaOAuthProviderClass: -- * @parent_class: The parent class. -- * @get_consumer_key: Virtual function for goa_oauth_provider_get_consumer_key(). -- * @get_consumer_secret: Virtual function for goa_oauth_provider_get_consumer_secret(). -- * @get_request_uri: Virtual function for goa_oauth_provider_get_request_uri(). -- * @get_authorization_uri: Virtual function for goa_oauth_provider_get_authorization_uri(). -- * @get_token_uri: Virtual function for goa_oauth_provider_get_token_uri(). -- * @get_callback_uri: Virtual function for goa_oauth_provider_get_callback_uri(). -- * @get_identity_sync: Virtual function for goa_oauth_provider_get_identity_sync(). -- * @parse_request_token_error: Virtual function for goa_oauth_provider_parse_request_token_error(). -- * @build_authorization_uri: Virtual function for goa_oauth_provider_build_authorization_uri(). -- * @get_use_mobile_browser: Virtual function for goa_oauth_provider_get_use_mobile_browser(). -- * @get_request_uri_params: Virtual function for goa_oauth_provider_get_request_uri_params(). -- * @add_account_key_values: Virtual function for goa_oauth_provider_add_account_key_values(). -- * @is_deny_node: Virtual function for goa_oauth_provider_is_deny_node(). -- * @is_identity_node: Virtual function for goa_oauth_provider_is_identity_node(). -- * @is_password_node: Virtual function for goa_oauth_provider_is_password_node(). -- * -- * Class structure for #GoaOAuthProvider. -- */ --struct _GoaOAuthProviderClass --{ -- GoaProviderClass parent_class; -- -- /* pure virtual */ -- const gchar *(*get_consumer_key) (GoaOAuthProvider *provider); -- const gchar *(*get_consumer_secret) (GoaOAuthProvider *provider); -- const gchar *(*get_request_uri) (GoaOAuthProvider *provider); -- const gchar *(*get_authorization_uri) (GoaOAuthProvider *provider); -- const gchar *(*get_token_uri) (GoaOAuthProvider *provider); -- const gchar *(*get_callback_uri) (GoaOAuthProvider *provider); -- -- gchar *(*get_identity_sync) (GoaOAuthProvider *provider, -- const gchar *access_token, -- const gchar *access_token_secret, -- gchar **out_presentation_identity, -- GCancellable *cancellable, -- GError **error); -- -- gchar *(*parse_request_token_error) (GoaOAuthProvider *provider, -- RestProxyCall *call); -- -- /* virtual but with default implementation */ -- gchar *(*build_authorization_uri) (GoaOAuthProvider *provider, -- const gchar *authorization_uri, -- const gchar *escaped_oauth_token); -- gboolean (*get_use_mobile_browser) (GoaOAuthProvider *provider); -- gchar **(*get_request_uri_params) (GoaOAuthProvider *provider); -- void (*add_account_key_values) (GoaOAuthProvider *provider, -- GVariantBuilder *builder); -- -- /* pure virtual */ -- gboolean (*is_identity_node) (GoaOAuthProvider *provider, -- WebKitDOMHTMLInputElement *element); -- -- /* virtual but with default implementation */ -- gboolean (*is_deny_node) (GoaOAuthProvider *provider, -- WebKitDOMNode *node); -- gboolean (*is_password_node) (GoaOAuthProvider *provider, -- WebKitDOMHTMLInputElement *element); --}; -- --const gchar *goa_oauth_provider_get_consumer_key (GoaOAuthProvider *provider); --const gchar *goa_oauth_provider_get_consumer_secret (GoaOAuthProvider *provider); --const gchar *goa_oauth_provider_get_request_uri (GoaOAuthProvider *provider); --gchar **goa_oauth_provider_get_request_uri_params (GoaOAuthProvider *provider); --const gchar *goa_oauth_provider_get_authorization_uri (GoaOAuthProvider *provider); --const gchar *goa_oauth_provider_get_token_uri (GoaOAuthProvider *provider); --const gchar *goa_oauth_provider_get_callback_uri (GoaOAuthProvider *provider); --gchar *goa_oauth_provider_get_identity_sync (GoaOAuthProvider *provider, -- const gchar *access_token, -- const gchar *access_token_secret, -- gchar **out_presentation_identity, -- GCancellable *cancellable, -- GError **error); --gboolean goa_oauth_provider_is_deny_node (GoaOAuthProvider *provider, -- WebKitDOMNode *node); --gboolean goa_oauth_provider_is_identity_node (GoaOAuthProvider *provider, -- WebKitDOMHTMLInputElement *element); --gboolean goa_oauth_provider_is_password_node (GoaOAuthProvider *provider, -- WebKitDOMHTMLInputElement *element); --gchar *goa_oauth_provider_parse_request_token_error (GoaOAuthProvider *provider, -- RestProxyCall *call); --gchar *goa_oauth_provider_get_access_token_sync (GoaOAuthProvider *provider, -- GoaObject *object, -- gboolean force_refresh, -- gchar **out_access_token_secret, -- gint *out_access_token_expires_in, -- GCancellable *cancellable, -- GError **error); --gchar *goa_oauth_provider_build_authorization_uri (GoaOAuthProvider *provider, -- const gchar *authorization_uri, -- const gchar *escaped_oauth_token); --gboolean goa_oauth_provider_get_use_mobile_browser (GoaOAuthProvider *provider); --void goa_oauth_provider_add_account_key_values (GoaOAuthProvider *provider, -- GVariantBuilder *builder); -- --G_END_DECLS -- --#endif /* __GOA_OAUTH_PROVIDER_H__ */ -diff --git a/src/goabackend/goapocketprovider.c b/src/goabackend/goapocketprovider.c -index 38f9863..0d1a8ce 100644 ---- a/src/goabackend/goapocketprovider.c -+++ b/src/goabackend/goapocketprovider.c -@@ -185,32 +185,6 @@ build_authorization_uri (GoaOAuth2Provider *oauth2_provider, - return url; - } - --static gboolean --decide_navigation_policy (GoaOAuth2Provider *oauth2_provider, -- WebKitWebView *web_view, -- WebKitNavigationPolicyDecision *decision) --{ -- GoaPocketProvider *self = GOA_POCKET_PROVIDER (oauth2_provider); -- WebKitNavigationAction *action; -- WebKitURIRequest *request; -- gboolean ret = FALSE; -- const gchar *uri; -- -- action = webkit_navigation_policy_decision_get_navigation_action (decision); -- request = webkit_navigation_action_get_request (action); -- uri = webkit_uri_request_get_uri (request); -- if (!g_str_has_prefix (uri, "https://getpocket.com/a/")) -- goto out; -- -- webkit_uri_request_set_uri (request, self->authorization_uri); -- webkit_web_view_load_request (web_view, request); -- -- ret = TRUE; -- -- out: -- return ret; --} -- - static gboolean - process_redirect_url (GoaOAuth2Provider *oauth2_provider, - const gchar *redirect_url, -@@ -279,68 +253,6 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --is_deny_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMNode *node) --{ -- WebKitDOMElement *element; -- gboolean ret = FALSE; -- gchar *id = NULL; -- gchar *class = NULL; -- gchar *text = NULL; -- -- if (!WEBKIT_DOM_IS_ELEMENT (node)) -- goto out; -- -- element = WEBKIT_DOM_ELEMENT (node); -- -- /* Desktop version */ -- id = webkit_dom_element_get_id (element); -- if (g_strcmp0 (id, "denyButton") == 0) -- { -- ret = TRUE; -- goto out; -- } -- -- /* Mobile version */ -- class = webkit_dom_element_get_class_name (element); -- if (g_strcmp0 (class, "toolbarButton") != 0) -- goto out; -- -- /* FIXME: This only seems to work if we don't click on the "Sign Up" -- * button, does the check need to be done again? */ -- text = webkit_dom_node_get_text_content (node); -- if (g_strcmp0 (text, "Cancel") != 0) -- goto out; -- -- ret = TRUE; -- -- out: -- g_free (id); -- g_free (class); -- g_free (text); -- return ret; --} -- --static gboolean --is_identity_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMHTMLInputElement *element) --{ -- gboolean ret = FALSE; -- gchar *name; -- -- name = webkit_dom_html_input_element_get_name (element); -- if (g_strcmp0 (name, "feed_id") != 0) -- goto out; -- -- ret = TRUE; -- --out: -- g_free (name); -- return ret; -- --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static gboolean - build_object (GoaProvider *provider, - GoaObjectSkeleton *object, -@@ -431,15 +343,12 @@ goa_pocket_provider_class_init (GoaPocketProviderClass *klass) - provider_class->build_object = build_object; - - oauth2_class->build_authorization_uri = build_authorization_uri; -- oauth2_class->decide_navigation_policy = decide_navigation_policy; - oauth2_class->get_authorization_uri = get_authorization_uri; - oauth2_class->get_token_uri = get_token_uri; - oauth2_class->get_redirect_uri = get_redirect_uri; - oauth2_class->get_client_id = get_client_id; - oauth2_class->get_client_secret = get_client_secret; - oauth2_class->get_identity_sync = get_identity_sync; -- oauth2_class->is_deny_node = is_deny_node; -- oauth2_class->is_identity_node = is_identity_node; - oauth2_class->add_account_key_values = add_account_key_values; - oauth2_class->process_redirect_url = process_redirect_url; - } -diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c -index c8f7f0d..fe8ce22 100644 ---- a/src/goabackend/goaprovider.c -+++ b/src/goabackend/goaprovider.c -@@ -28,7 +28,6 @@ - #include "goafacebookprovider.h" - #include "goaimapsmtpprovider.h" - #include "goaowncloudprovider.h" --#include "goaflickrprovider.h" - #include "goafoursquareprovider.h" - #include "goawindowsliveprovider.h" - #include "goatelepathyfactory.h" -@@ -968,9 +967,6 @@ static struct - #ifdef GOA_WINDOWS_LIVE_ENABLED - { GOA_WINDOWS_LIVE_NAME, goa_windows_live_provider_get_type }, - #endif --#ifdef GOA_FLICKR_ENABLED -- { GOA_FLICKR_NAME, goa_flickr_provider_get_type }, --#endif - #ifdef GOA_POCKET_ENABLED - { GOA_POCKET_NAME, goa_pocket_provider_get_type }, - #endif -diff --git a/src/goabackend/goatodoistprovider.c b/src/goabackend/goatodoistprovider.c -index d97c33c..7f17a59 100644 ---- a/src/goabackend/goatodoistprovider.c -+++ b/src/goabackend/goatodoistprovider.c -@@ -133,33 +133,6 @@ build_authorization_uri (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --is_identity_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMHTMLInputElement *element) --{ -- gboolean ret = FALSE; -- gchar *element_type = NULL; -- gchar *id = NULL; -- gchar *name = NULL; -- -- g_object_get (element, "type", &element_type, NULL); -- if (g_strcmp0 (element_type, "email") != 0) -- goto out; -- -- id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (element)); -- if (g_strcmp0 (id, "email") != 0) -- goto out; -- -- ret = TRUE; -- -- out: -- g_free (element_type); -- g_free (id); -- g_free (name); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static gchar * - get_identity_sync (GoaOAuth2Provider *oauth2_provider, - const gchar *access_token, -@@ -337,6 +310,5 @@ goa_todoist_provider_class_init (GoaTodoistProviderClass *klass) - oauth2_class->get_client_secret = get_client_secret; - oauth2_class->get_scope = get_scope; - oauth2_class->get_identity_sync = get_identity_sync; -- oauth2_class->is_identity_node = is_identity_node; - oauth2_class->add_account_key_values = add_account_key_values; - } -diff --git a/src/goabackend/goawebextension.c b/src/goabackend/goawebextension.c -deleted file mode 100644 -index 6a25ab9..0000000 ---- a/src/goabackend/goawebextension.c -+++ /dev/null -@@ -1,273 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2015 Damián Nohales -- * Copyright © 2015 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#include "config.h" -- --#include -- --#include "goaoauthprovider.h" --#include "goaoauth2provider.h" --#include "goaoauth2provider-web-extension.h" --#include "goaprovider.h" --#include "goawebextension.h" -- --struct _GoaWebExtension --{ -- GObject parent; -- GoaProvider *provider; -- WebKitWebExtension *wk_extension; -- gchar *existing_identity; -- gchar *provider_type; --}; -- --struct _GoaWebExtensionClass --{ -- GObjectClass parent; --}; -- --enum --{ -- PROP_0, -- PROP_EXISTING_IDENTITY, -- PROP_PROVIDER_TYPE, -- PROP_WK_EXTENSION --}; -- --G_DEFINE_TYPE (GoaWebExtension, goa_web_extension, G_TYPE_OBJECT) -- --static void --web_extension_dom_node_deny_click_cb (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data) --{ -- WebKitDOMDOMWindow *dom_window = WEBKIT_DOM_DOM_WINDOW (user_data); -- webkit_dom_dom_window_webkit_message_handlers_post_message (dom_window, "deny-click", ""); --} -- --static void --web_extension_dom_node_password_submit_cb (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data) --{ -- WebKitDOMDOMWindow *dom_window = WEBKIT_DOM_DOM_WINDOW (user_data); -- WebKitDOMHTMLInputElement *password_node; -- gchar *password; -- -- password_node = WEBKIT_DOM_HTML_INPUT_ELEMENT (g_object_get_data (G_OBJECT (dom_window), "goa-password-node")); -- password = webkit_dom_html_input_element_get_value (password_node); -- webkit_dom_dom_window_webkit_message_handlers_post_message (dom_window, "password-submit", password); -- g_free (password); --} -- --static void --web_extension_document_loaded_cb (WebKitWebPage *web_page, gpointer user_data) --{ -- GoaWebExtension *self = GOA_WEB_EXTENSION (user_data); -- WebKitDOMDocument *document; -- WebKitDOMDOMWindow *dom_window; -- WebKitDOMHTMLCollection *elements = NULL; -- gulong element_count; -- gulong i; -- -- document = webkit_web_page_get_dom_document (web_page); -- elements = webkit_dom_document_get_elements_by_tag_name_as_html_collection (document, "*"); -- element_count = webkit_dom_html_collection_get_length (elements); -- -- dom_window = webkit_dom_document_get_default_view (document); -- -- for (i = 0; i < element_count; i++) -- { -- WebKitDOMNode *element = webkit_dom_html_collection_item (elements, i); -- -- if ((GOA_IS_OAUTH_PROVIDER (self->provider) -- && goa_oauth_provider_is_deny_node (GOA_OAUTH_PROVIDER (self->provider), element)) -- || (GOA_IS_OAUTH2_PROVIDER (self->provider) -- && goa_oauth2_provider_is_deny_node (GOA_OAUTH2_PROVIDER (self->provider), element))) -- { -- webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (element), -- "click", -- G_CALLBACK (web_extension_dom_node_deny_click_cb), -- FALSE, -- dom_window); -- } -- else if (self->existing_identity != NULL -- && self->existing_identity[0] != '\0' -- && WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element) -- && ((GOA_IS_OAUTH_PROVIDER (self->provider) -- && goa_oauth_provider_is_identity_node (GOA_OAUTH_PROVIDER (self->provider), -- WEBKIT_DOM_HTML_INPUT_ELEMENT (element))) -- || (GOA_IS_OAUTH2_PROVIDER (self->provider) -- && goa_oauth2_provider_is_identity_node (GOA_OAUTH2_PROVIDER (self->provider), -- WEBKIT_DOM_HTML_INPUT_ELEMENT (element))))) -- { -- webkit_dom_html_input_element_set_value (WEBKIT_DOM_HTML_INPUT_ELEMENT (element), -- self->existing_identity); -- webkit_dom_html_input_element_set_read_only (WEBKIT_DOM_HTML_INPUT_ELEMENT (element), TRUE); -- } -- else if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element) -- && ((GOA_IS_OAUTH_PROVIDER (self->provider) -- && goa_oauth_provider_is_password_node (GOA_OAUTH_PROVIDER (self->provider), -- WEBKIT_DOM_HTML_INPUT_ELEMENT (element))) -- || (GOA_IS_OAUTH2_PROVIDER (self->provider) -- && goa_oauth2_provider_is_password_node (GOA_OAUTH2_PROVIDER (self->provider), -- WEBKIT_DOM_HTML_INPUT_ELEMENT (element))))) -- { -- WebKitDOMHTMLFormElement *form; -- -- form = webkit_dom_html_input_element_get_form (WEBKIT_DOM_HTML_INPUT_ELEMENT (element)); -- if (form != NULL) -- { -- g_object_set_data_full (G_OBJECT (dom_window), -- "goa-password-node", -- g_object_ref (element), -- g_object_unref); -- webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (form), -- "submit", -- G_CALLBACK (web_extension_dom_node_password_submit_cb), -- FALSE, -- dom_window); -- } -- } -- } -- -- g_clear_object (&elements); --} -- --static void --web_extension_page_created_cb (GoaWebExtension *self, WebKitWebPage *web_page) --{ -- g_signal_connect_object (web_page, "document-loaded", G_CALLBACK (web_extension_document_loaded_cb), self, 0); --} -- --static void --goa_web_extension_constructed (GObject *object) --{ -- GoaWebExtension *self = GOA_WEB_EXTENSION (object); -- -- G_OBJECT_CLASS (goa_web_extension_parent_class)->constructed (object); -- -- self->provider = goa_provider_get_for_provider_type (self->provider_type); -- -- g_signal_connect_object (self->wk_extension, -- "page-created", -- G_CALLBACK (web_extension_page_created_cb), -- self, -- G_CONNECT_SWAPPED); --} -- --static void --goa_web_extension_dispose (GObject *object) --{ -- GoaWebExtension *self = GOA_WEB_EXTENSION (object); -- -- g_clear_object (&self->provider); -- g_clear_object (&self->wk_extension); -- -- G_OBJECT_CLASS (goa_web_extension_parent_class)->dispose (object); --} -- --static void --goa_web_extension_finalize (GObject *object) --{ -- GoaWebExtension *self = GOA_WEB_EXTENSION (object); -- -- g_free (self->existing_identity); -- g_free (self->provider_type); -- -- G_OBJECT_CLASS (goa_web_extension_parent_class)->finalize (object); --} -- --static void --goa_web_extension_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) --{ -- GoaWebExtension *self = GOA_WEB_EXTENSION (object); -- -- switch (prop_id) -- { -- case PROP_EXISTING_IDENTITY: -- self->existing_identity = g_value_dup_string (value); -- break; -- -- case PROP_PROVIDER_TYPE: -- self->provider_type = g_value_dup_string (value); -- break; -- -- case PROP_WK_EXTENSION: -- self->wk_extension = WEBKIT_WEB_EXTENSION (g_value_dup_object (value)); -- break; -- -- default: -- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -- break; -- } --} -- --static void --goa_web_extension_class_init (GoaWebExtensionClass *klass) --{ -- GObjectClass *object_class = G_OBJECT_CLASS (klass); -- -- object_class->constructed = goa_web_extension_constructed; -- object_class->dispose = goa_web_extension_dispose; -- object_class->finalize = goa_web_extension_finalize; -- object_class->set_property = goa_web_extension_set_property; -- -- g_object_class_install_property (object_class, -- PROP_EXISTING_IDENTITY, -- g_param_spec_string ("existing-identity", -- "A GoaAccount identity", -- "The user name with which we want to prefill the form", -- NULL, -- G_PARAM_WRITABLE | -- G_PARAM_CONSTRUCT_ONLY | -- G_PARAM_STATIC_STRINGS)); -- -- g_object_class_install_property (object_class, -- PROP_PROVIDER_TYPE, -- g_param_spec_string ("provider-type", -- "A GoaProvider type", -- "The provider type that is represented by this view", -- NULL, -- G_PARAM_WRITABLE | -- G_PARAM_CONSTRUCT_ONLY | -- G_PARAM_STATIC_STRINGS)); -- -- g_object_class_install_property (object_class, -- PROP_WK_EXTENSION, -- g_param_spec_object ("wk-extension", -- "A WebKitWebExtension", -- "The associated WebKitWebExtension", -- WEBKIT_TYPE_WEB_EXTENSION, -- G_PARAM_WRITABLE | -- G_PARAM_CONSTRUCT_ONLY | -- G_PARAM_STATIC_STRINGS)); --} -- --static void --goa_web_extension_init (GoaWebExtension *self) --{ --} -- --GoaWebExtension * --goa_web_extension_new (WebKitWebExtension *wk_extension, -- const gchar *provider_type, -- const gchar *existing_identity) --{ -- return g_object_new (GOA_TYPE_WEB_EXTENSION, -- "existing-identity", existing_identity, -- "provider-type", provider_type, -- "wk-extension", wk_extension, -- NULL); --} -diff --git a/src/goabackend/goawebextension.h b/src/goabackend/goawebextension.h -deleted file mode 100644 -index 4a8cf8f..0000000 ---- a/src/goabackend/goawebextension.h -+++ /dev/null -@@ -1,42 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2015 Damián Nohales -- * Copyright © 2015 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#ifndef __GOA_WEB_EXTENSION_H__ --#define __GOA_WEB_EXTENSION_H__ -- --#include --#include -- --G_BEGIN_DECLS -- --#define GOA_TYPE_WEB_EXTENSION (goa_web_extension_get_type()) --#define GOA_WEB_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOA_TYPE_WEB_EXTENSION, GoaWebExtension)) --#define GOA_IS_WEB_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOA_TYPE_WEB_EXTENSION)) -- --typedef struct _GoaWebExtension GoaWebExtension; --typedef struct _GoaWebExtensionClass GoaWebExtensionClass; -- --GType goa_web_extension_get_type (void); --GoaWebExtension *goa_web_extension_new (WebKitWebExtension *wk_extension, -- const gchar *provider_type, -- const gchar *existing_identity); -- --G_END_DECLS -- --#endif /* __GOA_WEB_EXTENSION_H__ */ -diff --git a/src/goabackend/goawebextensionmain.c b/src/goabackend/goawebextensionmain.c -deleted file mode 100644 -index 4fc91e5..0000000 ---- a/src/goabackend/goawebextensionmain.c -+++ /dev/null -@@ -1,53 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ --/* -- * Copyright © 2015 Damián Nohales -- * Copyright © 2015 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#include "config.h" -- --#include --#include -- --#include "goawebextension.h" -- --static GoaWebExtension *the_extension; -- --/* Silence -Wmissing-prototypes */ --void webkit_web_extension_initialize (WebKitWebExtension *wk_extension); --void webkit_web_extension_initialize_with_user_data (WebKitWebExtension *wk_extension, GVariant *user_data); -- --G_MODULE_EXPORT void --webkit_web_extension_initialize (WebKitWebExtension *wk_extension) --{ -- g_warning ("Error initializing web extension: user data not set"); --} -- --G_MODULE_EXPORT void --webkit_web_extension_initialize_with_user_data (WebKitWebExtension *wk_extension, GVariant *user_data) --{ -- const gchar *existing_identity; -- const gchar *provider_type; -- -- g_variant_get (user_data, "(&s&s)", &provider_type, &existing_identity); -- the_extension = goa_web_extension_new (wk_extension, provider_type, existing_identity); --} -- --static void __attribute__((destructor)) --goa_web_extension_shutdown (void) --{ -- g_clear_object (&the_extension); --} -diff --git a/src/goabackend/goawebview.c b/src/goabackend/goawebview.c -deleted file mode 100644 -index b7af122..0000000 ---- a/src/goabackend/goawebview.c -+++ /dev/null -@@ -1,501 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- -- * -- * Copyright © 2015 Damián Nohales -- * Copyright © 2012 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --/* Based on code by the Epiphany team. -- */ -- --#include "config.h" -- --#include --#include --#include --#include --#include -- --#include "goawebview.h" --#include "nautilus-floating-bar.h" -- --struct _GoaWebView --{ -- GtkOverlay parent_instance; -- GoaProvider *provider; -- GtkWidget *floating_bar; -- GtkWidget *progress_bar; -- GtkWidget *web_view; -- WebKitUserContentManager *user_content_manager; -- WebKitWebContext *context; -- gchar *existing_identity; -- gulong clear_notify_progress_id; -- gulong notify_load_status_id; -- gulong notify_progress_id; --}; -- --struct _GoaWebViewClass --{ -- GtkOverlayClass parent_class; --}; -- --enum --{ -- PROP_0, -- PROP_EXISTING_IDENTITY, -- PROP_PROVIDER --}; -- --enum --{ -- DENY_CLICK, -- PASSWORD_SUBMIT, -- LAST_SIGNAL --}; -- --static guint signals[LAST_SIGNAL] = { 0 }; -- --G_DEFINE_TYPE (GoaWebView, goa_web_view, GTK_TYPE_OVERLAY) -- --static gboolean --web_view_clear_notify_progress_cb (gpointer user_data) --{ -- GoaWebView *self = GOA_WEB_VIEW (user_data); -- -- gtk_widget_hide (self->progress_bar); -- self->clear_notify_progress_id = 0; -- return FALSE; --} -- --static char * --web_view_create_loading_title (const gchar *url) --{ -- SoupURI *uri; -- const gchar *hostname; -- gchar *title; -- -- g_return_val_if_fail (url != NULL && url[0] != '\0', NULL); -- -- uri = soup_uri_new (url); -- hostname = soup_uri_get_host (uri); -- /* translators: %s here is the address of the web page */ -- title = g_strdup_printf (_("Loading “%s”…"), hostname); -- soup_uri_free (uri); -- -- return title; --} -- --static void --web_view_floating_bar_update (GoaWebView *self, const gchar *text) --{ -- nautilus_floating_bar_set_label (NAUTILUS_FLOATING_BAR (self->floating_bar), text); -- -- if (text == NULL || text[0] == '\0') -- { -- gtk_widget_hide (self->floating_bar); -- gtk_widget_set_halign (self->floating_bar, GTK_ALIGN_START); -- } -- else -- gtk_widget_show (self->floating_bar); --} -- --static void --web_view_initialize_web_extensions_cb (GoaWebView *self) --{ -- GVariant *data; -- const gchar *existing_identity; -- const gchar *provider_type; -- -- webkit_web_context_set_web_extensions_directory (self->context, PACKAGE_WEB_EXTENSIONS_DIR); -- -- if (self->provider == NULL) -- return; -- -- provider_type = goa_provider_get_provider_type (self->provider); -- existing_identity = (self->existing_identity == NULL) ? "" : self->existing_identity; -- data = g_variant_new ("(ss)", provider_type, existing_identity); -- webkit_web_context_set_web_extensions_initialization_user_data (self->context, data); --} -- --#ifdef GOA_INSPECTOR_ENABLED --static void --web_view_inspector_closed_cb (WebKitWebInspector *inspector) --{ -- GtkWidget *window; -- WebKitWebViewBase *inspector_web_view; -- -- inspector_web_view = webkit_web_inspector_get_web_view (inspector); -- window = gtk_widget_get_toplevel (GTK_WIDGET (inspector_web_view)); -- if (gtk_widget_is_toplevel (window)) -- gtk_widget_destroy (window); --} -- --static gboolean --web_view_inspector_open_window_cb (WebKitWebInspector *inspector) --{ -- GtkWidget *window; -- GtkWindowGroup *group; -- WebKitWebViewBase *inspector_web_view; -- -- group = gtk_window_group_new (); -- -- window = gtk_window_new (GTK_WINDOW_TOPLEVEL); -- gtk_window_resize (GTK_WINDOW (window), 800, 600); -- gtk_window_group_add_window (group, GTK_WINDOW (window)); -- g_object_unref (group); -- -- inspector_web_view = webkit_web_inspector_get_web_view (inspector); -- gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (inspector_web_view)); -- -- gtk_widget_show_all (window); -- gtk_window_present (GTK_WINDOW (window)); -- -- return GDK_EVENT_STOP; --} --#endif /* GOA_INSPECTOR_ENABLED */ -- --static void --web_view_load_changed_cb (WebKitWebView *web_view, -- WebKitLoadEvent load_event, -- gpointer user_data) --{ -- GoaWebView *self = GOA_WEB_VIEW (user_data); -- -- switch (load_event) -- { -- case WEBKIT_LOAD_STARTED: -- case WEBKIT_LOAD_COMMITTED: -- { -- const gchar *uri; -- gchar *title; -- -- uri = webkit_web_view_get_uri (web_view); -- title = web_view_create_loading_title (uri); -- -- web_view_floating_bar_update (self, title); -- g_free (title); -- break; -- } -- -- case WEBKIT_LOAD_REDIRECTED: -- /* TODO: Update the loading uri */ -- break; -- -- case WEBKIT_LOAD_FINISHED: -- web_view_floating_bar_update (self, NULL); -- break; -- -- default: -- break; -- } --} -- --static void --web_view_notify_estimated_load_progress_cb (GObject *object, -- GParamSpec *pspec, -- gpointer user_data) --{ -- GoaWebView *self = GOA_WEB_VIEW (user_data); -- WebKitWebView *web_view = WEBKIT_WEB_VIEW (object); -- gboolean loading; -- const gchar *uri; -- gdouble progress; -- -- if (self->clear_notify_progress_id != 0) -- { -- g_source_remove (self->clear_notify_progress_id); -- self->clear_notify_progress_id = 0; -- } -- -- uri = webkit_web_view_get_uri (web_view); -- if (!uri || g_str_equal (uri, "about:blank")) -- return; -- -- progress = webkit_web_view_get_estimated_load_progress (web_view); -- loading = webkit_web_view_is_loading (web_view); -- -- if (progress == 1.0 || !loading) -- self->clear_notify_progress_id = g_timeout_add (500, web_view_clear_notify_progress_cb, self); -- else -- gtk_widget_show (self->progress_bar); -- -- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (self->progress_bar), -- (loading || progress == 1.0) ? progress : 0.0); --} -- --static void --web_view_script_message_received_deny_click_cb (GoaWebView *self) --{ -- g_signal_emit (self, signals[DENY_CLICK], 0); --} -- --static void --web_view_script_message_received_password_submit_cb (GoaWebView *self, WebKitJavascriptResult *js_result) --{ -- JSGlobalContextRef js_context; -- JSStringRef js_string; -- JSValueRef js_value; -- gsize max_size; -- -- js_value = webkit_javascript_result_get_value (js_result); -- js_context = webkit_javascript_result_get_global_context (js_result); -- js_string = JSValueToStringCopy (js_context, js_value, NULL); -- max_size = JSStringGetMaximumUTF8CStringSize (js_string); -- if (max_size > 0) -- { -- gchar *password; -- -- password = g_malloc0 (max_size); -- JSStringGetUTF8CString (js_string, password, max_size); -- g_signal_emit (self, signals[PASSWORD_SUBMIT], 0, password); -- g_free (password); -- } -- -- JSStringRelease (js_string); --} -- --static void --goa_web_view_constructed (GObject *object) --{ -- GoaWebView *self = GOA_WEB_VIEW (object); -- const gchar *const *language_names; -- -- G_OBJECT_CLASS (goa_web_view_parent_class)->constructed (object); -- -- self->context = webkit_web_context_new (); -- language_names = g_get_language_names (); -- webkit_web_context_set_preferred_languages (self->context, language_names); -- g_signal_connect_swapped (self->context, -- "initialize-web-extensions", -- G_CALLBACK (web_view_initialize_web_extensions_cb), -- self); -- -- self->user_content_manager = webkit_user_content_manager_new (); -- g_signal_connect_swapped (self->user_content_manager, -- "script-message-received::deny-click", -- G_CALLBACK (web_view_script_message_received_deny_click_cb), -- self); -- g_signal_connect_swapped (self->user_content_manager, -- "script-message-received::password-submit", -- G_CALLBACK (web_view_script_message_received_password_submit_cb), -- self); -- webkit_user_content_manager_register_script_message_handler (self->user_content_manager, "deny-click"); -- webkit_user_content_manager_register_script_message_handler (self->user_content_manager, "password-submit"); -- -- self->web_view = GTK_WIDGET (g_object_new (WEBKIT_TYPE_WEB_VIEW, -- "user-content-manager", self->user_content_manager, -- "web-context", self->context, -- NULL)); -- gtk_widget_set_size_request (self->web_view, 500, 400); -- gtk_container_add (GTK_CONTAINER (self), self->web_view); -- --#ifdef GOA_INSPECTOR_ENABLED -- { -- WebKitSettings *settings; -- WebKitWebInspector *inspector; -- -- /* Setup the inspector */ -- settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (self->web_view)); -- g_object_set (settings, "enable-developer-extras", TRUE, NULL); -- -- inspector = webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (self->web_view)); -- g_signal_connect (inspector, "closed", G_CALLBACK (web_view_inspector_closed_cb), NULL); -- g_signal_connect (inspector, "open-window", G_CALLBACK (web_view_inspector_open_window_cb), NULL); -- } --#endif /* GOA_INSPECTOR_ENABLED */ -- -- /* statusbar is hidden by default */ -- self->floating_bar = nautilus_floating_bar_new (NULL, FALSE); -- gtk_widget_set_halign (self->floating_bar, GTK_ALIGN_START); -- gtk_widget_set_valign (self->floating_bar, GTK_ALIGN_END); -- gtk_widget_set_no_show_all (self->floating_bar, TRUE); -- gtk_overlay_add_overlay (GTK_OVERLAY (self), self->floating_bar); -- -- self->progress_bar = gtk_progress_bar_new (); -- gtk_style_context_add_class (gtk_widget_get_style_context (self->progress_bar), -- GTK_STYLE_CLASS_OSD); -- gtk_widget_set_halign (self->progress_bar, GTK_ALIGN_FILL); -- gtk_widget_set_valign (self->progress_bar, GTK_ALIGN_START); -- gtk_overlay_add_overlay (GTK_OVERLAY (self), self->progress_bar); -- -- self->notify_progress_id = g_signal_connect (self->web_view, -- "notify::estimated-load-progress", -- G_CALLBACK (web_view_notify_estimated_load_progress_cb), -- self); -- self->notify_load_status_id = g_signal_connect (self->web_view, -- "load_changed", -- G_CALLBACK (web_view_load_changed_cb), -- self); --} -- --static void --goa_web_view_dispose (GObject *object) --{ -- GoaWebView *self = GOA_WEB_VIEW (object); -- -- g_clear_object (&self->user_content_manager); -- g_clear_object (&self->context); -- -- if (self->clear_notify_progress_id != 0) -- { -- g_source_remove (self->clear_notify_progress_id); -- self->clear_notify_progress_id = 0; -- } -- -- if (self->notify_load_status_id != 0) -- { -- g_signal_handler_disconnect (self->web_view, self->notify_load_status_id); -- self->notify_load_status_id = 0; -- } -- -- if (self->notify_progress_id != 0) -- { -- g_signal_handler_disconnect (self->web_view, self->notify_progress_id); -- self->notify_progress_id = 0; -- } -- -- G_OBJECT_CLASS (goa_web_view_parent_class)->dispose (object); --} -- --static void --goa_web_view_finalize (GObject *object) --{ -- GoaWebView *self = GOA_WEB_VIEW (object); -- -- g_free (self->existing_identity); -- -- if (self->provider != NULL) -- g_object_remove_weak_pointer (G_OBJECT (self->provider), (gpointer *) &self->provider); -- -- G_OBJECT_CLASS (goa_web_view_parent_class)->finalize (object); --} -- --static void --goa_web_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) --{ -- GoaWebView *self = GOA_WEB_VIEW (object); -- -- switch (prop_id) -- { -- case PROP_EXISTING_IDENTITY: -- self->existing_identity = g_value_dup_string (value); -- break; -- -- case PROP_PROVIDER: -- self->provider = GOA_PROVIDER (g_value_get_object (value)); -- if (self->provider != NULL) -- g_object_add_weak_pointer (G_OBJECT (self->provider), (gpointer *) &self->provider); -- break; -- -- default: -- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -- break; -- } --} -- --static void --goa_web_view_init (GoaWebView *self) --{ --} -- --static void --goa_web_view_class_init (GoaWebViewClass *klass) --{ -- GObjectClass *object_class; -- -- object_class = G_OBJECT_CLASS (klass); -- object_class->constructed = goa_web_view_constructed; -- object_class->dispose = goa_web_view_dispose; -- object_class->finalize = goa_web_view_finalize; -- object_class->set_property = goa_web_view_set_property; -- -- g_object_class_install_property (object_class, -- PROP_EXISTING_IDENTITY, -- g_param_spec_string ("existing-identity", -- "A GoaAccount identity", -- "The user name with which we want to prefill the form", -- NULL, -- G_PARAM_WRITABLE | -- G_PARAM_CONSTRUCT_ONLY | -- G_PARAM_STATIC_STRINGS)); -- -- g_object_class_install_property (object_class, -- PROP_PROVIDER, -- g_param_spec_object ("provider", -- "A GoaProvider", -- "The provider that is represented by this view", -- GOA_TYPE_PROVIDER, -- G_PARAM_WRITABLE | -- G_PARAM_CONSTRUCT_ONLY | -- G_PARAM_STATIC_STRINGS)); -- -- signals[DENY_CLICK] = g_signal_new ("deny-click", -- G_TYPE_FROM_CLASS (klass), -- G_SIGNAL_RUN_LAST, -- 0, -- NULL, -- NULL, -- g_cclosure_marshal_VOID__VOID, -- G_TYPE_NONE, -- 0); -- -- signals[PASSWORD_SUBMIT] = g_signal_new ("password-submit", -- G_TYPE_FROM_CLASS (klass), -- G_SIGNAL_RUN_LAST, -- 0, -- NULL, -- NULL, -- g_cclosure_marshal_VOID__STRING, -- G_TYPE_NONE, -- 1, -- G_TYPE_STRING); --} -- --GtkWidget * --goa_web_view_new (GoaProvider *provider, const gchar *existing_identity) --{ -- return g_object_new (GOA_TYPE_WEB_VIEW, "provider", provider, "existing-identity", existing_identity, NULL); --} -- --GtkWidget * --goa_web_view_get_view (GoaWebView *self) --{ -- return self->web_view; --} -- --void --goa_web_view_fake_mobile (GoaWebView *self) --{ -- WebKitSettings *settings; -- -- settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (self->web_view)); -- -- /* This is based on the HTC Wildfire's user agent. Some -- * providers, like Google, refuse to provide the mobile -- * version of their authentication pages otherwise. eg., -- * in Google's case, passing btmpl=mobile does not help. -- * -- * The actual user agent used by a HTC Wildfire is: -- * Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; HTC Wildfire -- * Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 -- * Mobile Safari/533.1 -- * -- * Also note that the user agents of some mobile browsers may -- * not work. eg., Nokia N9. -- */ -- webkit_settings_set_user_agent (settings, -- "Mozilla/5.0 (GNOME; not Android) " -- "AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile"); --} -diff --git a/src/goabackend/goawebview.h b/src/goabackend/goawebview.h -deleted file mode 100644 -index 4b415cd..0000000 ---- a/src/goabackend/goawebview.h -+++ /dev/null -@@ -1,43 +0,0 @@ --/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- -- * -- * Copyright © 2012 – 2017 Red Hat, Inc. -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General -- * Public License along with this library; if not, see . -- */ -- --#ifndef __GOA_WEB_VIEW_H__ --#define __GOA_WEB_VIEW_H__ -- --#include -- --#include "goaprovider.h" -- --G_BEGIN_DECLS -- --#define GOA_TYPE_WEB_VIEW (goa_web_view_get_type ()) --#define GOA_WEB_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GOA_TYPE_WEB_VIEW, GoaWebView)) --#define GOA_IS_WEB_VIEW(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GOA_TYPE_WEB_VIEW)) -- --typedef struct _GoaWebView GoaWebView; --typedef struct _GoaWebViewClass GoaWebViewClass; -- --GType goa_web_view_get_type (void) G_GNUC_CONST; --GtkWidget *goa_web_view_new (GoaProvider *provider, -- const gchar *existing_identity); --GtkWidget *goa_web_view_get_view (GoaWebView *self); --void goa_web_view_fake_mobile (GoaWebView *self); -- --G_END_DECLS -- --#endif /* __GOA_WEB_VIEW_H__ */ -diff --git a/src/goabackend/goawindowsliveprovider.c b/src/goabackend/goawindowsliveprovider.c -index 10c2dcf..2135fbd 100644 ---- a/src/goabackend/goawindowsliveprovider.c -+++ b/src/goabackend/goawindowsliveprovider.c -@@ -94,7 +94,8 @@ get_token_uri (GoaOAuth2Provider *oauth2_provider) - static const gchar * - get_redirect_uri (GoaOAuth2Provider *oauth2_provider) - { -- return "https://login.live.com/oauth20_desktop.srf"; -+ /* See: https://learn.microsoft.com/en-us/entra/identity-platform/reply-url */ -+ return "goa-oauth2://localhost/"GOA_WINDOWS_LIVE_CLIENT_ID; - } - - static const gchar * -@@ -234,36 +235,6 @@ get_identity_sync (GoaOAuth2Provider *oauth2_provider, - - /* ---------------------------------------------------------------------------------------------------- */ - --static gboolean --is_identity_node (GoaOAuth2Provider *oauth2_provider, WebKitDOMHTMLInputElement *element) --{ -- gboolean ret = FALSE; -- gchar *element_type = NULL; -- gchar *name = NULL; -- -- /* FIXME: This does not show up in -- * webkit_dom_document_get_elements_by_tag_name, but can be -- * seen in the inspector. Needs further investigation. -- */ -- -- g_object_get (element, "type", &element_type, NULL); -- if (g_strcmp0 (element_type, "email") != 0) -- goto out; -- -- name = webkit_dom_html_input_element_get_name (element); -- if (g_strcmp0 (name, "login") != 0) -- goto out; -- -- ret = TRUE; -- -- out: -- g_free (element_type); -- g_free (name); -- return ret; --} -- --/* ---------------------------------------------------------------------------------------------------- */ -- - static gboolean - build_object (GoaProvider *provider, - GoaObjectSkeleton *object, -@@ -390,6 +361,5 @@ goa_windows_live_provider_class_init (GoaWindowsLiveProviderClass *klass) - oauth2_class->get_client_id = get_client_id; - oauth2_class->get_client_secret = get_client_secret; - oauth2_class->get_identity_sync = get_identity_sync; -- oauth2_class->is_identity_node = is_identity_node; - oauth2_class->add_account_key_values = add_account_key_values; - } diff --git a/SPECS/gnome-online-accounts.spec b/gnome-online-accounts.spec similarity index 63% rename from SPECS/gnome-online-accounts.spec rename to gnome-online-accounts.spec index a7d2d7c..c7f4d3d 100644 --- a/SPECS/gnome-online-accounts.spec +++ b/gnome-online-accounts.spec @@ -1,52 +1,56 @@ -%global gettext_version 0.19.8 -%global glib2_version 2.52 -%global gtk3_version 3.19.12 -%global libsoup_version 2.42 +%global gettext_version 0.22 +%global glib2_version 2.78.3 +%global gtk4_version 4.12.4 +%global libsoup_version 3.0 Name: gnome-online-accounts -Version: 3.28.2 -Release: 7%{?dist} +Version: 3.51.0 +Release: 1%{?dist} Summary: Single sign-on framework for GNOME -License: LGPLv2+ +# Sources are LGPL-2.0-or-later, icons are CC-BY-SA-4.0. +License: LGPL-2.0-or-later AND CC-BY-SA-4.0 URL: https://wiki.gnome.org/Projects/GnomeOnlineAccounts -Source0: https://download.gnome.org/sources/gnome-online-accounts/3.28/%{name}-%{version}.tar.xz +Source0: https://download.gnome.org/sources/gnome-online-accounts/3.51/%{name}-%{version}.tar.xz -Patch01: 0001-mute-debug-prints.patch -Patch02: 0002-Drop-dependency-on-WebKitGTK-139.patch +Patch: 0001-remove-google-files-backend.patch -Obsoletes: gnome-online-accounts-oauth2 < 3.28.2-6 - -BuildRequires: pkgconfig(gcr-3) +BuildRequires: pkgconfig(gcr-4) BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version} BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version} BuildRequires: pkgconfig(gobject-2.0) >= %{glib2_version} -BuildRequires: pkgconfig(gtk+-3.0) >= %{gtk3_version} BuildRequires: pkgconfig(gobject-introspection-1.0) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(libadwaita-1) +BuildRequires: docbook-style-xsl BuildRequires: gettext >= %{gettext_version} -BuildRequires: gtk-doc BuildRequires: krb5-devel -BuildRequires: pkgconfig(json-glib-1.0) -BuildRequires: pkgconfig(libsecret-1) >= 0.7 -BuildRequires: pkgconfig(libsoup-2.4) >= %{libsoup_version} -BuildRequires: pkgconfig(rest-0.7) -%if ! 0%{?fedora} && 0%{?rhel} <= 7 -BuildRequires: pkgconfig(telepathy-glib) -%endif -BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: meson BuildRequires: vala -BuildRequires: autoconf -BuildRequires: automake +BuildRequires: /usr/bin/desktop-file-validate +BuildRequires: /usr/bin/gi-docgen +BuildRequires: /usr/bin/xsltproc +%if !0%{?flatpak} +BuildRequires: pkgconfig(gtk4) >= %{gtk4_version} +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(libsecret-1) +BuildRequires: pkgconfig(libsoup-3.0) >= %{libsoup_version} +BuildRequires: pkgconfig(rest-1.0) +BuildRequires: pkgconfig(libxml-2.0) +%endif Requires: glib2%{?_isa} >= %{glib2_version} -Requires: gtk3%{?_isa} >= %{gtk3_version} -Requires: libsoup%{?_isa} >= %{libsoup_version} +%if !0%{?flatpak} +Requires: gtk4%{?_isa} >= %{gtk4_version} +Requires: libsoup3%{?_isa} >= %{libsoup_version} +Requires: gvfs-goa +%endif %description GNOME Online Accounts provides interfaces so that applications and libraries in GNOME can access the user's online accounts. It has providers for Google, -ownCloud, Facebook, Foursquare, Microsoft Account, Pocket, Microsoft -Exchange, IMAP/SMTP and Kerberos. +Nextcloud, Flickr, Foursquare, Microsoft Account, Microsoft Exchange, Fedora, +IMAP/SMTP and Kerberos. %package devel Summary: Development files for %{name} @@ -57,120 +61,274 @@ The %{name}-devel package contains libraries and header files for developing applications that use %{name}. %prep -%setup -q -%patch01 -p1 -b .mute-debug-prints -%patch02 -p1 -b .no-webkitgtk +%autosetup -p1 -S gendiff %build -aclocal -I m4 -autoheader -automake --add-missing -libtoolize -#intltoolize --force -autoconf +%meson \ +%if 0%{?flatpak} + -Dgoabackend=false \ +%else + -Dfedora=true \ +%endif + -Dms_graph=false \ + %{nil} -%configure \ - --disable-facebook \ - --disable-flickr \ - --disable-foursquare \ - --disable-lastfm \ - --disable-media-server \ - --disable-silent-rules \ - --disable-static \ - --disable-telepathy \ - --disable-todoist \ - --enable-exchange \ - --enable-google \ - --enable-gtk-doc \ - --enable-imap-smtp \ - --enable-kerberos \ - --enable-owncloud \ - --enable-pocket \ - --enable-windows-live -%make_build +%meson_build %install -%make_install -find $RPM_BUILD_ROOT -name '*.la' -delete +%meson_install %find_lang %{name} -%if ! 0%{?fedora} && 0%{?rhel} <= 7 -%find_lang %{name}-tpaw +%check +%if !0%{?flatpak} +desktop-file-validate %{buildroot}/%{_datadir}/applications/org.gnome.OnlineAccounts.OAuth2.desktop %endif -%ldconfig_scriptlets - -%if ! 0%{?fedora} && 0%{?rhel} <= 7 -%files -f %{name}.lang -f %{name}-tpaw.lang -%else %files -f %{name}.lang -%endif - %license COPYING -%doc COPYING +%doc NEWS README.md %dir %{_libdir}/girepository-1.0 %{_libdir}/girepository-1.0/Goa-1.0.typelib %{_libdir}/libgoa-1.0.so.0 %{_libdir}/libgoa-1.0.so.0.0.0 -%{_libdir}/libgoa-backend-1.0.so.1 -%{_libdir}/libgoa-backend-1.0.so.1.0.0 +%if !0%{?flatpak} +%{_libdir}/libgoa-backend-1.0.so.2 +%{_libdir}/libgoa-backend-1.0.so.2.0.0 %dir %{_libdir}/goa-1.0 +%{_mandir}/man8/goa-daemon.8* %{_prefix}/libexec/goa-daemon %{_prefix}/libexec/goa-identity-service %{_prefix}/libexec/goa-oauth2-handler %{_datadir}/applications/org.gnome.OnlineAccounts.OAuth2.desktop %{_datadir}/dbus-1/services/org.gnome.OnlineAccounts.service %{_datadir}/dbus-1/services/org.gnome.Identity.service -%{_datadir}/icons/hicolor/*/apps/goa-*.png -%{_datadir}/man/man8/goa-daemon.8* %{_datadir}/glib-2.0/schemas/org.gnome.online-accounts.gschema.xml - -%if ! 0%{?fedora} && 0%{?rhel} <= 7 -%{_datadir}/icons/hicolor/*/apps/im-*.png -%{_datadir}/icons/hicolor/*/apps/im-*.svg - -%dir %{_datadir}/%{name} -%{_datadir}/%{name}/irc-networks.xml %endif +%{_datadir}/icons/hicolor/*/apps/goa-*.svg %files devel +%{_pkgdocdir}/Goa-1.0/ %{_includedir}/goa-1.0/ %{_libdir}/libgoa-1.0.so -%{_libdir}/libgoa-backend-1.0.so %dir %{_datadir}/gir-1.0 %{_datadir}/gir-1.0/Goa-1.0.gir %{_libdir}/pkgconfig/goa-1.0.pc +%if !0%{?flatpak} +%{_libdir}/libgoa-backend-1.0.so %{_libdir}/pkgconfig/goa-backend-1.0.pc -%{_datadir}/gtk-doc/html/goa/ +%endif %{_libdir}/goa-1.0/include %{_datadir}/vala/ %changelog -* Wed Nov 15 2023 Milan Crha - 3.28.2-7 -- Related: RHEL-10493 (Add margin around OAuth2 prompt content) +* Tue Jul 16 2024 Milan Crha - 3.51.0-1 +- Related: RHEL-45844 (Update to 3.51.0) -* Thu Nov 09 2023 Milan Crha - 3.28.2-6 -- Resolves: RHEL-10493 (Move account types that depend on WebKitGTK into separate optional subpackage) -- backport upstream fix to use external browser for OAuth2 +* Wed Jun 26 2024 Milan Crha - 3.50.2-3 +- Resolves: RHEL-45186 (Fix issues found by Coverity Scan) -* Wed Oct 11 2023 Milan Crha - 3.28.2-5 -- Resolves: RHEL-10493 (Move account types that depend on WebKitGTK into separate optional subpackage) +* Mon Jun 24 2024 Troy Dawson - 3.50.2-2 +- Bump release for June 2024 mass rebuild -* Fri Sep 02 2022 Milan Crha - 3.28.2-4 -- Resolves: #2068010 (Turn runtime warnings around libsecret into debug prints) +* Mon Jun 03 2024 Milan Crha - 3.50.2-1 +- Resolves: RHEL-39689 (Update to 3.50.2) -* Sat Apr 24 2021 Debarshi Ray - 3.28.2-3 -- Disable the Facebook and Foursquare providers -Resolves: #1951086, #1952136 +* Wed Apr 24 2024 Milan Crha - 3.50.1-2 +- Resolves: RHEL-33893 +- Disable Microsoft 365 provider +- Remove support for 'files' in Google provider -* Mon Feb 01 2021 Tomas Popela - 3.28.2-2 -- Rebuild to fix multilib issues - Resolves: #1765627 +* Mon Apr 15 2024 Milan Crha - 3.50.1-1 +- Resolves: RHEL-32777 (Backport Fedora 40 changes) +- Update to 3.50.1 -* Tue Nov 05 2019 Debarshi Ray - 3.28.2-1 -- Update to 3.28.2 -Resolves: #1674535 +* Mon Mar 25 2024 Milan Crha - 3.50.0-1 +- Resolves: RHEL-30220 (Backport Fedora 40 changes) +- Update to 3.50.0 + +* Mon Feb 12 2024 Gwyn Ciesla - 3.49.1-1 +- 3.49.1 + +* Wed Jan 24 2024 Fedora Release Engineering - 3.49.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 3.49.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Thu Jan 11 2024 Tomas Popela - 3.49.0-2 +- Don't require WebKitGTK anymore as GOA now spawns your default web browser + instead of using the web view +- Remove the RHEL patch for dropping Google Photos support as it has + been dropped upstream. + +* Wed Jan 10 2024 Gwyn Ciesla - 3.49.0-1 +- 3.49.0 + +* Tue Dec 12 2023 Yaakov Selkowitz - 3.48.0-4 +- Fix build with libxml2 2.12 + +* Wed Oct 18 2023 Yaakov Selkowitz - 3.48.0-3 +- Disable backend components in flatpak builds + +* Wed Jul 19 2023 Fedora Release Engineering - 3.48.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Sat Mar 18 2023 David King - 3.48.0-1 +- Update to 3.48.0 + +* Fri Mar 03 2023 Gwyn Ciesla - 3.47.1-4 +- ...but not for flatpaks. + +* Thu Mar 02 2023 Gwyn Ciesla - 3.47.1-3 +- Require gvfs-goa + +* Thu Mar 02 2023 Gwyn Ciesla - 3.47.1-2 +- migrated to SPDX license + +* Sun Feb 26 2023 Gwyn Ciesla - 3.47.1-1 +- 3.47.1 + +* Fri Jan 20 2023 Ray Strode - 3.46.0-6 +- Add more kerberos fixes from upstream + Related: #2152695 + +* Thu Jan 19 2023 Fedora Release Engineering - 3.46.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Mon Dec 26 2022 FeRD (Frank Dana) - 3.46.0-4 +- Restore gtk-doc API documentation to -devel. + +* Thu Dec 15 2022 Gwyn Ciesla - 3.46.0-3 +- Patches for KRB cache issues. + +* Wed Nov 30 2022 Gwyn Ciesla - 3.46.0-2 +- Patch for multiple credential cache issues. + +* Mon Sep 19 2022 Gwyn Ciesla - 3.46.0-1 +- 3.46.0 + +* Mon Aug 08 2022 Kalev Lember - 3.45.2-1 +- Update to 3.45.2 + +* Thu Jul 21 2022 Fedora Release Engineering - 3.45.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Tue Jul 19 2022 Kalev Lember - 3.45.1-1 +- Update to 3.45.1 +- Switch to meson build system +- Build against libsoup3 + +* Wed Mar 30 2022 Debarshi Ray - 3.44.0-1 +- Update to 3.44.0 + +* Thu Jan 20 2022 Fedora Release Engineering - 3.43.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Fri Oct 15 2021 Debarshi Ray - 3.43.1-1 +- Update to 3.43.1 + +* Thu Jul 22 2021 Fedora Release Engineering - 3.40.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Tue Apr 27 2021 Debarshi Ray - 3.40.0-3 +- Disable the Foursquare provider on RHEL 8 too + +* Sat Apr 24 2021 Debarshi Ray - 3.40.0-2 +- Disable the Flickr and Foursquare providers on RHEL >= 9 +- Remove Photos support from the Google provider on RHEL >= 9 + +* Thu Apr 22 2021 Debarshi Ray - 3.40.0-1 +- Update to 3.40.0 +- Disable the Facebook provider + +* Tue Mar 16 2021 Debarshi Ray - 3.39.92-1 +- Update to 3.39.92 + +* Tue Jan 26 2021 Fedora Release Engineering - 3.38.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Fri Oct 16 2020 Kalev Lember - 3.38.0-1 +- Update to 3.38.0 + +* Mon Aug 10 2020 Debarshi Ray - 3.37.90-1 +- Update to 3.37.90 + +* Sat Aug 01 2020 Fedora Release Engineering - 3.36.0-3 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 3.36.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Mar 10 2020 Kalev Lember - 3.36.0-1 +- Update to 3.36.0 + +* Tue Feb 11 2020 Kalev Lember - 3.35.90-1 +- Update to 3.35.90 + +* Tue Jan 28 2020 Fedora Release Engineering - 3.35.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Sat Jan 04 2020 Debarshi Ray - 3.35.3-1 +- Update to 3.35.3 + +* Tue Oct 15 2019 Debarshi Ray - 3.35.1-1 +- Update to 3.35.1 + +* Wed Sep 11 2019 Kalev Lember - 3.34.0-1 +- Update to 3.34.0 + +* Tue Sep 03 2019 Kalev Lember - 3.33.92-1 +- Update to 3.33.92 + +* Wed Aug 21 2019 Debarshi Ray - 3.33.91-1 +- Update to 3.33.91 + +* Thu Jul 25 2019 Fedora Release Engineering - 3.32.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Mar 29 2019 Kalev Lember - 3.32.0-1 +- Update to 3.32.0 + +* Sat Feb 09 2019 Debarshi Ray - 3.31.90-1 +- Update to 3.31.90 + +* Thu Jan 31 2019 Fedora Release Engineering - 3.31.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Dec 17 2018 Debarshi Ray - 3.31.3-2 +- Drop the documents integration (fedora-workstation/issue/83) + +* Wed Dec 12 2018 Debarshi Ray - 3.31.3-1 +- Update to 3.31.3 + +* Fri Sep 07 2018 Kalev Lember - 3.30.0-3 +- Rebuilt against fixed atk (#1626575) + +* Fri Sep 07 2018 Kalev Lember - 3.30.0-2 +- Fix gtk-doc directory ownership + +* Mon Sep 03 2018 Debarshi Ray - 3.30.0-1 +- Update to 3.30.0 +- Disable Pocket + +* Thu Aug 16 2018 Debarshi Ray - 3.29.91-1 +- Update to 3.29.91 + +* Thu Aug 9 2018 Owen Taylor - 3.29.4-2 +- Remove Requires: gettext-libs - it is extraneous +- Use a glob for man page, to handle variations in man page compression. + +* Wed Jul 18 2018 Debarshi Ray - 3.29.4-1 +- Update to 3.29.4 + +* Mon Jul 16 2018 Debarshi Ray - 3.29.1-1 +- Update to 3.29.1 +- Drop RHEL 7 compatibility because Telepathy is no longer supported + +* Fri Jul 13 2018 Fedora Release Engineering - 3.28.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild * Thu Mar 15 2018 Kalev Lember - 3.28.0-1 - Update to 3.28.0 @@ -605,4 +763,3 @@ Resolves: #1674535 * Mon Jun 13 2011 Bastien Nocera 3.1.0-1 - First version - diff --git a/sources b/sources new file mode 100644 index 0000000..1266b50 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (gnome-online-accounts-3.51.0.tar.xz) = 36849c734c2fef152c67d6b0ec00cdcd126d1ddac055ce44d6daebafeaf665afd9b4f5b09dcd19a05612fdcfdbdb20d9f54a502b5a857e399f110d9fd5701ad2