static gboolean
sysroot_transform_transaction_to_attrs (GBinding *binding,
                                        const GValue *src_value,
                                        GValue *dst_value,
                                        gpointer user_data)
{
  RpmostreedTransaction *transaction;
  GVariant *variant;
  const char *method_name = "";
  const char *path = "";
  const char *sender_name = "";

  transaction = g_value_get_object (src_value);

  if (transaction != NULL)
    {
      GDBusMethodInvocation *invocation;

      invocation = rpmostreed_transaction_get_invocation (transaction);
      method_name = g_dbus_method_invocation_get_method_name (invocation);
      path = g_dbus_method_invocation_get_object_path (invocation);
      sender_name = g_dbus_method_invocation_get_sender (invocation);
    }

  variant = g_variant_new ("(sss)", method_name, sender_name, path);

  g_value_set_variant (dst_value, variant);

  return TRUE;
}
static gboolean
collection_method_search_items (GkdExportedCollection *skeleton,
				GDBusMethodInvocation *invocation,
				GVariant *attributes,
				GkdSecretObjects *self)
{
	return gkd_secret_objects_handle_search_items (self, invocation, attributes,
						       g_dbus_method_invocation_get_object_path (invocation),
						       FALSE);
}
static GckObject *
secret_objects_lookup_gck_object_for_invocation (GkdSecretObjects *self,
						 GDBusMethodInvocation *invocation)
{
	GError *error = NULL;
	GckObject *object;

	object = secret_objects_lookup_gck_object_for_path (self,
							    g_dbus_method_invocation_get_sender (invocation),
							    g_dbus_method_invocation_get_object_path (invocation),
							    &error);

	if (!object)
		g_dbus_method_invocation_take_error (invocation, error);

	return object;
}
static gboolean
collection_method_create_item (GkdExportedCollection *skeleton,
			       GDBusMethodInvocation *invocation,
			       GVariant *properties,
			       GVariant *secret_variant,
			       gboolean replace,
			       GkdSecretObjects *self)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckSession *pkcs11_session = NULL;
	GkdSecretSecret *secret = NULL;
	GckAttributes *attrs = NULL;
	const GckAttribute *fields;
	GckObject *item = NULL;
	const gchar *base;
	GError *error = NULL;
	gchar *path = NULL;
	gchar *identifier;
	gboolean created = FALSE;
	GckObject *object;

	object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
	if (!object) {
		return TRUE;
	}

	if (!gkd_secret_property_parse_all (properties, SECRET_ITEM_INTERFACE, &builder)) {
		g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_INVALID_ARGS,
							       "Invalid properties argument");
		goto cleanup;
	}

	base = g_dbus_method_invocation_get_object_path (invocation);
	secret = gkd_secret_secret_parse (self->service, g_dbus_method_invocation_get_sender (invocation),
					  secret_variant, &error);

	if (secret == NULL) {
		g_dbus_method_invocation_take_error (invocation, error);
		error = NULL;
		goto cleanup;
	}

	if (!gkd_secret_util_parse_path (base, &identifier, NULL))
		g_return_val_if_reached (FALSE);
	g_return_val_if_fail (identifier, FALSE);

	pkcs11_session = gck_object_get_session (object);
	g_return_val_if_fail (pkcs11_session, FALSE);

	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));

	if (replace) {
		fields = gck_attributes_find (attrs, CKA_G_FIELDS);
		if (fields)
			item = collection_find_matching_item (self, pkcs11_session, identifier, fields);
	}

	/* Replace the item */
	if (item) {
		if (!gck_object_set (item, attrs, NULL, &error))
			goto cleanup;

	/* Create a new item */
	} else {
		gck_builder_add_all (&builder, attrs);
		gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier);
		gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
		item = gck_session_create_object (pkcs11_session, gck_builder_end (&builder), NULL, &error);
		if (item == NULL)
			goto cleanup;
		created = TRUE;
	}

	/* Set the secret */
	if (!gkd_secret_session_set_item_secret (secret->session, item, secret, &error)) {
		if (created) /* If we created, then try to destroy on failure */
			gck_object_destroy (item, NULL, NULL);
		goto cleanup;
	}

	path = object_path_for_item (base, item);
	gkd_secret_objects_emit_item_created (self, object, path);

	gkd_exported_collection_complete_create_item (skeleton, invocation, path, "/");

cleanup:
	if (error) {
		if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
			g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
								       GKD_SECRET_ERROR_IS_LOCKED,
								       "Cannot create an item in a locked collection");
		else
			g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_FAILED,
							       "Couldn't create item: %s",
							       egg_error_message (error));
		g_clear_error (&error);
	}

	gkd_secret_secret_free (secret);
	gck_attributes_unref (attrs);
	if (item)
		g_object_unref (item);
	if (pkcs11_session)
		g_object_unref (pkcs11_session);
	g_free (path);
	g_object_unref (object);

	return TRUE;
}