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