[tracker/miner-web: 2/33] libtracker-miner: Rewrite TrackerMinerWeb in C



commit 2d90de3301a5769761795d72d590aa39e519b2c1
Author: Adrien Bustany <madcat mymadcat com>
Date:   Fri Nov 6 15:47:32 2009 +0100

    libtracker-miner: Rewrite TrackerMinerWeb in C
    
    This is a complete rewrite of TrackerMinerWeb. It is now an abstract class, and
    the API changed a bit to be clearer. I also added a Dissociate function, in case
    the user wants to stop using the service.

 configure.ac                                       |   44 +++
 data/dbus/tracker-miner-web.xml                    |   21 ++
 examples/libtracker-miner/Makefile.am              |   17 +-
 src/libtracker-miner/Makefile.am                   |   72 ++++-
 src/libtracker-miner/gnome-keyring-1.vapi          |  336 ++++++++++++++++++++
 src/libtracker-miner/gnome-password-provider.vala  |   69 ++++
 .../keyfile-password-provider.vala                 |   85 +++++
 src/libtracker-miner/password-provider.vala        |   33 ++
 src/libtracker-miner/test/password-provider-test.c |   56 ++++
 src/libtracker-miner/tracker-miner-0.7.vapi        |   40 +++
 src/libtracker-miner/tracker-miner-web-0.7.vapi    |   40 +++
 src/libtracker-miner/tracker-miner-web-dbus.h      |   47 +++
 src/libtracker-miner/tracker-miner-web.c           |  217 +++++++++++++
 src/libtracker-miner/tracker-miner-web.deps.in     |    1 +
 src/libtracker-miner/tracker-miner-web.h           |  128 ++++++++
 src/libtracker-miner/tracker-miner-web.vala        |   34 ++
 .../tracker-password-provider.vala                 |   32 ++
 17 files changed, 1267 insertions(+), 5 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index fbb9d1c..61e158f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,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])
@@ -752,6 +753,36 @@ fi
 
 AM_CONDITIONAL(HAVE_UNAC, test "x$have_unac" = "xyes")
 
+##################################################################
+# Enable Gnome Keyring support?
+##################################################################
+
+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
 ####################################################################
@@ -867,6 +898,19 @@ PKG_CHECK_MODULES(TRACKER_VALA,
 AC_SUBST(TRACKER_VALA_CFLAGS)
 AC_SUBST(TRACKER_VALA_LIBS)
 
+PKG_CHECK_MODULES(GNOMEKEYRING,
+                  [ gnome-keyring-1 >= $GNOMEKEYRING_REQUIRED ],
+                  [have_gnomekeyring=yes],
+                  [have_gnomekeyring=no])
+AC_SUBST(GNOMEKEYRING_LIBS)
+AC_SUBST(GNOMEKEYRING_CFLAGS)
+
+if test "x$have_gnomekeyring" = "xyes"; then
+	AC_DEFINE(HAVE_GNOMEKEYRING, [], [Define if we have Gnome Keyring for password storage])
+fi
+
+AM_CONDITIONAL(HAVE_GNOMEKEYRING, test "x$have_gnomekeyring" = "xyes")
+
 ##################################################################
 # Enable building libtracker-gtk?
 ##################################################################
diff --git a/data/dbus/tracker-miner-web.xml b/data/dbus/tracker-miner-web.xml
new file mode 100644
index 0000000..5c17a6a
--- /dev/null
+++ b/data/dbus/tracker-miner-web.xml
@@ -0,0 +1,21 @@
+<?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"/>
+    </method>
+    <method name="GetAssociationData">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+	  <arg name="result" type="a{ss}" direction="out"/>
+	</method>
+    <method name="Associate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+	  <arg name="data" type="a{ss}" direction="in"/>
+	</method>
+    <method name="Dissociate">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+	</method>
+	<property name="AssociationStatus" type="u" access="read"/>
+  </interface>
+</node>
diff --git a/examples/libtracker-miner/Makefile.am b/examples/libtracker-miner/Makefile.am
index d1e7da0..3f32814 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    				\
@@ -35,3 +35,18 @@ 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.la	\
+	$(DBUS_LIBS)                                    		\
+	$(GMODULE_LIBS)                                 		\
+	$(GTHREAD_LIBS)                                 		\
+	$(GIO_LIBS)                                     		\
+	$(GCOV_LIBS)                                    		\
+	$(GLIB2_LIBS)                                   		\
+	-lz                                             		\
+	-lm
+
diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am
index c2596a4..14a4447 100644
--- a/src/libtracker-miner/Makefile.am
+++ b/src/libtracker-miner/Makefile.am
@@ -17,7 +17,8 @@ INCLUDES =						\
 	$(HAL_CFLAGS)					\
 	$(DEVKIT_POWER_CFLAGS)				\
 	$(DBUS_CFLAGS)					\
-	$(UNAC_CFLAGS)
+	$(UNAC_CFLAGS)                  \
+	--include $(top_srcdir)/config.h
 
 lib_LTLIBRARIES = libtracker-miner- TRACKER_API_VERSION@.la
 
@@ -25,6 +26,12 @@ libtracker_minerdir = $(libdir)/tracker-$(TRACKER_API_VERSION)
 libtracker_minerincludedir=$(includedir)/tracker-$(TRACKER_API_VERSION)/libtracker-miner/
 
 libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES = 	\
+
+libtracker_miner_la_VALASOURCES=     \
+    tracker-password-provider.vala           \
+	keyfile-password-provider.vala
+
+libtracker_miner_la_SOURCES = 				\
 	tracker-crawler.c				\
 	tracker-crawler.h				\
 	tracker-dbus.c					\
@@ -36,17 +43,21 @@ 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				\
 	tracker-monitor.h				\
 	tracker-utils.c					\
-	tracker-utils.h
+	tracker-utils.h                 \
+	$(libtracker_miner_la_VALASOURCES:.vala=.c)
 
 libtracker_minerinclude_HEADERS = 			\
 	tracker-miner.h 				\
 	tracker-miner-dbus.h 				\
-	tracker-miner-fs.h
+	tracker-miner-fs.h              \
+	tracker-miner-web.h
 
 libtracker_miner_ TRACKER_API_VERSION@_la_LDFLAGS = 	\
 	-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
@@ -66,6 +77,17 @@ libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD = 	\
 	$(GLIB2_LIBS)					\
 	$(GDKPIXBUF_LIBS)
 
+vapidir=$(datadir)/vala/vapi
+vapi_DATA =                     \
+	tracker-miner-$(TRACKER_API_VERSION).vapi \
+	tracker-miner-web-$(TRACKER_API_VERSION).vapi \
+	tracker-miner-web-$(TRACKER_API_VERSION).deps \
+	tracker-password-provider-$(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 > $@
 
@@ -79,15 +101,57 @@ marshal_sources = 					\
 
 dbus_sources = 						\
 	tracker-miner-glue.h				\
+	tracker-miner-web-glue.h				\
 	tracker-miner-client.h
 
+VALAPKGS =                          \
+	--pkg dbus-glib-1               \
+	--pkg posix                     \
+	--pkg gio-2.0                   \
+	--pkg tracker-miner-0.7
+
+VALAFLAGS =                         \
+	--vapidir $(top_srcdir)/src/libtracker-miner
+
+if HAVE_GNOME_KEYRING
+VALAPKGS +=                         \
+	--pkg gnome-keyring-1
+VALAFLAGS +=                        \
+	-D HAVE_GNOME_KEYRING
+
+INCLUDES +=                         \
+	$(GNOME_KEYRING_CFLAGS)
+
+libtracker_miner_la_LIBADD +=       \
+	$(GNOME_KEYRING_LIBS)
+
+libtracker_miner_la_VALASOURCES +=     \
+    gnome-password-provider.vala
+endif
+
+
+libtracker-miner-web.vala.stamp: $(libtracker_miner_la_VALASOURCES)
+	$(VALAC) -C $(VALAPKGS) $(VALAFLAGS) -H tracker-password-provider.h --library tracker-password-provider-$(TRACKER_API_VERSION) $^
+	touch $@
+
+# 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 $(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) libtracker-miner-web.vala.stamp tracker-miner-web-full.xml
 
 CLEANFILES = $(BUILT_SOURCES)
 
diff --git a/src/libtracker-miner/gnome-keyring-1.vapi b/src/libtracker-miner/gnome-keyring-1.vapi
new file mode 100644
index 0000000..dcd7960
--- /dev/null
+++ b/src/libtracker-miner/gnome-keyring-1.vapi
@@ -0,0 +1,336 @@
+/* gnome-keyring-1.vapi generated by vapigen, do not modify. */
+
+[CCode (cprefix = "GnomeKeyring", lower_case_cprefix = "gnome_keyring_")]
+namespace GnomeKeyring {
+	[Compact]
+	[CCode (copy_function = "gnome_keyring_access_control_copy", cheader_filename = "gnome-keyring.h")]
+	public class AccessControl {
+		public unowned GnomeKeyring.AccessControl copy ();
+		[CCode (has_construct_function = false)]
+		public AccessControl (GnomeKeyring.ApplicationRef application, GnomeKeyring.AccessType types_allowed);
+	}
+	[Compact]
+	[CCode (copy_function = "gnome_keyring_application_ref_copy", cheader_filename = "gnome-keyring.h")]
+	public class ApplicationRef {
+		public unowned GnomeKeyring.ApplicationRef copy ();
+		[CCode (has_construct_function = false)]
+		public ApplicationRef ();
+	}
+	[Compact]
+	[CCode (cheader_filename = "gnome-keyring.h", free_function = "gnome_keyring_attribute_list_free", copy_function = "gnome_keyring_attribute_list_copy")]
+	public class AttributeList : GLib.Array<GnomeKeyring.Attribute> {
+		public AttributeList ();
+		public void append_string (string name, string value);
+		public void append_uint32 (string name, uint32 value);
+		public unowned GnomeKeyring.AttributeList copy ();
+		public GnomeKeyring.Attribute index (int i);
+	}
+	[Compact]
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public class Found {
+		public weak GnomeKeyring.AttributeList attributes;
+		public uint item_id;
+		public weak string keyring;
+		public weak string secret;
+	}
+
+	[Compact]
+	[CCode (copy_function = "gnome_keyring_info_copy", cheader_filename = "gnome-keyring.h")]
+	public class Info {
+		public unowned GnomeKeyring.Info copy ();
+		public ulong get_ctime ();
+		public bool get_is_locked ();
+		public bool get_lock_on_idle ();
+		public uint32 get_lock_timeout ();
+		public ulong get_mtime ();
+		public void set_lock_on_idle (bool value);
+		public void set_lock_timeout (uint32 value);
+	}
+	[Compact]
+	[CCode (copy_function = "gnome_keyring_item_info_copy", cheader_filename = "gnome-keyring.h")]
+	public class ItemInfo {
+		public unowned GnomeKeyring.ItemInfo copy ();
+		public ulong get_ctime ();
+		public unowned string get_display_name ();
+		public ulong get_mtime ();
+		public unowned string get_secret ();
+		[CCode (has_construct_function = false)]
+		public ItemInfo ();
+		public void set_display_name (string value);
+		public void set_secret (string value);
+		public void set_type (GnomeKeyring.ItemType type);
+	}
+	[Compact]
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public class NetworkPasswordData {
+		public weak string authtype;
+		public weak string domain;
+		public uint32 item_id;
+		public weak string keyring;
+		public weak string object;
+		public weak string password;
+		public uint32 port;
+		public weak string protocol;
+		public weak string server;
+		public weak string user;
+	}
+
+	[Compact]
+	public struct PasswordSchemaAttribute {
+		public unowned string name;
+		public GnomeKeyring.AttributeType type;
+	}
+
+	[Compact]
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public struct PasswordSchema {
+		public GnomeKeyring.ItemType item_type;
+		public PasswordSchemaAttribute[] attributes;
+	}
+
+	[Compact]
+	public struct AttributeValue {
+		public uint integer;
+		public string @string;
+	}
+
+	[SimpleType]
+	[CCode (type_id = "GNOME_KEYRING_TYPE_ATTRIBUTE", cheader_filename = "gnome-keyring.h")]
+	public struct Attribute {
+		public weak string name;
+		public unowned GnomeKeyring.AttributeType type;
+		public unowned AttributeValue value;
+	}
+	[CCode (cprefix = "GNOME_KEYRING_ACCESS_", has_type_id = "0", cheader_filename = "gnome-keyring.h")]
+	public enum AccessRestriction {
+		ASK,
+		DENY,
+		ALLOW
+	}
+	[CCode (cprefix = "GNOME_KEYRING_ACCESS_", has_type_id = "0", cheader_filename = "gnome-keyring.h")]
+	public enum AccessType {
+		READ,
+		WRITE,
+		REMOVE
+	}
+	[CCode (cprefix = "GNOME_KEYRING_ATTRIBUTE_TYPE_", has_type_id = "0", cheader_filename = "gnome-keyring.h")]
+	public enum AttributeType {
+		STRING,
+		UINT32
+	}
+	[CCode (cprefix = "GNOME_KEYRING_ITEM_INFO_", has_type_id = "0", cheader_filename = "gnome-keyring.h")]
+	public enum ItemInfoFlags {
+		ALL,
+		BASICS,
+		SECRET
+	}
+	[CCode (cprefix = "GNOME_KEYRING_ITEM_", has_type_id = "0", cheader_filename = "gnome-keyring.h")]
+	public enum ItemType {
+		APPLICATION_SECRET,
+		ITEM_TYPE_MASK,
+		GENERIC_SECRET,
+		NETWORK_PASSWORD,
+		NOTE,
+		CHAINED_KEYRING_PASSWORD,
+		ENCRYPTION_KEY_PASSWORD,
+		PK_STORAGE,
+		LAST_TYPE
+	}
+	[CCode (cprefix = "GNOME_KEYRING_RESULT_", has_type_id = "0", cheader_filename = "gnome-keyring.h")]
+	public enum Result {
+		OK,
+		DENIED,
+		NO_KEYRING_DAEMON,
+		ALREADY_UNLOCKED,
+		NO_SUCH_KEYRING,
+		BAD_ARGUMENTS,
+		IO_ERROR,
+		CANCELLED,
+		KEYRING_ALREADY_EXISTS,
+		NO_MATCH
+	}
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationDoneCallback (GnomeKeyring.Result result);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationGetAttributesCallback (GnomeKeyring.Result result, GnomeKeyring.AttributeList attributes);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationGetIntCallback (GnomeKeyring.Result result, uint32 val);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationGetItemInfoCallback (GnomeKeyring.Result result, GnomeKeyring.ItemInfo info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationGetKeyringInfoCallback (GnomeKeyring.Result result, GnomeKeyring.Info info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationGetListCallback (GnomeKeyring.Result result, GLib.List list);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public delegate void OperationGetStringCallback (GnomeKeyring.Result result, string str);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public const string DEFAULT;
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public const GnomeKeyring.PasswordSchema NETWORK_PASSWORD;
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public const string SESSION;
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static unowned GLib.List acl_copy (GLib.List list);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void acl_free (GLib.List acl);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void cancel_request (void* request);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* change_password (string keyring, string? original, string? password, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result change_password_sync (string keyring, string? original, string? password);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* create (string keyring_name, string? password, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result create_sync (string keyring_name, string? password);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result daemon_prepare_environment_sync ();
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result daemon_set_display_sync (string display);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* @delete (string keyring, GnomeKeyring.OperationDoneCallback callback, void* data, GLib.DestroyNotify destroy_data);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* delete_password (GnomeKeyring.PasswordSchema schema, owned GnomeKeyring.OperationDoneCallback callback, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result delete_password_sync (GnomeKeyring.PasswordSchema schema, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result delete_sync (string keyring);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* find_items (GnomeKeyring.ItemType type, GnomeKeyring.AttributeList attributes, owned GnomeKeyring.OperationGetListCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result find_items_sync (GnomeKeyring.ItemType type, GnomeKeyring.AttributeList attributes, out GLib.List found);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* find_itemsv (GnomeKeyring.ItemType type, owned GnomeKeyring.OperationGetListCallback callback, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result find_itemsv_sync (GnomeKeyring.ItemType type, GLib.List found, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* find_network_password (string? user, string? domain, string? server, string? object, string? protocol, string? authtype, uint32 port, owned GnomeKeyring.OperationGetListCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result find_network_password_sync (string? user, string? domain, string? server, string? object, string? protocol, string? authtype, uint32 port, out unowned GLib.List results);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* find_password (GnomeKeyring.PasswordSchema schema, owned GnomeKeyring.OperationGetStringCallback callback, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result find_password_sync (GnomeKeyring.PasswordSchema schema, out unowned string password, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void free_password (string password);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* get_default_keyring (owned GnomeKeyring.OperationGetStringCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result get_default_keyring_sync (out unowned string keyring);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* get_info (string? keyring, owned GnomeKeyring.OperationGetKeyringInfoCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result get_info_sync (string? keyring, out unowned GnomeKeyring.Info info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static bool is_available ();
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.AccessType item_ac_get_access_type (GnomeKeyring.AccessControl ac);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static unowned string item_ac_get_display_name (GnomeKeyring.AccessControl ac);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static unowned string item_ac_get_path_name (GnomeKeyring.AccessControl ac);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void item_ac_set_access_type (GnomeKeyring.AccessControl ac, GnomeKeyring.AccessType value);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void item_ac_set_display_name (GnomeKeyring.AccessControl ac, string value);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void item_ac_set_path_name (GnomeKeyring.AccessControl ac, string value);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_create (string? keyring, GnomeKeyring.ItemType type, string display_name, GnomeKeyring.AttributeList attributes, string secret, bool update_if_exists, owned GnomeKeyring.OperationGetIntCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_create_sync (string? keyring, GnomeKeyring.ItemType type, string display_name, GnomeKeyring.AttributeList attributes, string secret, bool update_if_exists, uint32 item_id);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_delete (string? keyring, uint32 id, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_delete_sync (string? keyring, uint32 id);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_get_acl (string? keyring, uint32 id, owned GnomeKeyring.OperationGetListCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_get_acl_sync (string? keyring, uint32 id, GLib.List acl);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_get_attributes (string? keyring, uint32 id, owned GnomeKeyring.OperationGetAttributesCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_get_attributes_sync (string? keyring, uint32 id, out unowned GnomeKeyring.AttributeList attributes);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_get_info (string? keyring, uint32 id, owned GnomeKeyring.OperationGetItemInfoCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_get_info_full (string? keyring, uint32 id, uint32 flags, owned GnomeKeyring.OperationGetItemInfoCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_get_info_full_sync (string? keyring, uint32 id, uint32 flags, out unowned GnomeKeyring.ItemInfo info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static unowned GnomeKeyring.Result? item_get_info_sync (string keyring, uint32 id, out unowned GnomeKeyring.ItemInfo info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_grant_access_rights (string? keyring, string display_name, string full_path, uint32 id, GnomeKeyring.AccessType rights, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_grant_access_rights_sync (string? keyring, string display_name, string full_path, uint32 id, GnomeKeyring.AccessType rights);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_set_acl (string? keyring, uint32 id, GLib.List acl, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_set_acl_sync (string? keyring, uint32 id, GLib.List acl);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_set_attributes (string? keyring, uint32 id, GnomeKeyring.AttributeList attributes, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_set_attributes_sync (string? keyring, uint32 id, GnomeKeyring.AttributeList attributes);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* item_set_info (string? keyring, uint32 id, GnomeKeyring.ItemInfo info, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result item_set_info_sync (string? keyring, uint32 id, GnomeKeyring.ItemInfo info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* list_item_ids (string? keyring, owned GnomeKeyring.OperationGetListCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result list_item_ids_sync (string? keyring, out GLib.List<uint> ids);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* list_keyring_names (owned GnomeKeyring.OperationGetListCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result list_keyring_names_sync (GLib.List keyrings);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* @lock (string keyring, GnomeKeyring.OperationDoneCallback callback, void* data, GLib.DestroyNotify destroy_data);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* lock_all (owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result lock_all_sync ();
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result lock_sync (string? keyring);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* memory_alloc (ulong sz);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void memory_free (void* p);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static bool memory_is_secure (void* p);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* memory_realloc (void* p, ulong sz);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static unowned string memory_strdup (string str);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* memory_try_alloc (ulong sz);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* memory_try_realloc (void* p, ulong sz);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void network_password_free (GnomeKeyring.NetworkPasswordData data);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void network_password_list_free (GLib.List list);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static unowned string result_to_message (GnomeKeyring.Result res);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* set_default_keyring (string keyring, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result set_default_keyring_sync (string keyring);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* set_info (string? keyring, GnomeKeyring.Info info, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result set_info_sync (string? keyring, GnomeKeyring.Info info);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* set_network_password (string? keyring, string? user, string? domain, string? server, string? object, string? protocol, string? authtype, uint32 port, string? password, owned GnomeKeyring.OperationGetIntCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result set_network_password_sync (string? keyring, string? user, string? domain, string? server, string? object, string? protocol, string? authtype, uint32 port, string? password, out uint32 item_id);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* store_password (GnomeKeyring.PasswordSchema schema, string? keyring, string display_name, string password, owned GnomeKeyring.OperationDoneCallback callback, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result store_password_sync (GnomeKeyring.PasswordSchema schema, string? keyring, string display_name, string password, ...);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void string_list_free (GLib.List strings);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static void* unlock (string? keyring, string? password, owned GnomeKeyring.OperationDoneCallback callback);
+	[CCode (cheader_filename = "gnome-keyring.h")]
+	public static GnomeKeyring.Result unlock_sync (string? keyring, string? password);
+}
diff --git a/src/libtracker-miner/gnome-password-provider.vala b/src/libtracker-miner/gnome-password-provider.vala
new file mode 100644
index 0000000..42fd7fc
--- /dev/null
+++ b/src/libtracker-miner/gnome-password-provider.vala
@@ -0,0 +1,69 @@
+namespace Tracker {
+	class GnomePasswordProvider : Tracker.PasswordProvider, GLib.Object {
+
+		private const GnomeKeyring.PasswordSchema password_schema = {
+			GnomeKeyring.ItemType.GENERIC_SECRET,
+			{ { "username", GnomeKeyring.AttributeType.STRING },
+			  { "service", GnomeKeyring.AttributeType.STRING },
+			  { null, 0 } }
+		};
+
+		public string name { get { return BACKEND_NAME; }}
+
+		public void store_password (string service, string description, string username, string password) throws PasswordProviderError
+		{
+			GnomeKeyring.Result r = GnomeKeyring.store_password_sync (password_schema, null /* default keyring */, description, password, "username", username, "service", service, null);
+
+			if (r != GnomeKeyring.Result.OK) {
+				throw new PasswordProviderError.SERVICE (_("Couldn't save the password in Gnome Keyring : %s"), GnomeKeyring.result_to_message (r));
+			}
+		}
+
+		public string get_password (string service, out string? username) throws PasswordProviderError
+		{
+			GnomeKeyring.AttributeList attributes = new GnomeKeyring.AttributeList ();
+			attributes.append_string ("service", service);
+
+			var results = new List<GnomeKeyring.Found> ();
+			GnomeKeyring.Result r = GnomeKeyring.find_items_sync (GnomeKeyring.ItemType.GENERIC_SECRET, attributes, out results);
+
+			if (r == GnomeKeyring.Result.OK) {
+				if (results.length () == 0) {
+					throw new PasswordProviderError.NOTFOUND (_("No results found"));
+				}
+
+				for (weak List<GnomeKeyring.Found> l = results.first() ; l != null ; l = l.next) {
+					weak GnomeKeyring.Found f = (GnomeKeyring.Found)l.data;
+					for (int j = 0 ; j < f.attributes.length ; ++j) {
+						weak GnomeKeyring.Attribute a = f.attributes.index (j);
+						if (a.name == "username" && &username != null) {
+							username = a.value.string;
+						}
+					}
+					string *secret = malloc (f.secret.size ()+1);
+					Posix.mlock (secret, f.secret.size ()+1);
+					Memory.copy (secret, f.secret, f.secret.size ()+1);
+					return (owned)secret;
+				}
+			} else if (r == GnomeKeyring.Result.NO_MATCH) {
+				throw new PasswordProviderError.NOTFOUND (_("No results found"));
+			} else {
+				// Throw error
+				throw new PasswordProviderError.SERVICE (_("Couldn't search in Gnome Keyring : %s"), GnomeKeyring.result_to_message (r));
+			}
+
+			// This point shouldn't be reached
+			return "";
+		}
+
+		public void forget_password (string service) throws PasswordProviderError
+		{
+			GnomeKeyring.Result r = GnomeKeyring.delete_password_sync (password_schema, "service", service, "username", username, null);
+			if (r != GnomeKeyring.Result.OK) {
+				// Throw error
+				throw new PasswordProviderError.SERVICE (_("Couldn't delete password from Gnome Keyring : %s"), GnomeKeyring.result_to_message (r));
+			}
+		}
+
+	}
+} // Namespace Tracker
diff --git a/src/libtracker-miner/keyfile-password-provider.vala b/src/libtracker-miner/keyfile-password-provider.vala
new file mode 100644
index 0000000..081cf74
--- /dev/null
+++ b/src/libtracker-miner/keyfile-password-provider.vala
@@ -0,0 +1,85 @@
+namespace Tracker {
+	class KeyFilePasswordProvider : Tracker.PasswordProvider, GLib.Object {
+		private const string BACKEND_NAME = "KeyFile";
+
+		private string PASSWORD_FILE_PATH = GLib.Environment.get_user_config_dir () + "/tracker/passwords.cfg";
+
+		public string name { get { return BACKEND_NAME; }}
+
+		public void store_password (string service, string description, string username, string password) throws PasswordProviderError
+		{
+			GLib.KeyFile password_file = new GLib.KeyFile ();
+
+			try {
+				password_file.load_from_file (PASSWORD_FILE_PATH, GLib.KeyFileFlags.NONE);
+			} catch (Error e) {
+				if (!(e is GLib.FileError.NOENT)) { // Don't throw error if the files does not exist, we'll create it
+					throw new PasswordProviderError.SERVICE (e.message);
+				}
+			}
+
+			password_file.set_string (service, "username", username);
+			password_file.set_string (service, "password", password);
+
+			try {
+				message (PASSWORD_FILE_PATH);
+				FileUtils.set_contents (PASSWORD_FILE_PATH, password_file.to_data ());
+			} catch (Error e) {
+				throw new PasswordProviderError.SERVICE (e.message);
+			}
+		}
+
+		public string get_password (string service, out string? username) throws PasswordProviderError
+		{
+			GLib.KeyFile password_file = new GLib.KeyFile ();
+
+			try {
+				password_file.load_from_file (PASSWORD_FILE_PATH, GLib.KeyFileFlags.NONE);
+			} catch (Error e) {
+				throw new PasswordProviderError.SERVICE (e.message);
+			}
+
+			if (&username != null) {
+				try {
+					username = password_file.get_string (service, "username");
+				} catch (Error e) {
+					throw new PasswordProviderError.NOTFOUND ("Unkown username/password");
+				}
+			}
+
+			string password = null;
+			try {
+				password = password_file.get_string (service, "password");
+				Posix.mlock (password, sizeof(string)*password.length);
+			} catch (Error e) {
+				throw new PasswordProviderError.NOTFOUND ("Unkown username/password");
+			}
+
+			return password;
+		}
+
+		public void forget_password (string service) throws PasswordProviderError
+		{
+			GLib.KeyFile password_file = new GLib.KeyFile ();
+
+			try {
+				password_file.load_from_file (PASSWORD_FILE_PATH, GLib.KeyFileFlags.NONE);
+			} catch (Error e) {
+				throw new PasswordProviderError.SERVICE (e.message);
+			}
+
+			try {
+				password_file.remove_group (service);
+			} catch (Error e) {
+				throw new PasswordProviderError.SERVICE (e.message);
+			}
+
+			try {
+				FileUtils.set_contents (PASSWORD_FILE_PATH, password_file.to_data ());
+			} catch (Error e) {
+				throw new PasswordProviderError.SERVICE (e.message);
+			}
+		}
+
+	}
+} // Namespace Tracker
diff --git a/src/libtracker-miner/password-provider.vala b/src/libtracker-miner/password-provider.vala
new file mode 100644
index 0000000..2b6401e
--- /dev/null
+++ b/src/libtracker-miner/password-provider.vala
@@ -0,0 +1,33 @@
+namespace Tracker {
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public errordomain PasswordProviderError {
+		SERVICE, // The service couldn't be contacted
+		NOTFOUND, // No results were found during a call to get
+	}
+
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public interface PasswordProviderIface : GLib.Object {
+		public abstract void store (string service, string description, string username, string password) throws PasswordProviderError;
+		public abstract string @get (string service, out string? username) throws PasswordProviderError;
+		public abstract void forget (string service, string username) throws PasswordProviderError;
+	}
+
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public class PasswordProvider : GLib.Object {
+		private static PasswordProviderIface _instance = null;
+
+		public static unowned PasswordProviderIface instance ()
+		{
+			if (_instance == null) {
+#if HAVE_GNOMEKEYRING
+				_instance = new GnomePasswordProvider ();
+#else
+				critical ("No password storage backend defined at compile time");
+#endif
+			}
+
+			assert (_instance != null);
+			return _instance;
+		}
+	}
+}
diff --git a/src/libtracker-miner/test/password-provider-test.c b/src/libtracker-miner/test/password-provider-test.c
new file mode 100644
index 0000000..80fdeac
--- /dev/null
+++ b/src/libtracker-miner/test/password-provider-test.c
@@ -0,0 +1,56 @@
+#include "config.h"
+#include <libtracker-miner/tracker-password-provider.h>
+
+#define SERVICE_NAME "TestService"
+
+int main (int argc, char **argv)
+{
+	g_type_init ();
+	g_set_application_name ("PasswordBackendTest");
+
+	TrackerPasswordProvider *p = tracker_password_provider_get_password_provider ();
+
+	GError *error = NULL;
+	tracker_password_provider_store_password (p, 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;
+	}
+
+	gchar *username = NULL;
+
+	gchar *password = tracker_password_provider_get_password (p, SERVICE_NAME, &username, &error);
+
+	if (error) {
+		g_critical ("tracker_password_provider_get: %s", error->message);
+		g_error_free (error);
+
+		return 1;
+	} else {
+		g_message ("Username: %s , Password:%s", username, password);
+	}
+
+	g_free (username);
+	username = NULL;
+	g_free (password);
+
+	// Also test without getting the username
+	password = tracker_password_provider_get_password (p, SERVICE_NAME, NULL, &error);
+
+	if (error) {
+		g_critical ("tracker_password_provider_get: %s", error->message);
+		g_error_free (error);
+
+		return 1;
+	} else {
+		g_message ("Username: %s , Password:%s", username, password);
+	}
+
+	g_free (username);
+	g_free (password);
+	g_free (p);
+	return 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..bb3c327
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-0.7.vapi
@@ -0,0 +1,40 @@
+[CCode (cprefix = "Tracker", lower_case_cprefix = "tracker_")]
+namespace Tracker {
+	[Compact]
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner.h")]
+	public abstract class Miner : GLib.Object {
+		public void start ();
+		public int pause (string application, string reason) throws GLib.Error;
+		public bool resume (int cookie) throws GLib.Error;
+		public bool is_started ();
+		public void stop ();
+
+		public async void execute_sparql (string sparql, GLib.Cancellable cancellable);
+		public unowned GLib.PtrArray execute_sparql_finish (GLib.AsyncResult result) throws GLib.Error;
+		public async void execute_update (string sparql, GLib.Cancellable cancellable);
+		public void execute_update_finish (GLib.AsyncResult result) throws GLib.Error;
+		public async void execute_batch_update (string sparql, GLib.Cancellable cancellable);
+		public void execute_batch_update_finish (GLib.AsyncResult result) throws GLib.Error;
+		public async void commit (GLib.Cancellable cancellable);
+		public void commit_finish (GLib.AsyncResult result) throws GLib.Error;
+
+		public static GLib.Quark error_quark ();
+
+		public abstract void error (GLib.Error error);
+		public abstract void paused ();
+		public abstract void progress (string status, double progress);
+		public abstract void resumed ();
+		public abstract void started ();
+		public abstract void stopped ();
+		public abstract void terminated ();
+	}
+
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-dbus.h")]
+	public const string MINER_DBUS_INTERFACE;
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-dbus.h")]
+	public const string MINER_DBUS_NAME_PREFIX;
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-dbus.h")]
+	public const string MINER_DBUS_PATH_PREFIX;
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner.h")]
+	public const string MINER_ERROR_DOMAIN;
+}
diff --git a/src/libtracker-miner/tracker-miner-web-0.7.vapi b/src/libtracker-miner/tracker-miner-web-0.7.vapi
new file mode 100644
index 0000000..55b550a
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web-0.7.vapi
@@ -0,0 +1,40 @@
+[CCode (cprefix = "Tracker", lower_case_cprefix = "tracker_")]
+namespace Tracker {
+
+	public errordomain MinerWebError {
+		WRONG_CREDENTIALS,
+		TOKEN_EXPIRED,
+		NO_CREDENTIALS,
+		KEYRING,
+		SERVICE,
+		TRACKER
+	}
+
+	[Compact]
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public abstract class MinerWeb : Miner {
+		public abstract void authenticate () throws GLib.Error;
+		public abstract GLib.HashTable<string, string> get_association_data () throws GLib.Error;
+		public abstract void associate (GLib.HashTable<string, string> association_data) throws GLib.Error;
+		public abstract void dissociate () throws GLib.Error;
+
+		[CCode (cprefix = "TRACKER_MINER_WEB_")]
+		public enum AssociationStatus {
+			UNASSOCIATED,
+			ASSOCIATED
+		}
+		public AssociationStatus association_status {
+			get {
+				AssociationStatus s;
+				this.get ("association-status", out s);
+				return s;
+			}
+			set {
+				this.set ("association-status", association_status);
+			}
+		}
+	}
+
+	public const string MINER_WEB_DBUS_INTERFACE;
+	public const string MINER_WEB_ERROR_DOMAIN;
+}
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..0141c13
--- /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) 2009, Nokia (urho konttori nokia com)
+ *
+ * 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_authenticate         (TrackerMinerWeb        *miner,
+                                             DBusGMethodInvocation  *context,
+                                             GError                **error);
+void tracker_miner_web_get_association_data (TrackerMinerWeb        *miner,
+                                             DBusGMethodInvocation  *context,
+                                             GError                **error);
+void tracker_miner_web_associate            (TrackerMinerWeb        *miner,
+                                             const GHashTable       *association_data,
+                                             DBusGMethodInvocation  *context,
+                                             GError                **error);
+void tracker_miner_web_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..f680404
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web.c
@@ -0,0 +1,217 @@
+/* -*- 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_WEB)
+
+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;
+	miner->private = 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);
+	switch (param_id) {
+		case PROP_ASSOCIATION_STATUS:
+			miner->private->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);
+	switch (param_id) {
+		case PROP_ASSOCIATION_STATUS:
+			g_value_set_uint (value, miner->private->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_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_authenticate (TrackerMinerWeb        *miner,
+                                DBusGMethodInvocation  *context,
+                                GError                **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	GError *local_error = NULL;
+	TRACKER_MINER_WEB_GET_CLASS (miner)->authenticate (miner, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+	} else {
+		dbus_g_method_return (context);
+	}
+}
+
+void
+tracker_miner_web_get_association_data (TrackerMinerWeb        *miner,
+                                        DBusGMethodInvocation  *context,
+                                        GError                **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	GError *local_error = NULL;
+	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);
+	} else {
+		dbus_g_method_return (context, association_data);
+	}
+}
+
+void
+tracker_miner_web_associate (TrackerMinerWeb        *miner,
+                             const GHashTable       *association_data,
+                             DBusGMethodInvocation  *context,
+                             GError                **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	GError *local_error = NULL;
+	TRACKER_MINER_WEB_GET_CLASS (miner)->associate (miner, association_data, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+	} else {
+		dbus_g_method_return (context);
+	}
+}
+
+void
+tracker_miner_web_dissociate (TrackerMinerWeb        *miner,
+                              DBusGMethodInvocation  *context,
+                              GError                **error)
+{
+	g_assert (TRACKER_IS_MINER_WEB (miner));
+
+	GError *local_error = NULL;
+	TRACKER_MINER_WEB_GET_CLASS (miner)->dissociate (miner, &local_error);
+
+	if (local_error != NULL) {
+		dbus_g_method_return_error (context, local_error);
+	} else {
+		dbus_g_method_return (context);
+	}
+}
+
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..2672d43
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
+ *
+ * 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>
+
+G_BEGIN_DECLS
+
+#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))
+
+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;
+	/*< private >*/
+	TrackerMinerWebPrivate *private;
+};
+
+/**
+ * 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);
+
+G_END_DECLS
+
+#endif /* __TRACKER_MINER_WEB_H__ */
diff --git a/src/libtracker-miner/tracker-miner-web.vala b/src/libtracker-miner/tracker-miner-web.vala
new file mode 100644
index 0000000..0d8f482
--- /dev/null
+++ b/src/libtracker-miner/tracker-miner-web.vala
@@ -0,0 +1,34 @@
+namespace Tracker {
+
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	[DBus (name = "org.freedesktop.Tracker1.MinerWebError")]
+	public errordomain MinerWebError {
+		WRONG_CREDENTIALS, // Wrong credentials
+		TOKEN_EXPIRED, // Token expired, need to associate again
+		NO_CREDENTIALS, // No credentials found in the keyring
+		KEYRING, // Error contacting the keyring
+		SERVICE, // Error contacting the web service
+		TRACKER // Error contacting Tracker
+	}
+
+	[DBus (name = "org.freedesktop.Tracker1.MinerWeb")]
+	public interface MinerWebIface : GLib.Object {
+		public abstract void Authenticate () throws DBus.Error, MinerWebError;
+	}
+
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public abstract class MinerWeb : Tracker.Miner, Tracker.MinerWebIface {
+		public abstract void Authenticate () throws DBus.Error, MinerWebError;
+		public abstract HashTable<string, string> AssociationData () throws DBus.Error, MinerWebError;
+		public abstract void Associate (HashTable<string, string> data) throws DBus.Error, MinerWebError;
+
+		public enum AssociationStatus {
+			ASSOCIATED,
+			UNASSOCIATED
+		}
+
+		public signal void AssociationStatusChanged (AssociationStatus s);
+		public abstract AssociationStatus GetAssociationStatus () throws DBus.Error;
+	}
+
+} // namespace Tracker
diff --git a/src/libtracker-miner/tracker-password-provider.vala b/src/libtracker-miner/tracker-password-provider.vala
new file mode 100644
index 0000000..100f5ac
--- /dev/null
+++ b/src/libtracker-miner/tracker-password-provider.vala
@@ -0,0 +1,32 @@
+namespace Tracker {
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public errordomain PasswordProviderError {
+		SERVICE, // The service couldn't be contacted
+		NOTFOUND, // No results were found during a call to get
+	}
+
+	private static PasswordProvider _password_provider_instance = null;
+
+	[CCode (cheader_filename = "libtracker-miner/tracker-miner-web.h")]
+	public interface PasswordProvider : GLib.Object {
+		public abstract string name { get; }
+		public abstract void store_password (string service, string description, string username, string password) throws PasswordProviderError;
+		public abstract string @get_password (string service, out string? username) throws PasswordProviderError;
+		public abstract void forget_password (string service) throws PasswordProviderError;
+
+		public static PasswordProvider password_provider {
+			get {
+				if (_password_provider_instance == null) {
+#if HAVE_GNOME_KEYRING
+					_password_provider_instance = new GnomePasswordProvider ();
+#else
+					_password_provider_instance = new KeyFilePasswordProvider ();
+#endif
+				}
+
+				assert (_password_provider_instance != null);
+				return _password_provider_instance;
+			}
+		}
+	}
+}



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