[tracker/miner-web-review] libtracker-miner: Add TrackerMinerWeb class



commit 7519f2b4945648b817653c536b5971060da0debe
Author: Adrien Bustany <abustany gnome org>
Date:   Fri Nov 6 15:25:19 2009 +0100

    libtracker-miner: Add TrackerMinerWeb class
    
    The TrackerMinerWeb class is a thin layer above TrackerMiner which adds
    functions commonly used by miners fetching data from remote services.

 configure.ac                                       |   31 ++
 data/dbus/tracker-miner-web.xml                    |   98 +++++
 examples/libtracker-miner/Makefile.am              |   16 +-
 examples/libtracker-miner/password-provider-test.c |   88 +++++
 src/libtracker-miner/Makefile.am                   |   47 +++-
 .../tracker-gnome-password-provider.c              |  291 ++++++++++++++
 .../tracker-keyfile-password-provider.c            |  396 ++++++++++++++++++++
 src/libtracker-miner/tracker-miner-0.7.deps        |    1 +
 src/libtracker-miner/tracker-miner-0.7.vapi        |  158 ++++++++
 src/libtracker-miner/tracker-miner-web-dbus.h      |   47 +++
 src/libtracker-miner/tracker-miner-web.c           |  263 +++++++++++++
 src/libtracker-miner/tracker-miner-web.deps.in     |    1 +
 src/libtracker-miner/tracker-miner-web.h           |  136 +++++++
 src/libtracker-miner/tracker-miner.c               |    4 +-
 src/libtracker-miner/tracker-password-provider.c   |  137 +++++++
 src/libtracker-miner/tracker-password-provider.h   |   88 +++++
 16 files changed, 1795 insertions(+), 7 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 37d47ac..5d32778 100644
--- a/configure.ac
+++ b/configure.ac
@@ -157,6 +157,7 @@ EDS_REQUIRED=2.25.5
 LIBSTREAMANALYZER_REQUIRED=0.7.0
 GEE_REQUIRED=0.3
 ID3LIB_REQUIRED=3.8.3
+GNOME_KEYRING_REQUIRED=2.26
 
 # Library Checks
 PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED])
@@ -761,6 +762,36 @@ fi
 
 AM_CONDITIONAL(HAVE_UNAC, test "x$have_unac" = "xyes")
 
+##################################################################
+# Enable Gnome Keyring support to store credentials (for web miners)
+##################################################################
+
+AC_ARG_ENABLE(gnome_keyring,
+	      AS_HELP_STRING([--enable-gnome-keyring],
+			     [enable Gnome Keyring support to store credentials [[default=auto]]]),,
+	      [enable_gnome_keyring=auto])
+
+if test "x$enable_gnome_keyring" != "xno"; then
+	PKG_CHECK_MODULES(GNOME_KEYRING,
+	                  [ gnome-keyring-1 >= $GNOME_KEYRING_REQUIRED ],
+	                  [have_gnome_keyring=yes],
+	                  [have_gnome_keyring=no])
+	AC_SUBST(GNOME_KEYRING_LIBS)
+	AC_SUBST(GNOME_KEYRING_CFLAGS)
+
+	if test "x$have_gnome_keyring" = "xyes"; then
+		AC_DEFINE(HAVE_GNOME_KEYRING, [], [Define if we have Gnome Keyring for password storage])
+	fi
+fi
+
+if test "x$enable_gnome_keyring" = "xyes"; then
+   if test "x$have_gnome_keyring" != "xyes"; then
+      AC_MSG_ERROR([Couldn't find Gnome Keyring >= $GNOME_KEYRING_REQUIRED.])
+   fi
+fi
+
+AM_CONDITIONAL(HAVE_GNOME_KEYRING, test "x$have_gnome_keyring" = "xyes")
+
 ####################################################################
 # Mail miners
 ####################################################################
diff --git a/data/dbus/tracker-miner-web.xml b/data/dbus/tracker-miner-web.xml
new file mode 100644
index 0000000..7b54da2
--- /dev/null
+++ b/data/dbus/tracker-miner-web.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<node name="/">
+  <interface name="org.freedesktop.Tracker1.Miner.Web">
+    <method name="Authenticate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            Tries to authenticate the miner against the remote web service.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+    <method name="GetAssociationData">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            Returns a hash containing the information necessary to know how to
+            associate the miner to its web service.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+      <arg name="result" type="a{ss}" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              A hash containing the association information. Its keys depend on
+              the type of association.
+              For a token based association, the following keys are always
+              defined:
+              * url: A url where the user can follow the association procedure
+              For a token based association, the following keys might be
+              defined:
+              * post_message: A message to display after he returns from the
+                              association procedure
+              * post_url: A url to point the user to after he returns from the
+                          association procedure
+              If both post_message and post_url are defined, the message will
+              shown to the user before he is pointer to post_url.
+              For a user/pass based based association, the hash table should be
+              empty.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+    </method>
+    <method name="Associate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            Associates the miner with its web service.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+      <arg name="data" type="a{ss}" direction="in">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              A hash containing the association information. Its keys depend on
+              the type of association.
+              For a token based association, the hash should be empty.
+              For a user/pass based based association, the following keys
+              should be defined:
+              * url: A url where the user can follow the association procedure
+              For a token based association, the following keys might be
+              defined:
+              * username: The username provided by the user
+              * password: The password provided by the user
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+    </method>
+    <method name="Dissociate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            Dissociates the miner from its web service.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+    <property name="AssociationStatus" type="u" access="read">
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            Holds the current association status of the miner. The possible values are
+            defined in tracker-miner-web.h.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+    </property>
+  </interface>
+</node>
diff --git a/examples/libtracker-miner/Makefile.am b/examples/libtracker-miner/Makefile.am
index 5f753ce..6e1da78 100644
--- a/examples/libtracker-miner/Makefile.am
+++ b/examples/libtracker-miner/Makefile.am
@@ -17,7 +17,7 @@ INCLUDES =							\
 	$(DBUS_CFLAGS)						\
 	$(UNAC_CFLAGS)
 
-noinst_PROGRAMS = tracker-miner-test
+noinst_PROGRAMS = tracker-miner-test password-provider-test
 
 tracker_miner_test_SOURCES =   					\
 	tracker-miner-test.c    				\
@@ -36,3 +36,17 @@ tracker_miner_test_LDADD =                             		\
        $(GLIB2_LIBS)                                   		\
        -lz                                             		\
        -lm
+
+password_provider_test_SOURCES =      \
+	password-provider-test.c
+
+password_provider_test_LDADD =        \
+	$(top_builddir)/src/libtracker-miner/libtracker-miner- TRACKER_API_VERSION@.la	\
+	$(DBUS_LIBS)                                    		\
+	$(GMODULE_LIBS)                                 		\
+	$(GTHREAD_LIBS)                                 		\
+	$(GIO_LIBS)                                     		\
+	$(GCOV_LIBS)                                    		\
+	$(GLIB2_LIBS)                                   		\
+	-lz                                             		\
+	-lm
diff --git a/examples/libtracker-miner/password-provider-test.c b/examples/libtracker-miner/password-provider-test.c
new file mode 100644
index 0000000..1417804
--- /dev/null
+++ b/examples/libtracker-miner/password-provider-test.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+#include <libtracker-miner/tracker-password-provider.h>
+
+#define SERVICE_NAME "TestService"
+
+int main (int argc, char **argv)
+{
+	gchar *username = NULL;
+	gchar *password = NULL;
+	GError *error = NULL;
+
+	g_type_init ();
+	g_set_application_name ("PasswordBackendTest");
+
+	TrackerPasswordProvider *provider = tracker_password_provider_get ();
+
+	tracker_password_provider_store_password (provider,
+	                                          SERVICE_NAME,
+	                                          "This is the test service",
+	                                          "testUser",
+	                                          "testPass",
+	                                          &error);
+
+	if (error) {
+		g_critical ("tracker_password_provider_store: %s", error->message);
+		g_error_free (error);
+
+		return 1;
+	}
+
+	password = tracker_password_provider_get_password (provider,
+	                                                   SERVICE_NAME,
+	                                                   &username,
+	                                                   &error);
+
+	if (error) {
+		g_critical ("tracker_password_provider_get: %s", error->message);
+		g_error_free (error);
+		g_free (username);
+		g_free (password);
+
+		return 1;
+	} else {
+		g_message ("Username: %s , Password:%s", username, password);
+	}
+
+	g_free (username);
+	g_free (password);
+
+	// Also test without getting the username
+	password = tracker_password_provider_get_password (provider,
+	                                                   SERVICE_NAME,
+	                                                   NULL,
+	                                                   &error);
+
+	if (error) {
+		g_critical ("tracker_password_provider_get: %s", error->message);
+		g_error_free (error);
+		g_free (password);
+
+		return 1;
+	} else {
+		g_message ("Password:%s", password);
+	}
+
+	g_free (password);
+	g_object_unref (provider);
+	return 0;
+}
diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am
index 72451ca..c079326 100644
--- a/src/libtracker-miner/Makefile.am
+++ b/src/libtracker-miner/Makefile.am
@@ -36,6 +36,8 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES = 	\
 	tracker-miner-dbus.h				\
 	tracker-miner-fs.c				\
 	tracker-miner-fs.h				\
+	tracker-miner-web.c				\
+	tracker-miner-web.h				\
 	tracker-miner-manager.c				\
 	tracker-miner-manager.h				\
 	tracker-monitor.c				\
@@ -43,8 +45,9 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES = 	\
 	tracker-storage.c				\
 	tracker-storage.h				\
 	tracker-utils.c					\
+	tracker-thumbnailer.c				\
 	tracker-utils.h					\
-	tracker-thumbnailer.c
+	tracker-password-provider.c
 
 libtracker_minerinclude_HEADERS = 			\
 	tracker-crawler.h				\
@@ -53,11 +56,13 @@ libtracker_minerinclude_HEADERS = 			\
 	tracker-miner-fs.h				\
 	tracker-miner-manager.h				\
 	tracker-storage.h				\
-	tracker-thumbnailer.h
+	tracker-thumbnailer.h				\
+	tracker-miner-web.h				\
+	tracker-password-provider.h
 
 libtracker_miner_ TRACKER_API_VERSION@_la_LDFLAGS = 	\
 	-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
-	-export-symbols-regex '^tracker_(miner|thumbnailer|crawler|storage)_.*'
+	-export-symbols-regex '^tracker_(miner|thumbnailer|crawler|storage|password_provider)_.*'
 
 libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD = 	\
 	$(top_builddir)/src/libstemmer/libstemmer.la	\
@@ -74,6 +79,28 @@ libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD = 	\
 	$(GLIB2_LIBS)					\
 	$(GDKPIXBUF_LIBS)
 
+if HAVE_GNOME_KEYRING
+libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES += 	\
+	tracker-gnome-password-provider.c
+
+libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD +=	\
+	$(GNOME_KEYRING_LIBS)
+
+INCLUDES +=						\
+	$(GNOME_KEYRING_CFLAGS)
+else
+libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES += 	\
+	tracker-keyfile-password-provider.c
+endif
+
+vapidir=$(datadir)/vala/vapi
+vapi_DATA =                     \
+	tracker-miner-$(TRACKER_API_VERSION).vapi
+
+tracker-miner-web-$(TRACKER_API_VERSION).deps: tracker-miner-web.deps.in
+	$(SED) -e "s|@VERSION[ ]|${TRACKER_API_VERSION}|" $< > $@
+
+
 tracker-marshal.h: tracker-marshal.list
 	$(AM_V_GEN)$(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --header > $@
 
@@ -87,15 +114,27 @@ marshal_sources = 					\
 
 dbus_sources = 						\
 	tracker-miner-glue.h				\
+	tracker-miner-web-glue.h			\
 	tracker-miner-client.h
 
+# Custom rule to avoid API duplication. There is also a workaround for bug
+# in dbus-binding-tool where it generates bad code when two files are passed
+# on the command line (though the man page says it supports it)
+# This bug is reported at https://bugs.freedesktop.org/show_bug.cgi?id=25056
+tracker-miner-web-glue.h: $(top_srcdir)/data/dbus/tracker-miner-web.xml $(top_srcdir)/data/dbus/tracker-miner.xml
+	echo '<?xml version="1.0" encoding="UTF-8"?>'        > $(top_srcdir)/src/libtracker-miner/tracker-miner-web-full.xml
+	echo '<node name="/">'                              >> $(top_srcdir)/src/libtracker-miner/tracker-miner-web-full.xml
+	cat $^ | grep -v -e '<node' -e '<?xml' -e '</node>' >> $(top_srcdir)/src/libtracker-miner/tracker-miner-web-full.xml
+	echo '</node>'                                      >> $(top_srcdir)/src/libtracker-miner/tracker-miner-web-full.xml
+	$(AM_V_GEN)$(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=tracker_miner_web_dbus $(top_srcdir)/src/libtracker-miner/tracker-miner-web-full.xml
+
 %-glue.h: $(top_srcdir)/data/dbus/%.xml
 	$(AM_V_GEN)$(DBUSBINDINGTOOL) --mode=glib-server --output=$@ --prefix=$(subst -,_,$*) $^
 
 %-client.h: $(top_srcdir)/data/dbus/%.xml
 	$(AM_V_GEN)$(DBUSBINDINGTOOL) --mode=glib-client --output=$@ --prefix=$(subst -,_,$*) $^
 
-BUILT_SOURCES = $(dbus_sources) $(marshal_sources)
+BUILT_SOURCES = $(dbus_sources) $(marshal_sources) tracker-miner-web-full.xml
 
 CLEANFILES = $(BUILT_SOURCES)
 
diff --git a/src/libtracker-miner/tracker-gnome-password-provider.c b/src/libtracker-miner/tracker-gnome-password-provider.c
new file mode 100644
index 0000000..5adc2c7
--- /dev/null
+++ b/src/libtracker-miner/tracker-gnome-password-provider.c
@@ -0,0 +1,291 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib-object.h>
+#include <gnome-keyring.h>
+
+#include "tracker-password-provider.h"
+
+#define TRACKER_TYPE_PASSWORD_PROVIDER_GNOME         (tracker_password_provider_gnome_get_type())
+#define TRACKER_PASSWORD_PROVIDER_GNOME(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_PASSWORD_PROVIDER_GNOME, TrackerPasswordProviderGnome))
+#define TRACKER_PASSWORD_PROVIDER_GNOME_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_PASSWORD_PROVIDER_GNOME, TrackerPasswordProviderGnomeClass))
+#define TRACKER_IS_PASSWORD_PROVIDER_GNOME(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_PASSWORD_PROVIDER_GNOME))
+#define TRACKER_IS_PASSWORD_PROVIDER_GNOME_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    TRACKER_TYPE_PASSWORD_PROVIDER_GNOME))
+#define TRACKER_PASSWORD_PROVIDER_GNOME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_PASSWORD_PROVIDER_GNOME, TrackerPasswordProviderGnomeClass))
+
+#define TRACKER_PASSWORD_PROVIDER_GNOME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_PASSWORD_PROVIDER_GNOME, TrackerPasswordProviderGnomePrivate))
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_PASSWORD_PROVIDER_GNOME, TrackerPasswordProviderGnomePrivate))
+
+#define PASSWORD_PROVIDER_GNOME_NAME "Gnome keyring"
+
+typedef struct TrackerPasswordProviderGnome TrackerPasswordProviderGnome;
+typedef struct TrackerPasswordProviderGnomeClass TrackerPasswordProviderGnomeClass;
+typedef struct TrackerPasswordProviderGnomePrivate TrackerPasswordProviderGnomePrivate;
+
+struct TrackerPasswordProviderGnome {
+	GObject parent;
+};
+
+struct TrackerPasswordProviderGnomeClass {
+	GObjectClass parent_class;
+};
+
+struct TrackerPasswordProviderGnomePrivate {
+	gchar    *name;
+};
+
+const GnomeKeyringPasswordSchema password_schema = {
+	GNOME_KEYRING_ITEM_GENERIC_SECRET, {
+		{ "service", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+		{ "username", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+		{ NULL, 0 }
+	}
+};
+
+enum {
+	PROP_0,
+	PROP_NAME
+};
+
+GType           tracker_password_provider_gnome_get_type (void) G_GNUC_CONST;
+
+static void     tracker_password_provider_iface_init (TrackerPasswordProviderIface  *iface);
+static void     password_provider_gnome_finalize     (GObject                       *object);
+static void     password_provider_set_property       (GObject                       *object,
+                                                      guint                          prop_id,
+                                                      const GValue                  *value,
+                                                      GParamSpec                    *pspec);
+static void     password_provider_get_property       (GObject                       *object,
+                                                      guint                          prop_id,
+                                                      GValue                        *value,
+                                                      GParamSpec                    *pspec);
+
+static void     password_provider_gnome_store        (TrackerPasswordProvider       *provider,
+                                                      const gchar                   *service,
+                                                      const gchar                   *description,
+                                                      const gchar                   *username,
+                                                      const gchar                   *password,
+                                                      GError                       **error);
+static gchar*   password_provider_gnome_get          (TrackerPasswordProvider       *provider,
+                                                      const gchar                   *service,
+                                                      gchar                        **username,
+                                                      GError                       **error);
+static void     password_provider_gnome_forget       (TrackerPasswordProvider       *provider,
+                                                      const gchar                   *service,
+                                                      GError                       **error);
+
+G_DEFINE_TYPE_WITH_CODE (TrackerPasswordProviderGnome,
+                         tracker_password_provider_gnome,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (TRACKER_TYPE_PASSWORD_PROVIDER,
+                                                tracker_password_provider_iface_init))
+
+static void
+tracker_password_provider_gnome_class_init (TrackerPasswordProviderGnomeClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize     = password_provider_gnome_finalize;
+	object_class->set_property = password_provider_set_property;
+	object_class->get_property = password_provider_get_property;
+
+	g_object_class_override_property (object_class,
+	                                  PROP_NAME,
+	                                  "name");
+	g_type_class_add_private (object_class,
+	                          sizeof (TrackerPasswordProviderGnomePrivate));
+}
+
+static void
+tracker_password_provider_gnome_init (TrackerPasswordProviderGnome *provider)
+{
+}
+
+static void
+tracker_password_provider_iface_init (TrackerPasswordProviderIface *iface)
+{
+	iface->store_password = password_provider_gnome_store;
+	iface->get_password = password_provider_gnome_get;
+	iface->forget_password = password_provider_gnome_forget;
+}
+
+static void
+password_provider_gnome_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (tracker_password_provider_gnome_parent_class)->finalize (object);
+}
+
+static void
+password_provider_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+	TrackerPasswordProviderGnomePrivate *priv = GET_PRIV (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_free (priv->name);
+		priv->name = g_value_dup_string (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static void
+password_provider_get_property (GObject      *object,
+                                guint         prop_id,
+                                GValue       *value,
+                                GParamSpec   *pspec)
+{
+	TrackerPasswordProviderGnomePrivate *priv = GET_PRIV (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_value_set_string (value, priv->name);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static void
+password_provider_gnome_store (TrackerPasswordProvider  *provider,
+                               const gchar              *service,
+                               const gchar              *description,
+                               const gchar              *username,
+                               const gchar              *password,
+                               GError                  **error)
+{
+	GnomeKeyringResult r = gnome_keyring_store_password_sync (&password_schema,
+	                                                          NULL,
+	                                                          description,
+	                                                          password,
+	                                                          "service", service,
+	                                                          "username", username,
+	                                                          NULL);
+	if (r != GNOME_KEYRING_RESULT_OK) {
+		g_set_error (error,
+		             TRACKER_PASSWORD_PROVIDER_ERROR,
+		             TRACKER_PASSWORD_PROVIDER_ERROR_SERVICE,
+		             "Cannot store password: %s",
+		             gnome_keyring_result_to_message (r));
+	}
+}
+
+static gchar*
+password_provider_gnome_get (TrackerPasswordProvider  *provider,
+                             const gchar              *service,
+                             gchar                   **username,
+                             GError                  **error)
+{
+	gchar *password;
+	GnomeKeyringAttributeList *search_attributes;
+	GList *found_items = NULL;
+	GnomeKeyringFound *found;
+	GnomeKeyringResult r;
+	gint i;
+
+	search_attributes = gnome_keyring_attribute_list_new ();
+	gnome_keyring_attribute_list_append_string (search_attributes,
+	                                            "service", service);
+
+	r = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+	                                   search_attributes,
+	                                   &found_items);
+
+	gnome_keyring_attribute_list_free (search_attributes);
+
+	if (r != GNOME_KEYRING_RESULT_OK) {
+		if (r == GNOME_KEYRING_RESULT_NO_MATCH) {
+			g_set_error_literal (error,
+			                     TRACKER_PASSWORD_PROVIDER_ERROR,
+			                     TRACKER_PASSWORD_PROVIDER_ERROR_NOTFOUND,
+			                     "Password not found");
+		} else {
+			g_set_error (error,
+			             TRACKER_PASSWORD_PROVIDER_ERROR,
+			             TRACKER_PASSWORD_PROVIDER_ERROR_SERVICE,
+			             "Keyring error: %s",
+			             gnome_keyring_result_to_message (r));
+		}
+
+		gnome_keyring_found_list_free (found_items);
+		return NULL;
+	}
+
+	found = (GnomeKeyringFound *)(found_items->data);
+
+	/* Walk through all attributes and select the ones we're interested in */
+	for (i = 0 ; i < found->attributes->len ; ++i) {
+		GnomeKeyringAttribute *attr = &gnome_keyring_attribute_list_index (found->attributes, i);
+		if (username && !g_strcmp0 (attr->name, "username")) {
+			*username = g_strdup (attr->value.string);
+		}
+	}
+
+	password = tracker_password_provider_strdup_mlock (found->secret);
+
+	gnome_keyring_found_list_free (found_items);
+
+	return password;
+}
+
+static void
+password_provider_gnome_forget (TrackerPasswordProvider  *provider,
+                                const gchar              *service,
+                                GError                  **error)
+{
+	GnomeKeyringResult r = gnome_keyring_delete_password_sync (&password_schema,
+	                                                           "service", service,
+	                                                           NULL);
+
+	if (r != GNOME_KEYRING_RESULT_OK) {
+		g_set_error (error,
+		             TRACKER_PASSWORD_PROVIDER_ERROR,
+		             TRACKER_PASSWORD_PROVIDER_ERROR_SERVICE,
+		             "Cannot delete password: %s",
+		             gnome_keyring_result_to_message (r));
+	}
+}
+
+const TrackerPasswordProvider*
+tracker_password_provider_get (void)
+{
+	static TrackerPasswordProvider *instance = NULL;
+	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+	g_static_mutex_lock (&mutex);
+	if (instance == NULL) {
+		instance = g_object_new (TRACKER_TYPE_PASSWORD_PROVIDER_GNOME,
+		                         "name", PASSWORD_PROVIDER_GNOME_NAME,
+		                         NULL);
+	}
+	g_static_mutex_unlock (&mutex);
+
+	g_assert (instance != NULL);
+
+	return instance;
+}
+
diff --git a/src/libtracker-miner/tracker-keyfile-password-provider.c b/src/libtracker-miner/tracker-keyfile-password-provider.c
new file mode 100644
index 0000000..f82f7f4
--- /dev/null
+++ b/src/libtracker-miner/tracker-keyfile-password-provider.c
@@ -0,0 +1,396 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib-object.h>
+
+#include <sys/mman.h>
+
+#include "tracker-password-provider.h"
+
+#define TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE         (tracker_password_provider_keyfile_get_type())
+#define TRACKER_PASSWORD_PROVIDER_KEYFILE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE, TrackerPasswordProviderKeyfile))
+#define TRACKER_PASSWORD_PROVIDER_KEYFILE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE, TrackerPasswordProviderKeyfileClass))
+#define TRACKER_IS_PASSWORD_PROVIDER_KEYFILE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE))
+#define TRACKER_IS_PASSWORD_PROVIDER_KEYFILE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE))
+#define TRACKER_PASSWORD_PROVIDER_KEYFILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE, TrackerPasswordProviderKeyfileClass))
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE, TrackerPasswordProviderKeyfilePrivate))
+
+#define PASSWORD_PROVIDER_KEYFILE_NAME "KeyFile"
+
+/* GKeyFile settings */
+#define KEYFILE_FILENAME "passwords.cfg"
+#define GROUP_GENERAL    "General"
+
+typedef struct TrackerPasswordProviderKeyfile TrackerPasswordProviderKeyfile;
+typedef struct TrackerPasswordProviderKeyfileClass TrackerPasswordProviderKeyfileClass;
+typedef struct TrackerPasswordProviderKeyfilePrivate TrackerPasswordProviderKeyfilePrivate;
+
+struct TrackerPasswordProviderKeyfile {
+	GObject parent;
+};
+
+struct TrackerPasswordProviderKeyfileClass {
+	GObjectClass parent_class;
+};
+
+struct TrackerPasswordProviderKeyfilePrivate {
+	gchar    *name;
+	GKeyFile *password_file;
+};
+
+enum {
+	PROP_0,
+	PROP_NAME
+};
+
+GType           tracker_password_provider_keyfile_get_type (void) G_GNUC_CONST;
+
+static void     tracker_password_provider_iface_init       (TrackerPasswordProviderIface    *iface);
+static void     password_provider_keyfile_constructed      (GObject                         *object);
+static void     password_provider_keyfile_finalize         (GObject                         *object);
+static void     password_provider_set_property             (GObject                         *object,
+                                                            guint                            prop_id,
+                                                            const GValue                    *value,
+                                                            GParamSpec                      *pspec);
+static void     password_provider_get_property             (GObject                         *object,
+                                                            guint                            prop_id,
+                                                            GValue                          *value,
+                                                            GParamSpec                      *pspec);
+
+void            password_provider_keyfile_store            (TrackerPasswordProvider         *provider,
+                                                            const gchar                     *service,
+                                                            const gchar                     *description,
+                                                            const gchar                     *username,
+                                                            const gchar                     *password,
+                                                            GError                         **error);
+gchar*          password_provider_keyfile_get              (TrackerPasswordProvider         *provider,
+                                                            const gchar                     *service,
+                                                            gchar                          **username,
+                                                            GError                         **error);
+void            password_provider_keyfile_forget           (TrackerPasswordProvider         *provider,
+                                                            const gchar                     *service,
+                                                            GError                         **error);
+
+static void     load_password_file                         (TrackerPasswordProviderKeyfile  *kf,
+                                                            GError                         **error);
+static gboolean save_password_file                         (TrackerPasswordProviderKeyfile  *kf,
+                                                            GError                         **error);
+
+G_DEFINE_TYPE_WITH_CODE (TrackerPasswordProviderKeyfile,
+                         tracker_password_provider_keyfile,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (TRACKER_TYPE_PASSWORD_PROVIDER,
+                                                tracker_password_provider_iface_init))
+
+static void
+tracker_password_provider_keyfile_class_init (TrackerPasswordProviderKeyfileClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize     = password_provider_keyfile_finalize;
+	object_class->constructed  = password_provider_keyfile_constructed;
+	object_class->set_property = password_provider_set_property;
+	object_class->get_property = password_provider_get_property;
+
+	g_object_class_override_property (object_class,
+	                                  PROP_NAME,
+	                                  "name");
+
+	g_type_class_add_private (object_class, sizeof (TrackerPasswordProviderKeyfilePrivate));
+}
+
+static void
+tracker_password_provider_keyfile_init (TrackerPasswordProviderKeyfile *provider)
+{
+}
+
+static void
+tracker_password_provider_iface_init (TrackerPasswordProviderIface *iface)
+{
+	iface->store_password = password_provider_keyfile_store;
+	iface->get_password = password_provider_keyfile_get;
+	iface->forget_password = password_provider_keyfile_forget;
+}
+
+static void
+password_provider_keyfile_constructed (GObject *object)
+{
+	TrackerPasswordProviderKeyfile *kf = TRACKER_PASSWORD_PROVIDER_KEYFILE (object);
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (object);
+	GError *error = NULL;
+
+	priv->password_file = g_key_file_new ();
+
+	load_password_file (kf, &error);
+
+	if (error) {
+		g_critical ("Cannot load password file: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+static void
+password_provider_keyfile_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (tracker_password_provider_keyfile_parent_class)->finalize (object);
+}
+
+static void
+password_provider_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_free (priv->name);
+		priv->name = g_value_dup_string (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+static void
+password_provider_get_property (GObject      *object,
+                                guint         prop_id,
+                                GValue       *value,
+                                GParamSpec   *pspec)
+{
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_value_set_string (value, priv->name);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	};
+}
+
+void
+password_provider_keyfile_store (TrackerPasswordProvider  *provider,
+                                 const gchar              *service,
+                                 const gchar              *description,
+                                 const gchar              *username,
+                                 const gchar              *password,
+                                 GError                  **error)
+{
+	TrackerPasswordProviderKeyfile *kf = TRACKER_PASSWORD_PROVIDER_KEYFILE (provider);
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (provider);
+	GError *local_error = NULL;
+
+	g_key_file_set_string (priv->password_file,
+	                       service,
+	                       "description",
+	                       description);
+	g_key_file_set_string (priv->password_file,
+	                       service,
+	                       "username",
+	                       username);
+	g_key_file_set_string (priv->password_file,
+	                       service,
+	                       "password",
+	                       password);
+
+	if (!save_password_file (kf, &local_error)) {
+		g_propagate_error (error, local_error);
+	}
+}
+
+gchar*
+password_provider_keyfile_get (TrackerPasswordProvider  *provider,
+                               const gchar              *service,
+                               gchar                   **username,
+                               GError                  **error)
+{
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (provider);
+	gchar *password = NULL;
+	GError *error_password = NULL;
+	GError *error_username = NULL;
+
+	password = g_key_file_get_string (priv->password_file,
+	                                  service,
+	                                  "password",
+	                                  &error_password);
+
+	mlock (password, sizeof (password));
+
+	if (username) {
+		*username = g_key_file_get_string (priv->password_file,
+		                                   service,
+		                                   "username",
+		                                   &error_username);
+	}
+
+	if (error_password || error_username) {
+		g_set_error_literal (error,
+		                     TRACKER_PASSWORD_PROVIDER_ERROR,
+		                     TRACKER_PASSWORD_PROVIDER_ERROR_NOTFOUND,
+		                     "Password not found");
+	}
+
+	if (error_password)
+		g_error_free (error_password);
+	if (error_username)
+		g_error_free (error_username);
+
+	return password;
+}
+
+void
+password_provider_keyfile_forget (TrackerPasswordProvider  *provider,
+                                  const gchar              *service,
+                                  GError                  **error)
+{
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (provider);
+
+	GError *e = NULL;
+
+	if (!g_key_file_remove_group (priv->password_file, service, &e)) {
+		g_warning ("Cannot remove group '%s' from password file: %s",
+		           service,
+		           e->message);
+		g_error_free (e);
+
+		g_set_error_literal (error,
+		                     TRACKER_PASSWORD_PROVIDER_ERROR,
+		                     TRACKER_PASSWORD_PROVIDER_ERROR_NOTFOUND,
+		                     "Service not found");
+	}
+}
+
+const TrackerPasswordProvider*
+tracker_password_provider_get (void)
+{
+	static TrackerPasswordProvider *instance = NULL;
+	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+	g_static_mutex_lock (&mutex);
+	if (instance == NULL) {
+		instance = g_object_new (TRACKER_TYPE_PASSWORD_PROVIDER_KEYFILE,
+		                         "name", PASSWORD_PROVIDER_KEYFILE_NAME,
+		                         NULL);
+	}
+	g_static_mutex_unlock (&mutex);
+
+	g_assert (instance != NULL);
+
+	return instance;
+}
+
+/* Copied from tracker-config-file.c */
+static gchar *
+config_dir_ensure_exists_and_return (GError **error)
+{
+	gchar *directory;
+
+	directory = g_build_filename (g_get_user_config_dir (),
+	                              "tracker",
+	                              NULL);
+
+	if (!g_file_test (directory, G_FILE_TEST_EXISTS)) {
+		g_print ("Creating config directory:'%s'\n", directory);
+
+		if (g_mkdir_with_parents (directory, 0700) == -1) {
+			if (error) {
+				*error = g_error_new (TRACKER_PASSWORD_PROVIDER_ERROR,
+				                      TRACKER_PASSWORD_PROVIDER_ERROR_SERVICE,
+				                      "Impossible to create directory: '%s'",
+				                      directory);
+			}
+			g_free (directory);
+			return NULL;
+		}
+	}
+
+	return directory;
+}
+
+static void
+load_password_file (TrackerPasswordProviderKeyfile  *kf,
+                    GError                         **error)
+{
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (kf);
+	gchar *filename;
+	gchar *directory;
+	GError *local_error = NULL;
+
+	directory = config_dir_ensure_exists_and_return (&local_error);
+	if (!directory) {
+		g_propagate_error (error, local_error);
+		return;
+	}
+
+	filename = g_build_filename (directory, KEYFILE_FILENAME, NULL);
+	g_free (directory);
+
+	if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+		return;
+	}
+
+	g_key_file_load_from_file (priv->password_file,
+	                           filename,
+	                           G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+	                           &local_error);
+
+	if (local_error) {
+		g_propagate_error (error, local_error);
+	}
+}
+
+static gboolean
+save_password_file (TrackerPasswordProviderKeyfile  *kf,
+                    GError                         **error)
+{
+	TrackerPasswordProviderKeyfilePrivate *priv = GET_PRIV (kf);
+	gchar *filename;
+	gchar *directory;
+	gchar *data;
+	gsize size;
+	GError *local_error = NULL;
+
+	directory = config_dir_ensure_exists_and_return (&local_error);
+	if (!directory) {
+		g_propagate_error (error, local_error);
+		return FALSE;
+	}
+
+	filename = g_build_filename (directory, KEYFILE_FILENAME, NULL);
+	g_free (directory);
+
+	data = g_key_file_to_data (priv->password_file, &size, NULL);
+
+	g_file_set_contents (filename, data, size, &local_error);
+	g_free (data);
+	g_free (filename);
+
+	if (local_error) {
+		g_propagate_error (error, local_error);
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/src/libtracker-miner/tracker-miner-0.7.deps b/src/libtracker-miner/tracker-miner-0.7.deps
new file mode 100644
index 0000000..cd10dfd
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-0.7.deps
@@ -0,0 +1 @@
+gio-2.0
diff --git a/src/libtracker-miner/tracker-miner-0.7.vapi b/src/libtracker-miner/tracker-miner-0.7.vapi
new file mode 100644
index 0000000..d44b231
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-0.7.vapi
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+[CCode (cprefix = "Tracker", lower_case_cprefix = "tracker_")]
+namespace Tracker {
+	[Compact]
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public class Crawler {
+		public weak GLib.Object parent;
+		[CCode (has_construct_function = false)]
+		public Crawler ();
+		public void pause ();
+		public void resume ();
+		public void set_throttle (double throttle);
+		public bool start (GLib.File file, bool recurse);
+		public void stop ();
+	}
+	[Compact]
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public class CrawlerClass {
+		public weak GLib.Callback check_directory;
+		public weak GLib.Callback check_directory_contents;
+		public weak GLib.Callback check_file;
+		public weak GLib.Callback directory_crawled;
+		public weak GLib.Callback finished;
+		public weak GLib.ObjectClass parent;
+	}
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner.h")]
+	public class Miner : GLib.Object {
+		public async void commit (GLib.Cancellable? cancellable = null) throws GLib.Error;
+		public static GLib.Quark error_quark ();
+		public async void execute_batch_update (string sparql, GLib.Cancellable? cancellable = null) throws GLib.Error;
+		public async unowned GLib.PtrArray execute_sparql (string sparql, GLib.Cancellable? cancellable = null) throws GLib.Error;
+		public async void execute_update (string sparql, GLib.Cancellable? cancellable = null) throws GLib.Error;
+		public void ignore_next_update (string[] urls);
+		public bool is_started ();
+		public int pause (string reason) throws GLib.Error;
+		public virtual void paused ();
+		public bool resume (int cookie) throws GLib.Error;
+		public virtual void resumed ();
+		public void start ();
+		public virtual void started ();
+		public void stop ();
+		public virtual void stopped ();
+		public virtual void writeback ([CCode (array_length = false)] string[] subjects);
+		public signal void error (GLib.Error e);
+	}
+	[CCode (ref_function = "tracker_miner_fs_ref", unref_function = "tracker_miner_fs_unref", cheader_filename = "libtracker-miner/tracker-miner-fs.h")]
+	public class MinerFS {
+		public virtual bool check_directory (GLib.File directory);
+		public virtual bool check_directory_contents (GLib.File directory, GLib.List<GLib.File> children);
+		public virtual bool check_file (GLib.File file);
+		public void directory_add (GLib.File file, bool recurse);
+		public bool directory_remove (GLib.File file);
+		public void file_add (GLib.File file);
+		public void file_notify (GLib.File file, GLib.Error error);
+		public unowned string get_parent_urn (GLib.File file);
+		public double get_throttle ();
+		public unowned string get_urn (GLib.File file);
+		public virtual bool monitor_directory (GLib.File directory);
+		public void set_throttle (double throttle);
+		public signal void finished (double elapsed, uint directories_found, uint directories_ignored, uint files_found, uint files_ignored);
+	}
+	[Compact]
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public class MinerManager {
+		public weak GLib.Object parent_instance;
+		[CCode (has_construct_function = false)]
+		public MinerManager ();
+		public unowned GLib.SList get_available ();
+		public unowned string get_description (string miner);
+		public unowned string get_display_name (string miner);
+		public unowned GLib.SList get_running ();
+		public bool get_status (string miner, string status, double progress);
+		public bool ignore_next_update (string miner, string urls);
+		public bool is_active (string miner);
+		public bool is_paused (string miner, string[] applications, string[] reasons);
+		public bool pause (string miner, string reason, uint32 cookie);
+		public bool resume (string miner, uint32 cookie);
+	}
+	[Compact]
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public class MinerManagerClass {
+		public weak GLib.Callback miner_activated;
+		public weak GLib.Callback miner_deactivated;
+		public weak GLib.Callback miner_paused;
+		public weak GLib.Callback miner_progress;
+		public weak GLib.Callback miner_resumed;
+		public weak GLib.ObjectClass parent_class;
+	}
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public class MinerWeb : Tracker.Miner {
+		public virtual void associate (GLib.HashTable association_data) throws Tracker.MinerWebError;
+		public virtual void authenticate () throws Tracker.MinerWebError;
+		public virtual void dissociate () throws Tracker.MinerWebError;
+		public static GLib.Quark error_quark ();
+		public virtual GLib.HashTable get_association_data () throws Tracker.MinerWebError;
+	}
+	[CCode (cheader_filename = "libtracker-miner/tracker-password-provider.h")]
+	public interface PasswordProvider : GLib.Object {
+		public void forget_password (string service) throws GLib.Error;
+		public static unowned Tracker.PasswordProvider @get ();
+		public unowned string get_name ();
+		public string get_password (string service, out string username) throws GLib.Error;
+		public void store_password (string service, string description, string username, string password) throws GLib.Error;
+	}
+	[CCode (cprefix = "TRACKER_MINER_WEB_", has_type_id = false, cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public enum MinerWebAssociationStatus {
+		UNASSOCIATED,
+		ASSOCIATED
+	}
+	[CCode (cprefix = "TRACKER_MINER_WEB_ERROR_", cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public errordomain MinerWebError {
+		WRONG_CREDENTIALS,
+		TOKEN_EXPIRED,
+		NO_CREDENTIALS,
+		KEYRING,
+		SERVICE,
+		TRACKER,
+	}
+	[CCode (cprefix = "TRACKER_PASSWORD_PROVIDER_ERROR_", cheader_filename = "libtracker-miner/tracker-password-provider.h")]
+	public errordomain PasswordProviderError {
+		SERVICE,
+		NOTFOUND,
+	}
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public const int MAX_TIMEOUT_INTERVAL;
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner.h")]
+	public const string MINER_WEB_DBUS_INTERFACE;
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public static bool thumbnailer_cleanup (string uri_prefix);
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public static bool thumbnailer_init ();
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public static bool thumbnailer_move_add (string from_uri, string mime_type, string to_uri);
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public static bool thumbnailer_remove_add (string uri, string mime_type);
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public static void thumbnailer_send ();
+	[CCode (cheader_filename = "tracker-miner-0.7.h")]
+	public static void thumbnailer_shutdown ();
+}
diff --git a/src/libtracker-miner/tracker-miner-web-dbus.h b/src/libtracker-miner/tracker-miner-web-dbus.h
new file mode 100644
index 0000000..7faa16d
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web-dbus.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2010, Adrien Bustany <abustany gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __LIBTRACKERMINER_WEB_DBUS_H__
+#define __LIBTRACKERMINER_WEB_DBUS_H__
+
+#include <glib-object.h>
+
+#include "tracker-miner-dbus.h"
+#include "tracker-miner-web.h"
+
+G_BEGIN_DECLS
+
+void tracker_miner_web_dbus_authenticate         (TrackerMinerWeb        *miner,
+                                                  DBusGMethodInvocation  *context,
+                                                  GError                **error);
+void tracker_miner_web_dbus_get_association_data (TrackerMinerWeb        *miner,
+                                                  DBusGMethodInvocation  *context,
+                                                  GError                **error);
+void tracker_miner_web_dbus_associate            (TrackerMinerWeb        *miner,
+                                                  const GHashTable       *association_data,
+                                                  DBusGMethodInvocation  *context,
+                                                  GError                **error);
+void tracker_miner_web_dbus_dissociate           (TrackerMinerWeb        *miner,
+                                                  DBusGMethodInvocation  *context,
+                                                  GError                **error);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKERMINER_DBUS_H__ */
diff --git a/src/libtracker-miner/tracker-miner-web.c b/src/libtracker-miner/tracker-miner-web.c
new file mode 100644
index 0000000..757e1ae
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web.c
@@ -0,0 +1,263 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "tracker-miner-web.h"
+#include "tracker-dbus.h"
+#include "tracker-miner-web-dbus.h"
+#include "tracker-miner-web-glue.h"
+
+/**
+ * SECTION:tracker-miner-web
+ * @short_description: Abstract base class for miners using web services
+ * @include: libtracker-miner/tracker-miner-web.h
+ *
+ * #TrackerMinerWeb is an abstract base class for miners retrieving data
+ * from web services. It's a very thin layer above #TrackerMiner, only
+ * adding virtual methods needed to handle association with the remote
+ * service.
+ **/
+
+#define TRACKER_MINER_WEB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_WEB, TrackerMinerWebPrivate))
+
+struct TrackerMinerWebPrivate {
+	TrackerMinerWebAssociationStatus association_status;
+};
+
+enum {
+	PROP_0,
+	PROP_ASSOCIATION_STATUS
+};
+
+static void miner_web_set_property (GObject *     object,
+                                    guint         param_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec);
+static void miner_web_get_property (GObject *     object,
+                                    guint         param_id,
+                                    GValue       *value,
+                                    GParamSpec   *pspec);
+static void miner_web_constructed  (GObject *object);
+static void miner_web_finalize     (GObject *object);
+
+G_DEFINE_ABSTRACT_TYPE (TrackerMinerWeb, tracker_miner_web, TRACKER_TYPE_MINER)
+
+static void
+tracker_miner_web_class_init (TrackerMinerWebClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->set_property = miner_web_set_property;
+	object_class->get_property = miner_web_get_property;
+	object_class->constructed  = miner_web_constructed;
+	object_class->finalize     = miner_web_finalize;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ASSOCIATION_STATUS,
+	                                 g_param_spec_uint ("association-status",
+	                                                    "Association status",
+	                                                    "Tells if the miner is associated with the remote service",
+	                                                    TRACKER_MINER_WEB_UNASSOCIATED, /* min value */
+	                                                    TRACKER_MINER_WEB_ASSOCIATED,   /* max value */
+	                                                    TRACKER_MINER_WEB_UNASSOCIATED, /* default value */
+	                                                    G_PARAM_READWRITE));
+
+	g_type_class_add_private (object_class, sizeof (TrackerMinerWebPrivate));
+}
+
+static void
+tracker_miner_web_init (TrackerMinerWeb *miner)
+{
+	TrackerMinerWebPrivate *priv;
+	priv = TRACKER_MINER_WEB_GET_PRIVATE (miner);
+	priv->association_status = TRACKER_MINER_WEB_UNASSOCIATED;
+}
+
+static void
+miner_web_set_property (GObject      *object,
+                        guint         param_id,
+                        const GValue *value,
+                        GParamSpec   *pspec)
+{
+	TrackerMinerWeb *miner = TRACKER_MINER_WEB (object);
+	TrackerMinerWebPrivate *priv;
+	priv = TRACKER_MINER_WEB_GET_PRIVATE (object);
+
+	switch (param_id) {
+	case PROP_ASSOCIATION_STATUS:
+		priv->association_status = g_value_get_uint (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+miner_web_get_property (GObject      *object,
+                        guint         param_id,
+                        GValue       *value,
+                        GParamSpec   *pspec)
+{
+	TrackerMinerWeb *miner = TRACKER_MINER_WEB (object);
+	TrackerMinerWebPrivate *priv;
+	priv = TRACKER_MINER_WEB_GET_PRIVATE (object);
+
+	switch (param_id) {
+	case PROP_ASSOCIATION_STATUS:
+		g_value_set_uint (value, priv->association_status);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+miner_web_constructed (GObject *object)
+{
+	tracker_miner_dbus_init (TRACKER_MINER (object),
+	                         &dbus_glib_tracker_miner_web_dbus_object_info);
+
+	G_OBJECT_CLASS (tracker_miner_web_parent_class)->constructed (object);
+}
+
+static void
+miner_web_finalize (GObject *object)
+{
+	/* TrackerMinerWeb *miner = TRACKER_MINER_WEB (object); */
+
+	G_OBJECT_CLASS (tracker_miner_web_parent_class)->finalize (object);
+}
+
+GQuark
+tracker_miner_web_error_quark (void)
+{
+	return g_quark_from_static_string (TRACKER_MINER_WEB_ERROR_DOMAIN);
+}
+
+void
+tracker_miner_web_dbus_authenticate (TrackerMinerWeb        *miner,
+                                     DBusGMethodInvocation  *context,
+                                     GError                **error)
+{
+	GError *local_error = NULL;
+
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	TRACKER_MINER_WEB_GET_CLASS (miner)->authenticate (miner, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+		g_error_free (local_error);
+	} else {
+		dbus_g_method_return (context);
+	}
+}
+
+void
+tracker_miner_web_dbus_get_association_data (TrackerMinerWeb        *miner,
+                                             DBusGMethodInvocation  *context,
+                                             GError                **error)
+{
+	GError *local_error = NULL;
+
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	GHashTable *association_data = TRACKER_MINER_WEB_GET_CLASS (miner)->get_association_data (miner, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+		g_error_free (local_error);
+	} else {
+		dbus_g_method_return (context, association_data);
+	}
+}
+
+void
+tracker_miner_web_dbus_associate (TrackerMinerWeb        *miner,
+                                  const GHashTable       *association_data,
+                                  DBusGMethodInvocation  *context,
+                                  GError                **error)
+{
+	GError *local_error = NULL;
+
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	TRACKER_MINER_WEB_GET_CLASS (miner)->associate (miner, association_data, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+		g_error_free (local_error);
+	} else {
+		dbus_g_method_return (context);
+	}
+}
+
+void
+tracker_miner_web_dbus_dissociate (TrackerMinerWeb        *miner,
+                                   DBusGMethodInvocation  *context,
+                                   GError                **error)
+{
+	GError *local_error = NULL;
+
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	TRACKER_MINER_WEB_GET_CLASS (miner)->dissociate (miner, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+		g_error_free (local_error);
+	} else {
+		dbus_g_method_return (context);
+	}
+}
+
+void
+tracker_miner_web_authenticate (TrackerMinerWeb     *miner,
+                                GError             **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+	TRACKER_MINER_WEB_GET_CLASS (miner)->authenticate (miner, error);
+}
+
+GHashTable*
+tracker_miner_web_get_association_data (TrackerMinerWeb     *miner,
+                                        GError             **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+	return TRACKER_MINER_WEB_GET_CLASS (miner)->get_association_data (miner, error);
+}
+
+void
+tracker_miner_web_associate (TrackerMinerWeb   *miner,
+                             const GHashTable  *association_data,
+                             GError           **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+	TRACKER_MINER_WEB_GET_CLASS (miner)->associate (miner, association_data, error);
+}
+
+void
+tracker_miner_web_dissociate (TrackerMinerWeb   *miner,
+                              GError           **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+	TRACKER_MINER_WEB_GET_CLASS (miner)->dissociate (miner, error);
+}
diff --git a/src/libtracker-miner/tracker-miner-web.deps.in b/src/libtracker-miner/tracker-miner-web.deps.in
new file mode 100644
index 0000000..0f1fc53
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web.deps.in
@@ -0,0 +1 @@
+tracker-miner- VERSION@
diff --git a/src/libtracker-miner/tracker-miner-web.h b/src/libtracker-miner/tracker-miner-web.h
new file mode 100644
index 0000000..6552674
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web.h
@@ -0,0 +1,136 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_MINER_WEB_H__
+#define __TRACKER_MINER_WEB_H__
+
+#include <libtracker-miner/tracker-miner.h>
+
+#define TRACKER_TYPE_MINER_WEB         (tracker_miner_web_get_type())
+#define TRACKER_MINER_WEB(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_WEB, TrackerMinerWeb))
+#define TRACKER_MINER_WEB_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_MINER_WEB, TrackerMinerWebClass))
+#define TRACKER_IS_MINER_WEB(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_WEB))
+#define TRACKER_IS_MINER_WEB_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    TRACKER_TYPE_MINER_WEB))
+#define TRACKER_MINER_WEB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_MINER_WEB, TrackerMinerWebClass))
+
+G_BEGIN_DECLS
+
+typedef struct TrackerMinerWeb TrackerMinerWeb;
+typedef struct TrackerMinerWebPrivate TrackerMinerWebPrivate;
+
+/**
+ * The name of the DBus interface exposed by the web miners
+ **/
+#define TRACKER_MINER_WEB_DBUS_INTERFACE "org.freedesktop.Tracker1.MinerWeb"
+
+/**
+ * TrackerMinerWebError:
+ * @TRACKER_MINER_WEB_ERROR_WRONG_CREDENTIALS: The stored credentials are refused by the remote service
+ * @TRACKER_MINER_WEB_ERROR_TOKEN_EXPIRED    : The service says the stored token has expired
+ * @TRACKER_MINER_WEB_ERROR_NO_CREDENTIALS   : There are currenty no credentials stored for this service
+ * @TRACKER_MINER_WEB_ERROR_KEYRING          : Error while contacting the credentials storage
+ * @TRACKER_MINER_WEB_ERROR_SERVICE          : Error while contacting the remote service
+ * @TRACKER_MINER_WEB_ERROR_TRACKER          : Error while contacting Tracker
+ *
+ * Describes the different errors that can occur while operating with the remote service.
+ **/
+typedef enum {
+	TRACKER_MINER_WEB_ERROR_WRONG_CREDENTIALS,
+	TRACKER_MINER_WEB_ERROR_TOKEN_EXPIRED,
+	TRACKER_MINER_WEB_ERROR_NO_CREDENTIALS,
+	TRACKER_MINER_WEB_ERROR_KEYRING,
+	TRACKER_MINER_WEB_ERROR_SERVICE,
+	TRACKER_MINER_WEB_ERROR_TRACKER
+} TrackerMinerWebError;
+#define TRACKER_MINER_WEB_ERROR        tracker_miner_web_error_quark ()
+#define TRACKER_MINER_WEB_ERROR_DOMAIN "TrackerMinerWeb"
+
+/**
+ * TrackerMinerWebAssociationStatus:
+ * @TRACKER_MINER_WEB_UNASSOCIATED : The miner is currently unassociated with the remote service
+ * @TRACKER_MINER_WEB_ASSOCIATED   : The miner is currently associated with the remote service
+ *
+ * Describes if the miner can currently communicate (import data) with the web service.
+ **/
+typedef enum {
+	TRACKER_MINER_WEB_UNASSOCIATED,
+	TRACKER_MINER_WEB_ASSOCIATED
+} TrackerMinerWebAssociationStatus;
+
+struct TrackerMinerWeb {
+	TrackerMiner            parent_instance;
+};
+
+/**
+ * TrackerMinerWebClass
+ * @parent_class        : parent object class
+ * @authenticate        : called when the miner is told to authenticate against the remote service
+ * @get_association_data: called when one requests the miner's association data.
+ *                        In the case of a user/pass based authentication, this should return
+ *                        an empty hash table.
+ *                        In the case of a token based authentication, the following keys must
+ *                        be defined in the returned hash table:
+ *                        - url: the url to point the user too
+ *                        Additionally, the miner can define the following keys :
+ *                        - post_message: a message to display after the user completes the
+ *                                        association process
+ *                        - post_url: a url to point the user after he completes the association
+ *
+ *                        If both post_message and post_url are defined, the message will be
+ *                        displayed before the url is opened.
+ * @associate           : called when the miner is told to associate with the web service.
+ *                        In the case of a user/pass based authentication, the following keys must be defined
+ *                        - username: the provided username
+ *                        - password: the provided password
+ *                        In the case of a token based authentication, the hash table can be ignored
+ *                        since it will be empty.
+ * @dissociate          : called when the miner is told to forget any user credentials it has stored
+ **/
+typedef struct {
+    TrackerMinerClass parent_class;
+
+    /* vmethods */
+	void        (* authenticate)         (TrackerMinerWeb     *miner,
+	                                      GError             **error);
+	GHashTable* (* get_association_data) (TrackerMinerWeb     *miner,
+	                                      GError             **error);
+	void        (* associate)            (TrackerMinerWeb     *miner,
+	                                      const GHashTable    *association_data,
+	                                      GError             **error);
+	void        (* dissociate)           (TrackerMinerWeb     *miner,
+	                                                           GError             **error);
+} TrackerMinerWebClass;
+
+GType        tracker_miner_web_get_type              (void) G_GNUC_CONST;
+GQuark       tracker_miner_web_error_quark           (void);
+
+void         tracker_miner_web_authenticate          (TrackerMinerWeb     *miner,
+                                                      GError             **error);
+GHashTable*  tracker_miner_web_get_association_data  (TrackerMinerWeb     *miner,
+                                                      GError             **error);
+void         tracker_miner_web_associate             (TrackerMinerWeb     *miner,
+                                                      const GHashTable    *association_data,
+                                                      GError             **error);
+void         tracker_miner_web_dissociate            (TrackerMinerWeb     *miner,
+                                                      GError             **error);
+
+G_END_DECLS
+
+#endif /* __TRACKER_MINER_WEB_H__ */
diff --git a/src/libtracker-miner/tracker-miner.c b/src/libtracker-miner/tracker-miner.c
index 2739527..f1f392b 100644
--- a/src/libtracker-miner/tracker-miner.c
+++ b/src/libtracker-miner/tracker-miner.c
@@ -435,8 +435,8 @@ miner_constructed (GObject *object)
 
 static void
 store_name_monitor_cb (TrackerMiner *miner,
-		       const gchar  *name,
-		       gboolean      available)
+                       const gchar  *name,
+                       gboolean      available)
 {
 	GError *error = NULL;
 
diff --git a/src/libtracker-miner/tracker-password-provider.c b/src/libtracker-miner/tracker-password-provider.c
new file mode 100644
index 0000000..7059eaa
--- /dev/null
+++ b/src/libtracker-miner/tracker-password-provider.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2009, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "tracker-password-provider.h"
+
+#include <sys/mman.h>
+#include <string.h>
+
+#include "config.h"
+
+static void
+tracker_password_provider_init (gpointer object_class)
+{
+	static gboolean is_initialized = FALSE;
+
+	if (!is_initialized) {
+		g_object_interface_install_property (object_class,
+		                                     g_param_spec_string ("name",
+		                                                          "Password provider name",
+		                                                          "Password provider name",
+		                                                          NULL,
+		                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		is_initialized = TRUE;
+	}
+}
+
+/* That would be better done with G_DECLARE_INTERFACE, but it's GLib 2.24 */
+GType
+tracker_password_provider_get_type (void)
+{
+	static GType iface_type = 0;
+
+	if (iface_type == 0) {
+		static const GTypeInfo info = {
+			sizeof (TrackerPasswordProviderIface),
+			tracker_password_provider_init,
+			NULL
+		};
+
+		iface_type = g_type_register_static (G_TYPE_INTERFACE,
+		                                     "TrackerPasswordProvider",
+		                                     &info,
+		                                     0);
+	}
+
+	return iface_type;
+}
+
+GQuark
+tracker_password_provider_error_quark (void)
+{
+	return g_quark_from_static_string (TRACKER_PASSWORD_PROVIDER_ERROR_DOMAIN);
+}
+
+gchar*
+tracker_password_provider_get_name (TrackerPasswordProvider *provider)
+{
+	g_assert (TRACKER_IS_PASSWORD_PROVIDER (provider));
+
+	gchar *name;
+	g_object_get (provider, "name", &name, NULL);
+
+	return name;
+}
+
+void
+tracker_password_provider_store_password (TrackerPasswordProvider   *provider,
+                                           const gchar               *service,
+                                           const gchar               *description,
+                                           const gchar               *username,
+                                           const gchar               *password,
+                                           GError                   **error)
+{
+	g_assert (TRACKER_IS_PASSWORD_PROVIDER (provider));
+
+	TRACKER_PASSWORD_PROVIDER_GET_INTERFACE (provider)->store_password (provider,
+	                                                                    service,
+	                                                                    description,
+	                                                                    username,
+	                                                                    password,
+	                                                                    error);
+}
+
+gchar*
+tracker_password_provider_get_password (TrackerPasswordProvider   *provider,
+                                        const gchar               *service,
+                                        gchar                    **username,
+                                        GError                   **error)
+{
+	g_assert (TRACKER_IS_PASSWORD_PROVIDER (provider));
+
+	gchar *password = TRACKER_PASSWORD_PROVIDER_GET_INTERFACE (provider)->get_password (provider,
+	                                                                                    service,
+	                                                                                    username,
+	                                                                                    error);
+	return password;
+}
+
+void
+tracker_password_provider_forget_password (TrackerPasswordProvider   *provider,
+                                           const gchar               *service,
+                                           GError                   **error)
+{
+	g_assert (TRACKER_IS_PASSWORD_PROVIDER (provider));
+
+	TRACKER_PASSWORD_PROVIDER_GET_INTERFACE (provider)->forget_password (provider,
+	                                                                     service,
+	                                                                     error);
+}
+
+gchar*
+tracker_password_provider_strdup_mlock (const gchar *source)
+{
+	gchar *dest;
+	dest = malloc (1 + strlen (source));
+	dest = memset (dest, 0, 1 + strlen (source));
+	mlock (dest, sizeof (dest));
+	memcpy (dest, source, strlen (source));
+
+	return dest;
+}
diff --git a/src/libtracker-miner/tracker-password-provider.h b/src/libtracker-miner/tracker-password-provider.h
new file mode 100644
index 0000000..87db402
--- /dev/null
+++ b/src/libtracker-miner/tracker-password-provider.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009, Adrien Bustany (abustany gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_PASSWORD_PROVIDER_H__
+#define __TRACKER_PASSWORD_PROVIDER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_PASSWORD_PROVIDER         (tracker_password_provider_get_type())
+#define TRACKER_PASSWORD_PROVIDER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_PASSWORD_PROVIDER, TrackerPasswordProvider))
+#define TRACKER_IS_PASSWORD_PROVIDER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_PASSWORD_PROVIDER))
+#define TRACKER_PASSWORD_PROVIDER_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o),  TRACKER_TYPE_PASSWORD_PROVIDER, TrackerPasswordProviderIface))
+
+#define TRACKER_PASSWORD_PROVIDER_ERROR_DOMAIN  "TrackerPasswordProvider"
+#define TRACKER_PASSWORD_PROVIDER_ERROR         tracker_password_provider_error_quark()
+
+typedef struct TrackerPasswordProvider TrackerPasswordProvider;
+typedef struct TrackerPasswordProviderIface TrackerPasswordProviderIface;
+
+typedef enum {
+	TRACKER_PASSWORD_PROVIDER_ERROR_SERVICE,
+	TRACKER_PASSWORD_PROVIDER_ERROR_NOTFOUND
+} TrackerPasswordProviderError;
+
+struct TrackerPasswordProviderIface
+{
+	GTypeInterface parent_iface;
+
+	void     (* store_password)        (TrackerPasswordProvider  *provider,
+	                                    const gchar              *service,
+	                                    const gchar              *description,
+	                                    const gchar              *username,
+	                                    const gchar              *password,
+	                                    GError                  **error);
+	gchar*   (* get_password)          (TrackerPasswordProvider  *provider,
+	                                    const gchar              *service,
+	                                    gchar                   **username,
+	                                    GError                  **error);
+	void     (* forget_password)       (TrackerPasswordProvider  *provider,
+	                                    const gchar              *service,
+	                                    GError                  **error);
+};
+
+GType  tracker_password_provider_get_type        (void) G_GNUC_CONST;
+GQuark tracker_password_provider_error_quark     (void);
+
+gchar* tracker_password_provider_get_name        (TrackerPasswordProvider   *provider);
+/* Must be defined by the selected implementation */
+const TrackerPasswordProvider*
+       tracker_password_provider_get             (void);
+void   tracker_password_provider_store_password  (TrackerPasswordProvider   *provider,
+                                                  const gchar              *service,
+                                                  const gchar              *description,
+                                                  const gchar              *username,
+                                                  const gchar              *password,
+                                                  GError                  **error);
+
+gchar* tracker_password_provider_get_password    (TrackerPasswordProvider   *provider,
+                                                  const gchar              *service,
+                                                  gchar                   **username,
+                                                  GError                  **error);
+void   tracker_password_provider_forget_password (TrackerPasswordProvider   *provider,
+                                                  const gchar              *service,
+                                                  GError                  **error);
+
+gchar* tracker_password_provider_strdup_mlock    (const gchar              *source);
+
+G_END_DECLS
+
+#endif



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