[gthumb] facebook: use the OAuth2 authentication method and the Graph API



commit d5cbcc43120090b97c619c43f5a013e1d67351f9
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Dec 11 23:13:24 2012 +0100

    facebook: use the OAuth2 authentication method and the Graph API

 configure.ac                                       |   36 +-
 extensions/facebook/Makefile.am                    |    4 +-
 extensions/facebook/data/ui/Makefile.am            |    2 -
 extensions/facebook/data/ui/export-to-facebook.ui  |   30 +--
 .../facebook/data/ui/facebook-account-manager.ui   |    6 +-
 .../facebook/data/ui/facebook-album-properties.ui  |   50 +--
 .../facebook/data/ui/facebook-ask-authorization.ui |   84 ----
 .../data/ui/facebook-complete-authorization.ui     |   86 ----
 extensions/facebook/dlg-export-to-facebook.c       |   59 ++-
 extensions/facebook/facebook-account.c             |   27 +-
 extensions/facebook/facebook-account.h             |    7 +-
 .../facebook/facebook-album-properties-dialog.c    |   53 ++-
 .../facebook/facebook-album-properties-dialog.h    |    4 +-
 extensions/facebook/facebook-album.c               |  255 ++++++-----
 extensions/facebook/facebook-album.h               |   24 +-
 extensions/facebook/facebook-authentication.c      |  387 +++++------------
 extensions/facebook/facebook-authentication.h      |    3 +-
 extensions/facebook/facebook-connection.c          |  382 +++--------------
 extensions/facebook/facebook-connection.h          |   42 +--
 extensions/facebook/facebook-service.c             |  454 ++++++--------------
 extensions/facebook/facebook-service.h             |   13 +-
 extensions/facebook/facebook-user.c                |  150 ++++---
 extensions/facebook/facebook-user.h                |    6 +-
 extensions/facebook/facebook.extension.in.in       |    2 +-
 extensions/oauth/Makefile.am                       |    6 +-
 extensions/oauth/data/ui/Makefile.am               |    2 +-
 extensions/oauth/oauth2-ask-authorization-dialog.c |  134 ++++++
 extensions/oauth/oauth2-ask-authorization-dialog.h |   62 +++
 gthumb/Makefile.am                                 |    2 +-
 29 files changed, 904 insertions(+), 1468 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4d058bd..14eb297 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,8 +70,8 @@ LIBBRASERO_REQUIRED=3.2.0
 LIBCHAMPLAIN_REQUIRED=0.12.0
 LIBRSVG_REQUIRED=2.34.0
 LIBWEBP_REQUIRED=0.2.0
-LIBJSON_GLIB_REQUIRED=0.15.0
-WEBKITGTK_REQUIRED=1.10.0
+JSON_GLIB_REQUIRED=0.15.0
+WEBKIT2_REQUIRED=1.10.0
 
 dnl ===========================================================================
 
@@ -518,19 +518,19 @@ AC_SUBST(LIBSOUP_LIBS)
 
 dnl ===========================================================================
 
-AC_ARG_ENABLE([libjson_glib],
+AC_ARG_ENABLE([json_glib],
 	      [AS_HELP_STRING([--disable-libjson-glib],[do not compile code that uses the libjson-glib library])],,
-	      [enable_libjson_glib=yes])
-
-if test x$enable_libjson_glib = xyes ; then
-	PKG_CHECK_MODULES(LIBJSON_GLIB,
-			  [libjson-glib-1.0 >= $LIBJSON_GLIB_REQUIRED],
-			  [AC_DEFINE(HAVE_LIBJSON_GLIB, 1, [Have libjson-glib])
-			   enable_libjson_glib=yes],
-			  [enable_libjson_glib=no])
+	      [enable_json_glib=yes])
+
+if test x$enable_json_glib = xyes ; then
+	PKG_CHECK_MODULES(JSON_GLIB,
+			  [json-glib-1.0 >= $JSON_GLIB_REQUIRED],
+			  [AC_DEFINE(HAVE_JSON_GLIB, 1, [Have libjson-glib])
+			   enable_json_glib=yes],
+			  [enable_json_glib=no])
 fi
-AC_SUBST(LIBJSON_GLIB_CFLAGS)
-AC_SUBST(LIBJSON_GLIB_LIBS)
+AC_SUBST(JSON_GLIB_CFLAGS)
+AC_SUBST(JSON_GLIB_LIBS)
 
 dnl ===========================================================================
 
@@ -548,7 +548,13 @@ fi
 AC_SUBST(WEBKIT2_CFLAGS)
 AC_SUBST(WEBKIT2_LIBS)
 
-AM_CONDITIONAL(ENABLE_WEB_SERVICES, test "x$enable_libsoup" = xyes && test "x$enable_libjson_glib" = xyes && test "x$enable_webkit2" = xyes)
+if [ test "x$enable_libsoup" = xyes && test "x$enable_json_glib" = xyes && test "x$enable_webkit2" = xyes ] ; then
+  enable_web_services=yes
+else
+  enable_web_services=no
+fi
+
+AM_CONDITIONAL(ENABLE_WEB_SERVICES, test "x$enable_web_services" = xyes)
 
 dnl ===========================================================================
 
@@ -787,7 +793,7 @@ Configuration:
 	Clutter support      : ${enable_clutter}
 	GStreamer support    : ${enable_gstreamer}
 	Use libopenraw       : ${enable_libopenraw}
-	Web services support : ${enable_libsoup}
+	Web services support : ${enable_web_services}
 	Use libsecret        : ${enable_libsecret}
 	Burn disc support    : ${enable_libbrasero}
 	Web albums           : ${enable_web_albums}
diff --git a/extensions/facebook/Makefile.am b/extensions/facebook/Makefile.am
index d3faec8..5456eec 100644
--- a/extensions/facebook/Makefile.am
+++ b/extensions/facebook/Makefile.am
@@ -36,9 +36,9 @@ libfacebook_la_SOURCES = 			\
 	main.c					\
 	preferences.h
 
-libfacebook_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBSECRET_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+libfacebook_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBSECRET_CFLAGS) $(WEBKIT2_CFLAGS) $(JSON_GLIB_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
 libfacebook_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
-libfacebook_la_LIBADD = $(GTHUMB_LIBS) $(LIBSOUP_LIBS) $(LIBSECRET_LIBS) ../export_tools/libexport_tools.la
+libfacebook_la_LIBADD = $(GTHUMB_LIBS) $(LIBSOUP_LIBS) $(LIBSECRET_LIBS) $(WEBKIT2_LIBS) $(JSON_GLIB_LIBS) ../export_tools/libexport_tools.la ../oauth/liboauth.la
 libfacebook_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
 
 extensioninidir = $(extensiondir)
diff --git a/extensions/facebook/data/ui/Makefile.am b/extensions/facebook/data/ui/Makefile.am
index ce64791..2007a37 100644
--- a/extensions/facebook/data/ui/Makefile.am
+++ b/extensions/facebook/data/ui/Makefile.am
@@ -4,8 +4,6 @@ ui_DATA = 					\
 	facebook-account-chooser.ui		\
 	facebook-account-manager.ui		\
 	facebook-album-properties.ui		\
-	facebook-ask-authorization.ui		\
-	facebook-complete-authorization.ui	\
 	facebook-export-completed.ui
 
 EXTRA_DIST = $(ui_DATA)
diff --git a/extensions/facebook/data/ui/export-to-facebook.ui b/extensions/facebook/data/ui/export-to-facebook.ui
index ca1ad1f..0688877 100644
--- a/extensions/facebook/data/ui/export-to-facebook.ui
+++ b/extensions/facebook/data/ui/export-to-facebook.ui
@@ -40,11 +40,9 @@
             <child>
               <object class="GtkButton" id="close_button">
                 <property name="label">gtk-cancel</property>
-                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
               </object>
               <packing>
@@ -56,11 +54,9 @@
             <child>
               <object class="GtkButton" id="upload_button">
                 <property name="label" translatable="yes">_Upload</property>
-                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="image">upload_image</property>
                 <property name="use_underline">True</property>
               </object>
@@ -70,23 +66,6 @@
                 <property name="position">1</property>
               </packing>
             </child>
-            <child>
-              <object class="GtkButton" id="button1">
-                <property name="label">gtk-help</property>
-                <property name="use_action_appearance">False</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-                <property name="secondary">True</property>
-              </packing>
-            </child>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -192,17 +171,15 @@
                             </child>
                             <child>
                               <object class="GtkButton" id="edit_accounts_button">
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
                                 <property name="tooltip_text" translatable="yes">Edit accounts</property>
-                                <property name="use_action_appearance">False</property>
                                 <child>
                                   <object class="GtkImage" id="image2">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="stock">gtk-edit</property>
+                                    <property name="icon_name">view-list-symbolic</property>
                                   </object>
                                 </child>
                               </object>
@@ -260,17 +237,15 @@
                         </child>
                         <child>
                           <object class="GtkButton" id="add_album_button">
-                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
                             <property name="tooltip_text" translatable="yes">Add a new album</property>
-                            <property name="use_action_appearance">False</property>
                             <child>
                               <object class="GtkImage" id="image1">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="stock">gtk-add</property>
+                                <property name="icon_name">list-add-symbolic</property>
                               </object>
                             </child>
                           </object>
@@ -363,7 +338,6 @@
     <action-widgets>
       <action-widget response="-6">close_button</action-widget>
       <action-widget response="-5">upload_button</action-widget>
-      <action-widget response="-11">button1</action-widget>
     </action-widgets>
   </object>
   <object class="GtkListStore" id="resize_liststore">
diff --git a/extensions/facebook/data/ui/facebook-account-manager.ui b/extensions/facebook/data/ui/facebook-account-manager.ui
index b63c358..29cf12b 100644
--- a/extensions/facebook/data/ui/facebook-account-manager.ui
+++ b/extensions/facebook/data/ui/facebook-account-manager.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkListStore" id="accounts_liststore">
     <columns>
       <!-- column-name data -->
@@ -78,16 +78,14 @@
             <property name="spacing">6</property>
             <child>
               <object class="GtkButton" id="delete_button">
-                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <child>
                   <object class="GtkImage" id="image3">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="stock">gtk-delete</property>
+                    <property name="icon_name">list-remove-symbolic</property>
                   </object>
                 </child>
               </object>
diff --git a/extensions/facebook/data/ui/facebook-album-properties.ui b/extensions/facebook/data/ui/facebook-album-properties.ui
index 1af54e8..8bcad05 100644
--- a/extensions/facebook/data/ui/facebook-album-properties.ui
+++ b/extensions/facebook/data/ui/facebook-album-properties.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.18"/>
+  <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkListStore" id="visibility_liststore">
     <columns>
       <!-- column-name name -->
@@ -30,7 +30,7 @@
       <object class="GtkTable" id="table1">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="n_rows">4</property>
+        <property name="n_rows">3</property>
         <property name="n_columns">2</property>
         <property name="column_spacing">6</property>
         <property name="row_spacing">6</property>
@@ -70,8 +70,8 @@
             <property name="use_underline">True</property>
           </object>
           <packing>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
             <property name="x_options">GTK_FILL</property>
             <property name="y_options">GTK_FILL</property>
           </packing>
@@ -94,7 +94,7 @@
                 </child>
               </object>
               <packing>
-                <property name="expand">False</property>
+                <property name="expand">True</property>
                 <property name="fill">True</property>
                 <property name="position">0</property>
               </packing>
@@ -103,47 +103,16 @@
           <packing>
             <property name="left_attach">1</property>
             <property name="right_attach">2</property>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkEntry" id="description_entry">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="invisible_char">â</property>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
             <property name="top_attach">2</property>
             <property name="bottom_attach">3</property>
             <property name="y_options">GTK_FILL</property>
           </packing>
         </child>
         <child>
-          <object class="GtkLabel" id="label3">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="xalign">0</property>
-            <property name="label" translatable="yes">D_escription:</property>
-            <property name="use_underline">True</property>
-            <property name="mnemonic_widget">description_entry</property>
-          </object>
-          <packing>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkEntry" id="location_entry">
-            <property name="width_request">300</property>
+          <object class="GtkEntry" id="description_entry">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="invisible_char">â</property>
-            <property name="invisible_char_set">True</property>
           </object>
           <packing>
             <property name="left_attach">1</property>
@@ -154,18 +123,17 @@
           </packing>
         </child>
         <child>
-          <object class="GtkLabel" id="label4">
+          <object class="GtkLabel" id="label3">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="xalign">0</property>
-            <property name="label" translatable="yes">_Location:</property>
+            <property name="label" translatable="yes">D_escription:</property>
             <property name="use_underline">True</property>
-            <property name="mnemonic_widget">location_entry</property>
+            <property name="mnemonic_widget">description_entry</property>
           </object>
           <packing>
             <property name="top_attach">1</property>
             <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
             <property name="y_options">GTK_FILL</property>
           </packing>
         </child>
diff --git a/extensions/facebook/dlg-export-to-facebook.c b/extensions/facebook/dlg-export-to-facebook.c
index 6fd71b9..96bd704 100644
--- a/extensions/facebook/dlg-export-to-facebook.c
+++ b/extensions/facebook/dlg-export-to-facebook.c
@@ -67,7 +67,7 @@ typedef struct {
 	FacebookConnection     *conn;
 	FacebookAuthentication *auth;
 	FacebookService        *service;
-	FacebookUser           *user;
+	FacebookAccount        *account;
 	GList                  *albums;
 	FacebookAlbum          *album;
 	GList                  *photos_ids;
@@ -86,7 +86,7 @@ destroy_dialog (DialogData *data)
 	_g_string_list_free (data->photos_ids);
 	_g_object_unref (data->album);
 	_g_object_list_unref (data->albums);
-	_g_object_unref (data->user);
+	_g_object_unref (data->account);
 	_g_object_unref (data->service);
 	_g_object_unref (data->auth);
 	_g_object_unref (data->conn);
@@ -177,7 +177,7 @@ upload_photos_ready_cb (GObject      *source_object,
 	DialogData *data = user_data;
 	GError     *error = NULL;
 
-	data->photos_ids = facebook_service_upload_photos_finish (FACEBOOK_SERVICE (source_object), result, &error);
+	data->photos_ids = facebook_service_upload_photos_finish (data->service, result, &error);
 	if (error != NULL) {
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not upload the files"), error);
 		g_clear_error (&error);
@@ -197,10 +197,6 @@ export_dialog_response_cb (GtkDialog *dialog,
 	DialogData *data = user_data;
 
 	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (data->browser), "gthumb-export-social");
-		break;
-
 	case GTK_RESPONSE_DELETE_EVENT:
 	case GTK_RESPONSE_CANCEL:
 		gth_file_list_cancel (GTH_FILE_LIST (data->list_view), (DataFunc) destroy_dialog, data);
@@ -212,9 +208,6 @@ export_dialog_response_cb (GtkDialog *dialog,
 			GList       *file_list;
 			int          max_resolution;
 
-			gtk_widget_hide (data->dialog);
-			gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-
 			data->album = NULL;
 			if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), &iter)) {
 				gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (GET_WIDGET ("album_combobox"))),
@@ -223,6 +216,12 @@ export_dialog_response_cb (GtkDialog *dialog,
 						    -1);
 			}
 
+			if (data->album == NULL)
+				return;
+
+			gtk_widget_hide (data->dialog);
+			gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
+
 			max_resolution = 0;
 			if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("resize_combobox")), &iter)) {
 				gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (GET_WIDGET ("resize_combobox"))),
@@ -301,7 +300,7 @@ update_album_list (DialogData    *data,
 		char          *size;
 		GtkTreeIter    iter;
 
-		size = g_strdup_printf ("(%d)", album->size);
+		size = g_strdup_printf ("(%d)", album->count);
 
 		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter);
 		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter,
@@ -328,7 +327,7 @@ get_albums_ready_cb (GObject      *source_object,
 	GError     *error = NULL;
 
 	_g_object_list_unref (data->albums);
-	data->albums = facebook_service_get_albums_finish (FACEBOOK_SERVICE (source_object), res, &error);
+	data->albums = facebook_service_get_albums_finish (data->service, res, &error);
 	if (error != NULL) {
 		if (data->conn != NULL)
 			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
@@ -338,7 +337,6 @@ get_albums_ready_cb (GObject      *source_object,
 		return;
 	}
 
-	gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), TRUE);
 	update_album_list (data, NULL);
 
 	gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
@@ -350,15 +348,13 @@ get_albums_ready_cb (GObject      *source_object,
 
 static void
 authentication_ready_cb (FacebookAuthentication *auth,
-			 FacebookUser           *user,
 			 DialogData             *data)
 {
-	_g_object_unref (data->user);
-	data->user = g_object_ref (user);
+	_g_object_unref (data->account);
+	data->account = _g_object_ref (facebook_authentication_get_account (auth));
 	update_account_list (data);
 
 	facebook_service_get_albums (data->service,
-				     data->user->id,
 				     data->cancellable,
 				     get_albums_ready_cb,
 				     data);
@@ -436,11 +432,11 @@ new_album_dialog_response_cb (GtkDialog *dialog,
 		{
 			FacebookAlbum *album;
 
-			album = facebook_album_new ();
-			facebook_album_set_name (album, facebook_album_properties_dialog_get_name (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog)));
-			facebook_album_set_location (album, facebook_album_properties_dialog_get_location (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog)));
-			facebook_album_set_description (album, facebook_album_properties_dialog_get_description (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog)));
-			album->visibility = facebook_album_properties_dialog_get_visibility (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog));
+			album = g_object_new (FACEBOOK_TYPE_ALBUM,
+					      "name", facebook_album_properties_dialog_get_name (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog)),
+					      "description", facebook_album_properties_dialog_get_description (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog)),
+					      "privacy", facebook_album_properties_dialog_get_visibility (FACEBOOK_ALBUM_PROPERTIES_DIALOG (dialog)),
+					      NULL);
 			facebook_service_create_album (data->service,
 						       album,
 						       data->cancellable,
@@ -467,7 +463,6 @@ add_album_button_clicked_cb (GtkButton *button,
 
 	dialog = facebook_album_properties_dialog_new (g_file_info_get_edit_name (data->location->info),
 						       NULL,
-						       NULL,
 						       FACEBOOK_VISIBILITY_SELF);
 	g_signal_connect (dialog,
 			  "delete-event",
@@ -485,6 +480,18 @@ add_album_button_clicked_cb (GtkButton *button,
 }
 
 
+static void
+album_combobox_changed_cb (GtkComboBox *combo_box,
+			   gpointer     user_data)
+{
+	DialogData *data = user_data;
+
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+					   GTK_RESPONSE_OK,
+					   gtk_combo_box_get_active (combo_box) >= 0);
+}
+
+
 void
 dlg_export_to_facebook (GthBrowser *browser,
 		        GList      *file_list)
@@ -586,7 +593,7 @@ dlg_export_to_facebook (GthBrowser *browser,
 	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("images_box")), data->list_view, TRUE, TRUE, 0);
 	gth_file_list_set_files (GTH_FILE_LIST (data->list_view), data->file_list);
 
-	gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), FALSE);
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, FALSE);
 
 	title = g_strdup_printf (_("Export to %s"), "Facebook");
 	gtk_window_set_title (GTK_WINDOW (data->dialog), title);
@@ -642,6 +649,10 @@ dlg_export_to_facebook (GthBrowser *browser,
 			  "clicked",
 			  G_CALLBACK (add_album_button_clicked_cb),
 			  data);
+	g_signal_connect (GET_WIDGET ("album_combobox"),
+			  "changed",
+			  G_CALLBACK (album_combobox_changed_cb),
+			  data);
 
 	data->conn = facebook_connection_new ();
 	data->service = facebook_service_new (data->conn);
diff --git a/extensions/facebook/facebook-account.c b/extensions/facebook/facebook-account.c
index e3ee154..36d1236 100644
--- a/extensions/facebook/facebook-account.c
+++ b/extensions/facebook/facebook-account.c
@@ -48,8 +48,7 @@ facebook_account_finalize (GObject *obj)
 
 	g_free (self->user_id);
 	g_free (self->username);
-	g_free (self->session_key);
-	g_free (self->secret);
+	g_free (self->token);
 
 	G_OBJECT_CLASS (facebook_account_parent_class)->finalize (obj);
 }
@@ -88,10 +87,8 @@ facebook_account_create_element (DomDomizable *base,
 #endif
 
 	if (set_secret) {
-		if (self->session_key != NULL)
-			dom_element_set_attribute (element, "session_key", self->session_key);
-		if (self->secret != NULL)
-			dom_element_set_attribute (element, "secret", self->secret);
+		if (self->token != NULL)
+			dom_element_set_attribute (element, "token", self->token);
 	}
 	if (self->is_default)
 		dom_element_set_attribute (element, "default", "1");
@@ -110,8 +107,7 @@ facebook_account_load_from_element (DomDomizable *base,
 
 	_g_strset (&self->user_id, dom_element_get_attribute (element, "uid"));
 	_g_strset (&self->username, dom_element_get_attribute (element, "username"));
-	_g_strset (&self->session_key, dom_element_get_attribute (element, "session_key"));
-	_g_strset (&self->secret, dom_element_get_attribute (element, "secret"));
+	_g_strset (&self->token, dom_element_get_attribute (element, "token"));
 	self->is_default = (g_strcmp0 (dom_element_get_attribute (element, "default"), "1") == 0);
 }
 
@@ -129,8 +125,7 @@ facebook_account_init (FacebookAccount *self)
 {
 	self->user_id = NULL;
 	self->username = NULL;
-	self->session_key = NULL;
-	self->secret = NULL;
+	self->token = NULL;
 	self->is_default = FALSE;
 }
 
@@ -143,18 +138,10 @@ facebook_account_new (void)
 
 
 void
-facebook_account_set_session_key (FacebookAccount *self,
+facebook_account_set_token (FacebookAccount *self,
 				  const char      *value)
 {
-	_g_strset (&self->session_key, value);
-}
-
-
-void
-facebook_account_set_secret (FacebookAccount *self,
-			     const char      *value)
-{
-	_g_strset (&self->secret, value);
+	_g_strset (&self->token, value);
 }
 
 
diff --git a/extensions/facebook/facebook-account.h b/extensions/facebook/facebook-account.h
index 72d246e..fd74731 100644
--- a/extensions/facebook/facebook-account.h
+++ b/extensions/facebook/facebook-account.h
@@ -44,8 +44,7 @@ struct _FacebookAccount {
 
 	char     *user_id;
 	char     *username;
-	char     *session_key;
-	char     *secret;
+	char     *token;
 	gboolean  is_default;
 };
 
@@ -55,9 +54,7 @@ struct _FacebookAccountClass {
 
 GType             facebook_account_get_type         (void);
 FacebookAccount * facebook_account_new              (void);
-void              facebook_account_set_session_key  (FacebookAccount *self,
-						     const char      *value);
-void              facebook_account_set_secret       (FacebookAccount *self,
+void              facebook_account_set_token        (FacebookAccount *self,
 						     const char      *value);
 void              facebook_account_set_user_id      (FacebookAccount *self,
 						     const char      *value);
diff --git a/extensions/facebook/facebook-album-properties-dialog.c b/extensions/facebook/facebook-album-properties-dialog.c
index 6fadb1c..f9fdc49 100644
--- a/extensions/facebook/facebook-album-properties-dialog.c
+++ b/extensions/facebook/facebook-album-properties-dialog.c
@@ -86,7 +86,6 @@ facebook_album_properties_dialog_init (FacebookAlbumPropertiesDialog *self)
 static void
 facebook_album_properties_dialog_construct (FacebookAlbumPropertiesDialog *self,
 				            const char                    *name,
-				            const char                    *location,
 				            const char                    *description,
 				            FacebookVisibility             visibility)
 {
@@ -94,8 +93,6 @@ facebook_album_properties_dialog_construct (FacebookAlbumPropertiesDialog *self,
 
 	if (name != NULL)
 		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("name_entry")), name);
-	if (location != NULL)
-		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("location_entry")), location);
 	if (description != NULL)
 		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("description_entry")), description);
 
@@ -119,14 +116,13 @@ facebook_album_properties_dialog_construct (FacebookAlbumPropertiesDialog *self,
 
 GtkWidget *
 facebook_album_properties_dialog_new (const char         *name,
-				      const char         *location,
 				      const char         *description,
 				      FacebookVisibility  visibility)
 {
 	FacebookAlbumPropertiesDialog *self;
 
 	self = g_object_new (FACEBOOK_TYPE_ALBUM_PROPERTIES_DIALOG, NULL);
-	facebook_album_properties_dialog_construct (self, name, location, description, visibility);
+	facebook_album_properties_dialog_construct (self, name, description, visibility);
 
 	return (GtkWidget *) self;
 }
@@ -140,32 +136,51 @@ facebook_album_properties_dialog_get_name (FacebookAlbumPropertiesDialog *self)
 
 
 const char *
-facebook_album_properties_dialog_get_location (FacebookAlbumPropertiesDialog *self)
+facebook_album_properties_dialog_get_description (FacebookAlbumPropertiesDialog *self)
 {
-	return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("location_entry")));
+	return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("description_entry")));
 }
 
 
-const char *
-facebook_album_properties_dialog_get_description (FacebookAlbumPropertiesDialog *self)
+static const char *
+get_privacy_from_visibility (FacebookVisibility visibility)
 {
-	return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("description_entry")));
+	char *value = NULL;
+
+	switch (visibility) {
+	case FACEBOOK_VISIBILITY_EVERYONE:
+		value = "{ 'value': 'EVERYONE' }";
+		break;
+
+	case FACEBOOK_VISIBILITY_ALL_FRIENDS:
+		value = "{ 'value': 'ALL_FRIENDS' }";
+		break;
+
+	case FACEBOOK_VISIBILITY_SELF:
+		value = "{ 'value': 'SELF' }";
+		break;
+
+	default:
+		break;
+	}
+
+	return value;
 }
 
 
-FacebookVisibility
+const char *
 facebook_album_properties_dialog_get_visibility (FacebookAlbumPropertiesDialog *self)
 {
 	GtkTreeIter        iter;
 	FacebookVisibility value;
 
-	if (! gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("visibility_combobox")), &iter))
-		return FACEBOOK_VISIBILITY_SELF;
-
-	gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (GET_WIDGET ("visibility_combobox"))),
-			    &iter,
-			    1, &value,
-			    -1);
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("visibility_combobox")), &iter))
+		gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (GET_WIDGET ("visibility_combobox"))),
+				    &iter,
+				    1, &value,
+				    -1);
+	else
+		value = FACEBOOK_VISIBILITY_SELF;
 
-	return value;
+	return get_privacy_from_visibility (value);
 }
diff --git a/extensions/facebook/facebook-album-properties-dialog.h b/extensions/facebook/facebook-album-properties-dialog.h
index 89e2421..2a3241c 100644
--- a/extensions/facebook/facebook-album-properties-dialog.h
+++ b/extensions/facebook/facebook-album-properties-dialog.h
@@ -50,13 +50,11 @@ struct _FacebookAlbumPropertiesDialogClass {
 
 GType               facebook_album_properties_dialog_get_type        (void);
 GtkWidget *         facebook_album_properties_dialog_new             (const char                    *name,
-								      const char                    *location,
 								      const char                    *description,
 								      FacebookVisibility             visibility);
 const char *        facebook_album_properties_dialog_get_name        (FacebookAlbumPropertiesDialog *self);
-const char *        facebook_album_properties_dialog_get_location    (FacebookAlbumPropertiesDialog *self);
 const char *        facebook_album_properties_dialog_get_description (FacebookAlbumPropertiesDialog *self);
-FacebookVisibility  facebook_album_properties_dialog_get_visibility  (FacebookAlbumPropertiesDialog *self);
+const char *        facebook_album_properties_dialog_get_visibility  (FacebookAlbumPropertiesDialog *self);
 
 G_END_DECLS
 
diff --git a/extensions/facebook/facebook-album.c b/extensions/facebook/facebook-album.c
index 49659c3..9d54b87 100644
--- a/extensions/facebook/facebook-album.c
+++ b/extensions/facebook/facebook-album.c
@@ -26,14 +26,19 @@
 #include "facebook-album.h"
 
 
-static void facebook_album_dom_domizable_interface_init (DomDomizableInterface *iface);
+G_DEFINE_TYPE (FacebookAlbum, facebook_album, G_TYPE_OBJECT)
 
 
-G_DEFINE_TYPE_WITH_CODE (FacebookAlbum,
-			 facebook_album,
-			 G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (DOM_TYPE_DOMIZABLE,
-					        facebook_album_dom_domizable_interface_init))
+enum {
+        PROP_0,
+        PROP_ID,
+        PROP_NAME,
+        PROP_DESCRIPTION,
+        PROP_LINK,
+        PROP_PRIVACY,
+        PROP_COUNT,
+        PROP_CAN_UPLOAD
+};
 
 
 static void
@@ -46,111 +51,153 @@ facebook_album_finalize (GObject *obj)
 	g_free (self->id);
 	g_free (self->name);
 	g_free (self->description);
-	g_free (self->location);
 	g_free (self->link);
+	g_free (self->privacy);
 
 	G_OBJECT_CLASS (facebook_album_parent_class)->finalize (obj);
 }
 
 
 static void
-facebook_album_class_init (FacebookAlbumClass *klass)
-{
-	G_OBJECT_CLASS (klass)->finalize = facebook_album_finalize;
-}
-
-
-static DomElement*
-facebook_album_create_element (DomDomizable *base,
-			       DomDocument  *doc)
+facebook_album_set_property (GObject      *object,
+			     guint         property_id,
+			     const GValue *value,
+			     GParamSpec   *pspec)
 {
 	FacebookAlbum *self;
-	DomElement    *element;
-
-	self = FACEBOOK_ALBUM (base);
-
-	element = dom_document_create_element (doc, "photoset", NULL);
-	if (self->id != NULL)
-		dom_element_set_attribute (element, "aid", self->id);
-	if (self->name != NULL)
-		dom_element_append_child (element, dom_document_create_element_with_text (doc, self->name, "name", NULL));
-	if (self->description != NULL)
-		dom_element_append_child (element, dom_document_create_element_with_text (doc, self->description, "description", NULL));
 
-	return element;
-}
-
-
-static FacebookVisibility
-get_visibility_by_name (const char *name)
-{
-	if (name == NULL)
-		return FACEBOOK_VISIBILITY_EVERYONE;
-	if (g_strcmp0 (name, "everyone") == 0)
-		return FACEBOOK_VISIBILITY_EVERYONE;
-	if (g_strcmp0 (name, "networks_friends") == 0)
-		return FACEBOOK_VISIBILITY_NETWORKS_FRIENDS;
-	if (g_strcmp0 (name, "friends_of_friends") == 0)
-		return FACEBOOK_VISIBILITY_FRIENDS_OF_FRIENDS;
-	if (g_strcmp0 (name, "all_friends") == 0)
-		return FACEBOOK_VISIBILITY_ALL_FRIENDS;
-	if (g_strcmp0 (name, "self") == 0)
-		return FACEBOOK_VISIBILITY_SELF;
-	if (g_strcmp0 (name, "custom") == 0)
-		return FACEBOOK_VISIBILITY_CUSTOM;
-
-	return FACEBOOK_VISIBILITY_EVERYONE;
+        self = FACEBOOK_ALBUM (object);
+
+	switch (property_id) {
+	case PROP_ID:
+		_g_strset (&self->id, g_value_get_string (value));
+		break;
+	case PROP_NAME:
+		_g_strset (&self->name, g_value_get_string (value));
+		break;
+	case PROP_DESCRIPTION:
+		_g_strset (&self->description, g_value_get_string (value));
+		break;
+	case PROP_LINK:
+		_g_strset (&self->link, g_value_get_string (value));
+		break;
+	case PROP_PRIVACY:
+		_g_strset (&self->privacy, g_value_get_string (value));
+		break;
+	case PROP_COUNT:
+		self->count = g_value_get_int (value);
+		break;
+	case PROP_CAN_UPLOAD:
+		self->can_upload = g_value_get_boolean (value);
+		break;
+	default:
+		break;
+	}
 }
 
 
 static void
-facebook_album_load_from_element (DomDomizable *base,
-				   DomElement   *element)
+facebook_album_get_property (GObject    *object,
+			     guint       property_id,
+			     GValue     *value,
+			     GParamSpec *pspec)
 {
 	FacebookAlbum *self;
-	DomElement     *node;
-
-	self = FACEBOOK_ALBUM (base);
-
-	_g_strset (&self->id, NULL);
-	_g_strset (&self->name, NULL);
-	_g_strset (&self->description, NULL);
-	_g_strset (&self->location, NULL);
-	_g_strset (&self->link, NULL);
-	self->size = 0;
-	self->visibility = FACEBOOK_VISIBILITY_SELF;
-
-	for (node = element->first_child; node; node = node->next_sibling) {
-		if (g_strcmp0 (node->tag_name, "aid") == 0) {
-			_g_strset (&self->id, dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "name") == 0) {
-			_g_strset (&self->name, dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "description") == 0) {
-			_g_strset (&self->description, dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "location") == 0) {
-			_g_strset (&self->location, dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "link") == 0) {
-			_g_strset (&self->link, dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "size") == 0) {
-			self->size = atoi (dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "visible") == 0) {
-			self->visibility = get_visibility_by_name (dom_element_get_inner_text (node));
-		}
+
+        self = FACEBOOK_ALBUM (object);
+
+	switch (property_id) {
+	case PROP_ID:
+		g_value_set_string (value, self->id);
+		break;
+	case PROP_NAME:
+		g_value_set_string (value, self->name);
+		break;
+	case PROP_DESCRIPTION:
+		g_value_set_string (value, self->description);
+		break;
+	case PROP_LINK:
+		g_value_set_string (value, self->link);
+		break;
+	case PROP_PRIVACY:
+		g_value_set_string (value, self->privacy);
+		break;
+	case PROP_COUNT:
+		g_value_set_int (value, self->count);
+		break;
+	case PROP_CAN_UPLOAD:
+		 g_value_set_boolean (value, self->can_upload);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
 	}
 }
 
 
 static void
-facebook_album_dom_domizable_interface_init (DomDomizableInterface *iface)
+facebook_album_class_init (FacebookAlbumClass *klass)
 {
-	iface->create_element = facebook_album_create_element;
-	iface->load_from_element = facebook_album_load_from_element;
+	GObjectClass *object_class;
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = facebook_album_finalize;
+	object_class->set_property = facebook_album_set_property;
+	object_class->get_property = facebook_album_get_property;
+
+	/* properties */
+
+	g_object_class_install_property (object_class,
+					 PROP_ID,
+					 g_param_spec_string ("id",
+                                                              "ID",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_NAME,
+					 g_param_spec_string ("name",
+                                                              "Name",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_DESCRIPTION,
+					 g_param_spec_string ("description",
+                                                              "Description",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_LINK,
+					 g_param_spec_string ("link",
+                                                              "Link",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_PRIVACY,
+					 g_param_spec_string ("privacy",
+                                                              "Privacy",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_COUNT,
+					 g_param_spec_int ("count",
+                                                           "Count",
+                                                           "",
+                                                           0,
+                                                           G_MAXINT,
+                                                           0,
+                                                           G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_CAN_UPLOAD,
+					 g_param_spec_boolean ("can_upload",
+                                                               "Can upload",
+                                                               "",
+                                                               FALSE,
+                                                               G_PARAM_READWRITE));
 }
 
 
@@ -160,10 +207,10 @@ facebook_album_init (FacebookAlbum *self)
 	self->id = NULL;
 	self->name = NULL;
 	self->description = NULL;
-	self->location = NULL;
 	self->link = NULL;
-	self->size = 0;
-	self->visibility = FACEBOOK_VISIBILITY_SELF;
+	self->privacy = NULL;
+	self->count = 0;
+	self->can_upload = FALSE;
 }
 
 
@@ -172,27 +219,3 @@ facebook_album_new (void)
 {
 	return g_object_new (FACEBOOK_TYPE_ALBUM, NULL);
 }
-
-
-void
-facebook_album_set_name (FacebookAlbum *self,
-			 const char    *value)
-{
-	_g_strset (&self->name, value);
-}
-
-
-void
-facebook_album_set_location (FacebookAlbum *self,
-			     const char    *value)
-{
-	_g_strset (&self->location, value);
-}
-
-
-void
-facebook_album_set_description (FacebookAlbum *self,
-				const char    *value)
-{
-	_g_strset (&self->description, value);
-}
diff --git a/extensions/facebook/facebook-album.h b/extensions/facebook/facebook-album.h
index f05f7b1..c51a7b1 100644
--- a/extensions/facebook/facebook-album.h
+++ b/extensions/facebook/facebook-album.h
@@ -41,27 +41,21 @@ typedef struct _FacebookAlbumClass FacebookAlbumClass;
 struct _FacebookAlbum {
 	GObject parent_instance;
 
-	char               *id;
-	char               *name;
-	char               *location;
-	char               *description;
-	char               *link;
-	int                 size;
-	FacebookVisibility  visibility;
+	char     *id;
+	char     *name;
+	char     *description;
+	char     *link;
+	char     *privacy;
+	int       count;
+	gboolean  can_upload;
 };
 
 struct _FacebookAlbumClass {
 	GObjectClass parent_class;
 };
 
-GType           facebook_album_get_type        (void);
-FacebookAlbum * facebook_album_new             (void);
-void            facebook_album_set_name        (FacebookAlbum *self,
-					        const char    *value);
-void            facebook_album_set_location    (FacebookAlbum *self,
-					        const char    *value);
-void            facebook_album_set_description (FacebookAlbum *self,
-						const char    *value);
+GType           facebook_album_get_type  (void);
+FacebookAlbum * facebook_album_new       (void);
 
 G_END_DECLS
 
diff --git a/extensions/facebook/facebook-authentication.c b/extensions/facebook/facebook-authentication.c
index 6e72fca..217000b 100644
--- a/extensions/facebook/facebook-authentication.c
+++ b/extensions/facebook/facebook-authentication.c
@@ -24,6 +24,7 @@
 #ifdef HAVE_LIBSECRET
 #include <libsecret/secret.h>
 #endif /* HAVE_LIBSECRET */
+#include <extensions/oauth/oauth2-ask-authorization-dialog.h>
 #include "facebook-account-chooser-dialog.h"
 #include "facebook-account-manager-dialog.h"
 #include "facebook-authentication.h"
@@ -31,7 +32,6 @@
 #include "facebook-service.h"
 
 
-#define SECRET_SEPARATOR ("::")
 #define FACEBOOK_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT 2
 
 
@@ -94,10 +94,9 @@ facebook_authentication_class_init (FacebookAuthenticationClass *class)
 			      G_SIGNAL_RUN_LAST,
 			      G_STRUCT_OFFSET (FacebookAuthenticationClass, ready),
 			      NULL, NULL,
-			      g_cclosure_marshal_VOID__OBJECT,
+			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE,
-			      1,
-			      G_TYPE_OBJECT);
+			      0);
 	facebook_authentication_signals[ACCOUNTS_CHANGED] =
 		g_signal_new ("accounts_changed",
 			      G_TYPE_FROM_CLASS (class),
@@ -181,7 +180,7 @@ show_authentication_error_dialog (FacebookAuthentication  *self,
 {
 	GtkWidget *dialog;
 
-	if (g_error_matches (*error, FACEBOOK_CONNECTION_ERROR, FACEBOOK_CONNECTION_ERROR_SESSION_KEY_INVALID)) {
+	if (g_error_matches (*error, FACEBOOK_CONNECTION_ERROR, FACEBOOK_CONNECTION_ERROR_TOKEN_EXPIRED)) {
 		start_authorization_process (self);
 		return;
 	}
@@ -211,88 +210,110 @@ show_authentication_error_dialog (FacebookAuthentication  *self,
 }
 
 
+static void
+set_current_account (FacebookAuthentication *self,
+		     FacebookAccount        *account)
+{
+	GList *link;
+
+	link = g_list_find_custom (self->priv->accounts, self->priv->account, (GCompareFunc) facebook_account_cmp);
+	if (link != NULL) {
+		self->priv->accounts = g_list_remove_link (self->priv->accounts, link);
+		_g_object_list_unref (link);
+	}
+
+	_g_object_unref (self->priv->account);
+	self->priv->account = NULL;
+
+	if (account != NULL) {
+		self->priv->account = g_object_ref (account);
+		self->priv->accounts = g_list_prepend (self->priv->accounts, g_object_ref (self->priv->account));
+	}
+}
+
+
 /* -- facebook_authentication_auto_connect -- */
 
 
 static void
-get_user_info_ready_cb (GObject      *source_object,
-			GAsyncResult *res,
-			gpointer      user_data)
+facebook_authentication_account_ready (FacebookAuthentication *self)
 {
-	FacebookAuthentication *self = user_data;
-	FacebookUser           *user;
-	GError                 *error = NULL;
-
-	user = facebook_service_get_user_info_finish (FACEBOOK_SERVICE (source_object), res, &error);
-	if (error != NULL) {
-		show_authentication_error_dialog (self, &error);
-		return;
-	}
+	g_signal_emit (self, facebook_authentication_signals[READY], 0);
+}
 
-	facebook_account_set_username (self->priv->account, user->username);
-	facebook_accounts_save_to_file (self->priv->accounts, self->priv->account);
 
-	g_signal_emit (self, facebook_authentication_signals[READY], 0, user);
+#ifdef HAVE_LIBSECRET
+static void
+password_store_ready_cb (GObject      *source_object,
+			 GAsyncResult *result,
+			 gpointer      user_data)
+{
+	FacebookAuthentication *self = user_data;
 
-	g_object_unref (user);
+	secret_password_store_finish (result, NULL);
+	facebook_authentication_account_ready (self);
 }
+#endif
 
 
 static void
-get_logged_in_user_ready_cb (GObject      *source_object,
-			     GAsyncResult *res,
-			     gpointer      user_data)
+get_user_ready_cb (GObject      *source_object,
+		   GAsyncResult *res,
+		   gpointer      user_data)
 {
 	FacebookAuthentication *self = user_data;
-	char                   *uid;
 	GError                 *error = NULL;
+	FacebookUser           *user;
+	FacebookAccount        *account;
 
-	uid = facebook_service_get_logged_in_user_finish (FACEBOOK_SERVICE (source_object), res, &error);
-	if (error != NULL) {
+	user = facebook_service_get_user_finish (self->priv->service, res, &error);
+	if (user == NULL) {
 		show_authentication_error_dialog (self, &error);
 		return;
 	}
 
-	if (g_strcmp0 (uid, self->priv->account->user_id) == 0) {
-		FacebookUser *user;
-
-		user = facebook_user_new ();
-		facebook_user_set_id (user, uid);
-		facebook_user_set_username (user, self->priv->account->username);
-		g_signal_emit (self, facebook_authentication_signals[READY], 0, user);
+	account = facebook_account_new ();
+	facebook_account_set_username (account, user->name);
+	facebook_account_set_user_id (account, user->id);
+	facebook_account_set_token (account, facebook_connection_get_access_token (self->priv->conn));
+	set_current_account (self, account);
+	facebook_accounts_save_to_file (self->priv->accounts, self->priv->account);
 
-		g_object_unref (user);
-	}
-	else {
-		/* Authorization required */
-		start_authorization_process (self);
+#ifdef HAVE_LIBSECRET
+	{
+		secret_password_store (SECRET_SCHEMA_COMPAT_NETWORK,
+				       NULL,
+				       "Facebook",
+				       account->token,
+				       self->priv->cancellable,
+				       password_store_ready_cb,
+				       self,
+				       "user", account->user_id,
+				       "server", FACEBOOK_HTTP_SERVER,
+				       "protocol", "https",
+				       NULL);
 	}
+#else
+	facebook_authentication_account_ready (self);
+#endif
 
-	g_free (uid);
+	g_object_unref (account);
+	g_object_unref (user);
 }
 
 
 static void
 connect_to_server_step2 (FacebookAuthentication *self)
 {
-	if ((self->priv->account->session_key == NULL) || (self->priv->account->secret == NULL)) {
+	if (self->priv->account->token == NULL) {
 		start_authorization_process (self);
 		return;
 	}
-	facebook_connection_set_session (self->priv->conn,
-					 self->priv->account->session_key,
-					 self->priv->account->secret);
-	if (self->priv->account->username == NULL)
-		facebook_service_get_user_info (self->priv->service,
-						"first_name,middle_name,last_name,name",
-						self->priv->cancellable,
-						get_user_info_ready_cb,
-						self);
-	else
-		facebook_service_get_logged_in_user (self->priv->service,
-						     self->priv->cancellable,
-						     get_logged_in_user_ready_cb,
-						     self);
+	facebook_connection_set_access_token (self->priv->conn, self->priv->account->token);
+	facebook_service_get_user (self->priv->service,
+				   self->priv->cancellable,
+				   get_user_ready_cb,
+				   self);
 }
 
 
@@ -303,20 +324,12 @@ password_lookup_ready_cb (GObject      *source_object,
 			  gpointer      user_data)
 {
 	FacebookAuthentication *self = user_data;
-	char                   *string;
-
-	string = secret_password_lookup_finish (result, NULL);
-	if (string != NULL) {
-		char **values;
-
-		values = g_strsplit (string, SECRET_SEPARATOR, 2);
-		if ((values[0] != NULL) && (values[1] != NULL)) {
-			self->priv->account->session_key = g_strdup (values[0]);
-			self->priv->account->secret = g_strdup (values[1]);
-		}
+	char                   *secret;
 
-		g_strfreev (values);
-		g_free (string);
+	secret = secret_password_lookup_finish (result, NULL);
+	if (secret != NULL) {
+		facebook_account_set_token (self->priv->account, secret);
+		g_free (secret);
 	}
 
 	connect_to_server_step2 (self);
@@ -328,15 +341,16 @@ static void
 connect_to_server (FacebookAuthentication *self)
 {
 	g_return_if_fail (self->priv->account != NULL);
+	g_return_if_fail (self->priv->account->user_id != NULL);
 
 #ifdef HAVE_LIBSECRET
-	if ((self->priv->account->session_key == NULL) || (self->priv->account->secret == NULL)) {
+	if (self->priv->account->token == NULL) {
 		secret_password_lookup (SECRET_SCHEMA_COMPAT_NETWORK,
 					self->priv->cancellable,
 					password_lookup_ready_cb,
 					self,
 					"user", self->priv->account->user_id,
-					"server", FACEBOOK_HTTPS_REST_SERVER,
+					"server", FACEBOOK_HTTP_SERVER,
 					"protocol", "https",
 					NULL);
 		return;
@@ -348,91 +362,9 @@ connect_to_server (FacebookAuthentication *self)
 
 
 static void
-set_account (FacebookAuthentication *self,
-	     FacebookAccount        *account)
-{
-	GList *link;
-
-	link = g_list_find_custom (self->priv->accounts, self->priv->account, (GCompareFunc) facebook_account_cmp);
-	if (link != NULL) {
-		self->priv->accounts = g_list_remove_link (self->priv->accounts, link);
-		_g_object_list_unref (link);
-	}
-
-	_g_object_unref (self->priv->account);
-	self->priv->account = NULL;
-
-	if (account != NULL) {
-		self->priv->account = g_object_ref (account);
-		self->priv->accounts = g_list_prepend (self->priv->accounts, g_object_ref (self->priv->account));
-	}
-}
-
-
-#ifdef HAVE_LIBSECRET
-static void
-password_store_ready_cb (GObject      *source_object,
-			 GAsyncResult *result,
-			 gpointer      user_data)
-{
-	FacebookAuthentication *self = user_data;
-
-	secret_password_store_finish (result, NULL);
-	connect_to_server (self);
-}
-#endif
-
-
-static void
-get_session_ready_cb (GObject      *source_object,
-		      GAsyncResult *res,
-		      gpointer      user_data)
-{
-	FacebookAuthentication *self = user_data;
-	GError                 *error = NULL;
-	FacebookAccount        *account;
-
-	if (! facebook_connection_get_session_finish (FACEBOOK_CONNECTION (source_object), res, &error)) {
-		show_authentication_error_dialog (self, &error);
-		return;
-	}
-
-	account = facebook_account_new ();
-	facebook_account_set_session_key (account, facebook_connection_get_session_key (self->priv->conn));
-	facebook_account_set_secret (account, facebook_connection_get_secret (self->priv->conn));
-	facebook_account_set_user_id (account, facebook_connection_get_user_id (self->priv->conn));
-	set_account (self, account);
-
-#ifdef HAVE_LIBSECRET
-	{
-		char *secret;
-
-		secret = g_strconcat (account->session_key, SECRET_SEPARATOR, account->secret, NULL);
-		secret_password_store (SECRET_SCHEMA_COMPAT_NETWORK,
-				       NULL,
-				       "Facebook",
-				       secret,
-				       self->priv->cancellable,
-				       password_store_ready_cb,
-				       self,
-				       "user", account->user_id,
-				       "server", FACEBOOK_HTTPS_REST_SERVER,
-				       "protocol", "https",
-				       NULL);
-
-		g_free (secret);
-	}
-#else
-	g_object_unref (account);
-	connect_to_server (self);
-#endif
-}
-
-
-static void
-complete_authorization_messagedialog_response_cb (GtkDialog *dialog,
-						  int        response_id,
-						  gpointer   user_data)
+ask_authorization_dialog_response_cb (GtkDialog *dialog,
+				      int        response_id,
+				      gpointer   user_data)
 {
 	FacebookAuthentication *self = user_data;
 
@@ -450,10 +382,10 @@ complete_authorization_messagedialog_response_cb (GtkDialog *dialog,
 	case GTK_RESPONSE_OK:
 		gtk_widget_destroy (GTK_WIDGET (dialog));
 		gth_task_dialog (GTH_TASK (self->priv->conn), FALSE, NULL);
-		facebook_connection_get_session (self->priv->conn,
-						 self->priv->cancellable,
-						 get_session_ready_cb,
-						 self);
+		facebook_service_get_user (self->priv->service,
+					   self->priv->cancellable,
+					   get_user_ready_cb,
+					   self);
 		break;
 
 	default:
@@ -463,144 +395,60 @@ complete_authorization_messagedialog_response_cb (GtkDialog *dialog,
 
 
 static void
-complete_authorization (FacebookAuthentication *self)
-{
-	GtkBuilder *builder;
-	GtkWidget  *dialog;
-	char       *text;
-	char       *secondary_text;
-
-	gth_task_dialog (GTH_TASK (self->priv->conn), TRUE, NULL);
-
-	builder = _gtk_builder_new_from_file ("facebook-complete-authorization.ui", "facebook");
-	dialog = _gtk_builder_get_widget (builder, "complete_authorization_messagedialog");
-	text = g_strdup_printf (_("Return to this window when you have finished the authorization process on %s"), "Facebook");
-	secondary_text = g_strdup (_("Once you're done, click the 'Continue' button below."));
-	g_object_set (dialog, "text", text, "secondary-text", secondary_text, NULL);
-	g_object_set_data_full (G_OBJECT (dialog), "builder", builder, g_object_unref);
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (complete_authorization_messagedialog_response_cb),
-			  self);
-
-	if (gtk_widget_get_visible (self->priv->dialog))
-		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->dialog));
-	else
-		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->browser));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
-
-	g_free (secondary_text);
-	g_free (text);
-}
-
-
-static void
-ask_authorization_messagedialog_response_cb (GtkDialog *dialog,
-					     int        response_id,
-					     gpointer   user_data)
+ask_authorization_dialog_redirected_cb (OAuth2AskAuthorizationDialog *dialog,
+					gpointer                      user_data)
 {
 	FacebookAuthentication *self = user_data;
+	const char             *uri;
 
-	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (dialog), "facebook-ask-authorization");
-		break;
+	uri = oauth2_ask_authorization_dialog_get_uri (dialog);
+	if (g_str_has_prefix (uri, FACEBOOK_REDIRECT_URI)) {
+		const char *uri_data;
+		GHashTable *data;
+		const char *access_token;
 
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_dialog_response (GTK_DIALOG (self->priv->dialog), GTK_RESPONSE_DELETE_EVENT);
-		break;
-
-	case GTK_RESPONSE_OK:
-		{
-			GdkScreen *screen;
-			char      *url;
-			GError    *error = NULL;
+		uri_data = uri + strlen (FACEBOOK_REDIRECT_URI "#");
 
-			screen = gtk_widget_get_screen (GTK_WIDGET (dialog));
-			gtk_widget_destroy (GTK_WIDGET (dialog));
-
-			url = facebook_connection_get_login_link (self->priv->conn, FACEBOOK_ACCESS_WRITE);
-			if (gtk_show_uri (screen, url, 0, &error))
-				complete_authorization (self);
-			else
-				show_authentication_error_dialog (self, &error);
-
-			g_free (url);
-		}
-		break;
+		data = soup_form_decode (uri_data);
+		access_token = g_hash_table_lookup (data, "access_token");
+		facebook_connection_set_access_token (self->priv->conn, access_token);
+		gtk_dialog_response (GTK_DIALOG (dialog),
+				     (access_token != NULL) ? GTK_RESPONSE_OK : GTK_RESPONSE_CANCEL);
 
-	default:
-		break;
+		g_hash_table_destroy (data);
 	}
 }
 
 
 static void
-ask_authorization (FacebookAuthentication *self)
+start_authorization_process (FacebookAuthentication *self)
 {
-	GtkBuilder *builder;
-	GtkWidget  *dialog;
-	char       *text;
-	char       *secondary_text;
+	GtkWidget *dialog;
 
 	gth_task_dialog (GTH_TASK (self->priv->conn), TRUE, NULL);
 
-	builder = _gtk_builder_new_from_file ("facebook-ask-authorization.ui", "facebook");
-	dialog = _gtk_builder_get_widget (builder, "ask_authorization_messagedialog");
+	dialog = oauth2_ask_authorization_dialog_new (_("Authorization Required"),
+						      facebook_utils_get_authorization_url (FACEBOOK_ACCESS_WRITE));
 	if (gtk_widget_get_visible (self->priv->dialog))
 		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->dialog));
 	else
 		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->browser));
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 
-	text = g_strdup_printf (_("gthumb requires your authorization to upload the photos to %s"), "Facebook");
-	secondary_text = g_strdup_printf (_("Click 'Authorize' to open your web browser and authorize gthumb to upload photos to %s. When you're finished, return to this window to complete the authorization."), "Facebook");
-	g_object_set (dialog, "text", text, "secondary-text", secondary_text, NULL);
-	g_object_set_data_full (G_OBJECT (dialog), "builder", builder, g_object_unref);
 	g_signal_connect (dialog,
 			  "delete-event",
 			  G_CALLBACK (gtk_true),
 			  NULL);
 	g_signal_connect (dialog,
 			  "response",
-			  G_CALLBACK (ask_authorization_messagedialog_response_cb),
+			  G_CALLBACK (ask_authorization_dialog_response_cb),
+			  self);
+	g_signal_connect (OAUTH2_ASK_AUTHORIZATION_DIALOG (dialog),
+			  "redirected",
+			  G_CALLBACK (ask_authorization_dialog_redirected_cb),
 			  self);
 
 	gtk_widget_show (dialog);
-
-	g_free (secondary_text);
-	g_free (text);
-}
-
-
-static void
-create_token_ready_cb (GObject      *source_object,
-		       GAsyncResult *res,
-		       gpointer      user_data)
-{
-	FacebookAuthentication *self = user_data;
-	GError                 *error = NULL;
-
-	if (! facebook_connection_create_token_finish (FACEBOOK_CONNECTION (source_object), res, &error))
-		show_authentication_error_dialog (self, &error);
-	else
-		ask_authorization (self);
-}
-
-
-static void
-start_authorization_process (FacebookAuthentication *self)
-{
-	facebook_connection_create_token (self->priv->conn,
-					  self->priv->cancellable,
-					  create_token_ready_cb,
-					  self);
 }
 
 
@@ -625,7 +473,6 @@ account_chooser_dialog_response_cb (GtkDialog *dialog,
 			gtk_widget_destroy (GTK_WIDGET (dialog));
 			connect_to_server (self);
 		}
-
 		break;
 
 	case FACEBOOK_ACCOUNT_CHOOSER_RESPONSE_NEW:
@@ -688,7 +535,7 @@ void
 facebook_authentication_connect (FacebookAuthentication *self,
 			         FacebookAccount        *account)
 {
-	set_account (self, account);
+	set_current_account (self, account);
 	facebook_authentication_auto_connect (self);
 }
 
diff --git a/extensions/facebook/facebook-authentication.h b/extensions/facebook/facebook-authentication.h
index 9e7882d..997515e 100644
--- a/extensions/facebook/facebook-authentication.h
+++ b/extensions/facebook/facebook-authentication.h
@@ -54,8 +54,7 @@ struct _FacebookAuthenticationClass {
 
 	/*< signals >*/
 
-	void  (*ready)             (FacebookAuthentication *auth,
-				    FacebookUser           *user);
+	void  (*ready)             (FacebookAuthentication *auth);
 	void  (*accounts_changed)  (FacebookAuthentication *auth);
 };
 
diff --git a/extensions/facebook/facebook-connection.c b/extensions/facebook/facebook-connection.c
index 12ae105..6cafad7 100644
--- a/extensions/facebook/facebook-connection.c
+++ b/extensions/facebook/facebook-connection.c
@@ -53,13 +53,8 @@ struct _FacebookConnectionPrivate
 	SoupSession        *session;
 	SoupMessage        *msg;
 	char               *token;
-	char               *secret;
-	char               *session_key;
-	char               *user_id;
 	GCancellable       *cancellable;
 	GSimpleAsyncResult *result;
-	GChecksum          *checksum;
-	char               *call_id;
 };
 
 
@@ -73,13 +68,8 @@ facebook_connection_finalize (GObject *object)
 
 	self = FACEBOOK_CONNECTION (object);
 
-	g_free (self->priv->call_id);
-	g_checksum_free (self->priv->checksum);
 	_g_object_unref (self->priv->result);
 	_g_object_unref (self->priv->cancellable);
-	g_free (self->priv->user_id);
-	g_free (self->priv->session_key);
-	g_free (self->priv->secret);
 	g_free (self->priv->token);
 	_g_object_unref (self->priv->session);
 
@@ -130,13 +120,8 @@ facebook_connection_init (FacebookConnection *self)
 	self->priv->session = NULL;
 	self->priv->msg = NULL;
 	self->priv->token = NULL;
-	self->priv->secret = NULL;
-	self->priv->session_key = NULL;
-	self->priv->user_id = NULL;
 	self->priv->cancellable = NULL;
 	self->priv->result = NULL;
-	self->priv->checksum = g_checksum_new (G_CHECKSUM_MD5);
-	self->priv->call_id = NULL;
 }
 
 
@@ -148,6 +133,31 @@ facebook_connection_new (void)
 
 
 void
+facebook_connection_set_access_token (FacebookConnection *self,
+				      const char         *token)
+{
+	_g_strset (&self->priv->token, token);
+}
+
+
+const char *
+facebook_connection_get_access_token (FacebookConnection *self)
+{
+	return self->priv->token;
+}
+
+
+void
+facebook_connection_add_access_token (FacebookConnection *self,
+				      GHashTable         *data_set)
+{
+	g_return_if_fail (self->priv->token != NULL);
+
+	g_hash_table_insert (data_set, "access_token", self->priv->token);
+}
+
+
+void
 facebook_connection_send_message (FacebookConnection  *self,
 				  SoupMessage         *msg,
 				  GCancellable        *cancellable,
@@ -180,7 +190,7 @@ facebook_connection_send_message (FacebookConnection  *self,
 	self->priv->cancellable = _g_object_ref (cancellable);
 
 	_g_object_unref (self->priv->result);
-	self->priv->result = g_simple_async_result_new (G_OBJECT (soup_session_cb_data),
+	self->priv->result = g_simple_async_result_new (G_OBJECT (self),
 							callback,
 							user_data,
 							source_tag);
@@ -210,132 +220,7 @@ facebook_connection_reset_result (FacebookConnection *self)
 }
 
 
-void
-facebook_connection_add_api_sig (FacebookConnection *self,
-			         GHashTable         *data_set)
-{
-	GList *keys;
-	GList *scan;
-
-	g_hash_table_insert (data_set, "api_key", GTHUMB_FACEBOOK_API_KEY);
-	g_hash_table_insert (data_set, "v", FACEBOOK_API_VERSION);
-	g_hash_table_insert (data_set, "format", "XML");
-
-	if (self->priv->session_key != NULL) {
-		GTimeVal current_time;
-
-		g_hash_table_insert (data_set, "session_key", self->priv->session_key);
-		g_hash_table_insert (data_set, "ss", "true");
-
-		g_free (self->priv->call_id);
-		g_get_current_time (&current_time);
-		self->priv->call_id = g_strdup_printf ("%ld.%ld", current_time.tv_sec, current_time.tv_usec);
-		g_hash_table_insert (data_set, "call_id", self->priv->call_id);
-	}
-
-	g_checksum_reset (self->priv->checksum);
-	keys = g_hash_table_get_keys (data_set);
-	keys = g_list_sort (keys, (GCompareFunc) strcmp);
-	for (scan = keys; scan; scan = scan->next) {
-		char *key = scan->data;
-
-		g_checksum_update (self->priv->checksum, (guchar *) key, -1);
-		g_checksum_update (self->priv->checksum, (guchar *) "=", -1);
-		g_checksum_update (self->priv->checksum, g_hash_table_lookup (data_set, key), -1);
-	}
-	if (self->priv->session_key != NULL)
-		g_checksum_update (self->priv->checksum, (guchar *) self->priv->secret, -1);
-	else
-		g_checksum_update (self->priv->checksum, (guchar *) GTHUMB_FACEBOOK_SHARED_SECRET, -1);
-	g_hash_table_insert (data_set, "sig", (gpointer) g_checksum_get_string (self->priv->checksum));
-
-	g_list_free (keys);
-}
-
-
-static void
-create_token_ready_cb (SoupSession *session,
-		       SoupMessage *msg,
-		       gpointer     user_data)
-{
-	FacebookConnection *self = user_data;
-	SoupBuffer         *body;
-	DomDocument        *doc = NULL;
-	GError             *error = NULL;
-
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement *root;
-
-		root = DOM_ELEMENT (doc)->first_child;
-		if (g_strcmp0 (root->tag_name, "auth_createToken_response") == 0)
-			self->priv->token = g_strdup (dom_element_get_inner_text (root));
-
-		if (self->priv->token == NULL) {
-			error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error"));
-			g_simple_async_result_set_from_error (self->priv->result, error);
-		}
-		else
-			g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
-
-		g_object_unref (doc);
-	}
-	else
-		g_simple_async_result_set_from_error (self->priv->result, error);
-
-	g_simple_async_result_complete_in_idle (self->priv->result);
-
-	soup_buffer_free (body);
-}
-
-
-void
-facebook_connection_create_token (FacebookConnection  *self,
-				  GCancellable        *cancellable,
-				  GAsyncReadyCallback  callback,
-				  gpointer             user_data)
-{
-	GHashTable  *data_set;
-	SoupMessage *msg;
-
-	g_free (self->priv->token);
-	g_free (self->priv->session_key);
-	g_free (self->priv->secret);
-	g_free (self->priv->user_id);
-	self->priv->token = NULL;
-	self->priv->session_key = NULL;
-	self->priv->secret = NULL;
-	self->priv->user_id = NULL;
-
-	gth_task_progress (GTH_TASK (self), _("Connecting to the server"), NULL, TRUE, 0.0);
-
-	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "method", "facebook.auth.createToken");
-	facebook_connection_add_api_sig (self, data_set);
-	msg = soup_form_request_new_from_hash ("POST", FACEBOOK_HTTPS_REST_SERVER, data_set);
-	facebook_connection_send_message (self,
-					  msg,
-					  cancellable,
-					  callback,
-					  user_data,
-					  facebook_connection_create_token,
-					  create_token_ready_cb,
-					  self);
-
-	g_hash_table_destroy (data_set);
-}
-
-
-gboolean
-facebook_connection_create_token_finish (FacebookConnection  *self,
-					 GAsyncResult        *result,
-				         GError             **error)
-{
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
-		return FALSE;
-	else
-		return TRUE;
-}
+/* utilities */
 
 
 static char *
@@ -345,13 +230,11 @@ get_access_type_name (FacebookAccessType access_type)
 
 	switch (access_type) {
 	case FACEBOOK_ACCESS_READ:
-		/*name = "read_stream,offline_access";*/
-		name = "user_photos,offline_access";
+		name = "";
 		break;
 
 	case FACEBOOK_ACCESS_WRITE:
-		/*name = "photo_upload,offline_access";*/
-		name = "user_photos,offline_access,publish_stream";
+		name = "publish_actions ";
 		break;
 	}
 
@@ -360,24 +243,20 @@ get_access_type_name (FacebookAccessType access_type)
 
 
 char *
-facebook_connection_get_login_link (FacebookConnection *self,
-				    FacebookAccessType  access_type)
+facebook_utils_get_authorization_url (FacebookAccessType access_type)
 {
 	GHashTable *data_set;
 	GString    *link;
 	GList      *keys;
 	GList      *scan;
 
-	g_return_val_if_fail (self->priv->token != NULL, NULL);
-
 	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "api_key", GTHUMB_FACEBOOK_API_KEY);
-	g_hash_table_insert (data_set, "auth_token", self->priv->token);
-	g_hash_table_insert (data_set, "req_perms", get_access_type_name (access_type));
-	g_hash_table_insert (data_set, "connect_display", "page");
-	g_hash_table_insert (data_set, "fbconnect", "true");
+	g_hash_table_insert (data_set, "client_id", GTHUMB_FACEBOOK_API_KEY);
+	g_hash_table_insert (data_set, "redirect_uri", FACEBOOK_REDIRECT_URI);
+	g_hash_table_insert (data_set, "scope", get_access_type_name (access_type));
+	g_hash_table_insert (data_set, "response_type", "token");
 
-	link = g_string_new ("http://www.facebook.com/login.php?";);
+	link = g_string_new ("https://www.facebook.com/dialog/oauth?";);
 	keys = g_hash_table_get_keys (data_set);
 	for (scan = keys; scan; scan = scan->next) {
 		char *key = scan->data;
@@ -400,176 +279,51 @@ facebook_connection_get_login_link (FacebookConnection *self,
 }
 
 
-static void
-get_session_ready_cb (SoupSession *session,
-		      SoupMessage *msg,
-		      gpointer     user_data)
-{
-	FacebookConnection *self = user_data;
-	SoupBuffer         *body;
-	DomDocument        *doc = NULL;
-	GError             *error = NULL;
-
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement *root;
-
-		root = DOM_ELEMENT (doc)->first_child;
-		if (g_strcmp0 (root->tag_name, "auth_getSession_response") == 0) {
-			DomElement *node;
-
-			for (node = root->first_child; node; node = node->next_sibling) {
-				if (g_strcmp0 (node->tag_name, "session_key") == 0) {
-					self->priv->session_key = g_strdup (dom_element_get_inner_text (node));
-				}
-				else if (g_strcmp0 (node->tag_name, "secret") == 0) {
-					self->priv->secret = g_strdup (dom_element_get_inner_text (node));
-				}
-				else if (g_strcmp0 (node->tag_name, "uid") == 0) {
-					self->priv->user_id = g_strdup (dom_element_get_inner_text (node));
-				}
-			}
-		}
-
-		if ((self->priv->session_key == NULL) || (self->priv->secret == NULL)) {
-			error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error"));
-			g_simple_async_result_set_from_error (self->priv->result, error);
-		}
-		else
-			g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
-
-		g_object_unref (doc);
-	}
-	else
-		g_simple_async_result_set_from_error (self->priv->result, error);
-
-	g_simple_async_result_complete_in_idle (self->priv->result);
-
-	soup_buffer_free (body);
-}
-
-
-void
-facebook_connection_get_session (FacebookConnection  *self,
-				 GCancellable        *cancellable,
-				 GAsyncReadyCallback  callback,
-				 gpointer             user_data)
-{
-	GHashTable  *data_set;
-	SoupMessage *msg;
-
-	gth_task_progress (GTH_TASK (self), _("Connecting to the server"), NULL, TRUE, 0.0);
-
-	g_free (self->priv->session_key);
-	g_free (self->priv->secret);
-	g_free (self->priv->user_id);
-	self->priv->session_key = NULL;
-	self->priv->secret = NULL;
-	self->priv->user_id = NULL;
-
-	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "method", "facebook.auth.getSession");
-	g_hash_table_insert (data_set, "auth_token", self->priv->token);
-	facebook_connection_add_api_sig (self, data_set);
-	msg = soup_form_request_new_from_hash ("POST", FACEBOOK_HTTPS_REST_SERVER, data_set);
-	facebook_connection_send_message (self,
-					  msg,
-					  cancellable,
-					  callback,
-					  user_data,
-					  facebook_connection_get_session,
-					  get_session_ready_cb,
-					  self);
-
-	g_hash_table_destroy (data_set);
-}
-
-
 gboolean
-facebook_connection_get_session_finish (FacebookConnection  *self,
-					GAsyncResult        *result,
-					GError             **error)
-{
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
-		return FALSE;
-	else
-		return TRUE;
-}
-
-
-void
-facebook_connection_set_session (FacebookConnection *self,
-				 const char         *session_key,
-				 const char         *secret)
-{
-	_g_strset (&self->priv->session_key, session_key);
-	_g_strset (&self->priv->secret, secret);
-}
-
-
-const char *
-facebook_connection_get_session_key (FacebookConnection *self)
-{
-	return self->priv->session_key;
-}
-
-
-const char *
-facebook_connection_get_secret (FacebookConnection *self)
+facebook_utils_parse_response (SoupMessage  *msg,
+			       JsonNode    **node,
+			       GError      **error)
 {
-	return self->priv->secret;
-}
+	JsonParser *parser;
+	SoupBuffer *body;
 
+	g_return_val_if_fail (msg != NULL, FALSE);
+	g_return_val_if_fail (node != NULL, FALSE);
 
-const char *
-facebook_connection_get_user_id (FacebookConnection *self)
-{
-	return self->priv->user_id;
-}
+	*node = NULL;
 
+	if ((msg->status_code != 200) && (msg->status_code != 400)) {
+		*error = g_error_new (SOUP_HTTP_ERROR,
+				      msg->status_code,
+				      "%s",
+				      soup_status_get_phrase (msg->status_code));
+		return FALSE;
+	}
 
-/* utilities */
+	body = soup_message_body_flatten (msg->response_body);
+	parser = json_parser_new ();
+	if (json_parser_load_from_data (parser, body->data, body->length, error)) {
+		JsonObject *obj;
 
+		*node = json_node_copy (json_parser_get_root (parser));
 
-gboolean
-facebook_utils_parse_response (SoupBuffer   *body,
-			       DomDocument **doc_p,
-			       GError      **error)
-{
-	DomDocument *doc;
-	DomElement  *node;
+		obj = json_node_get_object (*node);
+		if (json_object_has_member (obj, "error")) {
+			JsonObject *error_obj;
 
-	doc = dom_document_new ();
-	if (! dom_document_load (doc, body->data, body->length, error)) {
-		g_object_unref (doc);
-		return FALSE;
-	}
+			error_obj = json_object_get_object_member (obj, "error");
+			*error = g_error_new (FACEBOOK_CONNECTION_ERROR,
+					      json_object_get_int_member (error_obj, "code"),
+					      "%s",
+					      json_object_get_string_member (error_obj, "message"));
 
-	for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
-		if (g_strcmp0 (node->tag_name, "error_response") == 0) {
-			DomElement *child;
-			int         code = 0;
-			const char *message = NULL;
-
-			for (child = node->first_child; child; child = child->next_sibling) {
-				if (g_strcmp0 (child->tag_name, "error_code") == 0) {
-					code = atoi (dom_element_get_inner_text (child));
-				}
-				else if (g_strcmp0 (child->tag_name, "error_msg") == 0) {
-					message = dom_element_get_inner_text (child);
-				}
-			}
-
-			*error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR,
-						      code,
-						      message);
-
-			g_object_unref (doc);
-			return FALSE;
+			json_node_free (*node);
+			*node = NULL;
 		}
 	}
 
-	*doc_p = doc;
+	g_object_unref (parser);
+	soup_buffer_free (body);
 
-	return TRUE;
+	return *node != NULL;
 }
diff --git a/extensions/facebook/facebook-connection.h b/extensions/facebook/facebook-connection.h
index ddeeb1d..54152a5 100644
--- a/extensions/facebook/facebook-connection.h
+++ b/extensions/facebook/facebook-connection.h
@@ -23,6 +23,7 @@
 #define FACEBOOK_CONNECTION_H
 
 #include <glib-object.h>
+#include <json-glib/json-glib.h>
 #ifdef HAVE_LIBSOUP_GNOME
 #include <libsoup/soup-gnome.h>
 #else
@@ -35,14 +36,13 @@ typedef enum {
 	FACEBOOK_ACCESS_WRITE
 } FacebookAccessType;
 
-#define FACEBOOK_REST_SERVER "api.facebook.com/restserver.php"
-#define FACEBOOK_HTTP_REST_SERVER "http://"; FACEBOOK_REST_SERVER
-#define FACEBOOK_HTTPS_REST_SERVER "https://"; FACEBOOK_REST_SERVER
+#define FACEBOOK_REDIRECT_URI "https://www.facebook.com/connect/login_success.html";
+#define FACEBOOK_HTTP_SERVER "https://www.facebook.com";
 
 #define FACEBOOK_CONNECTION_ERROR facebook_connection_error_quark ()
 GQuark facebook_connection_error_quark (void);
 
-#define FACEBOOK_CONNECTION_ERROR_SESSION_KEY_INVALID 102
+#define FACEBOOK_CONNECTION_ERROR_TOKEN_EXPIRED 190
 
 #define FACEBOOK_TYPE_CONNECTION         (facebook_connection_get_type ())
 #define FACEBOOK_CONNECTION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), FACEBOOK_TYPE_CONNECTION, FacebookConnection))
@@ -68,6 +68,11 @@ struct _FacebookConnectionClass
 
 GType                facebook_connection_get_type             (void) G_GNUC_CONST;
 FacebookConnection * facebook_connection_new                  (void);
+void                 facebook_connection_set_access_token     (FacebookConnection    *self,
+							       const char            *token);
+const char *         facebook_connection_get_access_token     (FacebookConnection    *self);
+void                 facebook_connection_add_access_token     (FacebookConnection    *self,
+							       GHashTable            *data_set);
 void		     facebook_connection_send_message         (FacebookConnection    *self,
 						               SoupMessage           *msg,
 						               GCancellable          *cancellable,
@@ -78,35 +83,12 @@ void		     facebook_connection_send_message         (FacebookConnection    *self
 						               gpointer               soup_session_cb_data);
 GSimpleAsyncResult * facebook_connection_get_result           (FacebookConnection    *self);
 void                 facebook_connection_reset_result         (FacebookConnection    *self);
-void                 facebook_connection_add_api_sig          (FacebookConnection    *self,
-						               GHashTable            *data_set);
-void                 facebook_connection_create_token         (FacebookConnection    *self,
-						               GCancellable          *cancellable,
-						               GAsyncReadyCallback    callback,
-						               gpointer               user_data);
-gboolean             facebook_connection_create_token_finish  (FacebookConnection    *self,
-							       GAsyncResult          *result,
-							       GError               **error);
-char *               facebook_connection_get_login_link       (FacebookConnection    *self,
-							       FacebookAccessType     access_type);
-void                 facebook_connection_get_session          (FacebookConnection    *self,
-						               GCancellable          *cancellable,
-						               GAsyncReadyCallback    callback,
-						               gpointer               user_data);
-gboolean             facebook_connection_get_session_finish   (FacebookConnection    *self,
-							       GAsyncResult          *result,
-							       GError               **error);
-void                 facebook_connection_set_session          (FacebookConnection    *self,
-							       const char            *session_key,
-							       const char            *secret);
-const char *         facebook_connection_get_session_key      (FacebookConnection    *self);
-const char *         facebook_connection_get_secret           (FacebookConnection    *self);
-const char *         facebook_connection_get_user_id          (FacebookConnection    *self);
 
 /* utilities */
 
-gboolean             facebook_utils_parse_response            (SoupBuffer            *body,
-							       DomDocument          **doc_p,
+char *               facebook_utils_get_authorization_url     (FacebookAccessType     access_type);
+gboolean             facebook_utils_parse_response            (SoupMessage           *msg,
+							       JsonNode             **node,
 							       GError               **error);
 
 #endif /* FACEBOOK_CONNECTION_H */
diff --git a/extensions/facebook/facebook-service.c b/extensions/facebook/facebook-service.c
index 8874834..f211180 100644
--- a/extensions/facebook/facebook-service.c
+++ b/extensions/facebook/facebook-service.c
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <json-glib/json-glib.h>
 #include <gthumb.h>
 #include "facebook-account.h"
 #include "facebook-album.h"
@@ -117,7 +118,7 @@ facebook_service_new (FacebookConnection *conn)
 	FacebookService *self;
 
 	self = (FacebookService *) g_object_new (FACEBOOK_TYPE_SERVICE, NULL);
-	self->priv->conn = g_object_ref (conn);
+	self->priv->conn = _g_object_ref (conn);
 
 	return self;
 }
@@ -127,181 +128,58 @@ facebook_service_new (FacebookConnection *conn)
 
 
 static void
-get_logged_in_user_ready_cb (SoupSession *session,
-			     SoupMessage *msg,
-			     gpointer     user_data)
+facebook_service_get_user_ready_cb (SoupSession *session,
+				    SoupMessage *msg,
+				    gpointer     user_data)
 {
 	FacebookService    *self = user_data;
 	GSimpleAsyncResult *result;
-	SoupBuffer         *body;
-	DomDocument        *doc = NULL;
-	GError             *error = NULL;
-
-	result = facebook_connection_get_result (self->priv->conn);
-
-	if (msg->status_code != 200) {
-		g_simple_async_result_set_error (result,
-						 SOUP_HTTP_ERROR,
-						 msg->status_code,
-						 "%s",
-						 soup_status_get_phrase (msg->status_code));
-		g_simple_async_result_complete_in_idle (result);
-		return;
-	}
-
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement *root;
-		char       *uid = NULL;
-
-		root = DOM_ELEMENT (doc)->first_child;
-		if (g_strcmp0 (root->tag_name, "users_getLoggedInUser_response") == 0)
-			uid = g_strdup (dom_element_get_inner_text (root));
-
-		if (uid == NULL) {
-			error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error"));
-			g_simple_async_result_set_from_error (result, error);
-		}
-		else
-			g_simple_async_result_set_op_res_gpointer (result, uid, g_free);
-
-		g_object_unref (doc);
-	}
-	else
-		g_simple_async_result_set_from_error (result, error);
-
-	g_simple_async_result_complete_in_idle (result);
-
-	soup_buffer_free (body);
-}
-
-
-void
-facebook_service_get_logged_in_user (FacebookService     *self,
-				     GCancellable        *cancellable,
-				     GAsyncReadyCallback  callback,
-				     gpointer             user_data)
-{
-	GHashTable  *data_set;
-	SoupMessage *msg;
-
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Connecting to the server"), _("Getting account information"), TRUE, 0.0);
-
-	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "method", "facebook.users.getLoggedInUser");
-	facebook_connection_add_api_sig (self->priv->conn, data_set);
-	msg = soup_form_request_new_from_hash ("POST", FACEBOOK_HTTPS_REST_SERVER, data_set);
-	facebook_connection_send_message (self->priv->conn,
-					  msg,
-					  cancellable,
-					  callback,
-					  user_data,
-					  facebook_service_get_logged_in_user,
-					  get_logged_in_user_ready_cb,
-					  self);
-
-	g_hash_table_destroy (data_set);
-}
-
-
-char *
-facebook_service_get_logged_in_user_finish (FacebookService  *self,
-					    GAsyncResult     *result,
-					    GError          **error)
-{
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
-		return NULL;
-	else
-		return g_strdup (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
-}
-
-
-/* -- facebook_service_get_user_info -- */
-
-
-static void
-get_user_info_ready_cb (SoupSession *session,
-			SoupMessage *msg,
-			gpointer     user_data)
-{
-	FacebookService      *self = user_data;
-	GSimpleAsyncResult *result;
-	SoupBuffer         *body;
-	DomDocument        *doc = NULL;
 	GError             *error = NULL;
+	JsonNode           *node;
 
 	result = facebook_connection_get_result (self->priv->conn);
 
-	if (msg->status_code != 200) {
-		g_simple_async_result_set_error (result,
-						 SOUP_HTTP_ERROR,
-						 msg->status_code,
-						 "%s",
-						 soup_status_get_phrase (msg->status_code));
-		g_simple_async_result_complete_in_idle (result);
-		return;
-	}
-
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement   *node;
-		FacebookUser *user = NULL;
-
-		for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
-			if (g_strcmp0 (node->tag_name, "users_getInfo_response") == 0) {
-				DomElement *child;
-
-				for (child = node->first_child; child; child = child->next_sibling) {
-					if (g_strcmp0 (child->tag_name, "user") == 0) {
-						user = facebook_user_new ();
-						dom_domizable_load_from_element (DOM_DOMIZABLE (user), child);
-						g_simple_async_result_set_op_res_gpointer (result, user, (GDestroyNotify) g_object_unref);
-					}
-				}
-			}
-		}
-
-		if (user == NULL) {
-			error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error"));
-			g_simple_async_result_set_from_error (result, error);
-		}
+	if (facebook_utils_parse_response (msg, &node, &error)) {
+		_g_object_unref (self->priv->user);
+		self->priv->user = (FacebookUser *) json_gobject_deserialize (FACEBOOK_TYPE_USER, node);
+		g_simple_async_result_set_op_res_gpointer (result,
+							   g_object_ref (self->priv->user),
+							   (GDestroyNotify) g_object_unref);
 
-		g_object_unref (doc);
+		json_node_free (node);
 	}
 	else
 		g_simple_async_result_set_from_error (result, error);
 
 	g_simple_async_result_complete_in_idle (result);
-
-	soup_buffer_free (body);
 }
 
 
 void
-facebook_service_get_user_info (FacebookService     *self,
-				const char          *fields,
-				GCancellable        *cancellable,
-				GAsyncReadyCallback  callback,
-				gpointer             user_data)
+facebook_service_get_user (FacebookService     *self,
+			   GCancellable        *cancellable,
+			   GAsyncReadyCallback  callback,
+			   gpointer	        user_data)
 {
 	GHashTable  *data_set;
 	SoupMessage *msg;
 
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Connecting to the server"), _("Getting account information"), TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self->priv->conn),
+			   _("Connecting to the server"),
+			   _("Getting account information"),
+			   TRUE,
+			   0.0);
 
 	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "method", "facebook.users.getInfo");
-	g_hash_table_insert (data_set, "uids", (char *) facebook_connection_get_user_id (self->priv->conn));
-	g_hash_table_insert (data_set, "fields", (char *) fields);
-	facebook_connection_add_api_sig (self->priv->conn, data_set);
-	msg = soup_form_request_new_from_hash ("POST", FACEBOOK_HTTPS_REST_SERVER, data_set);
+	facebook_connection_add_access_token (self->priv->conn, data_set);
+	msg = soup_form_request_new_from_hash ("GET", "https://graph.facebook.com/me";, data_set);
 	facebook_connection_send_message (self->priv->conn,
 					  msg,
 					  cancellable,
 					  callback,
 					  user_data,
-					  facebook_service_get_user_info,
-					  get_user_info_ready_cb,
+					  facebook_service_get_user,
+					  facebook_service_get_user_ready_cb,
 					  self);
 
 	g_hash_table_destroy (data_set);
@@ -309,9 +187,9 @@ facebook_service_get_user_info (FacebookService     *self,
 
 
 FacebookUser *
-facebook_service_get_user_info_finish (FacebookService  *self,
-				       GAsyncResult     *result,
-				       GError          **error)
+facebook_service_get_user_finish (FacebookService  *self,
+				  GAsyncResult     *result,
+				  GError          **error)
 {
 	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
 		return NULL;
@@ -324,91 +202,78 @@ facebook_service_get_user_info_finish (FacebookService  *self,
 
 
 static void
-get_albums_ready_cb (SoupSession *session,
-		     SoupMessage *msg,
-		     gpointer     user_data)
+facebook_service_get_albums_ready_cb (SoupSession *session,
+				      SoupMessage *msg,
+				      gpointer     user_data)
 {
 	FacebookService    *self = user_data;
 	GSimpleAsyncResult *result;
-	SoupBuffer         *body;
-	DomDocument        *doc = NULL;
+	JsonNode           *node;
 	GError             *error = NULL;
 
 	result = facebook_connection_get_result (self->priv->conn);
 
-	if (msg->status_code != 200) {
-		g_simple_async_result_set_error (result,
-						 SOUP_HTTP_ERROR,
-						 msg->status_code,
-						 "%s",
-						 soup_status_get_phrase (msg->status_code));
-		g_simple_async_result_complete_in_idle (result);
-		return;
-	}
-
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement *node;
+	if (facebook_utils_parse_response (msg, &node, &error)) {
 		GList      *albums = NULL;
-
-		for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
-			if (g_strcmp0 (node->tag_name, "photos_getAlbums_response") == 0) {
-				DomElement *child;
-
-				for (child = node->first_child; child; child = child->next_sibling) {
-					if (g_strcmp0 (child->tag_name, "album") == 0) {
-						FacebookAlbum *album;
-
-						album = facebook_album_new ();
-						dom_domizable_load_from_element (DOM_DOMIZABLE (album), child);
-						albums = g_list_prepend (albums, album);
-					}
-				}
-			}
+		JsonObject *obj;
+		JsonArray  *data;
+		int         i;
+
+		obj = json_node_get_object (node);
+		data = json_object_get_array_member (obj, "data");
+		for (i = 0; i < json_array_get_length (data); i++) {
+			JsonNode      *album_node;
+			FacebookAlbum *album;
+
+			album_node = json_array_get_element (data, i);
+			album = (FacebookAlbum *) json_gobject_deserialize (FACEBOOK_TYPE_ALBUM, album_node);
+			albums = g_list_prepend (albums, album);
 		}
 
 		albums = g_list_reverse (albums);
 		g_simple_async_result_set_op_res_gpointer (result, albums, (GDestroyNotify) _g_object_list_unref);
 
-		g_object_unref (doc);
+		json_node_free (node);
 	}
 	else
 		g_simple_async_result_set_from_error (result, error);
 
 	g_simple_async_result_complete_in_idle (result);
-
-	soup_buffer_free (body);
 }
 
 
 void
 facebook_service_get_albums (FacebookService     *self,
-			     const char          *user_id,
 			     GCancellable        *cancellable,
 			     GAsyncReadyCallback  callback,
 			     gpointer             user_data)
 {
 	GHashTable  *data_set;
+	char        *uri;
 	SoupMessage *msg;
 
-	g_return_if_fail (user_id != NULL);
+	g_return_if_fail (self->priv->user != NULL);
 
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Getting the album list"), NULL, TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self->priv->conn),
+			   _("Getting the album list"),
+			   NULL,
+			   TRUE,
+			   0.0);
 
+	uri = g_strdup_printf ("https://graph.facebook.com/%s/albums";, self->priv->user->id);
 	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "method", "facebook.photos.getAlbums");
-	g_hash_table_insert (data_set, "uid", (char *) user_id);
-	facebook_connection_add_api_sig (self->priv->conn, data_set);
-	msg = soup_form_request_new_from_hash ("GET", FACEBOOK_HTTPS_REST_SERVER, data_set);
+	facebook_connection_add_access_token (self->priv->conn, data_set);
+	msg = soup_form_request_new_from_hash ("GET", uri, data_set);
 	facebook_connection_send_message (self->priv->conn,
 					  msg,
 					  cancellable,
 					  callback,
 					  user_data,
 					  facebook_service_get_albums,
-					  get_albums_ready_cb,
+					  facebook_service_get_albums_ready_cb,
 					  self);
 
+	g_free (uri);
 	g_hash_table_destroy (data_set);
 }
 
@@ -428,83 +293,67 @@ facebook_service_get_albums_finish (FacebookService  *service,
 /* -- facebook_service_create_album -- */
 
 
-static void
-create_album_ready_cb (SoupSession *session,
-		       SoupMessage *msg,
-		       gpointer     user_data)
-{
-	FacebookService    *self = user_data;
-	GSimpleAsyncResult *result;
-	SoupBuffer         *body;
-	DomDocument        *doc = NULL;
-	GError             *error = NULL;
-
-	result = facebook_connection_get_result (self->priv->conn);
-
-	if (msg->status_code != 200) {
-		g_simple_async_result_set_error (result,
-						 SOUP_HTTP_ERROR,
-						 msg->status_code,
-						 "%s",
-						 soup_status_get_phrase (msg->status_code));
-		g_simple_async_result_complete_in_idle (result);
-		return;
-	}
+typedef struct {
+	FacebookService *service;
+	FacebookAlbum   *album;
+} CreateAlbumData;
 
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement    *node;
-		FacebookAlbum *album = NULL;
 
-		for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
-			if (g_strcmp0 (node->tag_name, "photos_createAlbum_response") == 0) {
-				album = facebook_album_new ();
-				dom_domizable_load_from_element (DOM_DOMIZABLE (album), node);
-				break;
-			}
-		}
+static CreateAlbumData *
+create_album_data_new (FacebookService *service,
+		       FacebookAlbum   *album)
+{
+	CreateAlbumData *ca_data;
 
-		if (album == NULL) {
-			error = g_error_new_literal (FACEBOOK_CONNECTION_ERROR, 0, _("Unknown error"));
-			g_simple_async_result_set_from_error (result, error);
-		}
-		else
-			g_simple_async_result_set_op_res_gpointer (result, album, (GDestroyNotify) _g_object_unref);
+	ca_data = g_new0 (CreateAlbumData, 1);
+	ca_data->service = g_object_ref (service);
+	ca_data->album = g_object_ref (album);
 
-		g_object_unref (doc);
-	}
-	else
-		g_simple_async_result_set_from_error (result, error);
+	return ca_data;
+}
 
-	g_simple_async_result_complete_in_idle (result);
 
-	soup_buffer_free (body);
+static void
+create_album_data_free (CreateAlbumData *ca_data)
+{
+	_g_object_unref (ca_data->service);
+	_g_object_unref (ca_data->album);
+	g_free (ca_data);
 }
 
 
-static const char *
-get_privacy_from_visibility (FacebookVisibility visibility)
+static void
+facebook_service_create_album_ready_cb (SoupSession *session,
+					SoupMessage *msg,
+					gpointer     user_data)
 {
-	char *value = NULL;
+	CreateAlbumData    *ca_data = user_data;
+	FacebookService    *self = ca_data->service;
+	GSimpleAsyncResult *result;
+	JsonNode           *node;
+	GError             *error = NULL;
 
-	switch (visibility) {
-	case FACEBOOK_VISIBILITY_EVERYONE:
-		value = "{ value: \"EVERYONE\" }";
-		break;
+	result = facebook_connection_get_result (self->priv->conn);
 
-	case FACEBOOK_VISIBILITY_ALL_FRIENDS:
-		value = "{ value: \"ALL_FRIENDS\" }";
-		break;
+	if (facebook_utils_parse_response (msg, &node, &error)) {
+		FacebookAlbum *album;
+		JsonObject    *obj;
+		const char    *id;
 
-	case FACEBOOK_VISIBILITY_SELF:
-		value = "{ value: \"SELF\" }";
-		break;
+		album = g_object_ref (ca_data->album);
+		obj = json_node_get_object (node);
+		id = json_object_get_string_member (obj, "id");
+		g_object_set (album, "id", id, NULL);
+		g_simple_async_result_set_op_res_gpointer (result, album, (GDestroyNotify) _g_object_unref);
 
-	default:
-		break;
+		json_node_free (node);
 	}
+	else
+		g_simple_async_result_set_from_error (result, error);
 
-	return value;
+	g_simple_async_result_complete_in_idle (result);
+
+	create_album_data_free (ca_data);
 }
 
 
@@ -515,35 +364,36 @@ facebook_service_create_album (FacebookService     *self,
 			       GAsyncReadyCallback  callback,
 			       gpointer             user_data)
 {
-	GHashTable  *data_set;
-	const char  *privacy;
-	SoupMessage *msg;
+	CreateAlbumData *ca_data;
+	char            *uri;
+	GHashTable      *data_set;
+	SoupMessage     *msg;
 
+	g_return_if_fail (self->priv->user != NULL);
 	g_return_if_fail (album != NULL);
 	g_return_if_fail (album->name != NULL);
 
 	gth_task_progress (GTH_TASK (self->priv->conn), _("Creating the new album"), NULL, TRUE, 0.0);
 
+	ca_data = create_album_data_new (self, album);
+
+	uri = g_strdup_printf ("https://graph.facebook.com/%s/albums";, self->priv->user->id);
 	data_set = g_hash_table_new (g_str_hash, g_str_equal);
-	g_hash_table_insert (data_set, "method", "facebook.photos.createAlbum");
 	g_hash_table_insert (data_set, "name", album->name);
 	if (album->description != NULL)
-		g_hash_table_insert (data_set, "description", album->description);
-	if (album->location != NULL)
-		g_hash_table_insert (data_set, "location", album->location);
-	privacy = get_privacy_from_visibility (album->visibility);
-	if (privacy != NULL)
-		g_hash_table_insert (data_set, "privacy", (char *) privacy);
-	facebook_connection_add_api_sig (self->priv->conn, data_set);
-	msg = soup_form_request_new_from_hash ("POST", FACEBOOK_HTTPS_REST_SERVER, data_set);
+		g_hash_table_insert (data_set, "message", album->description);
+	if (album->privacy != NULL)
+		g_hash_table_insert (data_set, "privacy", album->privacy);
+	facebook_connection_add_access_token (self->priv->conn, data_set);
+	msg = soup_form_request_new_from_hash ("POST", uri, data_set);
 	facebook_connection_send_message (self->priv->conn,
 					  msg,
 					  cancellable,
 					  callback,
 					  user_data,
 					  facebook_service_create_album,
-					  create_album_ready_cb,
-					  self);
+					  facebook_service_create_album_ready_cb,
+					  ca_data);
 
 	g_hash_table_destroy (data_set);
 }
@@ -601,46 +451,25 @@ upload_photo_ready_cb (SoupSession *session,
 		       gpointer     user_data)
 {
 	FacebookService *self = user_data;
-	SoupBuffer    *body;
-	DomDocument   *doc = NULL;
-	GError        *error = NULL;
-	GthFileData   *file_data;
-
-	if (msg->status_code != 200) {
-		GError *error;
-
-		error = g_error_new_literal (SOUP_HTTP_ERROR, msg->status_code, soup_status_get_phrase (msg->status_code));
-		upload_photos_done (self, error);
-		g_error_free (error);
-
-		return;
-	}
-
-	body = soup_message_body_flatten (msg->response_body);
-	if (facebook_utils_parse_response (body, &doc, &error)) {
-		DomElement *node;
+	JsonNode        *node;
+	GError          *error = NULL;
+	GthFileData     *file_data;
 
-		/* save the photo id */
+	if (facebook_utils_parse_response (msg, &node, &error)) {
+		JsonObject *obj;
+		const char *id;
 
-		for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
-			if (g_strcmp0 (node->tag_name, "pid") == 0) {
-				const char *id;
+		obj = json_node_get_object (node);
+		id = json_object_get_string_member (obj, "id");
+		self->priv->post_photos->ids = g_list_prepend (self->priv->post_photos->ids, g_strdup (id));
 
-				id = dom_element_get_inner_text (node);
-				self->priv->post_photos->ids = g_list_prepend (self->priv->post_photos->ids, g_strdup (id));
-			}
-		}
-
-		g_object_unref (doc);
+		json_node_free (node);
 	}
 	else {
-		soup_buffer_free (body);
 		upload_photos_done (self, error);
 		return;
 	}
 
-	soup_buffer_free (body);
-
 	file_data = self->priv->post_photos->current->data;
 	self->priv->post_photos->uploaded_size += g_file_info_get_size (file_data->info);
 	self->priv->post_photos->current = self->priv->post_photos->current->next;
@@ -711,19 +540,14 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 
 		data_set = g_hash_table_new (g_str_hash, g_str_equal);
 
-		g_hash_table_insert (data_set, "method", "facebook.photos.upload");
-
 		title = gth_file_data_get_attribute_as_string (file_data, "general::title");
 		description = gth_file_data_get_attribute_as_string (file_data, "general::description");
 		if (description != NULL)
-			g_hash_table_insert (data_set, "caption", description);
+			g_hash_table_insert (data_set, "message", description);
 		else if (title != NULL)
-			g_hash_table_insert (data_set, "caption", title);
-
-		if (self->priv->post_photos->album != NULL)
-			g_hash_table_insert (data_set, "aid", self->priv->post_photos->album->id);
+			g_hash_table_insert (data_set, "message", title);
 
-		facebook_connection_add_api_sig (self->priv->conn, data_set);
+		facebook_connection_add_access_token (self->priv->conn, data_set);
 
 		keys = g_hash_table_get_keys (data_set);
 		for (scan = keys; scan; scan = scan->next) {
@@ -798,7 +622,7 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 	uri = g_file_get_uri (file_data->file);
 	body = soup_buffer_new (SOUP_MEMORY_TEMPORARY, *buffer, count);
 	soup_multipart_append_form_file (multipart,
-					 "filename",
+					 "source",
 					 _g_uri_get_basename (uri),
 					 gth_file_data_get_mime_type (file_data),
 					 body);
@@ -809,7 +633,8 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 	/* send the file */
 
 	self->priv->post_photos->wrote_body_data_size = 0;
-	msg = soup_form_request_new_from_multipart (FACEBOOK_HTTPS_REST_SERVER, multipart);
+	uri = g_strdup_printf ("https://graph.facebook.com/%s/photos";, self->priv->post_photos->album->id);
+	msg = soup_form_request_new_from_multipart (uri, multipart);
 	g_signal_connect (msg,
 			  "wrote-body-data",
 			  (GCallback) upload_photo_wrote_body_data_cb,
@@ -823,6 +648,7 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 					  upload_photo_ready_cb,
 					  self);
 
+	g_free (uri);
 	soup_multipart_free (multipart);
 }
 
@@ -881,7 +707,11 @@ facebook_service_upload_photos (FacebookService     *self,
 				GAsyncReadyCallback  callback,
 				gpointer             user_data)
 {
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Uploading the files to the server"), NULL, TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self->priv->conn),
+			   _("Uploading the files to the server"),
+			   NULL,
+			   TRUE,
+			   0.0);
 
 	post_photos_data_free (self->priv->post_photos);
 	self->priv->post_photos = g_new0 (PostPhotosData, 1);
diff --git a/extensions/facebook/facebook-service.h b/extensions/facebook/facebook-service.h
index 6571cf3..8396dca 100644
--- a/extensions/facebook/facebook-service.h
+++ b/extensions/facebook/facebook-service.h
@@ -53,23 +53,14 @@ struct _FacebookServiceClass
 
 GType             facebook_service_get_type                   (void) G_GNUC_CONST;
 FacebookService * facebook_service_new                        (FacebookConnection   *conn);
-void              facebook_service_get_logged_in_user         (FacebookService      *self,
+void              facebook_service_get_user                   (FacebookService      *self,
 							       GCancellable         *cancellable,
 							       GAsyncReadyCallback   callback,
 							       gpointer              user_data);
-char *            facebook_service_get_logged_in_user_finish  (FacebookService      *self,
-						               GAsyncResult         *result,
-						               GError              **error);
-void              facebook_service_get_user_info              (FacebookService      *self,
-							       const char           *fields,
-							       GCancellable         *cancellable,
-							       GAsyncReadyCallback   callback,
-							       gpointer              user_data);
-FacebookUser *    facebook_service_get_user_info_finish       (FacebookService      *self,
+FacebookUser *    facebook_service_get_user_finish            (FacebookService      *self,
 						               GAsyncResult         *result,
 						               GError              **error);
 void              facebook_service_get_albums                 (FacebookService      *self,
-							       const char           *user_id,
 							       GCancellable         *cancellable,
 							       GAsyncReadyCallback   callback,
 							       gpointer              user_data);
diff --git a/extensions/facebook/facebook-user.c b/extensions/facebook/facebook-user.c
index f745edb..3a6e60a 100644
--- a/extensions/facebook/facebook-user.c
+++ b/extensions/facebook/facebook-user.c
@@ -26,14 +26,16 @@
 #include "facebook-user.h"
 
 
-static void facebook_user_dom_domizable_interface_init (DomDomizableInterface *iface);
+G_DEFINE_TYPE (FacebookUser, facebook_user, G_TYPE_OBJECT)
 
 
-G_DEFINE_TYPE_WITH_CODE (FacebookUser,
-			 facebook_user,
-			 G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (DOM_TYPE_DOMIZABLE,
-					        facebook_user_dom_domizable_interface_init))
+enum {
+        PROP_0,
+        PROP_ID,
+        PROP_NAME,
+        PROP_LINK,
+        PROP_USERNAME
+};
 
 
 static void
@@ -44,6 +46,8 @@ facebook_user_finalize (GObject *obj)
 	self = FACEBOOK_USER (obj);
 
 	g_free (self->id);
+	g_free (self->name);
+	g_free (self->link);
 	g_free (self->username);
 
 	G_OBJECT_CLASS (facebook_user_parent_class)->finalize (obj);
@@ -51,56 +55,104 @@ facebook_user_finalize (GObject *obj)
 
 
 static void
-facebook_user_class_init (FacebookUserClass *klass)
-{
-	G_OBJECT_CLASS (klass)->finalize = facebook_user_finalize;
-}
-
-
-static DomElement*
-facebook_user_create_element (DomDomizable *base,
-			      DomDocument  *doc)
+facebook_user_set_property (GObject      *object,
+			    guint         property_id,
+			    const GValue *value,
+			    GParamSpec   *pspec)
 {
 	FacebookUser *self;
-	DomElement *element;
 
-	self = FACEBOOK_USER (base);
-
-	element = dom_document_create_element (doc, "user", NULL);
-	if (self->id != NULL)
-		dom_element_set_attribute (element, "id", self->id);
-	if (self->username != NULL)
-		dom_element_set_attribute (element, "name", self->username);
-
-	return element;
+        self = FACEBOOK_USER (object);
+
+	switch (property_id) {
+	case PROP_ID:
+		_g_strset (&self->id, g_value_get_string (value));
+		break;
+	case PROP_NAME:
+		_g_strset (&self->name, g_value_get_string (value));
+		break;
+	case PROP_LINK:
+		_g_strset (&self->link, g_value_get_string (value));
+		break;
+	case PROP_USERNAME:
+		_g_strset (&self->username, g_value_get_string (value));
+		break;
+	default:
+		break;
+	}
 }
 
 
 static void
-facebook_user_load_from_element (DomDomizable *base,
-			         DomElement   *element)
+facebook_user_get_property (GObject    *object,
+			    guint       property_id,
+			    GValue     *value,
+			    GParamSpec *pspec)
 {
 	FacebookUser *self;
-	DomElement *node;
-
-	self = FACEBOOK_USER (base);
 
-	for (node = element->first_child; node; node = node->next_sibling) {
-		if (g_strcmp0 (node->tag_name, "uid") == 0) {
-			_g_strset (&self->id, dom_element_get_inner_text (node));
-		}
-		else if (g_strcmp0 (node->tag_name, "name") == 0) {
-			_g_strset (&self->username, dom_element_get_inner_text (node));
-		}
+        self = FACEBOOK_USER (object);
+
+	switch (property_id) {
+	case PROP_ID:
+		g_value_set_string (value, self->id);
+		break;
+	case PROP_NAME:
+		g_value_set_string (value, self->name);
+		break;
+	case PROP_LINK:
+		g_value_set_string (value, self->link);
+		break;
+	case PROP_USERNAME:
+		g_value_set_string (value, self->username);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
 	}
 }
 
 
 static void
-facebook_user_dom_domizable_interface_init (DomDomizableInterface *iface)
+facebook_user_class_init (FacebookUserClass *klass)
 {
-	iface->create_element = facebook_user_create_element;
-	iface->load_from_element = facebook_user_load_from_element;
+	GObjectClass *object_class;
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = facebook_user_finalize;
+	object_class->set_property = facebook_user_set_property;
+	object_class->get_property = facebook_user_get_property;
+
+	/* properties */
+
+	g_object_class_install_property (object_class,
+					 PROP_ID,
+					 g_param_spec_string ("id",
+                                                              "ID",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_NAME,
+					 g_param_spec_string ("name",
+                                                              "Name",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_LINK,
+					 g_param_spec_string ("link",
+                                                              "Link",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_USERNAME,
+					 g_param_spec_string ("username",
+                                                              "Username",
+                                                              "",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
 }
 
 
@@ -108,7 +160,9 @@ static void
 facebook_user_init (FacebookUser *self)
 {
 	self->id = NULL;
+	self->name = NULL;
 	self->username = NULL;
+	self->link = NULL;
 }
 
 
@@ -117,19 +171,3 @@ facebook_user_new (void)
 {
 	return g_object_new (FACEBOOK_TYPE_USER, NULL);
 }
-
-
-void
-facebook_user_set_id (FacebookUser *self,
-		      const char   *value)
-{
-	_g_strset (&self->id, value);
-}
-
-
-void
-facebook_user_set_username (FacebookUser *self,
-			    const char   *value)
-{
-	_g_strset (&self->username, value);
-}
diff --git a/extensions/facebook/facebook-user.h b/extensions/facebook/facebook-user.h
index 7a97a68..5cf416d 100644
--- a/extensions/facebook/facebook-user.h
+++ b/extensions/facebook/facebook-user.h
@@ -41,6 +41,8 @@ struct _FacebookUser {
 	GObject parent_instance;
 
 	char *id;
+	char *name;
+	char *link;
 	char *username;
 };
 
@@ -50,10 +52,6 @@ struct _FacebookUserClass {
 
 GType          facebook_user_get_type     (void);
 FacebookUser * facebook_user_new          (void);
-void           facebook_user_set_id       (FacebookUser *self,
-				           const char   *value);
-void           facebook_user_set_username (FacebookUser *self,
-				           const char   *value);
 
 G_END_DECLS
 
diff --git a/extensions/facebook/facebook.extension.in.in b/extensions/facebook/facebook.extension.in.in
index 5be8ae0..4d77d95 100644
--- a/extensions/facebook/facebook.extension.in.in
+++ b/extensions/facebook/facebook.extension.in.in
@@ -11,4 +11,4 @@ Category=Exporter
 Type=module
 File=%LIBRARY%
 API=%GTHUMB_API_VERSION%
-Requires=export_tools
+Requires=export_tools;oauth
diff --git a/extensions/oauth/Makefile.am b/extensions/oauth/Makefile.am
index 044c127..009e29c 100644
--- a/extensions/oauth/Makefile.am
+++ b/extensions/oauth/Makefile.am
@@ -7,6 +7,8 @@ extension_LTLIBRARIES = liboauth.la
 
 liboauth_la_SOURCES = 				\
 	main.c					\
+	oauth2-ask-authorization-dialog.c	\
+	oauth2-ask-authorization-dialog.h	\
 	oauth-account.c				\
 	oauth-account.h				\
 	oauth-account-chooser-dialog.c		\
@@ -18,9 +20,9 @@ liboauth_la_SOURCES = 				\
 	oauth-connection.c			\
 	oauth-connection.h
 
-liboauth_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBSECRET_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+liboauth_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBSECRET_CFLAGS) $(WEBKIT2_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
 liboauth_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
-liboauth_la_LIBADD = $(GTHUMB_LIBS) $(JPEG_LIBS) $(LIBSECRET_LIBS) $(LIBSOUP_LIBS)
+liboauth_la_LIBADD = $(GTHUMB_LIBS) $(JPEG_LIBS) $(LIBSECRET_LIBS) $(LIBSOUP_LIBS) $(WEBKIT2_LIBS)
 liboauth_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
 
 extensioninidir = $(extensiondir)
diff --git a/extensions/oauth/data/ui/Makefile.am b/extensions/oauth/data/ui/Makefile.am
index fef8a90..01d55f9 100644
--- a/extensions/oauth/data/ui/Makefile.am
+++ b/extensions/oauth/data/ui/Makefile.am
@@ -3,7 +3,7 @@ ui_DATA = 				\
 	oauth-account-chooser.ui	\
 	oauth-account-manager.ui	\
 	oauth-ask-authorization.ui	\
-	oauth-complete-authorization.ui		
+	oauth-complete-authorization.ui
 
 EXTRA_DIST = $(ui_DATA)
 
diff --git a/extensions/oauth/oauth2-ask-authorization-dialog.c b/extensions/oauth/oauth2-ask-authorization-dialog.c
new file mode 100644
index 0000000..0b2bfc8
--- /dev/null
+++ b/extensions/oauth/oauth2-ask-authorization-dialog.c
@@ -0,0 +1,134 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <webkit2/webkit2.h>
+#include "oauth2-ask-authorization-dialog.h"
+
+
+#define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
+
+
+G_DEFINE_TYPE (OAuth2AskAuthorizationDialog, oauth2_ask_authorization_dialog, GTK_TYPE_DIALOG)
+
+
+/* Signals */
+enum {
+	REDIRECTED,
+	LAST_SIGNAL
+};
+
+
+static guint oauth2_ask_authorization_dialog_signals[LAST_SIGNAL] = { 0 };
+
+
+struct _OAuth2AskAuthorizationDialogPrivate {
+	GtkWidget *view;
+};
+
+
+static void
+oauth2_ask_authorization_dialog_class_init (OAuth2AskAuthorizationDialogClass *klass)
+{
+	g_type_class_add_private (klass, sizeof (OAuth2AskAuthorizationDialogPrivate));
+
+	oauth2_ask_authorization_dialog_signals[REDIRECTED] =
+		g_signal_new ("redirected",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (OAuth2AskAuthorizationDialogClass, redirected),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+}
+
+
+static void
+webkit_view_load_changed_cb (WebKitWebView   *web_view,
+                	     WebKitLoadEvent  load_event,
+                	     gpointer         user_data)
+{
+	OAuth2AskAuthorizationDialog *self = user_data;
+
+	if (load_event == WEBKIT_LOAD_REDIRECTED)
+		g_signal_emit (self, oauth2_ask_authorization_dialog_signals[REDIRECTED], 0);
+}
+
+
+static void
+oauth2_ask_authorization_dialog_init (OAuth2AskAuthorizationDialog *self)
+{
+	GtkWidget *box;
+
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG, OAuth2AskAuthorizationDialogPrivate);
+
+	gtk_window_set_default_size (GTK_WINDOW (self), 500, 500);
+	gtk_window_set_resizable (GTK_WINDOW (self), TRUE);
+	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
+	gtk_container_set_border_width (GTK_CONTAINER (self), 5);
+
+	box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+	gtk_widget_show (box);
+	gtk_container_set_border_width (GTK_CONTAINER (box), 5);
+	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), box, TRUE, TRUE, 0);
+
+	self->priv->view = webkit_web_view_new ();
+	gtk_widget_show (self->priv->view);
+	gtk_box_pack_start (GTK_BOX (box), self->priv->view, TRUE, TRUE, 0);
+
+	g_signal_connect (self->priv->view,
+			  "load-changed",
+			  G_CALLBACK (webkit_view_load_changed_cb),
+			  self);
+
+	gtk_dialog_add_button (GTK_DIALOG (self),
+			       GTK_STOCK_CANCEL,
+			       GTK_RESPONSE_CANCEL);
+}
+
+
+GtkWidget *
+oauth2_ask_authorization_dialog_new (const char *title,
+				     const char *uri)
+{
+	OAuth2AskAuthorizationDialog *self;
+
+	self = g_object_new (OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG, "title", title, NULL);
+	webkit_web_view_load_uri (WEBKIT_WEB_VIEW (self->priv->view), uri);
+
+	return (GtkWidget *) self;
+}
+
+
+GtkWidget *
+oauth2_ask_authorization_dialog_get_view (OAuth2AskAuthorizationDialog *self)
+{
+	return self->priv->view;
+}
+
+
+const char *
+oauth2_ask_authorization_dialog_get_uri (OAuth2AskAuthorizationDialog *self)
+{
+	return webkit_web_view_get_uri (WEBKIT_WEB_VIEW (self->priv->view));
+}
diff --git a/extensions/oauth/oauth2-ask-authorization-dialog.h b/extensions/oauth/oauth2-ask-authorization-dialog.h
new file mode 100644
index 0000000..5c19239
--- /dev/null
+++ b/extensions/oauth/oauth2-ask-authorization-dialog.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef OAUTH2_ASK_AUTHORIZATION_DIALOG_H
+#define OAUTH2_ASK_AUTHORIZATION_DIALOG_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG            (oauth2_ask_authorization_dialog_get_type ())
+#define OAUTH2_ASK_AUTHORIZATION_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG, OAuth2AskAuthorizationDialog))
+#define OAUTH2_ASK_AUTHORIZATION_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG, OAuth2AskAuthorizationDialogClass))
+#define OAUTH2_IS_ASK_AUTHORIZATION_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG))
+#define OAUTH2_IS_ASK_AUTHORIZATION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG))
+#define OAUTH2_ASK_AUTHORIZATION_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), OAUTH2_TYPE_ASK_AUTHORIZATION_DIALOG, OAuth2AskAuthorizationDialogClass))
+
+typedef struct _OAuth2AskAuthorizationDialog OAuth2AskAuthorizationDialog;
+typedef struct _OAuth2AskAuthorizationDialogClass OAuth2AskAuthorizationDialogClass;
+typedef struct _OAuth2AskAuthorizationDialogPrivate OAuth2AskAuthorizationDialogPrivate;
+
+struct _OAuth2AskAuthorizationDialog {
+	GtkDialog parent_instance;
+	OAuth2AskAuthorizationDialogPrivate *priv;
+};
+
+struct _OAuth2AskAuthorizationDialogClass {
+	GtkDialogClass parent_class;
+
+	/*< signals >*/
+
+	void  (*redirected)  (OAuth2AskAuthorizationDialog *self);
+};
+
+GType          oauth2_ask_authorization_dialog_get_type     (void);
+GtkWidget *    oauth2_ask_authorization_dialog_new          (const char *title,
+							     const char *url);
+GtkWidget *    oauth2_ask_authorization_dialog_get_view     (OAuth2AskAuthorizationDialog *self);
+const char *   oauth2_ask_authorization_dialog_get_uri      (OAuth2AskAuthorizationDialog *self);
+
+G_END_DECLS
+
+#endif /* OAUTH2_ASK_AUTHORIZATION_DIALOG_H */
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index ab1d71c..13d0c83 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -289,7 +289,7 @@ gthumb_LDADD =						\
 	$(LIBCHAMPLAIN_LIBS)				\
 	$(LIBRSVG_LIBS)					\
 	$(LIBWEBP_LIBS)					\
-	$(LIBJSON_GLIB_LIBS)				\
+	$(JSON_GLIB_LIBS)				\
 	$(WEBKIT2_LIBS)					\
 	$(NULL)
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]