tracker-0.16.2/src/libtracker-miner/tracker-miner-web.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found tracker-miner-web.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * Copyright (C) 2009, Adrien Bustany <abustany@gnome.org>
  3  *
  4  * This library is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2.1 of the License, or (at your option) any later version.
  8  *
  9  * This library is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with this library; if not, write to the
 16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17  * Boston, MA  02110-1301, USA.
 18  */
 19 
 20 #include "config.h"
 21 
 22 #include <libtracker-common/tracker-dbus.h>
 23 
 24 #include "tracker-miner-web.h"
 25 #include "tracker-miner-dbus.h"
 26 
 27 /* Introspection data for the service we are exporting */
 28 static const gchar introspection_xml[] =
 29   "<node>"
 30   "  <interface name='org.freedesktop.Tracker1.Miner.Web'>"
 31   "    <method name='Authenticate' />"
 32   "    <method name='GetAssociationData'>"
 33   "      <arg name='result' type='a{ss}' direction='out' />"
 34   "    </method>"
 35   "    <method name='Associate'>"
 36   "      <arg name='data' type='a{ss}' direction='in' />"
 37   "    </method>"
 38   "    <method name='Dissociate' />"
 39   "    <property name='Associated' type='b' access='read' />"
 40   "  </interface>"
 41   "</node>";
 42 
 43 /**
 44  * SECTION:tracker-miner-web
 45  * @short_description: Abstract base class for miners using web services
 46  * @include: libtracker-miner/tracker-miner.h
 47  *
 48  * #TrackerMinerWeb is an abstract base class for miners retrieving data
 49  * from web services. It's a very thin layer above #TrackerMiner, only
 50  * adding virtual methods needed to handle association with the remote
 51  * service.
 52  **/
 53 
 54 #define TRACKER_MINER_WEB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_WEB, TrackerMinerWebPrivate))
 55 
 56 struct TrackerMinerWebPrivate {
 57 	gboolean associated;
 58 	GDBusNodeInfo *introspection_data;
 59 	guint registration_id;
 60 };
 61 
 62 enum {
 63 	PROP_0,
 64 	PROP_ASSOCIATED
 65 };
 66 
 67 static void       miner_web_set_property        (GObject                *object,
 68                                                  guint                   param_id,
 69                                                  const GValue           *value,
 70                                                  GParamSpec             *pspec);
 71 static void       miner_web_get_property        (GObject                *object,
 72                                                  guint                   param_id,
 73                                                  GValue                 *value,
 74                                                  GParamSpec             *pspec);
 75 static void       miner_web_initable_iface_init (GInitableIface         *iface);
 76 static gboolean   miner_web_initable_init       (GInitable              *initable,
 77                                                  GCancellable           *cancellable,
 78                                                  GError                **error);
 79 static void       miner_web_finalize            (GObject                *object);
 80 static void       handle_method_call            (GDBusConnection        *connection,
 81                                                  const gchar            *sender,
 82                                                  const gchar            *object_path,
 83                                                  const gchar            *interface_name,
 84                                                  const gchar            *method_name,
 85                                                  GVariant               *parameters,
 86                                                  GDBusMethodInvocation  *invocation,
 87                                                  gpointer                user_data);
 88 static GVariant  *handle_get_property           (GDBusConnection        *connection,
 89                                                  const gchar            *sender,
 90                                                  const gchar            *object_path,
 91                                                  const gchar            *interface_name,
 92                                                  const gchar            *property_name,
 93                                                  GError                **error,
 94                                                  gpointer                user_data);
 95 static gboolean   handle_set_property           (GDBusConnection        *connection,
 96                                                  const gchar            *sender,
 97                                                  const gchar            *object_path,
 98                                                  const gchar            *interface_name,
 99                                                  const gchar            *property_name,
100                                                  GVariant               *value,
101                                                  GError                **error,
102                                                  gpointer                user_data);
103 
104 static GInitableIface* miner_web_initable_parent_iface;
105 
106 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TrackerMinerWeb, tracker_miner_web, TRACKER_TYPE_MINER,
107                                   G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
108                                                          miner_web_initable_iface_init));
109 
110 static void
111 tracker_miner_web_class_init (TrackerMinerWebClass *klass)
112 {
113 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
114 
115 	object_class->finalize     = miner_web_finalize;
116 	object_class->set_property = miner_web_set_property;
117 	object_class->get_property = miner_web_get_property;
118 
119 	g_object_class_install_property (object_class,
120 	                                 PROP_ASSOCIATED,
121 	                                 g_param_spec_boolean ("associated",
122 	                                                       "Associated",
123 	                                                       "Tells if the miner is associated with the remote service",
124 	                                                       FALSE,
125 	                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
126 
127 	g_type_class_add_private (object_class, sizeof (TrackerMinerWebPrivate));
128 }
129 
130 static void
131 tracker_miner_web_init (TrackerMinerWeb *miner)
132 {
133 	miner->priv = TRACKER_MINER_WEB_GET_PRIVATE (miner);
134 }
135 
136 static void
137 miner_web_initable_iface_init (GInitableIface *iface)
138 {
139 	miner_web_initable_parent_iface = g_type_interface_peek_parent (iface);
140 	iface->init = miner_web_initable_init;
141 }
142 
143 static gboolean
144 miner_web_initable_init (GInitable     *initable,
145                          GCancellable  *cancellable,
146                          GError       **error)
147 {
148 	TrackerMiner *miner;
149 	TrackerMinerWeb *mw;
150 	GError *inner_error = NULL;
151 	GDBusInterfaceVTable interface_vtable = {
152 		handle_method_call,
153 		handle_get_property,
154 		handle_set_property
155 	};
156 
157 	miner = TRACKER_MINER (initable);
158 	mw = TRACKER_MINER_WEB (initable);
159 
160 	/* Chain up parent's initable callback before calling child's one */
161 	if (!miner_web_initable_parent_iface->init (initable, cancellable, &inner_error)) {
162 		g_propagate_error (error, inner_error);
163 		return FALSE;
164 	}
165 
166 	/* Setup web-interface introspection data */
167 	mw->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, &inner_error);
168 	if (!mw->priv->introspection_data) {
169 		g_propagate_error (error, inner_error);
170 		return FALSE;
171 	}
172 
173 	g_message ("Registering Web interface in D-Bus object...");
174 	g_message ("  Path:'%s'", tracker_miner_get_dbus_full_path (miner));
175 	g_message ("  Object Type:'%s'", G_OBJECT_TYPE_NAME (initable));
176 
177 	mw->priv->registration_id =
178 		g_dbus_connection_register_object (tracker_miner_get_dbus_connection (miner),
179 		                                   tracker_miner_get_dbus_full_path (miner),
180 		                                   mw->priv->introspection_data->interfaces[0],
181 		                                   &interface_vtable,
182 		                                   mw,
183 		                                   NULL,
184 		                                   &inner_error);
185 	if (inner_error) {
186 		g_propagate_error (error, inner_error);
187 		g_prefix_error (error,
188 		                "Could not register the D-Bus object %s. ",
189 		                tracker_miner_get_dbus_full_path (miner));
190 		return FALSE;
191 	}
192 
193 	/* No need to RequestName again as already done by the parent TrackerMiner object */
194 
195 	return TRUE;
196 }
197 
198 static void
199 miner_web_set_property (GObject      *object,
200                         guint         param_id,
201                         const GValue *value,
202                         GParamSpec   *pspec)
203 {
204 	TrackerMinerWebPrivate *priv;
205 
206 	priv = TRACKER_MINER_WEB_GET_PRIVATE (object);
207 
208 	switch (param_id) {
209 	case PROP_ASSOCIATED:
210 		priv->associated = g_value_get_boolean (value);
211 		g_object_notify (object, "associated");
212 		break;
213 	default:
214 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
215 		break;
216 	}
217 }
218 
219 static void
220 miner_web_get_property (GObject    *object,
221                         guint       param_id,
222                         GValue     *value,
223                         GParamSpec *pspec)
224 {
225 	TrackerMinerWebPrivate *priv;
226 
227 	priv = TRACKER_MINER_WEB_GET_PRIVATE (object);
228 
229 	switch (param_id) {
230 	case PROP_ASSOCIATED:
231 		g_value_set_boolean (value, priv->associated);
232 		break;
233 	default:
234 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
235 		break;
236 	}
237 }
238 
239 static void
240 miner_web_finalize (GObject *object)
241 {
242 	TrackerMinerWebPrivate *priv;
243 
244 	priv = TRACKER_MINER_WEB_GET_PRIVATE (object);
245 
246 	if (priv->registration_id != 0) {
247 		g_dbus_connection_unregister_object (tracker_miner_get_dbus_connection (TRACKER_MINER (object)),
248 		                                     priv->registration_id);
249 	}
250 
251 	if (priv->introspection_data) {
252 		g_dbus_node_info_unref (priv->introspection_data);
253 	}
254 
255 	G_OBJECT_CLASS (tracker_miner_web_parent_class)->finalize (object);
256 }
257 
258 static void
259 handle_method_call_authenticate (TrackerMinerWeb       *miner,
260                                  GDBusMethodInvocation *invocation,
261                                  GVariant              *parameters)
262 {
263 	GError *local_error = NULL;
264 	TrackerDBusRequest *request;
265 
266 	request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__);
267 
268 	TRACKER_MINER_WEB_GET_CLASS (miner)->authenticate (miner, &local_error);
269 
270 	if (local_error != NULL) {
271 		tracker_dbus_request_end (request, local_error);
272 
273 		g_dbus_method_invocation_return_gerror (invocation, local_error);
274 
275 		g_error_free (local_error);
276 	} else {
277 		tracker_dbus_request_end (request, NULL);
278 		g_dbus_method_invocation_return_value (invocation, NULL);
279 	}
280 }
281 
282 static GVariant*
283 variant_from_hashtable (GHashTable *table)
284 {
285 	GVariantBuilder builder;
286 	GHashTableIter iter;
287 	gpointer key;
288 	gpointer value;
289 
290 	g_hash_table_iter_init (&iter, table);
291 	g_variant_builder_init (&builder, G_VARIANT_TYPE_DICTIONARY);
292 
293 	while (g_hash_table_iter_next (&iter, &key, &value)) {
294 		g_variant_builder_add (&builder, "{?*}",
295 		                       g_variant_new_string ((const gchar*) key),
296 		                       g_variant_new_string ((const gchar *) value));
297 	}
298 
299 	return g_variant_ref_sink (g_variant_builder_end (&builder));
300 }
301 
302 static GHashTable*
303 hashtable_from_variant (GVariant *variant)
304 {
305 	GHashTable* table;
306 	GVariantIter iter;
307 	GVariant* variant1;
308 	GVariant* variant2;
309 
310 	table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
311 	g_variant_iter_init (&iter, variant);
312 
313 	while (g_variant_iter_loop (&iter, "{?*}", &variant1, &variant2)) {
314 		g_hash_table_insert (table,
315 		                     g_variant_dup_string (variant1, NULL),
316 		                     g_variant_dup_string (variant2, NULL));
317 	}
318 
319 	return table;
320 }
321 
322 static void
323 handle_method_call_get_association_data (TrackerMinerWeb       *miner,
324                                          GDBusMethodInvocation *invocation,
325                                          GVariant              *parameters)
326 {
327 	GHashTable *association_data;
328 	GError *local_error = NULL;
329 	TrackerDBusRequest *request;
330 
331 	g_return_if_fail (TRACKER_IS_MINER_WEB (miner));
332 
333 	request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__);
334 
335 	association_data = TRACKER_MINER_WEB_GET_CLASS (miner)->get_association_data (miner, &local_error);
336 
337 	if (local_error != NULL) {
338 		tracker_dbus_request_end (request, local_error);
339 
340 		g_dbus_method_invocation_return_gerror (invocation, local_error);
341 
342 		g_error_free (local_error);
343 	} else {
344 		tracker_dbus_request_end (request, NULL);
345 		g_dbus_method_invocation_return_value (invocation, variant_from_hashtable (association_data));
346 
347 		/* This was commented out before GDBus port too
348 		 * g_hash_table_unref (association_data); */
349 	}
350 }
351 
352 static void
353 handle_method_call_associate (TrackerMinerWeb       *miner,
354                               GDBusMethodInvocation *invocation,
355                               GVariant              *parameters)
356 {
357 	GHashTable *association_data;
358 	GError *local_error = NULL;
359 	TrackerDBusRequest *request;
360 
361 	association_data = hashtable_from_variant (parameters);
362 
363 	request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__);
364 
365 	TRACKER_MINER_WEB_GET_CLASS (miner)->associate (miner, association_data, &local_error);
366 
367 	g_hash_table_unref (association_data);
368 
369 	if (local_error != NULL) {
370 		tracker_dbus_request_end (request, local_error);
371 
372 		g_dbus_method_invocation_return_gerror (invocation, local_error);
373 
374 		g_error_free (local_error);
375 	} else {
376 		tracker_dbus_request_end (request, NULL);
377 		g_dbus_method_invocation_return_value (invocation, NULL);
378 	}
379 }
380 
381 static void
382 handle_method_call_dissociate (TrackerMinerWeb       *miner,
383                                GDBusMethodInvocation *invocation,
384                                GVariant              *parameters)
385 {
386 	GError *local_error = NULL;
387 	TrackerDBusRequest *request;
388 
389 	request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__);
390 
391 	TRACKER_MINER_WEB_GET_CLASS (miner)->dissociate (miner, &local_error);
392 
393 	if (local_error != NULL) {
394 		tracker_dbus_request_end (request, local_error);
395 
396 		g_dbus_method_invocation_return_gerror (invocation, local_error);
397 
398 		g_error_free (local_error);
399 	} else {
400 		tracker_dbus_request_end (request, NULL);
401 		g_dbus_method_invocation_return_value (invocation, NULL);
402 	}
403 }
404 
405 static void
406 handle_method_call (GDBusConnection       *connection,
407                     const gchar           *sender,
408                     const gchar           *object_path,
409                     const gchar           *interface_name,
410                     const gchar           *method_name,
411                     GVariant              *parameters,
412                     GDBusMethodInvocation *invocation,
413                     gpointer               user_data)
414 {
415 	TrackerMinerWeb *miner = user_data;
416 
417 	tracker_gdbus_async_return_if_fail (miner != NULL, invocation);
418 	tracker_gdbus_async_return_if_fail (TRACKER_IS_MINER_WEB (miner), invocation);
419 
420 	if (g_strcmp0 (method_name, "Authenticate") == 0) {
421 		handle_method_call_authenticate (miner, invocation, parameters);
422 	} else
423 	if (g_strcmp0 (method_name, "GetAssociationData") == 0) {
424 		handle_method_call_get_association_data (miner, invocation, parameters);
425 	} else
426 	if (g_strcmp0 (method_name, "Associate") == 0) {
427 		handle_method_call_associate (miner, invocation, parameters);
428 	} else
429 	if (g_strcmp0 (method_name, "Dissociate") == 0) {
430 		handle_method_call_dissociate (miner, invocation, parameters);
431 	} else {
432 		g_assert_not_reached ();
433 	}
434 }
435 
436 static GVariant *
437 handle_get_property (GDBusConnection  *connection,
438                      const gchar      *sender,
439                      const gchar      *object_path,
440                      const gchar      *interface_name,
441                      const gchar      *property_name,
442                      GError          **error,
443                      gpointer          user_data)
444 {
445 	GVariant *ret = NULL;
446 	TrackerMinerWeb *miner = user_data;
447 	TrackerMinerWebPrivate *priv;
448 
449 	priv = TRACKER_MINER_WEB_GET_PRIVATE (miner);
450 
451 	if (g_strcmp0 (property_name, "Associated") == 0) {
452 		ret = g_variant_new ("b", priv->associated);
453 	} else {
454 		g_assert_not_reached ();
455 	}
456 
457 	return ret;
458 }
459 
460 static gboolean
461 handle_set_property (GDBusConnection  *connection,
462                      const gchar      *sender,
463                      const gchar      *object_path,
464                      const gchar      *interface_name,
465                      const gchar      *property_name,
466                      GVariant         *value,
467                      GError          **error,
468                      gpointer          user_data)
469 {
470 	g_assert_not_reached ();
471 	return TRUE;
472 }
473 
474 /**
475  * tracker_miner_web_error_quark:
476  *
477  * Returns: the #GQuark used to identify miner web errors in GError
478  * structures.
479  *
480  * Since: 0.8
481  **/
482 GQuark
483 tracker_miner_web_error_quark (void)
484 {
485 	return g_quark_from_static_string (TRACKER_MINER_WEB_ERROR_DOMAIN);
486 }
487 
488 /**
489  * tracker_miner_web_authenticate:
490  * @miner: a #TrackerMinerWeb
491  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
492  *
493  * Asks @miner to authenticate with a remote service. On failure
494  * @error will be set.
495  *
496  * Since: 0.8
497  **/
498 void
499 tracker_miner_web_authenticate (TrackerMinerWeb  *miner,
500                                 GError          **error)
501 {
502 	g_return_if_fail (TRACKER_IS_MINER_WEB (miner));
503 
504 	TRACKER_MINER_WEB_GET_CLASS (miner)->authenticate (miner, error);
505 }
506 
507 /**
508  * tracker_miner_web_get_association_data:
509  * @miner: a #TrackerMinerWeb
510  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
511  *
512  * Asks @miner to retrieve association_data for. The data returned in
513  * the %GHashTable depends on the @miner implementation and the type
514  * of authentication. See <classname>TrackerMinerWebClass</classname>
515  * for more information.
516  *
517  * Returns: (transfer full): a %GHashTable with the data. On failure @error will be set
518  * and %NULL will be returned.
519  *
520  * Since: 0.8
521  **/
522 GHashTable *
523 tracker_miner_web_get_association_data (TrackerMinerWeb  *miner,
524                                         GError          **error)
525 {
526 	g_return_val_if_fail (TRACKER_IS_MINER_WEB (miner), NULL);
527 
528 	return TRACKER_MINER_WEB_GET_CLASS (miner)->get_association_data (miner, error);
529 }
530 
531 /**
532  * tracker_miner_web_associate:
533  * @miner: a #TrackerMinerWeb
534  * @association_data: a %GHashTable with the data to use for
535  * associating with a remote service.
536  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
537  *
538  * Asks @miner to associate with a remote service using
539  * @association_data. To know what data to put into @association_data,
540  * see <classname>TrackerMinerWebClass</classname> for more
541  * information.
542  *
543  * On failure @error will be set.
544  *
545  * Since: 0.8
546  **/
547 void
548 tracker_miner_web_associate (TrackerMinerWeb  *miner,
549                              GHashTable       *association_data,
550                              GError          **error)
551 {
552 	g_return_if_fail (TRACKER_IS_MINER_WEB (miner));
553 	g_return_if_fail (association_data != NULL);
554 
555 	TRACKER_MINER_WEB_GET_CLASS (miner)->associate (miner, association_data, error);
556 }
557 
558 /**
559  * tracker_miner_web_dissociate:
560  * @miner: a #TrackerMinerWeb
561  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
562  *
563  * Asks @miner to dissociate from a remote service. At this point, the
564  * miner should stop storing any credentials or sensitive information
565  * which could be used to authenticate with the remote service.
566  *
567  * On failure @error will be set.
568  *
569  * Since: 0.8
570  **/
571 void
572 tracker_miner_web_dissociate (TrackerMinerWeb   *miner,
573                               GError           **error)
574 {
575 	g_return_if_fail (TRACKER_IS_MINER_WEB (miner));
576 
577 	TRACKER_MINER_WEB_GET_CLASS (miner)->dissociate (miner, error);
578 }